Page 1 of 1

API plug-in, muscle state parameters

Posted: Fri Oct 07, 2011 1:07 pm
by nataliakosterina
Hi all,

I am trying to write a plug-in for OpenSim. To start with, I want to store some muscle parameters such as forces, activations, lengths... Using an example template giving positions for bones as a basis, I am able now to store muscle names and time column correctly but the values for muscles' states are all zeros. When trying to find a proper function, I get an error "ArrayPtrs.get: Array index out of bounds."

:?:
// Do I need to compute equilibrium for the model or to realize it?
_model->getSystem().realize(s,SimTK::Stage::Velocity);
_model->getSystem().realize(s,SimTK::Stage::Acceleration);
_model->computeEquilibriumForAuxiliaryStates(s);


:?:
Is it right to call muscles using indices for actuators?


I am not an expert in C++ and have difficulties to figure out how to operate with the classes and functions. I will be very glad if you share your experience. I expect it should not be very complicated.

Best,
Natalia


Below are some fragments of my code. I suppose that my problem is in following lines:

//I defined muscle indexes as actuators' attributes:
_muscleIndices[j]=actuatorSet.getIndex(_muscleNames[j]);
labels.append(actuator.getName());


//I tried to use Actuators class:
const OpenSim::Set<Actuator>& actuatorSet = _model->getActuators();
const Actuator& actuator = actuatorSet.get(_muscleIndices);
OutputValues1=actuator.computeActuation(s);
OutputValues2=actuator.getForce(s);


//and also Muscles class:
const Muscle& muscle=_model->getMuscles().get(_muscleIndices);
OutputValues1=muscle.computeActuation(s);
OutputValues2=muscle.getForce(s);

Re: API plug-in, muscle state parameters

Posted: Fri Oct 07, 2011 9:30 pm
by aseth
Natalia,

If you are only concerned with muscles, use getMuscles(). If you build your list of indices using actuators and then do get(index) on a muscle set you are likely to see the Exception that you are getting since Acuators is a super set of Muscles and non muscle actuators will not be present in Muscles.

The easiest thing to do if you are interested in all muscles is to:

Code: Select all

const Set<Muscle>& muscles = _model.getMuscles();
for(int i=0; i<muscles.getsize(); ++i)
   labels.append(muscles[i].getName()); 

I am assuming you are writing your own analysis plugin then the above would go in the setup. In record() you don't have to realize to acceleration. You can call realize Dynamics only. This should realize all Forces (including Muscles) to the stage where forces are being applied to bodies.

Code: Select all

int MyAnalysis::record(const SimTK::State& s)
{
...
    // realize the system to dynamics to compute muscle dynamics
    _model->getMultibodySystem().realize(s,SimTK::Stage::Dynamics);
    const Set<Muscle>& muscles = _model.getMuscles();

   for(int i=0; i<muscles.getsize(); ++i) {
       // get values of interest
       double force = muscles[i].getForce(s);
       double fibforce = muscles[i].getFiberForce(s);
       ...
   
       // store the values of interest
       ...
    }
}
I would also recommend updating to OpenSim 2.4 as soon as it is released. The API is richer and hopefully more clear as well.

Re: API plug-in, muscle state parameters

Posted: Mon Oct 10, 2011 2:49 am
by nataliakosterina
Thanks a lot Ajay,

My plug-in works now.

But the reason for my long way to success is not just mistakes in the code.
After changing my plug-in according to your advices I still had the same error (Array index out of bounds). But after several tests I found the reason, it looks like a bug to me: the motion must be loaded before the plug-in analysis run. Otherwise OpenSim just closes unexpectedly during the analysis. But other analysis such as ID, CMC,... allow to analyze the system when the motion file is just given in the setup file.

Regards,
Natalia

Re: API plug-in, muscle state parameters

Posted: Mon Oct 10, 2011 1:24 pm
by nataliakosterina
Hi again,

I have problems with printing out the values for pennation angle, forces and activations, they all appear as zeros. Only fiber length values appear correctly (I guess because it is one of the states and does not require any analysis).
After realizing the system to dynamics, I tried to equilibrate the muscles, this lead to non-zero values of the initial (first) state of the muscles only. calcPennation and computeForce, computeActuation functions gave zero results.

Please give me a hint what do I miss in my code to be able to "get" muscle parameters.

Thanks for your help,
Natalia

Re: API plug-in, muscle state parameters

Posted: Tue Oct 11, 2011 12:31 am
by aseth
You should not be equilibrating muscles in a record method of an analysis. Equilibration changes the state of the muscle to be in equilibrium and makes the fiber-velocity zero. Equilibrate is called at the beginning of some Tools (like forward) where the initial muscle states are not known and this provides an initial state for the fiber length.

What do you mean by "the motion must be loaded before the plug-in analysis run"? Loaded in the GUI? Or before the run method is called in the analyzeTool which calls your analysis? The analyzeTool should be loading all necessary files before executing- if that is not the case then that would be a bug and we will look into it. If loaded in the GUI that should have no direct effect.

I also suspect there is a bug in how the storages are setup to store the results of the analysis. A quick way to check is to to cout (print to the messages window) the values as you get them. For example:

Code: Select all

    double time = s.getTime(s);
    double pennAngle= muscles[i].getPennationAngle(s);
    cout << "t = " << time << ": pennation angle for muscle " << muscles[i].getName() << " = " << pennAngle << endl;
At least this will rule out any storage/output issues if the values don't make sense. If the values are correct then you know you are not storing them correctly downstream. Hope this is helpful.

Re: API plug-in, muscle state parameters

Posted: Tue Oct 11, 2011 2:06 pm
by nataliakosterina
Hi,

1. "the motion must be loaded before the plug-in analysis run", I mean in GUI. It looks like a bug to me. If the motion is not loaded before running the analysis (my plug-in), then no output will be saved or the OpenSim will be crashed, while it the analysis has its place (maybe not complete, but it takes some time).

2. I noticed that there is a problem to rewrite STO file with the same name. I have to delete or rename it to avoid OpenSim crash.

3. I removed equilibrating muscles, it did not improve the output. I tested the storage, and it works properly, the values are zeros for all parameters except muscle length.

4. I used function "computeActuation" before getting the parameters, then I have got non-zero values for muscle forces :) Passive force ~0.02, active force ~35000.
"computeIsometricForce" does not work with "const state" parameter even though it should.
Pennation angle is still zero. I think the only way for me is to use "calcPennation" function.


Please let me know if any of the achievements are unexpected.
Thanks for your advices,
Natalia

Re: API plug-in, muscle state parameters

Posted: Wed Oct 12, 2011 6:47 am
by nataliakosterina
Hi Ayaj,

all the problems have been solved when I updated OpenSim and adopted my plug-in for the new version.
I had to copy "OpenSim_SimTKcpodes.lib" from the old version to the new \sdk\lib folder, to get a successful build.

I appreciate your help very much,
keep improving the software.

Natalia

Re: API plug-in, muscle state parameters

Posted: Wed Oct 12, 2011 10:09 am
by aymanh
Hi Natalia,

Great that you solved your problems. There's a document on the downloads page Upgrade_Notes_API_24.pdf (https://simtk.org/frs/download.php?file_id=2992) that explains how to upgrade your CMake files when upgrading from an older version (including the fact the OpenSim_SimTKcpodes is neither needed nor distributed any more and how to change old files). I hope this document would save you and others time as you migrate your plugins and/or API programs to the latest version.

All the best,
-Ayman