Page 1 of 1

State Variable Names do not match order of States?

Posted: Tue Nov 04, 2014 8:24 am
by bradh
I've noticed that the names of the states returned by model.getStateVariableNames(); do not match the order of the states returned by si.getY();.

For example, the code below uses the Arm26 model. It sets the shoulder angle to 0.1 radians and the elbow to 0.2 radians.

If you look at the state order from getStateVariableNames, you get:
'r_shoulder/r_shoulder_elev/r_shoulder_elev' <-- Shoulder Angle
'r_shoulder/r_shoulder_elev/r_shoulder_elev_u'
'r_elbow/r_elbow_flex/r_elbow_flex' <-- Elbow Angle
'r_elbow/r_elbow_flex/r_elbow_flex_u'
'TRIlong/activation' ....

So the shoulder is the 1st entry and the elbow is the 3rd. But when you look at the output from the states you get:

0.1 <-- Shoulder Angle
0.2 <-- Elbow Angle
0
0
0.05 ....

The elbow angle is the 2nd entry here (but was 3rd above).

Is this expected behavior and if so, is there a better way to get the titles of the states returned by getY?

Code: Select all

% Load Library
import org.opensim.modeling.*;

% Open a Model by name
model = Model('arm26.osim');

% Initialize the system and get the initial state
si = model.initSystem();

%Set the Shoulder to 0.1 Radians
model.getJointSet().get('r_shoulder').getCoordinateSet().get('r_shoulder_elev').setValue(si,0.1)

%Set the Elbow to 0.2 Radians
model.getJointSet().get('r_elbow').getCoordinateSet().get('r_elbow_flex').setValue(si,0.2)

%Realize the model
model.computeStateVariableDerivatives(si)


%Get the names of the state variables
stateVarArray=model.getStateVariableNames();
nStateVar=stateVarArray.getSize();  %Number of State Variables
for i=0:(nStateVar-1)
    stateVarNames{i+1}=char(stateVarArray.get(i))
end

%Now get the states
numVar = si.getNY();
stateArray = si.getY();
for i = 0:1:numVar-1
    stateValues(i+1)=stateArray.get(i);
end

Re: State Variable Names do not match order of States?

Posted: Tue Nov 04, 2014 11:13 am
by aymanh
Hi Brad,

Are you using the codebase from the repository or public release version 3.2? If the former then this discussion should be conducted off the forum to avoid confusing users of the latest public release 3.2. Please advise.

Thanks much,
-Ayman

Re: State Variable Names do not match order of States?

Posted: Tue Nov 04, 2014 11:25 am
by aseth
The order of values is in the underlying SimTK::State object should not be depended on. Adding a constraint or another joint will quickly break any assumed order. To reliably access state values use the services provided by the Component interface.
For example:

Code: Select all

    /**
     * Get all values of the state variables allocated by this Component.
     * Includes state variables allocated by its subcomponents.
     *
     * @param state   the State for which to get the value
     * @return Vector of state variable values of length getNumStateVariables()
     *                in the order returned by getStateVariableNames()
     */
    SimTK::Vector getStateVariableValues(const SimTK::State& state) const;

Re: State Variable Names do not match order of States?

Posted: Tue Nov 04, 2014 11:57 am
by bradh
Ayman - My apologies. I thought I had verified that this behavior was reproducible in the released 3.2. I just double checked again in 3.2, it does not seem to be an issue there. So it is limited to the pre-release code I am using.

