I am trying to write a python script in 4.4 that takes a point in a rigid body's reference frame and gives me that point in the ground reference frame throughout a motion to eventually apply a point force. I've done this with Point Kinematics under the Analyze Tool, but OpenSim seems to think it needs 30 minutes to a couple hours initializing the Analyze Tool before it runs the tool which then only takes a few minutes. So...the plan is to bypass the analyze tool and write a script that just pulls and applies the necessary transformation matrices. Unfortunately, I've hit a roadblock with my code and was hoping for some input.
Right now, I think the issue is with how I am trying to pull the transformation matrix of my rigid body with respect to ground. I figured using the getTransformInGround or findTransformBetween would save hard coding all the various transforms between rigid bodies. So far my results just look like noise compared to using the Point Kinematics results as truth (figures below). At first I thought I was using the wrong matrix multiplier function, could still be, but I tried all combinations of them (commented below). Then tried converting the opensim transform variable into a numpy arrays but got consistent results between the numpy array and opensim scripts. I did confirm that the joint coordinates of each model state matches the motion file.
Any thoughts greatly appreciated
Code: Select all
import opensim as osim
import numpy as np
import pandas as pd
# Load and Initialize the model
model = osim.Model('MyModel.osim')
state = model.initSystem()
#Load Motion
q = osim.TimeSeriesTable('MyMotion.mot')
time = q.getIndependentColumn()
# Define the point in the frame of the rigid body
local_point = osim.Vec3(0.00456791, -0.0194644, -0.0088202) # Point
rigid_body_name = 'distal_thumb' # Rigid body name
# Variable to store transformed point values
transformed_points=[]
for i,ii in enumerate(time):
value=osim.RowVector(q.getRowAtIndex(i))
for j, coordinate in enumerate(model.updCoordinateSet()):
coordinate.setValue(state, value[j], False)
model.realizePosition(state)
# Get the rigid body
rigid_body = model.getBodySet().get(rigid_body_name)
# Get the transformation from the local frame to ground frame
transform=rigid_body.getTransformInGround(state)
#transform = rigid_body.findTransformBetween(state,model.getGround())
# Apply transformation matrix to point
#point_in_ground=transform.xformFrameVecToBase(local_point)
#point_in_ground=transform.xformBaseVecToFrame(local_point)
point_in_ground=transform.shiftBaseStationToFrame(local_point)
#point_in_ground=transform.shiftFrameStationToBase(local_point)
# Store the transformed point
transformed_points.append([time[i],point_in_ground.get(0), point_in_ground.get(1), point_in_ground.get(2)])
#Convert Transformed points into dataframe for saving
transformed_points=pd.DataFrame(transformed_points, columns=['time','state_0','state_1','state_2'])