Page 1 of 1

Determining Muscle Forces From MOCO Solution

Posted: Sun Sep 29, 2024 11:24 pm
by brodiek
Hello,

I am trying to make sense of the outputted muscle forces from a tracking simulation I have run. As an example I will use the left soleus muscle.

My main question is, what does the value of /forceset/soleus_l represent? Is it the percentage of the maximum possible muscle force for that muscle or is it the actual force value in Newtons? I would imagine it would be the percentage of the maximum muscle force due to its magnitude and similarity to the activation but would like confirmation before continuing. Also I do not believe it is an issue with my simulation as I checked a solution provided in the Moco examples and it showed a similar trend. Image for reference:
Capture.PNG
Capture.PNG (34.8 KiB) Viewed 916 times
Cheers in Advance

Re: Determining Muscle Forces From MOCO Solution

Posted: Mon Sep 30, 2024 11:26 am
by pvb
Hi Brodie,

Moco automatically adds a controller to each muscle when you run an optimization. It computes the control inputs (i.e., muscle excitation signals) or whatever problem you've defined. These are normalized (so between 0 &1, or perhaps bounded between 0.00001 & 1 or similar). Control input (or muscle excitations) result a change in muscle activation (or muscle active state) via 1st order dynamics. You can actually see this in your graph - the muscle's activation basically follows the excitatory input, but is slightly delayed and slightly smoother. Activate state is also bounded between 0 - 1. You can think of these both as percentages.

A Hill-type muscle's force depends on active state, length, and contraction velocity. What you're after is the output "normalized tendon force" (since force in the tendon should be equal to force in the muscle fiber, if the muscle is equilibriated). This will also be bounded between 0 - 1, where 1 represents maximal isometric force (F_max) in Newtons. So you need to plot each muscle's normalized tendon force multiplied by its F_max.

Cheers,
Pasha

Re: Determining Muscle Forces From MOCO Solution

Posted: Thu Oct 03, 2024 12:43 am
by brodiek
Hi Pasha,

Thanks for the reply.

How would I go about finding the normalised tendon force? Would I need to change something in my simulation code in order for it to be included in the output?

Cheers in advance,
Brodie

Re: Determining Muscle Forces From MOCO Solution

Posted: Fri Oct 04, 2024 3:15 am
by rosshm
Hi Brodie,

The solution matrix/file from a Moco solution (.sto file) includes the time-varying values of the model's states and controls. If the normalized_tendon_force variables Pasha mentioned are not in your simulation's solution, it probably means your model has rigid tendons, which means the tendon forces are not state variables (the forces are uniquely determined by muscle activations and joint kinematics).

There is surely a post-hoc analysis (e.g. "MuscleAnalysis" class, I would guess) that can compute the various fiber/tendon forces, but for those forces to be state variables in the solution, the tendons need to be set as non-rigid.

Hope this helps!
Ross

Re: Determining Muscle Forces From MOCO Solution

Posted: Sun Oct 06, 2024 7:28 pm
by brodiek
Hello,

Wouldn't using this muscle analysis tool defeat the purpose of trying to find the muscle forces from the tracking simulation? Or am I misunderstanding this.

It just seems odd that almost every example simulation code I have seen uses the operator "ModOpIgnoreTendonCompliance" when doing this supposedly removes the ability to get the muscle forces from the simulation output.

Cheers

Re: Determining Muscle Forces From MOCO Solution

Posted: Mon Oct 07, 2024 12:57 pm
by nbianco
Hi Brodie,

You can use MocoStudy::analyze() to compute muscle forces from a MocoSolution. You need to provide the second argument "outputPaths", which is a list of paths to Outputs in the model for which you want to compute values. You can find the list of Muscle Outputs here. The Output path format is as follows: "/path/to/my_component|output_name".

Best,
Nick

Re: Determining Muscle Forces From MOCO Solution

Posted: Mon Oct 07, 2024 10:17 pm
by brodiek
Hi Nicholas,

Thank you for that, this is what I am looking for I believe. Is there any chance you could please provide some formatting assistance for me?

I am using MATLAB for this project and I cannot find an example of how to use "MocoStudy::analyze()". I Have tried multiple set ups but whenever I try to use "analyze" MATLAB thinks I am trying to use the analyze function from the radio frequency (RF) toolbox which makes me think I am formatting it wrong. For refference, the code I have tried is:

clc; clear all; close all;

% Import Libraries
import org.opensim.modeling.*;

% Set up moco trajectory from Moco Solution .sto output
tracking_solution = 'gait_solution_single_stride.sto';
traj = MocoTrajectory(tracking_solution);

% Create Moco Study and problem
study = MocoStudy();
study.setName('muscle_force_collection');
problem = study.updProblem();

% Create and assign model processor to problem
modelProcessor = ModelProcessor('subject_walk_onlyNecessaryMarkers.osim');
problem.setModelProcessor(modelProcessor);

% Use study.analyze to find tendon forces
muscle_force = study.analyze(traj, '/forceset/vaslat_r/tendon_force');

%% Attempt at getting all tendon forces
all_muscle_forces = problem.analyze(traj, '.*tendon_force');

I have checked that my MATLAB path is to OpenSim yet I still get this error:

Capture2.PNG
Capture2.PNG (4.39 KiB) Viewed 673 times

Would greatly appreciate some help on this and thank you in advance.
Brodie

Re: Determining Muscle Forces From MOCO Solution

Posted: Wed Oct 09, 2024 8:56 pm
by nbianco
Hi Brodie,

The correct format in Matlab would be as follows:

Code: Select all

study = MocoStudy();
% your study configuration here
solution = study.solve();

outputPaths = StdVectorString();
outputPaths.add('/forceset/vaslat_r|tendon_force');
outputs = study.analyze(solution, outputPaths);
The "outputPaths" argument takes a vector or paths; here we need StdVectorString(), our Matlab interface's version of the C++ std::vector<std::string> type. Also note the use of the vertical bar character in the output path.

Best,
Nick

Re: Determining Muscle Forces From MOCO Solution

Posted: Thu Oct 10, 2024 2:33 am
by brodiek
Hi Nicholas,

Thank you again. Just to clarify, do I need to change my original simulation (with all the set up, bounds, etc) to a MocoStudy instead of a MocoTrack and run it again in order to get these outputs? Or can I just set up a simple moco study (similar to what I did above) and use the solution I already have?

Cheers,
Brodie

Re: Determining Muscle Forces From MOCO Solution

Posted: Thu Oct 10, 2024 10:25 am
by nbianco
Hi Brodie,

MocoTrack is just a tool for configuring a MocoStudy for tracking optimization problems. You can access the internally configured MocoStudy using "initialize":

Code: Select all

track = MocoTrack();
% your tracking problem configuration

study = track.initialize();
solution = study.solve();

outputPaths = StdVectorString();
outputPaths.add('/forceset/vaslat_r|tendon_force');
outputs = study.analyze(solution, outputPaths);
Best,
Nick