Tips and tricks =============== .. container:: matlab .. highlight:: matlab User models ----------- Instead of assigning parameter in the code, parameters values can be introduced via “User Model” in MBsysPad. Back to the spring-pendulum example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal is to store the parameters of the model in the “User Model” and retrieving them in the user function. .. REMARK: Step 4 and 5 are not impacted by theses function. See the *Bodies and joints* part for more information Step 1: Draw your multibody system ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - In MBsysPad, click on “User Model” (under the *joint button*) - Click the upper “Add” button to add a new user model - Give a name to the user model - Add 3 parameters for the spring (K, C, L0) - Click the lower “Add” button to add a parameter - In the right part of the window, give a name and a value to the parameter .. figure:: figure/UserModel_snapshot_Step.png :alt: Steps to add user model in MBsysPad User model gui illustration .. WARNING: Press enter when modifying a parameter value to ensure that the change is correctly taken into account. .. REMARK: User model only serves for storing data. If nothing else is done, they do not modify the behaviour of the system. They must be accessed in user functions to be taken into account. Step 2: Generate your multibody equations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It is not necessary to regenerate the multibody equations after a modification or a creation of user models since the symbolic files are not affected by user models. However, you may need to re-generate the project with CMake to take into account the newly generated user model files. .. REMARK: When modifying a user model parameter in MBsysPad, you must save the model in MBsysPad and reload the model in your code so that the modification take effect. Step 3: Write your user function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The parameters defined in MBsysPad can then be accessed via the mbs data structure in the code. .. container:: matlab - Edit the *user_JointForces* function (open the file from the userfctR subfolder of your project); - Modify the spring-damper law to get the parameter values from the user model: - The attribution of K, C and L0 use ``mbs_data.user_model.Spring.PARAM`` to retrieve the value of the parameter defined in MBsysPad. .. code:: matlab function [Qq] = user_JointForces(mbs_data, tsim) %... % set the joint force in joint 2 id = 2; K = mbs_data.user_model.Spring.K; C = mbs_data.user_model.Spring.C; L0 = mbs_data.user_model.Spring.L0; Qq(id) = - ( K*(mbs_data.q(id)-L0) + C*mbs_data.qd(id) ); %... return Get the ID of a specific joint / body / link / “F sensor” / “S sensor” ---------------------------------------------------------------------- Instead of hardcoding the joint index in user functions, it is possible to get the joint (or another element) index on basis of its name using MBsysLab functions. .. REMARK: Joint numbering in MBsysPad may be modified when modifying the tree structure of the system. Since the user has no full control on the joint numbering, using function to retrieve the ID make the code more robust with respect to topology modifications. Using this function instead of hardcoding the ID may increase the simulation time. Only the function to retrieve a joint ID is illustrated, see the end of the section for the equivalent function. .. _back-to-the-spring-pendulum-example-1: Back to the spring-pendulum example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The model defined in the *Bodies and joints* section is used to illustrate this feature. The goal is to Get the slider joint id via a function in the *user_JointForce* function. .. figure:: figure/PendulumSpringExample.png :alt: The initial example model consists of a pendulum with a mass sliding along Pendulum spring illustration .. REMARK: Step 2, 4 and 5 are not impacted by theses function. See the *Bodies and joints* part for more information. .. _step-1-draw-your-multibody-system-1: Step 1: Draw your multibody system ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Open the existing \*.mbs file project with MBsysPad. - Select the T3 joint (q2) - Give an explicit name to the joint (in this example: “Spring_Slider”) .. figure:: figure/tipsAndTrick_GiveJointName.png :alt: The initial example model consists of a pendulum with a mass sliding along Joint name illustration Save your project. .. _step-3-write-your-user-function-1: Step 3: Write your user function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. container:: matlab - Modify the spring-damper law: - Edit the *user_JointForces* function (open the file from the userfctR subfolder of your project) - Look at the fourth line (“id =”) .. code:: matlab function [Qq] = user_JointForces(mbs_data, tsim) %... % set the joint force in joint named 'Spring_Slider' id = mbs_get_joint_id(MBS_info, 'Spring_Slider'); K = mbs_data.user_model.Spring.K; C = mbs_data.user_model.Spring.C; L0 = mbs_data.user_model.Spring.L0; Qq(id) = - ( K*(mbs_data.q(id)-L0) + C*mbs_data.qd(id) ); %... return .. REMARK: In case you want to retrieve several ids : .. code:: matlab [id_Spring_Slider, id_R2_pendulum] = mbs_get_joint_id(MBS_info, 'Spring_Slider', 'R2_pendulum'); Equivalent function for other element ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. container:: matlab .. code:: matlab %... % The *_Name refers to the name of the element defined in MBsysPad Joint_ID = mbs_get_joint_id(MBS_info, 'Joint_Name'); Body_ID = mbs_get_body_id(MBS_info, 'Body_Name'); Link_ID = mbs_get_link_id(MBS_info, 'Link_Name'); F_Sensor_ID = mbs_get_F_sensor_id(MBS_info, 'F_Sensor_Name'); S_Sensor_ID = mbs_get_S_sensor_id(MBS_info, 'S_Sensor_Name'); %... return Initial conditions ------------------ The initial condition `previously defined in MBsysPad <./bodiesJoint.html>`__ can also be defined in the code after project loading. .. REMARK: Step 1, 2, 3 and 5 are not impacted by theses modifications. .. _back-to-the-spring-pendulum-example-2: Back to the spring-pendulum example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal is to modify in the main script the initial rotation and rotationnal speed of the pendulum. Step 4: Run your simulation ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. container:: matlab - Open the exe_template.m file and add the following command - After the project loading (*mbs_load* function) - Before the coordinate partitioning (*mbs_exe_part* function) and time integration (*mbs_exe_didryn* function) .. code:: matlab %... % Define the initial condition of the joint 1 (rotation of the pendulum) Joint_ID = 1; mbs_data.q(Joint_ID) = 0.2; % The initial rotation of the pendulum is set to 0.2 rad mbs_data.qd(Joint_ID) = 0.01; % The initial angular velocity of the pendulum is set to 0.01 rad/s %... .. REMARK: If you change the value of an independent joint involved in a kinematic loop, you can fail to close the loop (max Newton-Raphson iteration reached). If you change the value of a dependent joint, you only change the initial configuration of the Newton-Raphson iteration. MBsysPad 2D diagram manipulation -------------------------------- Moving several elements at once ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Press the SHIFT key to move a component and all its descendence. Moving the base while pressing SHIFT will move all the drawing. .. figure:: figure/tipsTrick_snapshot_moveSubTree.png :alt: Press the SHIFT key to move a component and all its descendence Moving a component and all its descendence Modifying the attach point of a body, joint, anchor point, sensor… ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Select the element (body, joint, anchor point, sensor…) you want to modify. A small grey square appears next to the attach point of your element. Click on it (and keep the button pressed) and move the the mouse to the desired attach point. .. figure:: figure/tipsTrick_snapshot_modifyTree.png :alt: Use the small grey square to modify the attach point Modifying the attach point of a body, joint, anchor point, sensor .. REMARK: The attach point is colored in red while moving the mouse. Check that you have reached the desired location. Saving a custom quantity ------------------------ It is often useful to get the time history of a custom variable which is not contained by default in the result structure returned by the direct dynamics module. The variables contained by default are: - The position, velocity and acceleration of each joint at each time step - The state vectors at each time step (see `User derivatives <./userDerivatives.html>`__ if you don’t know what are state vectors) The way to save custom quantity highly differs between the codes (Matlab, python, C). .. container:: matlab In matlab this can be done using the *MBS_user* structure and the *user_DirDyn_io* function: - The *MBS_user* is declared as global, so it is accessible in all functions. - The *user_DirDyn_io* function is called at each valid time step of the solution (and not in internal time step of the integrator, or invalid time step due to the adaptive strategy of the integrator). The principle is the following: - During a time step, the quantity is saved to the MBS_user.curvar structure. This can be done in the *user_function* where the quantity is calculated. - The quantity is copied from the *MBS_user.curvar* structure to the *MBS_user.resdirdyn* structure in a vector containing all the values for each time step. .. _back-to-the-spring-pendulum-example-3: Back to the spring-pendulum example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal is to store the spring force and the damper force of the link. .. REMARK: Step 1, 2, 4 and 5 are not impacted by theses modifications. .. _step-3-write-your-user-function-2: Step 3: Write your user function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. container:: matlab - Open the user_LinkForces file and add the values in the *MBS_user.curvar* structure .. code:: matlab function Flink = user_LinkForces(Z,Zd,mbs_data,tsim,ilnk) %... switch(ilnk) case L1 %... Flink = K*(Z-Z0)+C*Zd; % Save the spring and damper forces: MBS_user.curvar.Fspring = K*(Z-Z0); MBS_user.curvar.Fdamper = C*Zd; %... - Open the user_dirDyn_io file: - In the ‘init’ case (“process starting”), initialize the result vectors. - In the ‘else’ part (“process running”), save the desired value. .. code:: matlab function [] = user_DirDyn_io(mbs_data,tsim,step,flag) %... if (nargin > 3) % process starting switch flag case 'init' MBS_user.resdirdyn.tsim = zeros(step,1); MBS_user.resdirdyn.FLinkSpr = zeros(step,1); MBS_user.resdirdyn.FLinkDamp = zeros(step,1); otherwise % unused ; end else % process running MBS_user.resdirdyn.tsim(step) = tsim; MBS_user.resdirdyn.FLinkSpr(step) = MBS_user.curvar.Fspring; MBS_user.resdirdyn.FLinkDamp(step) = MBS_user.curvar.Fdamper; end %... The results are accessible via the *MBS_user.resdirdyn* structure: - *MBS_user.resdirdyn.tsim*: the time - *MBS_user.resdirdyn.FLinkSpr*: the value of the variable at the correspondig time Integrator ---------- Integrator type ~~~~~~~~~~~~~~~ .. container:: matlab With MBsysLab, you can use the integrator provided by matlab by setting the field ``odemethod`` in the ``MBS_dirdyn_opt`` structure. Please refer to the `MBsysLab documentation `__. Force the integrator to pass at specific time value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. container:: matlab With MBsysLab, you select the time steps you want the results by setting the field ``time`` in the ``MBS_dirdyn_opt`` structure. Please refer to the `MBsysLab documentation `__.