Page 1 of 1

Parameters self-update without initSystem()

Posted: Wed Jun 23, 2021 12:12 pm
by 5453zzl
Hi fellow modelers,

I'm scripting in Matlab to set muscle parameters and obtain the according tendon force, and triggered a potential bug when parameters are changed after initSystem(). [I changed the post title as I realized the bug is not in initSystem() itself.]

My understanding is that, initSystem() must be called after muscle parameters are reset, otherwise simulation will be based on default parameters.

However, this theory seems to be model-dependent: with Arnold Model, yes; but with Gait2392 and Rajagopal Model, if initSystem() is called before parameters reset, muscle dynamics somehow changes, but it's not the same as when called after.

Please try the test code below in Matlab as an example:

soleus is activated 100% in default joint coordinates, and its optimal fiber length and tendon slack length are changed into 10 and 20 cm. [I wanted to attach a figure but was warned "the board attachment quota has been reached."]

For Gait2392, Arnold and Rajagapal:
1. The original tendon forces under this state are respectively 2794.3, 2942.0, 5205.6
2. initSystem() before parameter reset, the values become 3340.1, 2942.0, 5741.5
3. initSystem() after parameter reset, the values become 3164.4, 2822.6, 5254.6

Theoretically No.3 is the right answer, which is also the result I get manually from OpenSim, but why do the values change for Gait2392 and Rajagopal Model in No.2?

More precisely, why would some models partially update themselves without initSystem()?

Code: Select all

import org.opensim.modeling.*
modelFile = ;

myModel = Model(modelFile);
myMuscle = myModel.getMuscles().get("soleus_r");

% 1. Set muscle parameters here {
myMuscle.set_optimal_fiber_length(0.1);
myMuscle.set_tendon_slack_length(0.2);
% }

myState = myModel.initSystem();
myMuscle.setActivation(myState, 1);

% 2. Set muscle parameters here {

% }

myModel.equilibrateMuscles(myState);
myMuscle.getTendonForce(myState)

% 3. Set muscle parameters here {

% }

myModel.initSystem();
myMuscle.setActivation(myState, 1);

myModel.equilibrateMuscles(myState);    
myMuscle.getTendonForce(myState)

Re: Potential bug in initSystem()

Posted: Thu Jun 24, 2021 7:10 am
by tkuchida
Not sure what the objective of this code is (perhaps just for testing), but the lines after "2. Set muscle parameters here" don't really make sense. You are asking OpenSim to compute things in a Model using a State, but the Model was changed after the State was created. Consider what would have happened if, rather than just setting parameters, you had added a Body to the Model. In short, initSystem() must be called to create a new State if the Model is modified.

Re: Potential bug in initSystem()

Posted: Thu Jun 24, 2021 10:31 am
by 5453zzl
Hi Prof. Uchida, thanks for the reply.

Yes, the purpose of this code is purely for testing the peculiar case I triggered.

I am aware that initSystem() must be called after modification, and the test with Arnoldetal2010_2Legs_Default_v2.1.osim indeed shows that forces won't change if initSystem() is not called after.

What confuses me is that, for gait2392_simbody.osim and Rajagopal2015.osim, despite the lack of following initSystem(), somehow the results not only will change but is quite close to the correct answer.

For example, using my test code, set both the optimal fiber length and tendon slack length of soleus to 10 cm, the correct new tendon forces for gait2392 and Rajagopal model are respectively 18946 and 14218 N. However, though theoretically not making any sense, setting parameters after remodification yields 16639 and 13959 N.

It's not detrimental if results in this special case are much too messed up or remains unchanged, but the difference is not too big and people might not be aware. I only noticed it because this changes the "flow" of my optimization.

-------------------------------

I did extra tests and it seems the problem is muscle-model dependent:

Arnold uses Schutte1993 while gait2392 and Rajagopal use the more advanced Thelen2003 and Millard2012, which potentially leads to the automatic (but partial) parameter update.

If I remodel Arnold's soleus into Millard2012, and reset parameters without initSystem(), the result will now change into a value close to the correct answer.

Not sure if you see it as a bug, but if you wish, I could open an issue for opensim-core.
tkuchida wrote:
Thu Jun 24, 2021 7:10 am
Not sure what the objective of this code is (perhaps just for testing), but the lines after "2. Set muscle parameters here" don't really make sense. You are asking OpenSim to compute things in a Model using a State, but the Model was changed after the State was created. Consider what would have happened if, rather than just setting parameters, you had added a Body to the Model. In short, initSystem() must be called to create a new State if the Model is modified.

Re: Parameters self-update without initSystem()

Posted: Thu Jun 24, 2021 2:11 pm
by tkuchida
If I understand correctly, you are comparing the performance of various models when you compute something from the model using a state that was returned by initSystem() before the model was modified. The OpenSim API makes no guarantee about the results produced using a state from a different model, so sometimes the results might make sense and other times they might not. I think the best result from OpenSim in this situation (when the state being passed in was generated using a different model) would be to throw an Exception, but detecting this type of incompatibility between model and state would be expensive.

Re: Parameters self-update without initSystem()

Posted: Thu Jun 24, 2021 3:44 pm
by 5453zzl
Thank you for the explanation. Yes, that's what caused the slight discrepancy.

I guess modelers simply have to keep in mind that, initSystem() must be called after setting new parameters. Otherwise, even if myMuscle.get_certain_muscle_parameter() correctly returns changed values, this parameterization is only nominal and the calculation itself might be based on some other values.

Throwing an Exception would definitely be a solution, but I'm more curious about why such difference only exists for Thelen2003 and Millard2012, but not Schutte1993.

It might not be worthwhile to investigate, but I'll keep an eye for it, and do let me know if you ever came across the cause.

Thanks again.
tkuchida wrote:
Thu Jun 24, 2021 2:11 pm
If I understand correctly, you are comparing the performance of various models when you compute something from the model using a state that was returned by initSystem() before the model was modified. The OpenSim API makes no guarantee about the results produced using a state from a different model, so sometimes the results might make sense and other times they might not. I think the best result from OpenSim in this situation (when the state being passed in was generated using a different model) would be to throw an Exception, but detecting this type of incompatibility between model and state would be expensive.

Re: Parameters self-update without initSystem()

Posted: Thu Jun 24, 2021 4:40 pm
by tkuchida
I guess modelers simply have to keep in mind that, initSystem() must be called after setting new parameters.
Yes: initSystem() creates the underlying computational system from the model description. If you change the model, the system must be recreated. I think all the examples separate model building from simulation.
I'm more curious about why such difference only exists for Thelen2003 and Millard2012, but not Schutte1993.
Different muscle models are implemented differently (and the Schutte1993 model is deprecated). Nothing in the API specifies what should happen in the situation you are describing, so different behavior is not surprising.
do let me know if you ever came across the cause.
If you are interested, you can read through the code on GitHub---e.g., https://github.com/opensim-org/opensim- ... Muscle.cpp.