Sensors

Sensors are used to compute the kinematics of a point of the system. They can compute the following information for a given point:

  • The absolute position vector

  • The absolute rotation matrix of the body on which the point is attached

  • The absolute velocity vector

  • The absolute angular velocity vector of the body

  • The absolute acceleration

  • The absolute angular acceleration vector of the body

  • The Jacobian matrix of the sensor, i.e. the relation between generalized velocities and the sensor velocity and angular velocity

There are two kinds of sensors:

  • S sensor: sensor attached to a given point;

  • F sensor: sensor used to compute external force (see the external force);

Note that there also exist Gen sensor: it is equivalent to S sensors attached on each joint of the system.

Back to the pendulum-spring example

The goal is to capture the vertical acceleration of the point located at the middle of the blue rod.

A sensor has to be placed at the middle of the blue rod

Position of the sensor

Step 1: Draw your multibody system

Open the existing *.mbs file project with MBsysPad:

  • Set back the pendulum joint to independent and the crank joint to dependent;

  • Add an anchor point on the rod and enter its coordinates;

  • Add a sensor to the anchor point:

    • Click on the Sensor button;

    • Click on the anchor point at the end of the rod;

    • A “S” is added next to the anchor point;

    • Click on the “S” to edit its properties and give it a name;

Step 2: Generate your multibody equations

Regenerate the multibody equations with the same options as previously.

You also need to regenerate the user models files.

REMARK:

As it is the first added sensor, you will also need to call again CMake to reconfigure.

Step 3: Write your user function

Edit the user_DrivenJoints function to remove the imposed trajectory of the crank. You can delete or comment the part which imposes the trajectory of the crank.

WARNING:

Imposing the trajectory of an independent or dependent joint will lead to inconsistent results.

In C there are 2 options in order to store the result of a sensor:

  1. During the simulation in the user_dirdyn_loop function (defined in the user_dirdyn.c file);

  2. After the simulation, during the post-process.

    • This method is not explained in the tutorial.

The acceleration is saved in the resultsR/ folder.

Option 1: on-line sensor calculation

  • Open the user_dirdyn.c file

    • You have to include:

      • set_output.h to export the result of the computation in a file.

      • user_all_id.h to retrieve the id of your sensor.

      • mbs_sensor.h to achieve sensor computations.

    • In the user_dirdyn_init function, do nothing:

      • The MbsAux structure initializes one MbsSensor structure, we will use this one.

      • If you need informations from multiple sensors you can either:

        1. Compute one sensor and store the useful information; repeat the operation for the other sensors.

        2. Or declare enough a sensor structure in your User Model, initialized the sensors in the user_dirdyn_init.

    • In the user_dirdyn_loop, calculate the sensor kinematics using the sensor function and save the desired value.

    • In the user_dirdyn_finish, do nothing except if you create an array of sensor in the user_dirdyn_init.

//...
#include "set_output.h"
#include "user_all_id.h"
#include "mbs_sensor.h"
//...

void user_dirdyn_loop(MbsData *mbs_data, MbsDirdyn *mbs_dd)
{
    //...

    int id = RodSensor_id;

    // retrieve the pointer to the sensor structure defined in mbs_aux
    MbsSensor *PtrSensor = mbs_dd->mbs_aux->psens;

    // compute the sensor (position, velocity...)
    mbs_comp_S_sensor(PtrSensor, mbs_data, id);

    // save the vertical acceleration
    set_output(PtrSensor->A[3], "Vertical_Acc");

    //...
}

REMARK:

The calculation of sensor kinematics can be done in any user function if it is useful for defining the constitutive law, see hereafter. Note that this way of doing is not very efficient.

To compute a force sensor use the function mbs_comp_F_sensor.

If you compute multiple sensors in the same pointer, you should call init_sensor(…) to reset all fields to 0.0. Without this, you could keep some value computed in the previous sensor in memory.

The following solution should also work:

#include "mbs_sensor.h"
#include "mbs_project_interface.h"
...
...
...
MbsSensor *psens = mbs_new_sensor(mbs_data); // Creation of a pointer to a sensor struct.
mbs_sensor(psens, mbs_data, RodSensor_id);   // Compute the sensor
printf("%f", psens->P[1])                    // Print the X position (for example)
mbs_delete_sensor(psens);                    // Free the memory (always better)

REMARK:

An equivalent function exists to directly save a vector in a file, see set_output_vector and set_output_vector_from_id in doc of mbsysc.

Check the results

Plot the graph of the sensor acceleration (results ares available in resultsR/ folder) and check your results with the following graph. The evolution of the system is the same as for the Cuts part of the tutorial

Plot the time history of the sensor acceleration of the pendulum spring example

Time history of the joint position