Joint Reaction Analysis

OpenSim Moco is a software toolkit to solve optimal control problems with musculoskeletal models defined in OpenSim using the direct collocation method.
User avatar
Ross Miller
Posts: 375
Joined: Tue Sep 22, 2009 2:02 pm

Re: Joint Reaction Analysis

Post by Ross Miller » Fri Jun 09, 2023 6:07 am

Hi Nick,

"Stride" and "Gait Cycle" are the same thing to me, a full periodic cycle from one gait event to the next instance of that same event, for example right heel-strike to the next right heel-strike.

Over a full cycle you typically want all the states and controls to be periodic, except the pelvis anterior-posterior position which is constrained (if desired) by an average speed goal. I do that with something like this:

Code: Select all

% All states are periodic except pelvis anterior-posterior translation
for i = 1:model.getNumStateVariables()
    currentStateName = string(model.getStateVariableNames().getitem(i-1));
    if (~contains(currentStateName,'pelvis_tx/value'))
       periodicityGoal.addStatePair(MocoPeriodicityGoalPair(currentStateName));
    end
end

% All controls are periodic too
for i = 1:model.getNumControls()
    currentControlName = string(problem.createRep().createControlInfoNames().get(i-1));
    periodicityGoal.addControlPair(MocoPeriodicityGoalPair(currentControlName));
end

% Average speed goal
speedGoal = MocoAverageSpeedGoal('speed');
speedGoal.set_desired_average_speed(1.45); % The number here is the average speed in m/s
problem.addGoal(speedGoal);
On model moving backwards, if you are using any data-tracking goals it could be that the coordinate systems of the pelvis tracking data and your model's pelvis are inconsistent, or maybe the AP GRF too. Also, if you are minimizing metabolic cost, the cost goes negative if the model steps backwards, so the optimizer sees a big benefit from this (use a ton of muscle activity and take a small step backwards = large negative metabolic cost = minimizing cost function). I used to square the metabolic cost in the cost function to avoid this, but I don't think Moco can presently do that. The speed goal and making sure the model and data coordinate systems are consistent should take care of that though.

Ross

User avatar
Nicholas Vandenberg
Posts: 71
Joined: Wed Jan 20, 2021 12:47 pm

Re: Joint Reaction Analysis

Post by Nicholas Vandenberg » Mon Jul 10, 2023 2:05 pm

Hi Ross,

Thanks for the info. I've been messing around with using these periodicity goal definitions, running tracking problems over strides in a few models. I'm able to get decent kinematic solutions but I'm still running into these high muscle activations in the iliopsoas where I'm not getting a loading response and the vertical HJRF never drops as low as I'd expect throughout the stride. I do get the unloading going into swing but then I have a huge HJRF from the hip flexors in push-off
AL_HJRF_Stride.png
AL_HJRF_Stride.png (59.39 KiB) Viewed 1999 times
I use an average speed goal set to 1 m/s, which is a functional target for rehab in this population, but I also have each subject's selected gait speed. Would it make sense to set the average speed goal to whatever the patient was actually walking at?

I've done a fair amount of quality checking to make sure that the coordinate systems from what I'm tracking are consistent, but it always pays to check again. I had also been minimizing effort squared in my current setup. I fixed the backward movement by adding a speed bound to pelvis tx so that it never goes negative, not the most elegant but it seems to work.

Additionally, and I know there was discussion about this being a questionable assumption, I tried adding the MocoInitialActivationGoal to see if that would fix the high initial activations that my model is using. I don't know if I implemented that correctly though?

Code: Select all

initAct = MocoInitialActivationGoal();
problem.addGoal(initAct);
I tried over a stride and a stance each, but I'm still having some high activations and missing the loading
AL_HJRF_InitAct.png
AL_HJRF_InitAct.png (50.93 KiB) Viewed 1999 times

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

Re: Joint Reaction Analysis

Post by Nicholas Bianco » Mon Jul 10, 2023 6:47 pm

Hi Nick,

You've added the MocoInitialActivationGoal to the problem correctly.

At this point, it might be helpful to plot all the muscle forces and the muscle contributions to the net joint moments to see if there's unwanted co-contraction that is leading to the contact forces you are seeing.

You could also try directly minimizing hip contact force to see if that helps or leads to large kinematic deviations from the tracking data.

-Nick

User avatar
Ross Miller
Posts: 375
Joined: Tue Sep 22, 2009 2:02 pm

Re: Joint Reaction Analysis

Post by Ross Miller » Tue Jul 11, 2023 4:27 am

Hi Nick,

I would use whatever speed the subject(s) in the tracking target data walked at, but I also doubt that an inconsistency there is the source of the hip JCF issue. Various questions below:

- What does the overall tracking result look like? Is it tracking the target data fairly well?
- What are you using for the initial guess?
- How are you modeling the prosthetic joints, and the knee in particular?

