GRF not being applied correctly to Inverse Dynamics in Python
Posted: Tue Sep 26, 2023 1:15 am
Hello OpenSim Community,
I am trying to implement inverse dynamics in Python. I am using the full body model developed by Rajagopal and their dataset from which I am taking the kinematics and the GRF.
So below is the code I use to run ID
import opensim as osim
mydata = pd.read_excel("ik_output_walk.xlsx",'Sheet1') #Changed IK mot file into xlsx format to extract data. Also converted degrees into
radians
ID_model = osim.Model('Rajagopal2015.osim') #This model has no muscles
#The GRF mot file was divided into two files containing right and left GRF data
grffile_right="grf_walk_for_python_right.mot"
rGRF = osim.ExternalForce(osim.Storage(grffile_right), 'ground_force_r_v', 'ground_force_r_p','ground_torque_r_', 'calcn_r', 'ground', ground')
ID_model.addForce(rGRF)
# The above was throwing an exception, therefore had to use a fix as mentioned here https://github.com/opensim-org/opensim-core/issues/3204
grf_r_storage = osim.Storage('grf_walk_for_python_right.mot', False); # loading the external force data in a storage object
right_GRF_in_model = ID_model.getForceSet().get(0); # getting the force from the model
rGRF.safeDownCast(right_GRF_in_model).setDataSource(grf_r_storage); # resetting the data source
ID_model.finalizeConnections()
grffile_left="grf_walk_for_python_left.mot"
lGRF = osim.ExternalForce(osim.Storage(grffile_left), 'ground_force_l_v', 'ground_force_l_p','ground_torque_l_', 'calcn_l', 'ground', 'ground')
ID_model.addForce(lGRF)
grf_l_storage = osim.Storage('grf_walk_for_python_left.mot', False); # loading the external force data in a storage object
left_GRF_in_model = ID_model.getForceSet().get(1); # getting the force from the model
lGRF.safeDownCast(left_GRF_in_model).setDataSource(grf_l_storage); # resetting the data source
ID_model.finalizeConnections()
ID_state = ID_model.initSystem()
for m in range(ID_model.getCoordinateSet().getSize()): #Setting the initial pose from first row of ik data
ID_model.getCoordinateSet().get(m).setValue(ID_state,float(mydata.iloc[1,m+1]))
#Simulation time from 0.24s to 1.8s
for i in range(2,len(time)):
timed = time[i+1]-time
ID = osim.InverseDynamicsSolver(ID_model)
for j in range(ID_model.getCoordinateSet().getSize()):
model.getCoordinateSet().get(j).setValue(state, mydata[i,j])
model.getCoordinateSet().get(j).setSpeedValue(state, (mydata(i+1,j)-mydata(i,j))/timed)
u_dot = osim.Vector(39,0)
tau = ID.solve(ID_state,u_dot)
But the graphs being produced report very high moments esp. hip and arm flexion moments, whereas ankle moment is very low, indicating the GRF is not being implemented properly. In the figure starting from the top is ankle moment, arm_flex moment, hip_flex moment and then knee_flex moment of right leg.
Please anyone can tell me how I can check whether GRF is being applied correctly? Or is it something else I should look into?
Thanks in advance.
Regards,
Shivangi
I am trying to implement inverse dynamics in Python. I am using the full body model developed by Rajagopal and their dataset from which I am taking the kinematics and the GRF.
So below is the code I use to run ID
import opensim as osim
mydata = pd.read_excel("ik_output_walk.xlsx",'Sheet1') #Changed IK mot file into xlsx format to extract data. Also converted degrees into
radians
ID_model = osim.Model('Rajagopal2015.osim') #This model has no muscles
#The GRF mot file was divided into two files containing right and left GRF data
grffile_right="grf_walk_for_python_right.mot"
rGRF = osim.ExternalForce(osim.Storage(grffile_right), 'ground_force_r_v', 'ground_force_r_p','ground_torque_r_', 'calcn_r', 'ground', ground')
ID_model.addForce(rGRF)
# The above was throwing an exception, therefore had to use a fix as mentioned here https://github.com/opensim-org/opensim-core/issues/3204
grf_r_storage = osim.Storage('grf_walk_for_python_right.mot', False); # loading the external force data in a storage object
right_GRF_in_model = ID_model.getForceSet().get(0); # getting the force from the model
rGRF.safeDownCast(right_GRF_in_model).setDataSource(grf_r_storage); # resetting the data source
ID_model.finalizeConnections()
grffile_left="grf_walk_for_python_left.mot"
lGRF = osim.ExternalForce(osim.Storage(grffile_left), 'ground_force_l_v', 'ground_force_l_p','ground_torque_l_', 'calcn_l', 'ground', 'ground')
ID_model.addForce(lGRF)
grf_l_storage = osim.Storage('grf_walk_for_python_left.mot', False); # loading the external force data in a storage object
left_GRF_in_model = ID_model.getForceSet().get(1); # getting the force from the model
lGRF.safeDownCast(left_GRF_in_model).setDataSource(grf_l_storage); # resetting the data source
ID_model.finalizeConnections()
ID_state = ID_model.initSystem()
for m in range(ID_model.getCoordinateSet().getSize()): #Setting the initial pose from first row of ik data
ID_model.getCoordinateSet().get(m).setValue(ID_state,float(mydata.iloc[1,m+1]))
#Simulation time from 0.24s to 1.8s
for i in range(2,len(time)):
timed = time[i+1]-time
ID = osim.InverseDynamicsSolver(ID_model)
for j in range(ID_model.getCoordinateSet().getSize()):
model.getCoordinateSet().get(j).setValue(state, mydata[i,j])
model.getCoordinateSet().get(j).setSpeedValue(state, (mydata(i+1,j)-mydata(i,j))/timed)
u_dot = osim.Vector(39,0)
tau = ID.solve(ID_state,u_dot)
But the graphs being produced report very high moments esp. hip and arm flexion moments, whereas ankle moment is very low, indicating the GRF is not being implemented properly. In the figure starting from the top is ankle moment, arm_flex moment, hip_flex moment and then knee_flex moment of right leg.
Please anyone can tell me how I can check whether GRF is being applied correctly? Or is it something else I should look into?
Thanks in advance.
Regards,
Shivangi