IMU Inverse Kinematics cpp code

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Claudia Pr
Posts: 4
Joined: Fri Jul 19, 2024 2:25 am

IMU Inverse Kinematics cpp code

Post by Claudia Pr » Tue Dec 17, 2024 4:27 am

Hello everyone!
I am working on IMU data analysis in C++ and I have integrated the OpenSim API into my project. Even though there are not many examples online, I tried to figure out how the IMUPlacer and IMUInverseKinematics tools and classes work.
The fact is that what I obtain from my code is slightly different from what I can obtain from the OpenSim GUI Application, and I am not able to understand what I am doing wrong.
Here is the C++ snippet:

Code: Select all

 
        auto modelProcessor = OpenSim::ModelProcessor('Rajagopal_2015.osim');
        OpenSim::Model osimModel = modelProcessor.process();
        osimModel.setName("Rajagopal_2015");
        osimModel.finalizeFromProperties();
        auto imuPlacer = OpenSim::IMUPlacer();
        imuPlacer.set_orientation_file_for_calibration(placement_fileForOpensim);
	imuPlacer.set_base_imu_label(sensorPelvis);
	SimTK::Vec3 imuPlacerRotations(-90, 0, 0);
        imuPlacer.set_sensor_to_opensim_rotations(imuPlacerRotations);
        osimModel.initSystem();
        imuPlacer.setModel(osimModel);
        imuPlacer.run();
	OpenSim::Model outputModel = imuPlacer.getCalibratedModel();
        outputModel.finalizeFromProperties();
        auto inverseKinematics = OpenSim::IMUInverseKinematicsTool();
        inverseKinematics.setModel(outputModel);
        inverseKinematics.set_orientations_file(legmvmnt_fileForOpensim);
        inverseKinematics.set_sensor_to_opensim_rotations(imuPlacerRotations);
	inverseKinematics.set_output_motion_file(output_fileForOpensim);
        inverseKinematics.run(true);
The recorded movement is a short walk, a 180-degree turn, and another short walk in the opposite direction.
If I use the same files for the IMU Placer Tool (Orientation file at placement pose as 'placement_fileForOpensim' and Rotation X set to -90) and for the IMU Inverse Kinematics Tool (Sensor orientation file as 'imuPlacerRotations' and Rotation X set to -90), I obtain the expected movement. However, it seems that the code reconstructs the movement in a different reference frame.
Here are the GUI results: https://youtube.com/shorts/dAPu3CIu2bY?feature=share and the C++ motion result https://youtube.com/shorts/dAPu3CIu2bY. Note that they are both 'frontal view'. I am using OpenSim 4.5

Tags:

User avatar
Claudia Pr
Posts: 4
Joined: Fri Jul 19, 2024 2:25 am

Re: IMU Inverse Kinematics cpp code

Post by Claudia Pr » Wed Jan 08, 2025 4:47 am

can anyone help me?

User avatar
Alexander Bush
Posts: 2
Joined: Fri Nov 15, 2024 4:46 am

Re: IMU Inverse Kinematics cpp code

Post by Alexander Bush » Fri Jan 10, 2025 11:21 am

Hi,
What IMUs are you using and what format is the data in? I am working on a similar project, so interested in your progress and will try to help if I can.
Alex

User avatar
Claudia Pr
Posts: 4
Joined: Fri Jul 19, 2024 2:25 am

Re: IMU Inverse Kinematics cpp code

Post by Claudia Pr » Mon Jan 13, 2025 3:46 am

Hi Alexander,

thank you for your response.
I am using BNO085 IMUs by Bosch, and I saved the quaternion in a data format compatible with OpenSim standards. Both placement_fileForOpensim and legmvmnt_fileForOpensim are ".sto" files.

User avatar
Claudia Pr
Posts: 4
Joined: Fri Jul 19, 2024 2:25 am

Re: IMU Inverse Kinematics cpp code

Post by Claudia Pr » Tue Jan 14, 2025 2:56 am

I can add further information. I am using the same model for both approaches ("<path>/Rajagopal_2015.osim"), but the C++ computed IMU offsets are not the same as the GUI's computed ones:

OpenSim GUI:

Code: Select all

Updating Model file from 40000 to latest format...
Loaded model Rajagopal_2015 from file <path>\Rajagopal_2015.osim
No heading correction is applied.
Processing torso_imu
Computed offset for torso_imu
Offset is 
[0.12018,0.0205795,0.992539]
[-0.992699,0.0128051,0.119934]
[-0.0102414,-0.999706,0.0219682]

Creating offset frame for torso_imu
Added offset frame for torso_imu.
torso_imu offset computed from torso_imu data from file.
Processing pelvis_imu
Computed offset for pelvis_imu
Offset is 
[-0.0956206,-0.746262,0.658749]
[-0.83013,-0.305413,-0.466484]
[0.549309,-0.591453,-0.59029]

Creating offset frame for pelvis_imu
Added offset frame for pelvis_imu.
pelvis_imu offset computed from pelvis_imu data from file.
Processing femur_l_imu
Computed offset for femur_l_imu
Offset is 
[0.142449,0.055014,-0.988272]
[0.986331,0.0756574,0.146381]
[0.0828231,-0.995615,-0.0434847]

Creating offset frame for femur_l_imu
Added offset frame for femur_l_imu.
femur_l_imu offset computed from femur_l_imu data from file.
Processing calcn_r_imu
Computed offset for calcn_r_imu
Offset is 
[0.120766,-0.0875746,0.988811]
[-0.992484,-0.0304822,0.118515]
[0.0197622,-0.995691,-0.0905977]

