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
calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
- Nicos Haralabidis
- Posts: 196
- Joined: Tue Aug 16, 2016 1:46 am
- Dimitar Stanev
- Posts: 1096
- Joined: Fri Jan 31, 2014 5:14 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
Hi Nicos,
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.
Regards
Please note that you have to disable muscle forces before performing inverse dynamics calculations, because you will get unreasonable results.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 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.
Regards
- Nicos Haralabidis
- Posts: 196
- Joined: Tue Aug 16, 2016 1:46 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
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
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
- Dimitar Stanev
- Posts: 1096
- Joined: Fri Jan 31, 2014 5:14 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
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
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
- Nicos Haralabidis
- Posts: 196
- Joined: Tue Aug 16, 2016 1:46 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
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
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
- Dimitar Stanev
- Posts: 1096
- Joined: Fri Jan 31, 2014 5:14 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
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?
https://github.com/simbody/simbody/blob ... .cpp#L2040
Are you providing the correct mobilized body index?
Code: Select all
body.getMobilizedBodyIndex()
- Nicos Haralabidis
- Posts: 196
- Joined: Tue Aug 16, 2016 1:46 am
Re: calcResidualForceIgnoringConstraints - transformation and inclusion of GRFs
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
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