def perform_ik(model_file, trc_file, results_dir): """Performs Inverse Kinematics using OpenSim. Parameters ---------- model_file: str OpenSim model (.osim) trc_file: str the experimentally measured marker trajectories (.trc) results_dir: str directory to store the results """ model = opensim.Model(model_file) model.initSystem() marker_data = opensim.MarkerData(trc_file) name = os.path.basename(trc_file)[:-4] ik_tool = opensim.InverseKinematicsTool() task_set = ik_tool.getIKTaskSet() construct_ik_task_set(model, marker_data, task_set) ik_tool.setName(name) ik_tool.setModel(model) ik_tool.setStartTime(marker_data.getStartFrameTime()) ik_tool.setEndTime(marker_data.getLastFrameTime()) ik_tool.setMarkerDataFileName(trc_file) ik_tool.setResultsDir(results_dir) ik_file = results_dir + name + '_ik.mot' ik_tool.setOutputMotionFileName(ik_file) ik_tool.run() return ik_file
def inverseKinematics(): import os import re import shutil import opensim as osim import directories # Global Directories allDir = list(directories.main(directories)) parentDir = allDir[0] paramsDir = allDir[1] subID = allDir[4] subResultsDir = allDir[5] ikResultsDir = allDir[6] # Clear Inverse Kinematics Folder if os.path.exists(ikResultsDir): shutil.rmtree(ikResultsDir, ignore_errors=True) if not os.path.exists(ikResultsDir): os.mkdir(ikResultsDir) # Input settings File genericSettings = paramsDir + "/setupIK.xml" # Input trc File dataFiles = parentDir + "/data/osDemo" ikMarkerFileName = "subject01_walk1.trc" ikMarkerFile = dataFiles + "/" + ikMarkerFileName shutil.copy(ikMarkerFile, ikResultsDir + "/" + ikMarkerFileName) # Load scaled Model aModel = osim.Model(subResultsDir + "/" + subID + ".osim") # Import Inverse Kinematics Tool ikTool = osim.InverseKinematicsTool(genericSettings) # Tell IK tool to use loaded model ikTool.setModel(aModel) # Get scaled marker file + data markerData = osim.MarkerData(ikMarkerFile) # Get Initial and Final Time initial_time = markerData.getStartFrameTime() final_time = markerData.getLastFrameTime() # set IK tool for this trial ikName = re.sub('.trc', '', ikMarkerFileName) ikTool.setName(ikName) ikTool.setMarkerDataFileName(ikMarkerFile) ikTool.setStartTime(initial_time) ikTool.setEndTime(final_time) ikTool.setOutputMotionFileName(ikResultsDir + "/" + ikName + "_ik.mot") # Run IK ikTool.run() ikTool.printToXML(ikResultsDir + "/" + "setupIK.xml") # Clear terminal os.system('cls' if os.name == 'nt' else 'clear') return()
def run_ik_tool(self, trial): model = osim.Model(self.model_input) # initialize inverse kinematic tool from setup file ik_tool = osim.InverseKinematicsTool(self.xml_input) ik_tool.setModel(model) print(f'\t{trial.stem}') # initialize inverse kinematic tool from setup file ik_tool = osim.InverseKinematicsTool(self.xml_input) ik_tool.setModel(model) # set name of input (trc) file and output (mot) if self.prefix: filename = f"{self.prefix}_{trial.stem}" else: filename = trial.stem ik_tool.setName(filename) ik_tool.setMarkerDataFileName(f'{trial}') ik_tool.setOutputMotionFileName( f"{Path(self.mot_output) / filename}.mot") ik_tool.setResultsDir(self.mot_output) if trial.stem in self.onsets: # set start and end times from configuration file start = self.onsets[trial.stem][0] end = self.onsets[trial.stem][1] else: # use the trc file to get the start and end times m = osim.MarkerData(f'{trial}') start = m.getStartFrameTime() end = m.getLastFrameTime( ) - 1e-2 # -1e-2 because removing last frame resolves some bug ik_tool.setStartTime(start) ik_tool.setEndTime(end) ik_tool.printToXML(self.xml_output) ik_tool.run()
def perform_ik(model_file, trc_file, results_dir, settings_dir, opensimtools_dir, opensimplugin_dir): """Performs Inverse Kinematics using OpenSim. Parameters ---------- model_file: str OpenSim model (.osim) trc_file: str the experimentally measured marker trajectories (.trc) results_dir: str directory to store the results """ model = opensim.Model(model_file) # model.set_assembly_accuracy(1e-3) #model.initSystem() marker_data = opensim.MarkerData(trc_file) trial = os.path.basename(trc_file)[:-4] ik_tool = opensim.InverseKinematicsTool() task_set = ik_tool.getIKTaskSet() construct_ik_task_set(model, marker_data, task_set) ik_tool.setName(trial) ik_tool.setModel(model) ik_tool.setStartTime(marker_data.getStartFrameTime()) ik_tool.setEndTime(marker_data.getLastFrameTime()) ik_tool.setMarkerDataFileName(trc_file) ik_tool.setResultsDir(results_dir) ik_file = results_dir + trial + '_IK.mot' ik_xml = settings_dir + trial + '_Setup_IK.xml' ik_tool.setOutputMotionFileName(ik_file) ik_tool.printToXML(ik_xml) ##parsing the previously created setup file and change the model_file item ik_set_file = parse(ik_xml) ik_set_file.getElementsByTagName( "model_file")[0].childNodes[0].nodeValue = model_file ## save the xml file F = open(ik_xml, "w") ik_set_file.writexml(F) F.close() # run the IK tool through cmd ik_cmd = opensimtools_dir + '\ik -S ' + ik_xml print(os.system(ik_cmd)) return ik_file
def _load_from_setup_file(self, file_path): # type: (str) -> None """ Initialize properties for the IK tool from an OpenSim Inverse Kinematics setup file. Settings for 'results_directory', 'input_directory', 'report_errors' and 'ouput_motion_file' are ignored. """ tool = opensim.InverseKinematicsTool(file_path) self.accuracy = float(tool.getPropertyByName("accuracy").toString()) self.constraint_weight = float( tool.getPropertyByName("constraint_weight").toString()) self.coordinate_file = tool.getCoordinateFileName() self.ik_task_set = tool.getIKTaskSet().clone() self.marker_file = tool.getMarkerDataFileName() self.model_file = tool.getPropertyByName("model_file").toString() self.time_final = tool.getEndTime() self.time_start = tool.getStartTime()
def access_model(params): hlx = params[0] hly = params[1] hlz = params[2] # print('Params: %f %f %f' %(hlx,hly,hlz)) # Load model for running IK on model = osim.Model( r'C:\Users\llim726\Documents\infant_analysis\jw\jw_Scaled_offset.osim') # Add geometry path to ensure the geometry files are found path = r'C:\OpenSim 4.0\Geometry' osim.ModelVisualizer.addDirToGeometrySearchPaths(path) # Locate the left hip joint and edit the location of the parent (pelvis) frame jointset = model.getJointSet() hip_l = jointset.get('hip_l') # print('Translation before: %f %f %f' % (hip_l.get_frames(0).get_translation()[0],hip_l.get_frames(0).get_translation()[1],hip_l.get_frames(0).get_translation()[2])) hip_l.get_frames(0).set_translation(osim.Vec3(hlx, hly, hlz)) s = model.initSystem() #model.printToXML(r"C:\Users\llim726\Documents\infant_analysis\jw\jw_Scaled_changing.osim") # print('Translation after: %f %f %f' % (hip_l.get_frames(0).get_translation()[0],hip_l.get_frames(0).get_translation()[1],hip_l.get_frames(0).get_translation()[2])) # Load preconfigured IK settings file - create this using the IKTool GUI and save the necessary parameters ik_settings = osim.InverseKinematicsTool( r'C:\Users\llim726\Documents\infant_analysis\jw\jw_ik_tools.xml') ik_taskset = ik_settings.getIKTaskSet() ik_taskset.printToXML( r"C:\Users\llim726\Documents\infant_analysis\jw\iktaskset.xml") # Apply IK settings to the loaded model and run ik_settings.setOutputMotionFileName( r'C:\Users\llim726\Documents\infant_analysis\jw\opt_ik.mot') #ik_settings.setName(r'G:\My Drive\infant_analysis\4_opensim\jw\jw_Scaled.osim') ik_settings.setModel(model) # ik_settings.run() # ik_settings.printToXML(r"C:\Users\llim726\Documents\infant_analysis\jw\jw_ik_tools.xml") # # Open log file to read in the IK RMS errors # f = open(r'C:\Users\llim726\Documents\infant_analysis\out.log', 'r') # ik_log = f.readlines() # # Get the start of the Error output of the most recent IK # for i in range(len(ik_log)): # if ik_log[i] == 'Running tool .\n': # rmse_start = i+1 # if not rmse_start: # sys.exit('No error output found in out.log.') # # for i in range(rmse_start,len(ik_log)): # ind_start = ik_log[i].find('RMS=') # ind_end = ik_log[i].find(', max') # if ind_start == -1: # check = ik_log[i].find('completed') # if check: # end of results found, can generate the rms array # break # elif i == rmse_start: # rmse = np.array(float(ik_log[i][ind_start+4:ind_end-1])) # else: # rmse = np.vstack((rmse,float(ik_log[i][ind_start+4:ind_end-1]))) ik_setup_file = r"C:\Users\llim726\Documents\infant_analysis\jw\jw_ik_tools.xml" # Create InverseKinematicsTool. ik_tool = InverseKinematicsTool(ik_setup_file) ik_tool.model = model rmse = ik_tool.solve() # Calculate the mean RMSE mean_rmse = np.mean(rmse) print(mean_rmse) return mean_rmse
Initialize properties for the IK tool from an OpenSim Inverse Kinematics setup file. Settings for 'results_directory', 'input_directory', 'report_errors' and 'ouput_motion_file' are ignored. """ tool = opensim.InverseKinematicsTool(file_path) self.accuracy = float(tool.getPropertyByName("accuracy").toString()) self.constraint_weight = float( tool.getPropertyByName("constraint_weight").toString()) self.coordinate_file = tool.getCoordinateFileName() self.ik_task_set = tool.getIKTaskSet().clone() self.marker_file = tool.getMarkerDataFileName() self.model_file = tool.getPropertyByName("model_file").toString() self.time_final = tool.getEndTime() self.time_start = tool.getStartTime() if __name__ == "__main__": # Set paths to model and marker data. ik_setup_file = r"C:\Users\llim726\Documents\infant_analysis\jw\jw_ik_tools_changing.xml" # Create InverseKinematicsTool. ik_tool = InverseKinematicsTool(ik_setup_file) rmse = ik_tool.solve() ik_tool_opensim = opensim.InverseKinematicsTool(ik_setup_file) ik_tool_opensim.run() #assert np.isclose(rmse[-1], 0.0158721) pass
def run_tracking_problem(self, root_dir, config): modelProcessor = self.create_model_processor(root_dir, for_inverse=False, config=config) model = modelProcessor.process() model.initSystem() # Count the number of Force objects in the model. We'll use this to # normalize the control effort cost. numForces = 0 for actu in model.getComponentsList(): if (actu.getConcreteClassName().endswith('Muscle') or actu.getConcreteClassName().endswith('Actuator')): numForces += 1 # Construct the base tracking problem # ----------------------------------- track = osim.MocoTrack() track.setName('tracking_walking') track.setModel(modelProcessor) if self.coordinate_tracking: tableProcessor = osim.TableProcessor(os.path.join(root_dir, 'resources/Rajagopal2016/coordinates.mot')) tableProcessor.append(osim.TabOpLowPassFilter(6)) tableProcessor.append(osim.TabOpUseAbsoluteStateNames()) track.setStatesReference(tableProcessor) track.set_states_global_tracking_weight( config.tracking_weight / (2 * model.getNumCoordinates())) # Don't track some pelvis coordinates to avoid poor walking motion # solutions. stateWeights = osim.MocoWeightSet() weightList = list() weightList.append(('/jointset/ground_pelvis/pelvis_ty/value', 0)) weightList.append(('/jointset/ground_pelvis/pelvis_tz/value', 0)) weightList.append(('/jointset/ground_pelvis/pelvis_list/value', 0)) weightList.append(('/jointset/ground_pelvis/pelvis_tilt/value', 0)) weightList.append(('/jointset/ground_pelvis/pelvis_rotation/value', 0)) weightList.append(('/jointset/hip_r/hip_rotation_r/value', 0)) # weightList.append(('/jointset/hip_r/hip_adduction_r/value', 0)) weightList.append(('/jointset/hip_l/hip_rotation_l/value', 0)) # weightList.append(('/jointset/hip_l/hip_adduction_l/value', 0)) # weightList.append(('/jointset/ankle_r/ankle_angle_r/value', 10)) # weightList.append(('/jointset/ankle_l/ankle_angle_l/value', 10)) for weight in weightList: stateWeights.cloneAndAppend(osim.MocoWeight(weight[0], weight[1])) track.set_states_weight_set(stateWeights) track.set_apply_tracked_states_to_guess(True) # track.set_scale_state_weights_with_range(True); else: track.setMarkersReferenceFromTRC(os.path.join(root_dir, 'resources/Rajagopal2016/markers.trc')) track.set_markers_global_tracking_weight( config.tracking_weight / (2 * model.getNumMarkers())) iktool = osim.InverseKinematicsTool(os.path.join(root_dir, 'resources/Rajagopal2016/ik_setup_walk.xml')) iktasks = iktool.getIKTaskSet() markerWeights = osim.MocoWeightSet() for marker in model.getComponentsList(): if not type(marker) is osim.Marker: continue for i in np.arange(iktasks.getSize()): iktask = iktasks.get(int(i)) if iktask.getName() == marker.getName(): weight = osim.MocoWeight(iktask.getName(), iktask.getWeight()) markerWeights.cloneAndAppend(weight) track.set_markers_weight_set(markerWeights) track.set_allow_unused_references(True) track.set_track_reference_position_derivatives(True) track.set_control_effort_weight(config.effort_weight / numForces) track.set_initial_time(self.initial_time) track.set_final_time(self.half_time) track.set_mesh_interval(self.mesh_interval) # Customize the base tracking problem # ----------------------------------- study = track.initialize() problem = study.updProblem() problem.setTimeBounds(self.initial_time, [self.half_time-0.2, self.half_time+0.2]) # Set the initial values for the lumbar and pelvis coordinates that # produce "normal" walking motions. problem.setStateInfo('/jointset/back/lumbar_extension/value', [], -0.12) problem.setStateInfo('/jointset/back/lumbar_bending/value', [], 0) problem.setStateInfo('/jointset/back/lumbar_rotation/value', [], 0.04) problem.setStateInfo('/jointset/ground_pelvis/pelvis_tx/value', [], 0.446) problem.setStateInfo('/jointset/ground_pelvis/pelvis_tilt/value', [], 0) problem.setStateInfo('/jointset/ground_pelvis/pelvis_list/value', [], 0) problem.setStateInfo('/jointset/ground_pelvis/pelvis_rotation/value', [], 0) # Update the control effort goal to a cost of transport type cost. effort = osim.MocoControlGoal().safeDownCast( problem.updGoal('control_effort')) effort.setDivideByDisplacement(True) # Weight residual and reserve actuators low in the effort cost since # they are already weak. if config.effort_weight: for actu in model.getComponentsList(): actuName = actu.getName() if actu.getConcreteClassName().endswith('Actuator'): effort.setWeightForControl(actu.getAbsolutePathString(), 0.001) for muscle in ['psoas', 'iliacus']: for side in ['l', 'r']: effort.setWeightForControl( '/forceset/%s_%s' % (muscle, side), 0.25) speedGoal = osim.MocoAverageSpeedGoal('speed') speedGoal.set_desired_average_speed(1.235) problem.addGoal(speedGoal) # MocoFrameDistanceConstraint # --------------------------- if self.coordinate_tracking: distanceConstraint = osim.MocoFrameDistanceConstraint() distanceConstraint.setName('distance_constraint') # Step width is 0.13 * leg_length # distance = 0.10 # TODO Should be closer to 0.11. # Donelan JM, Kram R, Kuo AD. Mechanical and metabolic determinants # of the preferred step width in human walking. # Proc Biol Sci. 2001;268(1480):1985–1992. # doi:10.1098/rspb.2001.1761 # https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1088839/ distanceConstraint.addFramePair( osim.MocoFrameDistanceConstraintPair( '/bodyset/calcn_l', '/bodyset/calcn_r', 0.09, np.inf)) distanceConstraint.addFramePair( osim.MocoFrameDistanceConstraintPair( '/bodyset/toes_l', '/bodyset/toes_r', 0.06, np.inf)) # distanceConstraint.addFramePair( # osim.MocoFrameDistanceConstraintPair( # '/bodyset/calcn_l', '/bodyset/toes_r', distance, np.inf)) # distanceConstraint.addFramePair( # osim.MocoFrameDistanceConstraintPair( # '/bodyset/toes_l', '/bodyset/calcn_r', distance, np.inf)) distanceConstraint.setProjection("vector") distanceConstraint.setProjectionVector(osim.Vec3(0, 0, 1)) problem.addPathConstraint(distanceConstraint) # Symmetry constraints # -------------------- statesRef = osim.TimeSeriesTable('tracking_walking_tracked_states.sto') initIndex = statesRef.getNearestRowIndexForTime(self.initial_time) symmetry = osim.MocoPeriodicityGoal('symmetry') # Symmetric coordinate values (except for pelvis_tx) and speeds. for coord in model.getComponentsList(): if not type(coord) is osim.Coordinate: continue coordName = coord.getName() coordValue = coord.getStateVariableNames().get(0) coordSpeed = coord.getStateVariableNames().get(1) if coordName.endswith('_r'): symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordValue, coordValue.replace('_r/', '_l/'))) symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordSpeed, coordSpeed.replace('_r/', '_l/'))) elif coordName.endswith('_l'): symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordValue, coordValue.replace('_l/', '_r/'))) symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordSpeed, coordSpeed.replace('_l/', '_r/'))) elif (coordName.endswith('_bending') or coordName.endswith('_rotation') or coordName.endswith('_tz') or coordName.endswith('_list')): # This does not include hip rotation, # because that ends with _l or _r. symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordValue)) symmetry.addNegatedStatePair(osim.MocoPeriodicityGoalPair( coordSpeed)) elif not coordName.endswith('_tx'): symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordValue)) symmetry.addStatePair(osim.MocoPeriodicityGoalPair( coordSpeed)) symmetry.addStatePair(osim.MocoPeriodicityGoalPair( '/jointset/ground_pelvis/pelvis_tx/speed')) # Symmetric activations. for actu in model.getComponentsList(): if (not actu.getConcreteClassName().endswith('Muscle') and not actu.getConcreteClassName().endswith('Actuator')): continue if actu.getName().endswith('_r'): symmetry.addStatePair(osim.MocoPeriodicityGoalPair( actu.getStateVariableNames().get(0), actu.getStateVariableNames().get(0).replace('_r/', '_l/'))) elif actu.getName().endswith('_l'): symmetry.addStatePair(osim.MocoPeriodicityGoalPair( actu.getStateVariableNames().get(0), actu.getStateVariableNames().get(0).replace('_l/', '_r/'))) elif (actu.getName().endswith('_bending') or actu.getName().endswith('_rotation') or actu.getName().endswith('_tz') or actu.getName().endswith('_list')): symmetry.addNegatedStatePair(osim.MocoPeriodicityGoalPair( actu.getStateVariableNames().get(0), actu.getStateVariableNames().get(0))) else: symmetry.addStatePair(osim.MocoPeriodicityGoalPair( actu.getStateVariableNames().get(0), actu.getStateVariableNames().get(0))) problem.addGoal(symmetry) # Contact tracking # ---------------- forceNamesRightFoot = ['forceset/contactSphereHeel_r', 'forceset/contactLateralRearfoot_r', 'forceset/contactLateralMidfoot_r', 'forceset/contactLateralToe_r', 'forceset/contactMedialToe_r', 'forceset/contactMedialMidfoot_r'] forceNamesLeftFoot = ['forceset/contactSphereHeel_l', 'forceset/contactLateralRearfoot_l', 'forceset/contactLateralMidfoot_l', 'forceset/contactLateralToe_l', 'forceset/contactMedialToe_l', 'forceset/contactMedialMidfoot_l'] if self.contact_tracking: contactTracking = osim.MocoContactTrackingGoal('contact', 0.001) contactTracking.setExternalLoadsFile( 'resources/Rajagopal2016/grf_walk.xml') contactTracking.addContactGroup(forceNamesRightFoot, 'Right_GRF') contactTracking.addContactGroup(forceNamesLeftFoot, 'Left_GRF') contactTracking.setProjection("plane") contactTracking.setProjectionVector(osim.Vec3(0, 0, 1)) problem.addGoal(contactTracking) # Configure the solver # -------------------- solver = osim.MocoCasADiSolver.safeDownCast(study.updSolver()) solver.resetProblem(problem) solver.set_optim_constraint_tolerance(1e-3) solver.set_optim_convergence_tolerance(1e-3) solver.set_multibody_dynamics_mode('implicit') solver.set_minimize_implicit_multibody_accelerations(True) solver.set_implicit_multibody_accelerations_weight( 1e-6 / model.getNumCoordinates()) solver.set_implicit_multibody_acceleration_bounds( osim.MocoBounds(-200, 200)) # Set the guess # ------------- # Create a guess compatible with this problem. guess = solver.createGuess() # Load the inverse problem solution and set its states and controls # trajectories to the guess. inverseSolution = osim.MocoTrajectory( os.path.join(root_dir, self.inverse_solution_relpath)) inverseStatesTable = inverseSolution.exportToStatesTable() guess.insertStatesTrajectory(inverseStatesTable, True) # Changing this initial guess has a large negative effect on the # solution! Lots of knee flexion. # guess.setState('/jointset/ground_pelvis/pelvis_ty/value', # osim.Vector(guess.getNumTimes(), 1.01)) inverseControlsTable = inverseSolution.exportToControlsTable() guess.insertControlsTrajectory(inverseControlsTable, True) solver.setGuess(guess) # Solve and print solution. # ------------------------- solution = study.solve() solution.write(self.get_solution_path(root_dir, config)) # Create a full gait cycle trajectory from the periodic solution. fullTraj = osim.createPeriodicTrajectory(solution) fullTraj.write(self.get_solution_path_fullcycle(root_dir, config)) # Compute ground reaction forces generated by contact sphere from the # full gait cycle trajectory. externalLoads = osim.createExternalLoadsTableForGait( model, fullTraj, forceNamesRightFoot, forceNamesLeftFoot) osim.writeTableToFile(externalLoads, self.get_solution_path_grfs(root_dir, config))
# #Run the torque driven marker tracking problem # torqueDrivenMarkerTracking(startTime = startTime,endTime = endTime,meshInterval = 0.05, # scaledModelFile = 'scaledModelAdjusted.osim', # grfXml = 'Jog05_grf.xml', trcFile = 'Jog05_virtualMarkers.trc', # ikTasksXml = 'ikTasks.xml') ##### Marker tracking looks fairly good - compare to IK? ##### Still getting visualiser error though - weird considering it works for Moco examples? # %% Inverse kinematics ##### TODO: could set this in osimHelper function #Initialise IK tool ikTool = osim.InverseKinematicsTool() #Set model ikTool.setModel(scaledModel) #Set task set ikTool.set_IKTaskSet(osim.IKTaskSet('ikTasks.xml')) #Set marker file ikTool.set_marker_file('Jog05_virtualMarkers.trc') #Set times ikTool.setStartTime(startTime) ikTool.setEndTime(endTime) #Set output filename
TRC_file = TRC_files[0] path, filename = os.path.split(TRC_file) filename, ext = os.path.splitext(filename) MOT_file = 'MOT\\' + filename + '.mot' # Path to the output .MOT file that will be created and contain the IK results XML_IK_file = 'XML\\' + filename + '_IK.xml' # Path to the IK XML file that will be created # Marker Data markerData = osim.MarkerData(TRC_file) initial_time = markerData.getStartFrameTime() final_time = markerData.getLastFrameTime() # Set the IK tool ikTool = osim.InverseKinematicsTool(XML_generic_IK_path) ikTool.setModel(osimModel) ikTool.setName(filename + ext) ikTool.setMarkerDataFileName(TRC_file) ikTool.setStartTime(initial_time) ikTool.setEndTime(final_time) ikTool.setOutputMotionFileName(MOT_file) # Set the ikTool with the MarkerTask for j in range(0, markerList.shape[0]): ikMarkerTask = osim.IKMarkerTask() ikMarkerTask.setName(markerList[j]) ikMarkerTask.setApply(1) ikMarkerTask.setWeight(markerWeight[j]) ikTool.getIKTaskSet().adoptAndAppend(ikMarkerTask)
def setup_IK_xml(trial: str, model: str, directory: str, time_range: list, marker_names: list): ''' Rewrites the IK setup xml file for a new trial Inputs: trial: trial name, e.g., "_12Mar_ss_12ms_01" model: model name, e.g., "AB08" directory: output directory name time_range: start and end times marker_names: list of the markers names which we are using ''' # Create an instance of the inverse kinematics tool IK_tool = osim.InverseKinematicsTool() # Set the name of the tool IK_tool.setName(model) # Set the input and results directory IK_tool.setInputsDir(directory + "\\" + model + "\\" + trial) IK_tool.setResultsDir(directory + "\\" + model + "\\" + trial) # Set the time range, NOTE: Must be a double (np.float64) IK_tool.setStartTime(np.float64(time_range[0])) IK_tool.setEndTime(np.float64(time_range[-1])) # Set the marker file marker_file_name = directory + "\\" + model + "\\" + trial + "\\" + trial + ".trc" IK_tool.setMarkerDataFileName(marker_file_name) # Set the coordinate file coordinate_file_name = '' IK_tool.setCoordinateFileName(coordinate_file_name) # Set the output motion file output_file_name = directory + "\\" + model + "\\" + trial + "\\" + trial + "IKResults.mot" IK_tool.setOutputMotionFileName(output_file_name) ''' Add markers and set weighting ''' # List of bony anatomical landmarkers to give high weighting bony_landmarks = ['LMMAL','RMMAL','LLMAL','RLMAL','LASI','RASI','LPSI','RPSI'] # Create IKTaskSet IK_task_set = IK_tool.getIKTaskSet() # Assign markers and weights for marker in marker_names: IK_marker_task = osim.IKMarkerTask() IK_marker_task.setName(marker) if marker in bony_landmarks: IK_marker_task.setApply(True) IK_marker_task.setWeight(10) else: IK_marker_task.setApply(True) IK_marker_task.setWeight(1) IK_task_set.cloneAndAppend(IK_marker_task) ''' Write changes to an XML setup file ''' xml_setup_path = directory + "\\" + model + "\\" + trial + "\\" + trial + "IKSetup.xml" IK_tool.printToXML(xml_setup_path) ''' Temporary fix for setting model name using XML parsing ''' dom = minidom.parse(xml_setup_path) dom.getElementsByTagName("model_file")[0].firstChild.nodeValue = directory + "\\" + model + "\\" + model + ".osim" with open(xml_setup_path, 'w') as xml_file: dom.writexml(xml_file, addindent='\t', newl='\n', encoding='UTF-8')
scale_tool.getGenericModelMaker().processModel() scale_tool.getModelScaler().setMarkerFileName(marker_file) # scale_tool.getModelScaler().setOutputModelFileName(os.path.join(data_folder,scaled_model_filename)) scale_tool.getModelScaler().processModel(model, '', subject_mass) scale_tool.getMarkerPlacer().setMarkerFileName(marker_file) scale_tool.getMarkerPlacer().processModel(model) scale_tool.run() #Save Model model.printToXML(os.path.join(location_motion_data, scaled_model_filename)) #Perform IK ik_tool = opensim.InverseKinematicsTool(os.path.join(location_XMLs, ik_file)) ik_tool.setModel(model) ik_tool.setName(marker_data_filenames) ik_tool.setMarkerDataFileName( os.path.join(location_motion_data, marker_data_filenames)) ik_tool.setStartTime(ik_start_time) ik_tool.setEndTime(ik_end_time) ik_tool.setOutputMotionFileName( os.path.join(location_motion_data, save_ik_name)) ik_tool.run() #Build external loads file and save to disk - this will be loaded in for IK and SO external_loads = opensim.ExternalLoads( os.path.join(location_XMLs, external_loads_xml), True) external_loads.setLowpassCutoffFrequencyForLoadKinematics( kinematic_filter_frequency)