Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
-
Hide Kimpara
- Posts: 135
- Joined: Mon Sep 19, 2016 5:12 am
Post
by Hide Kimpara » Tue Nov 28, 2017 10:31 am
Dear Experts,
We are trying to obtain joint reaction forces during run-time from MATLAB. We use OpenSim 4.0.
After integration using Manager function, we tried following codes on MATLAB.
When we check the method of "calcMobilizerReactionForces", this method is asking to input "Vector_< SpatialVec > & forcesAtMInG".
https://simtk.org/api_docs/simbody/3.5/ ... 160787d4af
Code: Select all
simulationManager.integrate(s);
osimModel.realizeDynamics(s);
smss = osimModel.getMatterSubsystem();
JointRF = VectorOfSpatialVec();
smss.calcMobilizerReactionForces(s, JointRF);
However, we received following error messages.
Code: Select all
Java exception occurred:
java.lang.RuntimeException: SimTK Exception thrown at State.cpp:974:
Error detected by Simbody method getCacheEntry: State Cache entry was out of date at Stage Dynamics. This entry depends on version 1 of
Stage Dynamics but was last updated at version 169.
(Required condition 'version == m_dependsOnVersionWhenLastComputed' was not met.)
at org.opensim.modeling.opensimSimbodyJNI.SimbodyMatterSubsystem_calcMobilizerReactionForces(Native Method)
at org.opensim.modeling.SimbodyMatterSubsystem.calcMobilizerReactionForces(SimbodyMatterSubsystem.java:311)
What other scripts are necessary to obtain joint reaction forces?
Thank you and Best,
Hide
-
jimmy d
- Posts: 1375
- Joined: Thu Oct 04, 2007 11:51 pm
Post
by jimmy d » Tue Nov 28, 2017 4:16 pm
Below are a list of outputs that are possible from Joints in 4.0;
Code: Select all
Outputs from /subject01/ankle_r [CustomJoint]
=============================================
[double] power
[SpatialVec] reaction_on_child
[SpatialVec] reaction_on_parent
Outputs from /subject01/ankle_r/ankle_angle_r [Coordinate]
==========================================================
[double] acceleration
[double] speed
[double] value
Outputs from /subject01/ankle_r/tibia_r_offset [PhysicalOffsetFrame]
====================================================================
[SpatialVec] acceleration
[Vec3] angular_acceleration
[Vec3] angular_velocity
[Vec3] linear_acceleration
[Vec3] linear_velocity
[Vec3] position
[Transform] transform
[SpatialVec] velocity
You would add a reporter to the model that collected either 'reaction_on_child' or 'reaction_on_parent' and then integrate using the manager. There is a Matlab example of using a reporter to collect marker positions
here.
** EDIT **
Actually, Table reporter may not be able to handle SpatialVec() (the reaction data type) yet. I will add and test this in the Master branch and get back to you when it is available.
-
Hide Kimpara
- Posts: 135
- Joined: Mon Sep 19, 2016 5:12 am
Post
by Hide Kimpara » Tue Nov 28, 2017 5:06 pm
Hello James,
Thank you for your prompt response!
I thought Table reporter can cover position-based data. However, there are no example for reaction forces or contact forces. For example, contact forces could be obtained from state variables with realizeDynamics after the integration. On the other hand, Table reporter requires to register variables on osimModel before the integration.
Is using Table Reporter the only to get joint reaction forces in MATLAB with 4.0?
Is there other strategy such as "calcMobilizerReactionForces"?
Thank you and Best,
Hide
-
jimmy d
- Posts: 1375
- Joined: Thu Oct 04, 2007 11:51 pm
Post
by jimmy d » Wed Nov 29, 2017 12:57 pm
Access to SpatialVecs from reporters and outputs have not yet been included in the swig interface, so they couldn't yet be accessed from Matlab. I have submitted a PR for this; you can view and track the PR
here. Once this has been accepted, the code to get the reactions will look like this;
Code: Select all
import org.opensim.modeling.*
model = Model('arm26.osim');
s = model.initSystem();
% Realize System to Accelerations
model.realizeAcceleration(s)
% Get reference to a joint
elbow = model.getJointSet.get(1);
% Get reaction output from the joint (Abstract Output)
ao = elbow.getOutput('reaction_on_child');
% Downcast to concrete output type (AbstractOutputSpatialVec)
aosv = OutputSpatialVec.safeDownCast(ao);
% Get the reaction as a Spatial Vec
sv = aosv.getValue(s);
-
Christopher Dembia
- Posts: 506
- Joined: Fri Oct 12, 2012 4:09 pm
Post
by Christopher Dembia » Wed Nov 29, 2017 3:10 pm
It'll be good for the TableReporterSpatialVec to be available in the bindings, though I think the cause of the original issue was that you must realize to Acceleration to access reaction forces (Dynamics is not sufficient).
-
Hide Kimpara
- Posts: 135
- Joined: Mon Sep 19, 2016 5:12 am
Post
by Hide Kimpara » Wed Nov 29, 2017 4:01 pm
Hello James and Christopher,
It's very prompt solutions! When the new interface passes through the test, I'm happy to use it with MATLAB.
Also Thank you for letting know that acceleration must be realized. After reading your suggestion, I go back to SimBody manual. Then I found a note saying "Stage::acceleration".
Thank you so much!
Hide
-
Hide Kimpara
- Posts: 135
- Joined: Mon Sep 19, 2016 5:12 am
Post
by Hide Kimpara » Fri Dec 15, 2017 6:45 pm
Hello Jimmy,
jimmy wrote:Once this has been accepted, the code to get the reactions will look like this;
Code: Select all
import org.opensim.modeling.*
model = Model('arm26.osim');
s = model.initSystem();
% Realize System to Accelerations
model.realizeAcceleration(s)
% Get reference to a joint
elbow = model.getJointSet.get(1);
% Get reaction output from the joint (Abstract Output)
ao = elbow.getOutput('reaction_on_child');
% Downcast to concrete output type (AbstractOutputSpatialVec)
aosv = OutputSpatialVec.safeDownCast(ao);
% Get the reaction as a Spatial Vec
sv = aosv.getValue(s);
I tried to do similar thing on C++ API with OpenSim 4.0.
However, I cannot find alternative keyword of "OutputSpatialVec.safeDownCast" in C++.
In the meanwhile, I found other methods such as calcReactionOnChildExpressedInGround and calcReactionOnParentExpressedInGround. Both methods may give us spacial vectors in ground coordinate system. I remember forward simulation tool in OpenSim GUI has an output option that enables joint reaction force on child or parent coordinate systems. In similar way, if we wish to get those vectors in child or parent local coordinates, we may need to transfer those from ground to desired coordinates. Or does OpenSim have another output options providing data on local coordinates?
Many thanks, Hide
-
Thomas Uchida
- Posts: 1793
- Joined: Wed May 16, 2012 11:40 am
Post
by Thomas Uchida » Mon Dec 18, 2017 2:47 pm
I cannot find alternative keyword of "OutputSpatialVec.safeDownCast" in C++.
You can use dynamic_cast in C++.
-
Shelby Walford
- Posts: 7
- Joined: Tue Sep 04, 2018 12:05 pm
Post
by Shelby Walford » Fri Oct 30, 2020 12:58 pm
Hi All,
I found this thread while I was looking for how to retrieve joint reaction forces from the Table Reporter. I am using Matlab, and I am able to create the TableReporterSpatialVec, but unfortunately the function "addToReport" doesn't exist in Matlab under this class for OpenSim 4.0. Is there another way to retrieve the time history of the joint reaction force without having to use the Analysis tool to run a JointReaction Analysis? It'd be great to not have to run another tool because I am running forward dynamics with the manager. I suppose I could run the manager in small increments and at each state, use "calcReactionOnParent" for my joint of interest. However, this seems like it wouldn't be very efficient.
Thanks for your help!
Shelby