How To Get the Torque at Specific Positions?
How To Get the Torque at Specific Positions?
We have a model, and we are trying to get an approximation of how difficult certain poses are. We are trying to get the torque at different positions in python. Does anyone have any sample scripts or pointers on how to do that?
Tags:
- Mohammadreza Rezaie
- Posts: 407
- Joined: Fri Nov 24, 2017 12:48 am
Re: How To Get the Torque at Specific Positions?
Hi, if I'm not mistaken, InverseDynamicsSolver could help. This requires accelerations; after updating the coordinates' value and speed, call realizeVelocity, prepare a vector of accelerations in multibody tree order, and solve it. The general form should be something like this (you can also use a loop to solve it at each time frame):We are trying to get the torque at different positions in python.
Code: Select all
import opensim as osim
import numpy as np
model = osim.Model('./input/scaled.osim')
state = model.initSystem()
IDSolver = osim.InverseDynamicsSolver(model)
for coordinate in model.getCoordinateSet():
coordinate.setValue(state, 1) # test in radians
coordinate.setSpeedValue(state, 1) # test in radians/s
model.realizeVelocity(state)
# # accelerations vector must be in multibody tree order:
# CTree = model.getCoordinateNamesInMultibodyTreeOrder()
# CTree = [CTree.getElt(i) for i in range(CTree.size())]
n = state.getNU()
uDot = osim.Vector(np.ones(n)) # test in radians/s^2
IDSolver.solve(state, uDot).to_numpy()
Hope this helps.
-Mohammadreza
Re: How To Get the Torque at Specific Positions?
Thank you so much for the response! I tried using InverseDynamicsSolver but got very strange values as output. the values (below) are very large, and don't seem to match up with what I think the torque should be.
here's my code:
here is what test_torque_values printed out:
[-525.8879515086584, 1759.1103165292966, -315.1703446028086, 0.07566166921931483, 58.50165393582534, -16.38013139804234, 9.067275629231764]
1759.1103165292966
2049.6546823307117
2066.793696377007
shoulder_elv ranges from zero to pi. When at shoulder_elv is at pi/2, the arm is parallel with the ground in opensim creator. To me it seems that the highest torque on this joint should be when the arm is held parallel to the ground, but the values don't reflect that. Also, I don't understand why the values are so large.
here's my code:
Code: Select all
def get_torque_values(model, state, pos=None, coord_names = ["elv_angle", "shoulder_elv", "shoulder_rot", "elbow_flexion", "pro_sup", "deviation", "flexion"]):
inverse_dynamics_solver = osim.InverseDynamicsSolver(model)
coords = model.getCoordinateSet()
to_keep_index = []
for i in range(coords.getSize()):
coord = coords.get(i)
coord.setSpeedValue(state,0)
if coord.getName() in coord_names:
to_keep_index.append(i)
if pos is not None:
coord.setValue(state,pos[coords.get(i).getName()])
coord.setSpeedValue(state,0)
model.realizeVelocity(state)
udot = osim.Vector(model.getNumSpeeds(), 0.0)
torque_values = inverse_dynamics_solver.solve(state,udot)
relevant_torque_values = [torque_values[to_keep_index[i]] for i in range(len(to_keep_index))]
return relevant_torque_values
def test_torque_values(model_path, joint_names=["elv_angle", "shoulder_elv", "shoulder_rot", "elbow_flexion", "pro_sup", "deviation", "flexion"]):
model = osim.Model(model_path)
state = model.initSystem()
default = get_torque_values(model,state)
testCoord = model.getCoordinateSet().get("shoulder_elv")
testCoord.setValue(state,3.14/2)
raised = get_torque_values(model,state)
# testCoord = model.getCoordinateSet().get("elbow_flexion")
testCoord.setValue(state,3.14)
high = get_torque_values(model,state)
print('range max: ',testCoord.getRangeMax())
print(default)
print(default[1])
print(raised[1])
print(high[1])
test_torque_values(model_path)
[-525.8879515086584, 1759.1103165292966, -315.1703446028086, 0.07566166921931483, 58.50165393582534, -16.38013139804234, 9.067275629231764]
1759.1103165292966
2049.6546823307117
2066.793696377007
shoulder_elv ranges from zero to pi. When at shoulder_elv is at pi/2, the arm is parallel with the ground in opensim creator. To me it seems that the highest torque on this joint should be when the arm is held parallel to the ground, but the values don't reflect that. Also, I don't understand why the values are so large.
Re: How To Get the Torque at Specific Positions?
Also I am hoping to use InverseDynamicTools to get the torque values through a motion from a motion sto file. On the API it says:
If I am interpreting this correctly, the run() function of InverseDynamicsTool returns the generalized forces, and I need to use some other function to get the torque? I am wondering how I can get the torque and force? I don't see functions listed in the api that would allow me to do so.
https://simtk.org/api_docs/opensim/api_ ... l#details"As an additional service, the InverseDynamicsTool can provide an equivalent body force (torque and force) applied to the joint frame. Since generalized forces include scaling (due to units conversion as well as coupling between translations and rotations, for example) they are not necessarily joint torques or forces. "
If I am interpreting this correctly, the run() function of InverseDynamicsTool returns the generalized forces, and I need to use some other function to get the torque? I am wondering how I can get the torque and force? I don't see functions listed in the api that would allow me to do so.