Tips and tricks

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 retriving 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
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.

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.

Python section:

  • 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 the function get_user_model(‘Spring’, ‘PARAM’) to retrieve the value of the parameter defined in MBsysPad.
def user_JointForces(mbs,tsim):
   #...

   # set the joint force in joint 2
   id = 2
   K = mbs.get_user_model('Spring', 'K')
   C = mbs.get_user_model('Spring', 'C')
   L0 = mbs.get_user_model('Spring', 'L0')
   mbs.Qq[id] = - ( K*(mbs.q[id]-L0) + C*mbs.qd[id] )

   #...

Initial conditions

The initial condition previously defined in MBsysPad 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

The goal is to modify in the main script the initial rotation and rotationnal speed of the pendulum.

Step 4: Run your simulation

Python section:

  • Open the main.py file and add the following command
    • After the project loading (load() function)
    • Before the coordinate paritioning and time integration (run() function for both but they are called on different python class)
#...

# Define the initial condition of the joint 1 (rotation of the pendulum)
Joint_ID = 1

mbs.q[Joint_ID] = 0.2
# The initial rotation of the pendulum is set to 0.2 rad

mbs.qd[Joint_ID] = 0.01
# The initial angular velocity of the pendulum is set to 0.01 rad/s

#...

REMARK:

The initial conditions are stored in the q0, qd0 and qdd0 vectors at the loading of the .mbs file. If you need to access to q0 (or qd0 or qdd0) during the computation you need to update these values aswell.

REMARK:

If you change the value of an independent joint involved in a kinematic loop, you can fail to close the loop (max Newton-Rapson iteration reached).

If you change the value of a dependent joint, you only change the initial configuration of the Newton-Rapson 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.

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.

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 if you don’t know what are state vectors)

The way to save custom quantity highly differs between the codes (Matlab, python, C).

In python this can be done using the mbs Data and Dirdyn classes.

The principle is the following:

  • During a time step, the quantity is saved in a dictionnary of the mbs Data class. This can be done in the user_function where the quantity is calculated.
  • The quantity is copied from the dictionnary of the mbs Data class to the Result class of the Dirdyn classes containing all the values for each time step.

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

Python section:

  • Open the main.py file and declare the quantity you want to save.
#...
dirdyn=Dirdyn(mbs)
#...

# Adding the output keys in the mbs Data class trough the Dirdyn class.
dirdyn.set_output_other('Fspring')
dirdyn.set_output_other('Fdamper')

#...
  • Edit the link_forces.py file from the userfctR subfolder of your project
def user_LinkForces(Z,Zd,mbs,tsim,identity):
   #...

   Flink = K*(Z-Z0)+C*Zd

   # Save the spring and damper forces
   mbs.add_output_other('Fspring', K*(Z-Z0))
   mbs.add_output_other('Fdamper', C*Zd)
  #...

REMARK:

In python to save a quantity computed by a sensor, you can use the function set_output_sensor in the main.py. The quantity will be automatically saved, you don’t need to call another function in order to add the result at each timestep.

The results are accessible via the dirdyn.result structure:

  • dirdyn.result.timeParam: the time
  • dirdyn.result.paramToSave[‘Fspring’]: the value of the variable at the correspondig time