Using metabolics probe with DeGrooteFregly2016Muscle

OpenSim Moco is a software toolkit to solve optimal control problems with musculoskeletal models defined in OpenSim using the direct collocation method.
User avatar
Karthick Ganesan
Posts: 119
Joined: Thu Oct 10, 2013 12:11 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Karthick Ganesan » Mon May 11, 2020 10:52 am

Before setting up and running analyze tool try defining a study: study = MocoStudy().
Please see one of my posts above where I have uploaded a setup file specifying states and controls.

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Christopher Dembia » Mon May 11, 2020 3:50 pm

The function analyze() is available in two places: MocoStudy (study.analyze()) and as a free function (opensimMoco.analyze()). MocoInverse does not provide analyze().

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

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Nicholas Bianco » Mon May 11, 2020 4:40 pm

Iris,

Based on your error message,
WARNING: Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter: Muscle 'muscle name' not found in model. Ignoring...)
it looks like you need to provide the muscle names for each metabolic muscle parameter. Double check your model file to make sure they all have the correct muscle names. If that doesn't help, then I think we'll need more information to debug this issue.

To expand on Karthick's helpful suggestions: the study.analyze() method doesn't need a PrescribedController, the controls from the provided MocoTrajectory are applied to the model for you. If you do decide to use study.analyze() over the AnalyzeTool, then look into the Output called "probe_outputs" that is included for every class derived from Probe (including the Umberger2010MuscleMetabolicsProbe).

-Nick

User avatar
Iris Magnusdottir
Posts: 19
Joined: Thu Nov 01, 2018 2:04 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Iris Magnusdottir » Tue May 12, 2020 6:18 am

Thank you all for the helpful feedback.

My previous error disappeared when I edited my ProbeSet, adding <enabled>true</enabled> and <aerobic_factor>1.5</aerobic_factor>.

If I use the Analyze Tool (instead of analyze.study()), do I then need a PrescribedController?
I am now running the Analyze Tool as shown in the code below. I get error messages when reading the controls.sto and states.sto, see attached file (Errors.txt). Still, I get very high values for metabolic cost, which seem to be too high, see figure below.

How would I make sure that the Analyze Tool can read the actuators and fiber_lengths from the model (the nature of the errors)?

For the other approach (analyze.study()), how would I define a MocoStudy when using MocoInverse? Will I then need to define a outputPath for the Probe?

I will attach my model file below as well (which is a slightly modified version of the gait2392 model).

Thank you for taking the time to help me out.

Code: Select all

import org.opensim.modeling.*;
inverse = MocoInverse();
modelProcessor = ModelProcessor('subject_walk_rra2_probed_weld_millard.osim');
modelProcessor.append(ModOpAddExternalLoads('grf_walk.xml'));
modelProcessor.append(ModOpIgnoreTendonCompliance());
modelProcessor.append(ModOpReplaceMusclesWithDeGrooteFregly2016());
modelProcessor.append(ModOpIgnorePassiveFiberForcesDGF());
modelProcessor.append(ModOpScaleActiveFiberForceCurveWidthDGF(1.5));
modelProcessor.append(ModOpAddReserves(1.0));
inverse.setModel(modelProcessor);

inverse.setKinematics(TableProcessor('rra_walk_2_Kinematics_q.sto'));
inverse.set_initial_time(0.81);
inverse.set_final_time(1.79);
inverse.set_mesh_interval(0.02);

inverse.set_kinematics_allow_extra_columns(true);

solution = inverse.solve();
solution.getMocoSolution().write('MocoInverse_solution.sto');

% States and controls
prevSolution = MocoTrajectory('MocoInverse_solution.sto'); 
prevStatesTable = prevSolution.exportToStatesTable(); 
prevControlsTable = prevSolution.exportToControlsTable(); 
opensimMoco.writeTableToFile(prevStatesTable,'states.sto'); 
opensimMoco.writeTableToFile(prevControlsTable,'controls.sto'); 

analyzeTool = AnalyzeTool('Setup_Analyze.xml'); % this file calls the states and controls files created above
analyzeTool.run();
Image
Attachments
Setup_Analyze.xml
(4.8 KiB) Downloaded 113 times
subject_walk_rra2_probed_weld_millard.osim
(739.41 KiB) Downloaded 114 times
gait.png
gait.png (17.05 KiB) Viewed 2399 times
Errors.txt
(21.81 KiB) Downloaded 100 times

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

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Nicholas Bianco » Tue May 12, 2020 11:38 am

Hi Iris,