When recently doing something similar (https://www.biorxiv.org/content/10.1101 ... 6.546515v1), I found tracking simulations with a transfemoral model to be pretty difficult optimization problems. I sometimes had to try ~10-15 different initial guesses to get a good result with the transfemoral model ("good" = reasonable tracking with realistic metabolic cost). Adding a small bit of power to the prosthetic knee via an ActivationCoordinateActuator seemed to make the optimization problem considerably easier but I still usually had to use multiple initial guesses to find a good result. "Small" here is very small, the peak torque from the actuator was ~0.3 Nm and peak power ~0.5 W.

When I first started using Moco, I was not able to get good results in MocoTrack with a complex/3-D/high-dimensional model and arbitrary initial guesses. I had to first start with a much simpler model, get a good result there, then gradually add complexity to that model, each time using the previous solution as the basis for the initial guess in the new model. Now I have a bunch of such results from complex models to use as initial guesses and don't have to repeat that process every time, which is nice (it took months). For limb loss simulations I'll usually get pretty good results by using a result from a non-limb loss version of the same model tracking able-bodied data as the initial guess. This worked great for transtibial simulations but was less consistently good for transfemoral simulations.

Hope this helps,
Ross

User avatar
Nicholas Vandenberg
Posts: 71
Joined: Wed Jan 20, 2021 12:47 pm

Re: Joint Reaction Analysis

Post by Nicholas Vandenberg » Fri Jul 28, 2023 2:16 pm

Nick,

That's good to know, it's not exactly behaving how I expect where I'm still having a lot of hip flexor muscles active at the beginning of the gait cycle. Is there any way to constrain a muscle group or specific muscles (iliopsoas) to try and limit these activations at heelstrike?

Also I tried out minimizing the hip joint contact force and it crashed everything, not sure if I did something wrong here:

Code: Select all

% Test minimzing the JRF in the amputated limb hip
minHJRF = MocoJointReactionGoal();
minHJRF.setJointPath('/jointset/hip_l');
minHJRF.setLoadsFrame('parent');
minHJRF.setExpressedInFramePath('/bodyset/femur_l');
minHJRF.setReactionMeasures({'force-y'});
minHJRF.setWeight(15);
problem.addGoal(minHJRF);
Ross,

Overall I have pretty good tracking, the output kinematics look good. Currently my workflow has been to get an initial kinematic solution using a torque-driven model with a bounded initial guess, I then take that trajectory and pull the states for my muscle-driven sim. Recently I've been trying to use my full muscle-driven models and refining the mesh consecutively -- work in progress.

I've been modeling the prosthetic knee/ankle using a coordinate actuator with a low effort cost associated, my thinking with that was trying to allow the model to use it like an "ideal" prosthesis in order to track the subject-specific kinematics better. I've been wondering if that's doing what I want it to though, especially with the article you shared (thank by the way!) I'm wondering if it makes sense to attempt to model the powered knee better. If that will pick up some of the slack that's causing the hip flexors to be so active?

Thanks!
Nick

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

Re: Joint Reaction Analysis

Post by Nicholas Bianco » Mon Aug 14, 2023 10:19 am

Hi Nick,

Adding the goal as you've done shouldn't crash everything, but since joint reaction forces can be pretty large, you could try reducing the weight on the cost term by a few orders of magnitude and see if you at least get convergence.

-Nick

User avatar
Nicholas Vandenberg
Posts: 71
Joined: Wed Jan 20, 2021 12:47 pm

Re: Joint Reaction Analysis

Post by Nicholas Vandenberg » Fri Aug 18, 2023 3:53 pm

Thanks Nick, that worked like a charm! I still need to tweak to find the Goldilocks weight for that but it's working!

The only line I wasn't able to use was:

Code: Select all

minHJRF.setReactionMeasures({'force-y'});
Probably just a syntax thing between the documentation and Matlab though, I didn't want to mess around with it too much.

Thanks again,
Nick

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

Re: Joint Reaction Analysis

Post by Nicholas Bianco » Mon Aug 21, 2023 9:42 am

Yes, it's C++ to Matlab syntax thing. Here's how to do it in Matlab:

Code: Select all

measures = StdVectorString();
measures.add("force-y");
minHJRF.setReactionMeasures(measures);

User avatar
Nicholas Vandenberg
Posts: 71
Joined: Wed Jan 20, 2021 12:47 pm

Re: Joint Reaction Analysis

Post by Nicholas Vandenberg » Mon Aug 21, 2023 10:37 am

That makes sense, thanks for sharing!

I have some follow up questions real quick. I've tweaked the weight for the goal so that I'm getting a better motion while still minimizing the JRF in the amputated limb hip, it's also helping with the abnormal activations of the hip flexors I was seeing.
minHJRF_plot.png
minHJRF_plot.png (60.42 KiB) Viewed 1774 times
However, in the process of not using the hip flexors the abductors (glmed, and glmin, specifically) are turning off as well which is pretty weird. Could this be a weighting thing where the JointReactionGoal is still being tracked too heavily? Or is it a matter of implementing the directional tracking (i.e., Fy) do you think?
My A/P force is also looking a little weird for stance, might be affected by those muscles being 'off'

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

Re: Joint Reaction Analysis

Post by Nicholas Bianco » Mon Aug 21, 2023 2:01 pm

Since you expressed the contact force in the y-direction of the parent frame, you're most likely minimizing the force along hip joint force along the femur (you can open the model to double check). In this case, most muscles crossing the hip joint will contribute to the Fy force, and therefore might turn down or turn off completely. And yes, the A/P forces might be affected in a similar way.

You could check to see how large the hip joint force weight is in the cost function to get a sense if the problem is minimizing hip joint force at the expense of normal kinematics and/or muscle activation.

POST REPLY