However, when I perform setValue and setLocked operations on the corresponding joints in Python and then perform IK on the entire dataset, the resulting .mot file shows that the joint values are not locked as expected. I am unsure why this is happening.
Additionally, I noticed that for setting angle parameters, the range in OpenSim is [-360, 360], but when using setValue in Python, the range should be [-2pi, 2pi]. This is evident from the getValue output because when setValue is set to 170, the getValue actually shows a value of 2*pi, indicating that the range is capped at the maximum value.
Code: Select all
import opensim as osim
import pandas as pd
import numpy as np
from decimal import Decimal
# Load the model
model = osim.Model('C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\MOBL_ARMS_module5_scaleIK_try2Scaled.osim')
model.initSystem()
# Create an InverseKinematicsTool instance
ik_tool = osim.InverseKinematicsTool()
ik_tool.setModel(model)
# Set the marker data file
marker_data_file = 'C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\InputFiles\\InputFiles_module5_scaleIK\\Take 2024-06-20 09.32.47 PM_modified.trc'
ik_tool.setMarkerDataFileName(marker_data_file)
# Set the IK task file
ik_task_set = osim.IKTaskSet('C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\InputFiles\\InputFiles_module5_scaleIK\\MoBL_ARMS_module5_IK_Setup_try.xml')
ik_tool.set_IKTaskSet(ik_task_set)
# Temporary output file
temp_output_file = 'C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\InputFiles\\InputFiles_module5_scaleIK\\outputFile\\temp_ik_output.mot'
ik_tool.setOutputMotionFileName(temp_output_file)
# Run the IK analysis using the first 50 rows of marker data
ik_tool.setStartTime(0.0) # Assuming time starts at 0, adjust according to actual data
ik_tool.setEndTime(49 * 0.005) # Assuming a sampling rate of 200Hz (0.005s per frame), first 50 rows of data
ik_tool.run()
# Read the temporary output file to get joint angle data
ik_output = pd.read_csv(temp_output_file, sep='\t', skiprows=10) # Adjust skiprows according to file format
ik_output_first_50 = ik_output.iloc[:50]
# Calculate the average values of specific joints
target_fixed_joint_names = ['r_x', 'r_y', 'r_z', 't_x', 't_y', 't_z'] # Joints to calculate average values
average_values = {}
for joint in target_fixed_joint_names:
average_values[joint] = ik_output_first_50[joint].mean()
for joint in target_fixed_joint_names[0:3]:
average_values[joint] = average_values[joint] * np.pi / 180
# Set the locked values of the joints
state = model.initSystem()
coordinate_set = model.getCoordinateSet()
for joint, avg_value in average_values.items():
coordinate_set.get(joint).setLocked(state, False)
coordinate_set.get(joint).setValue(state, avg_value)
coordinate_set.get(joint).setLocked(state, True)
model.assemble(state)
# Read and check the joint values and locked status
for joint in target_fixed_joint_names:
coord = coordinate_set.get(joint)
value = coord.getValue(state)
is_locked = coord.getLocked(state)
print(f"{joint}: value = {value}, locked = {is_locked}")
# Set the full output file
full_output_file = 'C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\InputFiles\\InputFiles_module5_scaleIK\\outputFile\\full_ik_output.mot'
ik_tool.setOutputMotionFileName(full_output_file)
# Run the IK analysis using all the marker data
ik_tool.setStartTime(0.0) # Adjust according to actual data
ik_tool.setEndTime(float(250 * Decimal('0.005'))) # Set to the last time point of the marker data
ik_tool.run()
# Read the full output file and extract the joint angle data
ik_full_output = pd.read_csv(full_output_file, sep='\t', skiprows=10) # Adjust skiprows according to file format
target_joint_names = ['elv_angle', 'shoulder_elv', 'shoulder_rot', 'elbow_flexion', 'pro_sup', 'deviation', 'flexion']
result_data = ik_full_output[target_joint_names]
# Save the results to a file (optional)
result_data.to_csv('C:\\Users\\User\\Documents\\OpenSim\\4.5-2024-01-10-3b63585\\Models\\MobL_ARMS_unimanual\\4.1 Model with Millard-Schutte Matched Curves\\InputFiles\\InputFiles_module5_scaleIK\\outputFile\\result_joint_angles.csv', index=False)
print(f"The average values of the specific joints have been locked and the complete IK results have been generated.")