Part of your issue is that you need to print out the model created by the ModelProcessor so that it's compatible with your states and controls file. For example, you've added reserves to the model that the base model doesn't have and you've disabled tendon compliance but the base model hasn't (hence why you see errors related to fiber length states). To do this, you can do the following:

Code: Select all

modelUpdated = modelProcessor.process();
modelUpdated.print('model_updated.osim'); % or whatever you want to name it
If you call initialize on the MocoInverse object you can retrieve the underlying MocoStudy. The Umberger2010MuscleMetabolicsProbe has an output called "probe_outputs" that returns a vector of values from the problem. Based on your model it would look something like this:

Code: Select all

study = inverse.initialize();
outputPaths = StdVectorString();
outputPaths.add('/probeset/metabolics\|probe_outputs');
outputTable = study.analyze(solution.getMocoSolution(), outputPaths);
However, I'm not sure this will work in MATLAB, since the outputTable should be of type TimeSeriesTable_<Vector> (this is C++ notation), but it doesn't seem like that type is supported in MATLAB.

So it seems like you'll need the AnalyzeTool. If you use the AnalyzeTool, you will need a PrescribedController so that the correct controls are applied to the model at each time point.

-Nick

User avatar
Iris Magnusdottir
Posts: 19
Joined: Thu Nov 01, 2018 2:04 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Iris Magnusdottir » Wed May 13, 2020 9:20 am

Thank you Nick!

I believe I managed to get the PrescribedController to work. My error occurred as the header in my control.sto file was not the same as in the ForceSet in my model (.sto had a /forceset/ prefix).

What I did was:

Code: Select all

model = Model('model_updated.osim');
pc = PrescribedController('controls.sto'); % file generated from solution
model.addController(pc);
model.finalizeConnections(); 
model.print('model_updated_pc.osim');
Where I then used the model_updated_pc.osim file in the Analyze Tool.
My results are now similar to the Metabolic Cost Tutorial.

Thank you all!

User avatar
Karthick Ganesan
Posts: 119
Joined: Thu Oct 10, 2013 12:11 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Karthick Ganesan » Sat Jul 18, 2020 12:58 am

Dear All,
As Iris pointed out, the name of the controls in the storage file has '/forceset/' prefix whereas name of the control in the model does not have it. I manually removed this prefix in the storage file using 'replace all' in Matlab editor. I want to do this with scripting since I have to run many simulations. Any suggestions?
Thanks,
Karthick.

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Christopher Dembia » Mon Jul 20, 2020 1:35 pm

You can edit the column labels before you write the controls storage file:

Code: Select all

controls = solution.exportToControlsTable();
labels = controls.getColumnLabels();
<edit the labels to remove the prefix>
controls.setColumnLabels(labels);
STOFileAdapter.write(controls, "controls.sto");
In a future release of Moco, PrescribedController will accept the `/forceset/` prefix.

User avatar
Iris Magnusdottir
Posts: 19
Joined: Thu Nov 01, 2018 2:04 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Iris Magnusdottir » Sat Jul 25, 2020 10:36 am

Hi all,

I would like to compute the ankle plantarflexion moment using my exoskeleton and compare the moment generated by my device with muscle moments with and without assistance, as done by Dembia et al (2017).

Previously in this thread, Nick suggested the following:

Code: Select all

coordSet = model.getCoordinateSet();
coord = coordSet.get('<desired_coord_name>');

muscle = model.getMuscles().get('<desired_muscle_name>');

% state must be realized to Position stage
momentArmAboutCoord = muscle.computeMomentArm(state, coord);
And then to multiply moment arm and muscle force. However, this does not seem to work in Matlab. I get the following error: No method 'computeMomentArm' with matching signature found for class 'org.opensim.modeling.Muscle'.

Correct me if I'm wrong, but the "state" in this code, refers to the state of the muscle selected right?

I am using MocoInverse and so far used the Analyze Tool to get various parameters from my solution.

Is it possible to use JointReaction to compute joint moment?

I saw that Karthick was interested in something similar. Would love to know if that worked out.

Thanks!
Iris

User avatar
Iris Magnusdottir
Posts: 19
Joined: Thu Nov 01, 2018 2:04 am

Re: Using metabolics probe with DeGrooteFregly2016Muscle

Post by Iris Magnusdottir » Mon Jul 27, 2020 9:55 am

Just to answer my own question in case it might help someone else.

I managed to find the joint moments using MuscleAnalysis and sum up the muscle moments that act around the ankle joint.
However, it only reports the moments of muscles in the model. How can I see the contribution of my PathActuator (motor) to ankle moment?

Thanks!

POST REPLY