calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Nicos Haralabidis
Posts: 196
Joined: Tue Aug 16, 2016 1:46 am

calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Nicos Haralabidis » Mon Mar 11, 2019 8:51 am

Hi all,

I am trying to use the calcResidualForceIgnoringConstraints method (https://simtk.org/api_docs/simbody/3.5/ ... d43db05df0) to perform my own inverse dynamics analysis - as I would like to use my own computed accelerations.

I have also got measured ground reaction forces (expressed relative to the lab) that I need to account for - I realise I can add those to the vector of spatial vectors, specifically the spatial vector corresponding to the calcaneus.

My question is how can I transform my measured ground reaction forces ({0,Tz,0},{fx,fy,fz}) so they are in the correct reference frame? I am sure there is a simple method but I haven't been able to find it. The ID Tool must do something similar from knowledge of the body to which the forces should be applied to, along with the COP in the lab frame.

Kind regards,

Nicos Haralabidis

Tags:

User avatar
Dimitar Stanev
Posts: 1096
Joined: Fri Jan 31, 2014 5:14 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Dimitar Stanev » Tue Mar 12, 2019 3:00 am

Hi Nicos,
I am trying to use the calcResidualForceIgnoringConstraints method (https://simtk.org/api_docs/simbody/3.5/ ... d43db05df0) to perform my own inverse dynamics analysis - as I would like to use my own computed accelerations.
Please note that you have to disable muscle forces before performing inverse dynamics calculations, because you will get unreasonable results.

Please find attached a code that I wrote for executing ID. I am not attaching the whole project, thus there might be some missing classes. However, if you study the code you will be able to adapt it for your purpose. Essentially, you have to understand the ExternalWrench class. Then take a look at the implementation of InverseDynamics. Finally, examine the test file which utilizes the tool.
InverseDynamics.h
(2.56 KiB) Downloaded 19 times
InverseDynamics.cpp
(6.24 KiB) Downloaded 23 times
testIDFromFile.cpp
(6.45 KiB) Downloaded 18 times
Regards

User avatar
Nicos Haralabidis
Posts: 196
Joined: Tue Aug 16, 2016 1:46 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Nicos Haralabidis » Wed Mar 13, 2019 11:07 am

Hello Dimitar,

Thank you very much for sharing those pieces of code! They have definitely given me a blue print to work from! Thanks! :-)

I have been following your code up to the point where I use the SimbodyEngine transformPosition method - the code I am working with compiles, but I am not able able to receive the new transformed position on the screen which makes me believe I am doing something wrong. Here is my code at the minute:

#include <OpenSim/OpenSim.h>

using namespace OpenSim;
using namespace SimTK;
using namespace std;

Model myModel = Model("C:/Users/Nicos/Desktop/v1_NewModeling/DC_Model/Scaled_Torque_Hamner_wHC_x1.osim");
SimTK::State &myState = myModel.initSystem();

const int nActuators = myModel.getActuators().getSize();
const int nStates = myModel.getNumStateVariables();
const ControllerSet &controllerSet = myModel.getControllerSet();
Array<string> stateNames = myModel.getStateVariableNames();

int main()
{

int index;
int n0 = 0;
int n1 = 2;

for (index = 0; index < nStates; index++)
{
myModel.setStateVariable(myState, stateNames[index], n0);
}

myModel.setStateVariable(myState, stateNames[4], n1);

int mbi_calcR = myModel.getBodySet().get("calcn_r").getIndex();
int mbi_calcL = myModel.getBodySet().get("calcn_l").getIndex();

OpenSim::Body calcR = myModel.getBodySet().get("calcn_r");
OpenSim::Body gro = myModel.getBodySet().get("ground");

cout << gro.getName() << endl;
Vec3 pointGround(0.1, 0, 0.1);
Vec3 pointCalc(0);

SimbodyEngine engine = myModel.getSimbodyEngine();

myModel.updMultibodySystem().realize(myState, Stage::Dynamics);

engine.transformPosition(myState, gro, pointGround, calcR, pointCalc);

cout << pointGround << endl;
cout << pointCalc << endl;

}


Any suggestions as to why it is breaking down would be greatly appreciated!

Kind regards,

Nicos Haralabidis

User avatar
Dimitar Stanev
Posts: 1096
Joined: Fri Jan 31, 2014 5:14 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Dimitar Stanev » Thu Mar 14, 2019 1:08 am

Hi,

I would move everything into a function and wouldn't use global variables, because you may get an exception there. Try to wrap your code into a try catch statement (see my test example) so you can catch any error thrown by Simbody or OpenSim. Also, you can step your code by adding a break point and find which function causes the problem.

Regards

User avatar
Nicos Haralabidis
Posts: 196
Joined: Tue Aug 16, 2016 1:46 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Nicos Haralabidis » Sat Mar 16, 2019 12:14 pm

Hi Dimitar,

Thanks again for your advice. I have now managed to get to the stage of adding in the forces (fx, fy, fz) following conversion of the COP in the calcaneus' frame by using the following:

myModel.getMatterSubsystem().addInStationForce(myState, MobilizedBodyIndex(mbi_calcR), COP_local, forces, appliedForces);

The forces are getting added to the correct spatial vector of appliedForces. I am also expecting the moments aspect of the spatial vector to be updated (to account for COP_local x forces), although they are still {0,0,0}. Am I right in thinking they should be updated automatically? or should I also include them manually?

Kind regards,

Nicos Haralabidis

User avatar
Dimitar Stanev
Posts: 1096
Joined: Fri Jan 31, 2014 5:14 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Dimitar Stanev » Sat Mar 16, 2019 1:25 pm

This should update the moment component of the spatial vector automatically:

https://github.com/simbody/simbody/blob ... .cpp#L2040

Are you providing the correct mobilized body index?

Code: Select all

body.getMobilizedBodyIndex()

User avatar
Nicos Haralabidis
Posts: 196
Joined: Tue Aug 16, 2016 1:46 am

Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs

Post by Nicos Haralabidis » Mon Mar 18, 2019 8:56 am

Hello Dimitar,

I spotted my mistake. As I was testing the code I was using the same values for the COPlocal and forces vectors. Due to them being parallel it is therefore not surprising now why they were returned as {0,0,0} following application of the cross product. Silly me. The function now works as expected!

Thanks again!

Kind regards,

Nicos Haralabidis

POST REPLY