Get joint moment in a simulation

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Thomas Geijtenbeek
Posts: 10
Joined: Wed Mar 12, 2014 8:08 am

Get joint moment in a simulation

Post by Thomas Geijtenbeek » Fri Mar 02, 2018 4:38 am

I need to find the joint moment of a specific degree of freedom (i.e. the generalized force of a coordinate) of a simulation using the OpenSim API. I know it should be easy, but I've been looking at the docs for hours and can't seem to figure it out :?

Can anyone help me out?

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

Re: Get joint moment in a simulation

Post by Dimitar Stanev » Sat Mar 03, 2018 3:36 am

Hi,

You can run the InverseDynamicsTool and then read the results that are stored in .sto file. To use the ID tool I have the following C++ code

Code: Select all

/**
* \brief Performs inverse dynamics given a IK motion and externally applied
* forces. Results are stored in the provided result directory as
* subjectName_id.sto.
*/
class OactivePipeline_API InverseDynamicsModule {
public:
    struct Parameters {
        std::string subjectName;
        OpenSim::Model model;
        std::string inverseKinematicsMotion;
        std::string groundReactionXMLTemplate;
        std::string groundReactionForces;
        std::string resultsDir;
    };
    InverseDynamicsModule(Parameters& parameters);
    void run();
private:
    Parameters parameters;
};

InverseDynamicsModule::InverseDynamicsModule(Parameters& parameters)
    : parameters(parameters) {
}

void InverseDynamicsModule::run() {
    string tempExternalLoadsXML = parameters.resultsDir +
        parameters.subjectName + "_external_loads.xml";
    // prepare external loads
    ExternalLoads externalLoads(parameters.model,
                                parameters.groundReactionXMLTemplate);
    // update template
    externalLoads.setExternalLoadsModelKinematicsFileName(
        parameters.inverseKinematicsMotion);
    externalLoads.setDataFileName(parameters.groundReactionForces);
    externalLoads.setLowpassCutoffFrequencyForLoadKinematics(6);
    externalLoads.print(tempExternalLoadsXML);

    // ID tool
    InverseDynamicsTool id;
    id.setModel(parameters.model);
    Storage motion(parameters.inverseKinematicsMotion);
    id.setStartTime(motion.getFirstTime());
    id.setEndTime(motion.getLastTime());
    id.setCoordinatesFileName(parameters.inverseKinematicsMotion);
    // let createExternalLoads handle the creation of the external loads (internally)
    id.setExternalLoadsFileName(tempExternalLoadsXML);
    id.setOutputGenForceFileName(parameters.subjectName + "_id.sto");
    id.setResultsDir(parameters.resultsDir);
    // if muscles are not excluded then the results are wrong (very high)
    Array<string> forcesToExclude;
    forcesToExclude.append("Muscles");
    id.setExcludedForces(forcesToExclude);
    id.setLowpassCutoffFrequency(6);
    id.run();
}

and in order to call

Code: Select all

    // perform ID
    InverseDynamicsModule::Parameters idParameters{
    	"subject01_walk1",
    	model,
    	subjectDir + "results_cpp/subject01_walk1_ik.mot" ,
    	subjectDir + "subject01_walk1_grf.xml",
    	subjectDir + "subject01_walk1_grf.mot",
    	subjectDir + "results_cpp/"
    };
    InverseDynamicsModule id(idParameters);
    id.run();
Best

User avatar
Thomas Geijtenbeek
Posts: 10
Joined: Wed Mar 12, 2014 8:08 am

Re: Get joint moment in a simulation

Post by Thomas Geijtenbeek » Sat Mar 03, 2018 6:40 am

Hi Dimitar,

Thanks for the quick reply! However, I'm looking to find the joint moments in a FORWARD simulation (I'm sorry I wasn't clear about this in my initial post). Any idea how to extract those from an OpenSim::Model instance?

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

Re: Get joint moment in a simulation

Post by Dimitar Stanev » Sat Mar 03, 2018 11:39 am

Hi,

If you mean a forward dynamics settings you can't get the generalized forces because they are the input to your model. If your model is actuated by the muscles then you may want to compute τ = R * fm (τ: generalized forces, R: muscle moment arm, fm: muscle forces). Is this what you want?

User avatar
Thomas Geijtenbeek
Posts: 10
Joined: Wed Mar 12, 2014 8:08 am

Re: Get joint moment in a simulation

Post by Thomas Geijtenbeek » Mon Mar 05, 2018 3:55 am

Thanks again! What I need is indeed the generalized forces of the model, but these are not only generated by muscles, but also by contact forces, coordinate limit forces, etc. During forward dynamics simulation, OpenSim / Simbody computes these forces and adds them together before computing the accelerations and integrating the results.

So during the SimTK::Stage::Acceleration stage, all the generalized forces should be available. Instead of recomputing them, I simply wish to extract them from the Simbody subsystem. I'm fairly certain this is possible, I simply can't seem to find the proper API call. I hope this makes sense?

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

Re: Get joint moment in a simulation

Post by Dimitar Stanev » Mon Mar 05, 2018 8:24 am

This is a bit tricky. Here is a code (OpenSim v4.0) that I used to calculate the total forces (muscles are excluded).

https://github.com/mitkof6/task-space/b ... el.cpp#L99

You will have to change this line:

https://github.com/mitkof6/task-space/b ... el.cpp#L59

so that the muscle contribution is accounted. Furthermore, I have used a different convention of the model dynamics (as compared to Simbody). For more details:

https://github.com/mitkof6/task-space/b ... Model.h#L7

https://simbody.github.io/simbody-3.6-d ... ml#details

Hope this helps

User avatar
Thomas Geijtenbeek
Posts: 10
Joined: Wed Mar 12, 2014 8:08 am

Re: Get joint moment in a simulation

Post by Thomas Geijtenbeek » Mon Mar 12, 2018 3:10 am

Thank you, this is indeed what I was looking for!

I must say it's a lot more intricate than I expected -- especially since Simbody already computes the same generalized forces internally :? Would it make sense to post a separate feature request for Simbody on that?

Anyway, thanks again for the great support!

POST REPLY