# User derivatives¶

• It is possible to add additional constitutive equations to the equation of motion
• This can be used to deal with multiphysics problem involving electrical circuits, pneumatics, hydraulics, …
• The additional state equations will be added to the set of mechanical equations
• In practice
• The user must declare the state in a user model
• The user must compute the state derivative equation in the user_Derivatives function
• The state value can be accessed in any user function of the project

## Back to the spring-pendulum example¶

The exercice consists in adding an electrical DC motor to the pendulum example

• The motor will be connected to the revolute joint of the crank
• The motor obeys the following relation
• Electrical circuit equation: $$U_{mot} = R_{mot}*i_{mot}+k_{\phi}*\omega_{mot} + L \frac{di_{mot}}{dt}$$
• Torque equation: $$T_{mot} = k_{\phi} * i_{mot}$$
• A reductor is inserted between the motor and the axle: $$\begin{matrix} T_{axle} = \rho * T_{mot}\\ \omega_{axle} = \omega_{mot}/\rho \end{matrix}$$

The parameter values are:

• $$U_{mot} = 48\ V$$
• $$k_{\phi} = 48.6\ mNm/A$$
• $$\rho = 200$$
• $$R_{mot} = 4.49\ \Omega$$
• $$L = 0.573\ mH$$

### Step 1: Draw your multibody system¶

• Open the PendulumSpring model in MBsysPad
• Add a user model for the motor
• Add a scalar variable for each parameter
• Add a state variable for the current
• Set the nature of the :
• crank joint to independent;
• pendulum joint to dependent;
• If you had modified the joint nature in the code in the previous section you have to update the code, modifications done in MBsysPad are overwritten.

REMARK

Several state variables can be introduced either by introducing several values for a single state variable (state vector) or by defining several parameters with “state” type.

WARNING:

You can have two state variable with the same name in two different user model. However it is recommended to set an unique name for each state variable.

### Step 3: Write your user function¶

Python section:

• Edit the user_Derivatives function and introduce the state equation for the current:
def user_derivatives(y,yd,mbs,tsim):
#...

id_crank = mbs.get_joint_id('R2_crank')
rho = mbs.get_user_model('Motor', 'rho')
U   = mbs.get_user_model('Motor', 'U')
Rmot= mbs.get_user_model('Motor', 'Rmot')
kphi= mbs.get_user_model('Motor', 'Kphi')
L   = mbs.get_user_model('Motor', 'L')

omMot = -mbs.qd[id_crank]*rho
iMot = y[1]
yd[1] = (U-Rmot*iMot-kphi*omMot)/L

#...


REMARK

The user state vector is accessed via the ux field of the mbs Data class

You can access to the ID of a state variable via the get_state_id function. If the state variable is a vector, you retrieve the ID of the first value of the vector.

• Edit the user_JointForces function and introduce the torque equation:
def user_JointForces(mbs,tsim):
#...

id_crank = mbs.get_joint_id('R2_crank')
iMot = mbs.ux[1]
kphi= mbs.get_user_model('Motor', 'Kphi')
rho = mbs.get_user_model('Motor', 'rho')

mbs.Qq[id_crank] = -rho*kphi*iMot

#...
return


The time history of the motor current can be directly plotted from the state field of the dirdyn.result class.

REMARK:

To let the motor rotate freely one may remove the wall (by modifying the external forces).

REMARK:

The resolution of the motor dynamics requires a smaller time step than before. The computation time will increase.

### Check the results¶

Plot the graph of the joint position (results ares avilaible in resultsR/ folder) and check your results with the following graph. Please note that the wall force has been removed.