User model structures --------------------- .. container:: python The user models are introduced in the `Robotran tutorial `__. As a consequence you should have read the `user models part of the tips & tricks `__. **The type structure of the user model is specific to MBsysC**. The type *structure* is dedicated to handle C structure in your multibody system. Such structure may be used to store some parameters of a model which interacts with the multibody system, such as the parameters of a tire for a car. They can also be used to easily share information between different user functions, for example storing a matrix which is computed when the external force are computed and forward the matrix to the joint force computation. Header file and structure declaration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For the sake of simplicity your header file must be located in the project *userfctR/* folder. The file in our tutorial is called *my_user_model_struct.h*. The structure alias is **MyUmStruct**. In this simple example the structure will only have one member and is defined as: .. code:: c typedef struct MyUserModelStructure{ int damping; } MyUmStruct; or under another form: .. code:: c typedef struct MyUserModelStructure MyUmStruct struct MyUserModelStructure{ int damping; }; In this header you should ideally declare the functions used to allocate and free your structure **MyUmStruct**. If you have such functions you should also place the source file(s) related to your function in the project *userfctR/* folder. .. REMARK: It is possible to place the header file in any directory of your computer. However this requires modifications in the CMakeLists.txt files. User model creation ~~~~~~~~~~~~~~~~~~~ In the user model window, add a new parameter (remind that the *Parameters* must be created in an existing *User Model*), for this example we will name our user model *my_user_model*. In the *Parameter properties* change the *Type* to *structure* in the dropdown list. .. figure:: figure/my_user_model_struct.PNG :alt: Fields a user model structure in MBsysPad User model gui In this example we will name this parameter **my_user_model_struct**. In the *Struct. name* field, set the alias of the structure, which is in our example **MyUmStruct**. In the *Header* field, you give the header filename which is *my_user_model_struct.h* in our example. Then a ``MyUmStruct* my_user_model_struct`` pointer is created and available in ``MbsData->user_model->my_user_model.my_user_model_struct``. In our example, you can access the *damping* member with ``MbsData->user_model->my_user_model.my_user_model_struct->damping``. Usage in C function ~~~~~~~~~~~~~~~~~~~ Structure allocation ^^^^^^^^^^^^^^^^^^^^ **MBsysC** does not know how to allocate your structure, it only creates a pointer that you have to feed. The best places to create the structure and fill the pointer is either in the *user_load_post* function (in file *userfctR/user_load.c*) or in your *main* function (file *main.c*). In the file of your choice you have to include at least the header of the user models, of your structure and of MbsData. Then allocate and fill your structure, for example in the file *user_load.c*: .. code:: c #include "mbs_data.h" #include "user_model.h" #include "my_user_model_struct.h" void user_load_post(MbsData *mbs_data) { MyUmStruct *usrmod; usrmod = (MyUmStruct*)malloc(sizeof(MyUmStruct)); usrmod->damping = 1.0; mbs_data->user_model->my_user_model.my_user_model_struct = usrmod; } You may also create a function *mbs_new_my_user_model_struct()* declared in your *my_user_model_struct.h* .. code:: c /* INITIALIZE the custom user Model structure */ MyUmStruct* mbs_new_my_user_model_struct(); and defined in a source file (for example *my_user_model_struct.c*): .. code:: c MyUmStruct* mbs_new_my_user_model_struct() { MyUmStruct *usrmod; usrmod = (MyUmStruct*) malloc(sizeof(MyUmStruct)); usrmod->damping = 1.0; // fill and allocate any variables : damping of the joint return usrmod; } and call this function in *user_load* (or in *main* ) function: .. code:: c void user_load_post(MbsData *mbs_data) { mbs_data->user_model->my_user_model.my_user_model_struct = mbs_new_my_user_model_struct(); printf(" Custom user_model structure initialized!\n"); } Accessing to your structure ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Any function that has the structure ``MbsData`` in argument can access to you structure (meaning all user functions of a MBsysC project). All you have to do is to include the following three headers: .. code:: c #include "mbs_data.h" #include "user_model.h" #include "my_user_model_struct.h" And then in the function of your choice the structure is: .. code:: c mbs_data->user_model->my_user_model.my_user_model_struct Freeing your structure ^^^^^^^^^^^^^^^^^^^^^^ **Do not forget to free your stucture** (and so pointor that you could have allocated …) *!* The best place to do so is at the end of the *main* file. For a function *delete* declared in your header and defined in a source file: .. code:: c /* FREE the custom structure */ void mbs_delete_my_user_model_struct(MyUmStruct *usrmod); .. code:: c void mbs_delete_my_user_model_struct(MyUmStruct *usrmod) { //free_sensor(usrmod->???); // do not forget to free any pointer free(usrmod); } In the *main*: .. code:: c /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* CLOSING OPERATIONS * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ mbs_delete_my_user_model_struct(mbs_data->user_model->my_user_model.my_user_model_struct); mbs_delete_data(mbs_data);