Ajay - While this looks to be a moot point, I wanted to point out why I believe it is important to be able to use getY and getStateVariableNames. (I'm also not changing joints or constraints during a run, but understand the problem there).

Similar to the Dynamic Walker Starter: http://simtk-confluence.stanford.edu:80 ... Id=5113821

I am using MATLAB to integrate the states. With getY and setY, MATLAB's ODE solvers can be used. It is problematic though to return other calculated values at the integrator time steps (which is what your suggestion creates). If I know what the states are, I don't have to perform any additional calculations. So please retain the functionality.

Regards,

Brad

Re: State Variable Names do not match order of States?

Posted: Tue Nov 04, 2014 12:31 pm
by aseth
We cannot stop you from calling s.getY() etc.. on the State. I guess you can always figure out the order yourself. For others reading this post I strongly advise against doing this since their is absolutely no guarantee that the state layout will remain the same between model versions or releases of OpenSim. Instead using the Component interface: model.getStateVariableNames() and model.getStateVariableValues() are guaranteed to be consistent.

In the case of numerical integration in MATLAB you don't care about order as long as the derivatives correspond, in which case you can safely integrate s.getYDot() and update the state with s.setY() -no problem. The problem arises when you want to know what the state variables are and to what Component they belong to. For that use getStateVariableNames() and getStateVariableValues() since the component maintains the internal bookkeeping and knows its allocation in the State. The purpose of a Component is to provide context (names, relationships) of a model, while the SimTK::System and State are for fast computation.

Re: State Variable Names do not match order of States?

Posted: Thu Jun 09, 2016 8:51 am
by ngilltz
If I use model.getStateVariableValues() instead of states.getY() is there a corresponding alternative for states.updY().set() to update the state values during an integration?

Re: State Variable Names do not match order of States?

Posted: Thu Dec 14, 2017 7:09 am
by antoinefalisse
Hi,

I am having a similar "issue" with OpenSim 4.0.
I built the gait2354 model from scratch through the C++ API and then called

Code: Select all

getStateVariableNames()
to get the order of my states. I obtained, as expected, the state names in the same order as the order I used when adding the joints to my model. However, when testing, I imposed the angular position of the lumbar extension mobility and it affected the ankle angle (as seen with the Visualizer). I used

Code: Select all

state.setQ(Qs);
where Qs is a vector with all my joint angles. It therefore seems that internally the order is not the one reported by

Code: Select all

getStateVariableNames()
. Is that normal? Or am I doing something wrong?

I am wondering whether that could be related to the fact that I am adding the lumbar joint at last and that joint is connected to the pelvis which is the first joint. When I add the lumbar joint just after the pelvis (so before hip/knee/ankle), it seems to work as expected (also if I do not include the lumbar joint).

Thanks in advance,

Antoine

Re: State Variable Names do not match order of States?

Posted: Thu Dec 14, 2017 12:12 pm
by tkuchida
You probably want to use setStateVariableValues() instead (http://myosin.sourceforge.net/2039/clas ... b146973f5e). Model::getStateVariableNames() will return the names of the variables in OpenSim, which I think can differ from the Q vector in the State (e.g., if quaternions are used under the hood but OpenSim uses Euler angles). You might want to confirm that these vectors (i) are the same length, and (ii) store variables in the same order.

Re: State Variable Names do not match order of States?

Posted: Fri Jan 12, 2018 2:40 pm
by antoinefalisse
Thanks for the answer Tom. It looks better using setStateVariableValues().
I have a related question though: I am using calcResidualForceIgnoringConstraints() to get my ID torques. However, it seems that the order of the residualMobilityForces (output) does not correspond to the order of the states such as reported by getStateVariableNames(), which I think could be expected based on your answer. What would be a way to know what is the order of the residualMobilityForces? I can kind of guess based on the results but I would like to be sure.
Many thanks!

Re: State Variable Names do not match order of States?

Posted: Fri Jan 12, 2018 2:55 pm
by tkuchida
I am using calcResidualForceIgnoringConstraints()
The doxygen for this method is here: https://simtk.org/api_docs/simbody/3.5/ ... d43db05df0. Note that this method lives in Simbody, so it doesn't know about OpenSim's naming/ordering conventions; however, you should be able to ask OpenSim objects for their indices on the Simbody side. See, for example, ModelComponent::getStateIndex() (https://simtk.org/api_docs/opensim/api_ ... 204dc0532f). You might check the code (e.g., SimbodyEngine.cpp) for methods and code snippets, as OpenSim will need to do similar things internally.