User model structures¶
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:
typedef struct MyUserModelStructure{
int damping;
} MyUmStruct;
or under another form:
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.
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:
#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
/* 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):
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:
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:
#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:
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:
/* FREE the custom structure */
void mbs_delete_my_user_model_struct(MyUmStruct *usrmod);
void mbs_delete_my_user_model_struct(MyUmStruct *usrmod)
{
//free_sensor(usrmod->???); // do not forget to free any pointer
free(usrmod);
}
In the main:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/* CLOSING OPERATIONS *
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
mbs_delete_my_user_model_struct(mbs_data->user_model->my_user_model.my_user_model_struct);
mbs_delete_data(mbs_data);