User model Look-Up-Tables ------------------------- .. container:: python c-code .. container:: c-code 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 *lut1D* and *lut2D* are dedicated to handle a look-up-table in your multibody system. Such table may be used to compute of the force in an actuator whose behavior is not given by a function but by data points: - The 1D look-up-tables interpol a unique value based on the value of 1 parameter: ``y=f(x)``. - The 2D look-up-tables interpol a unique value based on the value of 2 parameters: ``z=f(x, y)``. .. rubric:: 1D look up table: File definition :name: d-look-up-table-file-definition The content of the file have to respect the following: 1. The first line (maximum 256 characters): the human-readable description of the file content. This line is skipped by the software, but must be present (even if empty). 2. The second line (an integer): number of point in the look-up-table. 3. The third line (floats separated by space): the coordinate of the table. 4. The fourth line (floats separated by space): the value of the function. For example the file below implement the look-up-table representing ``y=x^2``. This simple txt file will be saved as **x_pow_2.MbsLut1D**. .. code:: text This file computes y=x^2 between -5 and 5 at each integer value 11 -5.0 -4.0 -3 -2 -1 0 1 +2.0 3 4 5 25.0 16.0 9 4 1 0 1 4 9 16 25.0 The coordinates of the data points must be strictly increasing. .. rubric:: 2D look up table: File definition :name: d-look-up-table-file-definition-1 The content of the file have to respect the following: 1. The first line (maximum 256 characters): the human-readable description of the file content. This line is skipped by the software, but must be present (even if empty). 2. The second line (two integers separated by space): number of ``x`` (called ``nx``) then ``y`` (called ``ny``) evaluated values. 3. The third line (``ny`` floats separated by space): the coordinates ``y`` of the table. 4. The next ``nx`` lines (each line is ``ny + 1`` floats separated by space): the coordinate ``x`` then the ``ny`` function value ``z`` For example the file below implement the look-up-table representing ``z=x^2 + y``. This simple txt file will be saved as **x_pow_2_plus_y.MbsLut2D**. .. code:: text This file computes z=x^2 + y for x between (-5;5) and y between(0;3) at each integer value 11 4 0 1 2 3 -5.0 25 26 27 28 -4.0 16 17 18 19 -3 9 10 11 12 -2 4 5 6 7 -1 1 2 3 4 0 0 1 2 3 1 1 2 3 4 +2.0 4 5 6 7 3 9 10 11 12 4 16 17 18 19 5 25 26 27 28 The coordinates of the data points (``x`` and ``y``) must be strictly increasing. .. rubric:: User model creation :name: 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 *lut1D* in the dropdown list. .. figure:: figure/my_user_model_lut1D.PNG :alt: Fields a user model 1D look-up-table in MBsysPad User model gui, for 1D look-up-table In this example we will name this parameter **my_lut_1D**. In the *File* field, set the file (including the path) to the table to be loaded, which is in our example **x_pow_2.Lut1D**. For a 2D look-up-table use: - *Type*: *lut2D* - *name*: **my_lut_2D** - *file*: **x_pow_2_plus_y.Lut2D** .. container:: c-code For memory, you have to save the model and then generate the user model file after the creation of a user model or its suppression or any change of type. The change of the values does not require a new generation. Then a ``MbsLut1D* my_lut_1D`` pointer is created and the table in loaded with the multibody system in the memory pointed by ``MbsData->user_model->my_user_model.my_lut_1D``. .. rubric:: 1D look up table: Usage :name: d-look-up-table-usage Please note that the look up table should only be interpolated in the domain defined by the data points. If called outside the domain the current behavior is a linear extrapolation, but this behavior is not guarantee. Any function that has ``MbsData`` as argument can access to the table (meaning all user functions of the project). .. rubric:: Interpolating the table :name: interpolating-the-table .. container:: c-code All you have to do is to include the following header (if not yet included): .. code:: c #include "mbs_data.h" #include "user_model.h" #include "lut.h" And then in the function of your choice retrieve the table and use it: .. code:: c // Retrieve the memory adress of the loaded table: MbsLut1D *my_lut = mbs_data->user_model->my_user_model.my_lut_1D; // Interpol the table at 1.5 double value = 0.0; int my_lut_error = mbs_lut_1D_interp(my_lut, 1.5, &value); // Print the result printf("interpolation of y=x^2 at x=1.5 : %g\n", value); // Or provide the pointer directly int my_lut_error = mbs_lut_1D_interp(mbs_data->user_model->my_user_model.my_lut_1D, 1.5, &value); .. rubric:: Changing the table in memory :name: changing-the-table-in-memory During the computation you can change the file to be stored in the user model. This requires to firstly delete the current table in memory, and then load and assign the new one in the user model. It is not required to free the memory of the newly loaded table as it will be freed with the user models. .. container:: c-code All you have to do is to include the following header (if not yet included): .. code:: c #include "mbs_data.h" #include "user_model.h" #include "lut.h" And then in the function of your choice change the table to be used: .. code:: c // Free the memory currently used by the table. mbs_lut_1D_free(mbs_data->user_model->my_user_model.my_lut_1D); // set pointer to NULL for safety mbs_data->user_model->my_user_model.my_lut_1D = NULL; // Load and assign a new lut, y=x^3 MbsLut1D *my_lut = mbs_lut_1D_load_file("../x_pow_3.Lut1D"); mbs_data->user_model->my_user_model.my_lut_1D = my_lut; // test the new table double value = 0.0; int my_lut_error = mbs_lut_1D_interp(my_lut, 2, &value); // Print the result, should be 8 (=2^3) printf("interpolation of y=x^3 at x=2.0 : %g\n", value); You can also change the value in the array pointed by ``my_lut->x`` and ``my_lut->y`` to edit the look-up-table. And all the function called after this operation will use ``y=x^3`` instead of ``y=x^2``. .. rubric:: 2D look up table: Usage :name: d-look-up-table-usage-1 Please note that the look up table **must** be interpolated in the domain defined by the data points. **If called outside the domain the behavior is undefined**. Any function that has ``MbsData`` as argument can access to the table (meaning all user functions of a the project). .. rubric:: Interpolating the table :name: interpolating-the-table-1 .. container:: c-code All you have to do is to include the following header (if not yet included): .. code:: c #include "mbs_data.h" #include "user_model.h" #include "lut.h" And then in the function of your choice retrieve the table and use it: .. code:: c // Retrieve the memory address of the loaded table: MbsLut2D *my_lut = mbs_data->user_model->my_user_model.my_lut_2D; // Interpol the table at x=1.5, y=0.5 double value = 0.0; int my_lut_error = mbs_lut_2D_interp(my_lut, 1.5, 0.5, &value); // Print the result printf("interpolation of z=x^2+y at x=1.5 and y=0.5 : %g\n", value); // Or provide the pointer directly my_lut_error = mbs_lut_2D_interp(mbs_data->user_model->my_user_model.my_lut_2D, 1.5, 0.5, &value); .. rubric:: Changing the table in memory :name: changing-the-table-in-memory-1 During the computation you can change the file to be stored in the user model. This requires to firstly delete the current table in memory, and then load and assign the new one in the user model. It is not required to free the memory of the newly loaded table as it will be freed with the user models. .. container:: c-code All you have to do is to include the following header (if not yet included): .. code:: c #include "mbs_data.h" #include "user_model.h" #include "lut.h" And then in the function of your choice change the table to be used: .. code:: c // Free the memory currently used by the table. mbs_lut_2D_free(mbs_data->user_model->my_user_model.my_lut_2D); // set pointer to NULL for safety mbs_data->user_model->my_user_model.my_lut_2D = NULL; // Load and assign a new lut, y=x^3 + 2*y // The file must exist. MbsLut2D *my_lut = mbs_lut_2D_load_file("../x_pow_3_plus_2y.Lut2D"); mbs_data->user_model->my_user_model.my_lut_2D = my_lut; // test the new table double value = 0.0; int my_lut_error mbs_lut_2D_interp(my_lut, 2, 5, &value); // Print the result, should be 18 (=2^3+2*5) printf("interpolation of z=x^3+2*y at x=2.0 and y=5 : %g\n", value); You can also change the value in the array pointed by ``my_lut->x``, ``my_lut->y`` and ``my_lut->z`` to edit the look-up-table. And all the function called after this operation will use ``z=x^3+2*y`` instead of ``z=x^2 + y``.