Creating offset frame for calcn_r_imu
Added offset frame for calcn_r_imu.
calcn_r_imu offset computed from calcn_r_imu data from file.
Processing femur_r_imu
Computed offset for femur_r_imu
Offset is 
[0.179228,-0.0327713,-0.983262]
[0.983805,0.0036643,0.179205]
[-0.00226982,-0.999456,0.0328973]

Creating offset frame for femur_r_imu
Added offset frame for femur_r_imu.
femur_r_imu offset computed from femur_r_imu data from file.
Processing calcn_l_imu
Computed offset for calcn_l_imu
Offset is 
[0.0109776,0.0135553,0.999848]
[-0.999486,0.0302708,0.0105632]
[-0.030123,-0.99945,0.0138806]

Creating offset frame for calcn_l_imu
Added offset frame for calcn_l_imu.
calcn_l_imu offset computed from calcn_l_imu data from file.
Processing tibia_l_imu
Computed offset for tibia_l_imu
Offset is 
[0.201148,-0.208446,-0.957126]
[0.966574,0.200815,0.159399]
[0.158979,-0.957196,0.241872]

Creating offset frame for tibia_l_imu
Added offset frame for tibia_l_imu.
tibia_l_imu offset computed from tibia_l_imu data from file.
Processing tibia_r_imu
Computed offset for tibia_r_imu
Offset is 
[0.147099,-0.0815253,-0.985756]
[0.987478,0.0695367,0.141605]
[0.0570018,-0.994243,0.0907332]

Creating offset frame for tibia_r_imu
Added offset frame for tibia_r_imu.
tibia_r_imu offset computed from tibia_r_imu data from file.
C++ console:

Code: Select all

[info] Updating Model file from 40000 to latest format...
[info] Loaded model Rajagopal_2015 from file Rajagopal_2015.osim
pelvis_imu
[info] No heading correction is applied.
[info] Processing torso_imu
[info] Computed offset for torso_imu
[info] Offset is
[0.12018,0.0205795,0.992539]
[-0.892059,-0.436494,0.117064]
[0.435647,-0.899472,-0.0340996]

[info] Creating offset frame for torso_imu
[info] Added offset frame for torso_imu.
[info] torso_imu offset computed from torso_imu data from file.
[info] Processing pelvis_imu
[info] Computed offset for pelvis_imu
[info] Offset is
[-0.0956206,-0.746262,0.658749]
[-0.496002,-0.538053,-0.681528]
[0.86304,-0.391909,-0.318699]

[info] Creating offset frame for pelvis_imu
[info] Added offset frame for pelvis_imu.
[info] pelvis_imu offset computed from pelvis_imu data from file.
[info] Processing femur_l_imu
[info] Computed offset for femur_l_imu
[info] Offset is
[0.142449,0.055014,-0.988272]
[0.918887,-0.378471,0.11138]
[-0.367905,-0.923977,-0.104464]

[info] Creating offset frame for femur_l_imu
[info] Added offset frame for femur_l_imu.
[info] femur_l_imu offset computed from femur_l_imu data from file.
[info] Processing calcn_r_imu
[info] Computed offset for calcn_r_imu
[info] Offset is
[0.120766,-0.0875746,0.988811]
[-0.878423,-0.473394,0.0653576]
[0.462373,-0.876487,-0.134097]

[info] Creating offset frame for calcn_r_imu
[info] Added offset frame for calcn_r_imu.
[info] calcn_r_imu offset computed from calcn_r_imu data from file.
[info] Processing femur_r_imu
[info] Computed offset for femur_r_imu
[info] Offset is
[0.179228,-0.0327713,-0.983262]
[0.878501,-0.444554,0.174949]
[-0.442846,-0.895152,-0.0508871]

[info] Creating offset frame for femur_r_imu
[info] Added offset frame for femur_r_imu.
[info] femur_r_imu offset computed from femur_r_imu data from file.
[info] Processing calcn_l_imu
[info] Computed offset for calcn_l_imu
[info] Offset is
[0.0109776,0.0135553,0.999848]
[-0.907034,-0.420765,0.015663]
[0.420913,-0.907068,0.00767611]

[info] Creating offset frame for calcn_l_imu
[info] Added offset frame for calcn_l_imu.
[info] calcn_l_imu offset computed from calcn_l_imu data from file.
[info] Processing tibia_l_imu
[info] Computed offset for tibia_l_imu
[info] Offset is
[0.201148,-0.208446,-0.957126]
[0.935348,-0.249366,0.250879]
[-0.290969,-0.94571,0.14481]

[info] Creating offset frame for tibia_l_imu
[info] Added offset frame for tibia_l_imu.
[info] tibia_l_imu offset computed from tibia_l_imu data from file.
[info] Processing tibia_r_imu
[info] Computed offset for tibia_r_imu
[info] Offset is
[0.147099,-0.0815253,-0.985756]
[0.908343,-0.383328,0.16725]
[-0.391503,-0.920007,0.0176656]

[info] Creating offset frame for tibia_r_imu
[info] Added offset frame for tibia_r_imu.
[info] tibia_r_imu offset computed from tibia_r_imu data from file.

User avatar
Nicholas Bianco
Posts: 1069
Joined: Thu Oct 04, 2012 8:09 pm

Re: IMU Inverse Kinematics cpp code

Post by Nicholas Bianco » Thu Jan 23, 2025 2:42 pm

Hi Claudia,

What commit of OpenSim are you using for your C++ analysis? Also, the two videos you linked are the same.

-Nick

POST REPLY