def generate_results(self, root_dir, args): self.parse_args(args) from transform_and_filter_ground_reaction import \ transform_and_filter_ground_reaction # TODO: We aren't actually using this filtered file yet. transform_and_filter_ground_reaction( os.path.join(root_dir, 'resources/Rajagopal2016/emg_walk_raw.anc'), os.path.join(root_dir, 'resources/Rajagopal2016/grf_walk.mot'), 'ground_reaction_forces', 'rlr', mode='multicutoff') modelProcessor = self.create_model_processor(root_dir) cmc = osim.CMCTool( os.path.join(root_dir, 'code/motion_prescribed_walking_cmc_setup.xml')) analyze = osim.AnalyzeTool( os.path.join(root_dir, 'code/motion_prescribed_walking_analyze_setup.xml')) # 2.5 minute if self.cmc: cmc.run() analyze.run() mesh_interval = (self.final_time - self.initial_time) / 25.0 # 8 minutes if self.inverse: solution_filepath = self.mocoinverse_solution_file % root_dir self.solve_inverse(root_dir, modelProcessor, mesh_interval, solution_filepath) # TODO # # 0.04 and 0.03 work # inverse.set_mesh_interval(0.01) # # inverse.set_convergence_tolerance(1e-4) # solution = inverse.solve() # solution.getMocoSolution().write(self.mocoinverse_fine_solution_file % root_dir) # MocoInverse, minimize joint reactions # ------------------------------------- inverse = self.create_inverse(root_dir, modelProcessor, mesh_interval) study = inverse.initialize() problem = study.updProblem() reaction_r = osim.MocoJointReactionGoal('reaction_r', 0.005) reaction_r.setJointPath('/jointset/walker_knee_r') reaction_r.setReactionMeasures(['force-x', 'force-y']) reaction_l = osim.MocoJointReactionGoal('reaction_l', 0.005) reaction_l.setJointPath('/jointset/walker_knee_l') reaction_l.setReactionMeasures(['force-x', 'force-y']) problem.addGoal(reaction_r) problem.addGoal(reaction_l) solver = osim.MocoCasADiSolver.safeDownCast(study.updSolver()) # 13 minutes. if self.knee: solution_reaction = study.solve() solution_reaction.write(self.mocoinverse_jointreaction_solution_file % root_dir)
def getStepStatistics(results_folder, force_threshold = 10, minimum_step_time = 0.5): # find states file and model file for fname in os.listdir(results_folder): if fname.endswith('states.sto'): states_file = os.path.join(results_folder, fname) for fname in os.listdir(results_folder): if fname.endswith('.osim'): model_file = os.path.join(results_folder, fname) # get ground contact information from HuntCrossleyForce's model = opensim.Model(model_file) states = opensim.States(states_file) analyzeTool = opensim.AnalyzeTool() analyzeTool.setModel(model) analyzeTool.setStates(states) left_foot_forces = opensim.getForce('foot_l').getOutput() #<HuntCrossleyForce name="foot_l"> right_foot_forces = opensim.getForce('foot_r').getOutput() #<HuntCrossleyForce name="foot_r"> analyzeTool.add(leftFootForces) analyzeTool.add(rightFootForces)
def run(initial_time, final_time): """ inputs initial time final time actuator file = soActuators kinematics file = subject01_walk1_ik.mot outputs """ import os import re import shutil import opensim as osim import directories allDir = list(directories.main(directories)) paramsDir = allDir[1] subID = allDir[4] subResultsDir = allDir[5] ikResultsDir = allDir[6] idResultsDir = allDir[7] soResultsDir = allDir[8] actuatorFile = paramsDir + "/soActuators.xml" genericSetupSO = paramsDir + "/" + "setupSO.xml" ikFileName = "subject01_walk1_ik.mot" ikFile = ikResultsDir + "/" + ikFileName if os.path.exists(soResultsDir): shutil.rmtree(soResultsDir, ignore_errors=True) if not os.path.exists(soResultsDir): os.mkdir(soResultsDir) # Load Model aModel = osim.Model(subResultsDir + "/" + subID + ".osim") pelvisIndex = aModel.getBodySet().getIndex("pelvis") pelvisCOM_Vec3 = osim.Vec3() aModel.getBodySet().get(pelvisIndex).getMassCenter(pelvisCOM_Vec3) # add reserve actuators myForceSet = osim.ForceSet(aModel, actuatorFile) # print(aModel.getForceSet().getSize()) FX = osim.PointActuator.safeDownCast(myForceSet.get(0)) FX.set_point(pelvisCOM_Vec3) FY = osim.PointActuator.safeDownCast(myForceSet.get(1)) FY.set_point(pelvisCOM_Vec3) FZ = osim.PointActuator.safeDownCast(myForceSet.get(2)) FZ.set_point(pelvisCOM_Vec3) for i in range(myForceSet.getSize()): aModel.updForceSet().append(myForceSet.get(i)) print(aModel.getForceSet().getSize()) # initialize system aModel.initSystem() # Initialize External Loads File from Generic File extLoads = idResultsDir + "/subject01_walk1_extLoads.xml" # Get .mot data to determine time range # motCoordsData = osim.Storage(ikFile) # Get initial and final time # initial_time = motCoordsData.getFirstTime() # final_time = motCoordsData.getLastTime() # Analyze Tool Setup analyzeTool = osim.AnalyzeTool(genericSetupSO) analyzeTool.setInitialTime(initial_time) analyzeTool.setFinalTime(final_time) analyzeTool.setResultsDir(soResultsDir) analyzeTool.setModelFilename("") analyzeTool.setName(re.sub('_ik.mot', '', ikFileName)) myForceSetArray = analyzeTool.getForceSetFiles() myForceSetArray.set(0, "") analyzeTool.setReplaceForceSet(False) analyzeTool.setForceSetFiles(myForceSetArray) # Set coordinates coordtype = "mot" if coordtype == "mot": analyzeTool.setStatesFileName("") analyzeTool.setCoordinatesFileName(ikFile) elif coordtype == "states": analyzeTool.setStatesFileName(ikFile) analyzeTool.setCoordinatesFileName("") analyzeTool.setExternalLoadsFileName(extLoads) analyzeTool.setModel(aModel) analyzeTool.run() analyzeTool.printToXML(soResultsDir + "/" + re.sub('ik.mot', 'outSetupSO.xml', ikFileName)) aModel.printToXML(soResultsDir + "/" + subID + "_soActuators.osim") os.system('cls' if os.name == 'nt' else 'clear') return ()
def setup_muscle_analysis_xml(trial: str, model: str, directory: str, time_range: list, cut_off_freq: np.float64): ''' NOTE: Any attribute not changed within this function must be changed in the original template file 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 cuf_off_frequency: low pass cut-off frequency ''' # Get analyze tool analyze_tool = osim.AnalyzeTool() # Set tool name new_analyze_tool_name = model + trial analyze_tool.setName(new_analyze_tool_name) # Set the opensim model name analyze_tool.setModelFilename(directory + "\\" + model + "\\" + model + ".osim") # Set the results directory analyze_tool.setResultsDir(directory + "\\" + model + "\\" + trial) # Set the external loads file external_loads_file = directory + "\\" + model + "\\" + trial + "\\" + trial + 'ExternalLoads.xml' analyze_tool.setExternalLoadsFileName(external_loads_file) # Set the coordinates file coord_file = directory + "\\" + model + "\\" + trial + "\\" + trial + 'IKResults.mot' analyze_tool.setCoordinatesFileName(coord_file) # Set low pass cut-off frequency, NOTE: Must be a double (np.float64) analyze_tool.setLowpassCutoffFrequency(np.float64(cut_off_freq)) # Set the time range, NOTE: Must be a double (np.float64) analyze_tool.setInitialTime(np.float64(time_range[0])) analyze_tool.setFinalTime(np.float64(time_range[-1])) ''' Add muscle analysis ''' analysis_set = analyze_tool.getAnalysisSet() muscle_analysis = osim.MuscleAnalysis() muscle_analysis.setStartTime(np.float64(time_range[0])) muscle_analysis.setEndTime(np.float64(time_range[-1])) muscle_analysis.setComputeMoments( True) # Bug, this is not being set to true in the xml file analysis_set.cloneAndAppend(muscle_analysis) ''' Write file ''' xml_setup_path = directory + "\\" + model + "\\" + trial + "\\" + trial + "MuscleAnalysisSetup.xml" analyze_tool.printToXML(xml_setup_path) ''' Temporary fix to set compute moments to true and to remove numerical inaccuracy in times ''' dom = minidom.parse(xml_setup_path) analysis_set = dom.getElementsByTagName("AnalysisSet") analysis_set_child = analysis_set.item(0) objects_set = analysis_set_child.getElementsByTagName("objects") objects_set_child = objects_set.item(0) muscle_analysis = objects_set_child.getElementsByTagName("MuscleAnalysis") muscle_analysis_child = muscle_analysis.item(0) muscle_analysis_child.getElementsByTagName( "compute_moments")[0].firstChild.nodeValue = "true" dom.getElementsByTagName("initial_time")[0].firstChild.nodeValue = round( time_range[0], 3) dom.getElementsByTagName("final_time")[0].firstChild.nodeValue = round( time_range[-1], 3) muscle_analysis_child.getElementsByTagName( "start_time")[0].firstChild.nodeValue = round(time_range[0], 3) muscle_analysis_child.getElementsByTagName( "end_time")[0].firstChild.nodeValue = round(time_range[-1], 3) with open(xml_setup_path, 'w') as xml_file: dom.writexml(xml_file, addindent='\t', newl='\n', encoding='UTF-8')
def perform_jra(model_file, ik_file, grf_file, grf_xml, reserve_actuators, muscle_forces_file, results_dir, prefix=''): """Performs Static Optimization using OpenSim. Parameters ---------- model_file: str OpenSim model (.osim) ik_file: str kinematics calculated from Inverse Kinematics grf_file: str the ground reaction forces grf_xml: str xml description containing how to apply the GRF forces reserve_actuators: str path to the reserve actuator .xml file muscle_forces_file: str path to the file containing the muscle forces from SO results_dir: str directory to store the results prefix: str prefix of the resultant joint reaction loads """ # model model = opensim.Model(model_file) # prepare external forces xml file name = os.path.basename(grf_file)[:-8] external_loads = opensim.ExternalLoads(model, grf_xml) external_loads.setExternalLoadsModelKinematicsFileName(ik_file) external_loads.setDataFileName(grf_file) external_loads.setLowpassCutoffFrequencyForLoadKinematics(6) external_loads.printToXML(results_dir + name + '.xml') # TODO this may not be needed # add reserve actuators (must not be appended when performing JRA) # force_set = opensim.ForceSet(model, reserve_actuators) # force_set.setMemoryOwner(False) # model will be the owner # for i in range(0, force_set.getSize()): # model.updForceSet().append(force_set.get(i)) # # model.addForce(force_set.get(i)) # construct joint reaction analysis motion = opensim.Storage(ik_file) joint_reaction = opensim.JointReaction(model) joint_reaction.setName('JointReaction') joint_reaction.setStartTime(motion.getFirstTime()) joint_reaction.setEndTime(motion.getLastTime()) joint_reaction.setForcesFileName(muscle_forces_file) model.addAnalysis(joint_reaction) model.initSystem() # analysis analysis = opensim.AnalyzeTool(model) analysis.setName(prefix + name) analysis.setModel(model) analysis.setModelFilename(model_file) analysis.setInitialTime(motion.getFirstTime()) analysis.setFinalTime(motion.getLastTime()) analysis.setLowpassCutoffFrequency(6) analysis.setCoordinatesFileName(ik_file) analysis.setExternalLoadsFileName(results_dir + name + '.xml') analysis.setLoadModelAndInput(True) analysis.setResultsDir(results_dir) analysis.run() jra_file = results_dir + name + '_JointReaction_ReactionLoads.sto' return jra_file
def perform_so(model_file, ik_file, grf_file, grf_xml, reserve_actuators, results_dir): """Performs Static Optimization using OpenSim. Parameters ---------- model_file: str OpenSim model (.osim) ik_file: str kinematics calculated from Inverse Kinematics grf_file: str the ground reaction forces grf_xml: str xml description containing how to apply the GRF forces reserve_actuators: str path to the reserve actuator .xml file results_dir: str directory to store the results """ # model model = opensim.Model(model_file) # prepare external forces xml file name = os.path.basename(grf_file)[:-8] external_loads = opensim.ExternalLoads(model, grf_xml) external_loads.setExternalLoadsModelKinematicsFileName(ik_file) external_loads.setDataFileName(grf_file) external_loads.setLowpassCutoffFrequencyForLoadKinematics(6) external_loads.printToXML(results_dir + name + '.xml') # add reserve actuators force_set = opensim.ForceSet(model, reserve_actuators) force_set.setMemoryOwner(False) # model will be the owner for i in range(0, force_set.getSize()): model.updForceSet().append(force_set.get(i)) # construct static optimization motion = opensim.Storage(ik_file) static_optimization = opensim.StaticOptimization() static_optimization.setStartTime(motion.getFirstTime()) static_optimization.setEndTime(motion.getLastTime()) static_optimization.setUseModelForceSet(True) static_optimization.setUseMusclePhysiology(True) static_optimization.setActivationExponent(2) static_optimization.setConvergenceCriterion(0.0001) static_optimization.setMaxIterations(100) model.addAnalysis(static_optimization) # analysis analysis = opensim.AnalyzeTool(model) analysis.setName(name) analysis.setModel(model) analysis.setInitialTime(motion.getFirstTime()) analysis.setFinalTime(motion.getLastTime()) analysis.setLowpassCutoffFrequency(6) analysis.setCoordinatesFileName(ik_file) analysis.setExternalLoadsFileName(results_dir + name + '.xml') analysis.setLoadModelAndInput(True) analysis.setResultsDir(results_dir) analysis.run() so_force_file = results_dir + name + '_StaticOptimization_force.sto' so_activations_file = results_dir + name + \ '_StaticOptimization_activation.sto' return (so_force_file, so_activations_file)
solver = study.initCasADiSolver() solver.set_num_mesh_intervals(25) solver.set_multibody_dynamics_mode("implicit") solver.set_optim_convergence_tolerance(1e-4) solver.set_optim_constraint_tolerance(1e-4) solution = study.solve() osim.STOFileAdapter.write(solution.exportToStatesTable(), "exampleHangingMuscle_states.sto") osim.STOFileAdapter.write(solution.exportToControlsTable(), "exampleHangingMuscle_controls.sto") # Conduct an analysis using MuscleAnalysis and ProbeReporter. # Create an AnalyzeTool setup file. analyze = osim.AnalyzeTool() analyze.setName("analyze") analyze.setModelFilename("hanging_muscle.osim") analyze.setStatesFileName("exampleHangingMuscle_states.sto") analyze.updAnalysisSet().cloneAndAppend(osim.MuscleAnalysis()) analyze.updAnalysisSet().cloneAndAppend(osim.ProbeReporter()) analyze.updControllerSet().cloneAndAppend( osim.PrescribedController("exampleHangingMuscle_controls.sto")) analyze.printToXML("exampleHangingMuscle_AnalyzeTool_setup.xml") # Run the analysis. analyze = osim.AnalyzeTool("exampleHangingMuscle_AnalyzeTool_setup.xml") analyze.run() table_force = osim.TimeSeriesTable( "analyze_MuscleAnalysis_ActiveFiberForce.sto") table_velocity = osim.TimeSeriesTable(
def run(setup, resultsDirectory): import os import re import shutil import opensim as osim import directories allDir = list(directories.main(directories)) paramsDir = allDir[1] subID = allDir[4] subResultsDir = allDir[5] # ikResultsDir = allDir[6] # idResultsDir = allDir[7] # soResultsDir = allDir[8] # cmcResultsDir = allDir[10] # jrResultsDir = allDir[11] # # actuatorFile = paramsDir + "/soActuators.xml" # # genericSetupSO = paramsDir + "/" + "setupSO.xml" # ikFileName = "subject01_walk1_ik.mot" # ikFile = ikResultsDir + "/" + ikFileName # # soForces = soResultsDir + "/" + "subject01_walk1_StaticOptimization_force.sto" # if os.path.exists(jrResultsDir): # shutil.rmtree(jrResultsDir, ignore_errors=True) # if not os.path.exists(jrResultsDir): # os.mkdir(jrResultsDir) # # Load Model aModel = osim.Model(subResultsDir + "/" + subID + ".osim") # # initialize system aModel.initSystem() # # Initialize External Loads File from Generic File # extLoads = idResultsDir + "/subject01_walk1_extLoads.xml" # # Get .mot data to determine time range # motCoordsData = osim.Storage(ikFile) # # Get initial and final time # initial_time = motCoordsData.getFirstTime() # final_time = motCoordsData.getLastTime() # Analyze Tool Setup for Static Optimization analyzeTool = osim.AnalyzeTool(setup) analyzeTool.setModel(aModel) analyzeTool.setResultsDir(resultsDirectory) analyzeTool.run() # analyzeTool = osim.AnalyzeTool(cmcJrSetup) # analyzeTool.setExternalLoadsFileName(extLoads) # analyzeTool.setInitialTime(initial_time) # analyzeTool.setFinalTime(final_time) # analyzeTool.setLowpassCutoffFrequency(6) # analyzeTool.setOutputPrecision(20) # myForceSet = osim.ForceSet(aModel, actuatorFile) # for i in range(myForceSet.getSize()): # aModel.updForceSet().append(myForceSet.get(i)) # print(aModel.getForceSet().getSize()) # analysisSet = analyzeTool.getAnalysisSet() # myForceSetArray = analyzeTool.getForceSetFiles() # myForceSetArray.set(0, "") # analyzeTool.setReplaceForceSet(False) # analyzeTool.setForceSetFiles(myForceSetArray) # # Joint Reaction Analysis # jrTool = osim.JointReaction(jrSetup) # analysisSet.cloneAndAppend(jrTool) # # Set coordinates # coordtype = "mot" # if coordtype == "mot": # analyzeTool.setStatesFileName("") # analyzeTool.setCoordinatesFileName(ikFile) # elif coordtype == "states": # analyzeTool.setStatesFileName(ikFile) # analyzeTool.setCoordinatesFileName("") # analyzeTool.verifyControlsStates() # analyzeTool.setResultsDir(jrResultsDir) # # analyzeTool.printToXML(paramsDir +"/setupJR.xml") # analyzeTool.run() return () os.system('cls' if os.name == 'nt' else 'clear')
def run_analyze_tool(self, trial): if self.prefix and not trial.stem.startswith(self.prefix): # skip file if user specified a prefix and prefix is not present in current file pass else: print(f"\t{trial.stem}") # model model = osim.Model(self.model_input) if isinstance(self.model_input, str) is True else self.model_input model.initSystem() # get starting and ending time motion = osim.Storage(f"{trial.resolve()}") first_time = motion.getFirstTime() last_time = motion.getLastTime() # prepare external forces xml file if self.xml_forces: external_loads = osim.ExternalLoads(self.xml_forces, True) if self.prefix: external_loads.setDataFileName( f"{Path(self.ext_forces_dir, trial.stem.replace(f'{self.prefix}_', '')).resolve()}.sto" ) else: external_loads.setDataFileName( f"{Path(self.ext_forces_dir, trial.stem).resolve()}.sto" ) external_loads.setExternalLoadsModelKinematicsFileName( f"{trial.resolve()}" ) if self.low_pass: external_loads.setLowpassCutoffFrequencyForLoadKinematics( self.low_pass ) temp_xml = Path(f"{trial.stem}_temp.xml") external_loads.printToXML(f"{temp_xml.resolve()}") # temporary xml file current_class = self.get_class_name() params = self.parse_analyze_set_xml(self.xml_input, node=current_class) solve_for_equilibrium = False if current_class == "StaticOptimization": analysis = osim.StaticOptimization(model) analysis.setUseModelForceSet(params["use_model_force_set"]) analysis.setActivationExponent(params["activation_exponent"]) analysis.setUseMusclePhysiology(params["use_muscle_physiology"]) analysis.setConvergenceCriterion( params["optimizer_convergence_criterion"] ) analysis.setMaxIterations(int(params["optimizer_max_iterations"])) elif current_class == "MuscleAnalysis": solve_for_equilibrium = True analysis = osim.MuscleAnalysis(model) coord = osim.ArrayStr() for c in params["moment_arm_coordinate_list"]: coord.append(c) analysis.setCoordinates(coord) mus = osim.ArrayStr() for m in params["muscle_list"]: mus.append(m) analysis.setMuscles(mus) # analysis.setComputeMoments(params["compute_moments"]) elif current_class == "JointReaction": # construct joint reaction analysis analysis = osim.JointReaction(model) if params["forces_file"] or self.forces_file: force_file = self.forces_file if self.forces_file else params["forces_file"] analysis.setForcesFileName(force_file) joint = osim.ArrayStr() for j in params["joint_names"]: joint.append(j) analysis.setJointNames(joint) body = osim.ArrayStr() for b in params["apply_on_bodies"]: body.append(b) analysis.setOnBody(body) frame = osim.ArrayStr() for f in params["express_in_frame"]: frame.append(f) analysis.setInFrame(frame) else: raise ValueError("AnalyzeTool must be called from a child class") analysis.setModel(model) analysis.setName(current_class) analysis.setOn(params["on"]) analysis.setStepInterval(int(params["step_interval"])) analysis.setInDegrees(params["in_degrees"]) analysis.setStartTime(first_time) analysis.setEndTime(last_time) model.addAnalysis(analysis) if self.print_to_xml is True: analysis.printToXML(f"{self.xml_output}/{current_class}_analysis.xml") # analysis tool analyze_tool = osim.AnalyzeTool(model) analyze_tool.setName(trial.stem) analyze_tool.setModel(model) analyze_tool.setModelFilename(Path(model.toString()).stem) analyze_tool.setSolveForEquilibrium(solve_for_equilibrium) if self.xml_actuators: force_set = osim.ArrayStr() force_set.append(self.xml_actuators) analyze_tool.setForceSetFiles(force_set) analyze_tool.updateModelForces(model, self.xml_actuators) analyze_tool.setInitialTime(first_time) analyze_tool.setFinalTime(last_time) if self.low_pass: analyze_tool.setLowpassCutoffFrequency(self.low_pass) analyze_tool.setCoordinatesFileName(f"{trial.resolve()}") if self.xml_forces: analyze_tool.setExternalLoadsFileName(f"{temp_xml}") analyze_tool.setLoadModelAndInput(True) analyze_tool.setResultsDir(f"{self.sto_output}") analyze_tool.run() if self.xml_forces: temp_xml.unlink() # delete temporary xml file if self.remove_empty_files: self._remove_empty_files(directory=self.sto_output) if self.contains: self._subset_output(directory=self.sto_output, contains=self.contains)
def run_static_optimization(so_file): # model = osim.Model(model_path) tool = osim.AnalyzeTool(so_file) # # model t and r coordinates have to be locked tool.run()
import opensim as osim modelFilename = 'Model/Driving.osim' actuatorFilename = 'Actuator/Actuators_upper_limb.xml' settingFile = 'so.xml' resultDir = 'Result' #Subject file list subjectList = ['SubUnknown'] #External force list exforceList = [220, 260] #Motion file list motList = [30, -30] model = osim.Model(modelFilename) model.initSystem() aTool = osim.AnalyzeTool() ##Set actuator (Optional) actuatorSet = osim.ArrayStr() actuatorSet.append(actuatorFilename) aTool.setForceSetFiles(actuatorSet) ##Set the directory for the result aTool.setResultsDir(resultDir) ##Set the condition of SO aSet = aTool.getAnalysisSet() so = osim.StaticOptimization() so.setName('StaticOptimization') aSet.insert(0, so)
def run_analyze_tool(self, trial): if self.prefix and not trial.stem.startswith(self.prefix): # skip file if user specified a prefix and prefix is not present in current file pass else: print(f'\t{trial.stem}') # model model = osim.Model(self.model_input) model.initSystem() # get starting and ending time motion = osim.Storage(f'{trial.resolve()}') first_time = motion.getFirstTime() last_time = motion.getLastTime() # prepare external forces xml file if self.xml_forces: external_loads = osim.ExternalLoads(model, self.xml_forces) if self.prefix: external_loads.setDataFileName( f"{Path(self.ext_forces_dir, trial.stem.replace(f'{self.prefix}_', '')).resolve()}.sto" ) else: external_loads.setDataFileName( f"{Path(self.ext_forces_dir, trial.stem).resolve()}.sto" ) external_loads.setExternalLoadsModelKinematicsFileName(f'{trial.resolve()}') if self.low_pass: external_loads.setLowpassCutoffFrequencyForLoadKinematics(self.low_pass) temp_xml = Path(f'{trial.stem}_temp.xml') external_loads.printToXML(f'{temp_xml.resolve()}') # temporary xml file current_class = self.get_class_name() params = self.parse_analyze_set_xml(self.xml_input, node=current_class) if current_class == 'StaticOptimization': analysis = osim.StaticOptimization(model) analysis.setUseModelForceSet(params['use_model_force_set']) analysis.setActivationExponent(params['activation_exponent']) analysis.setUseMusclePhysiology(params['use_muscle_physiology']) analysis.setConvergenceCriterion(params['optimizer_convergence_criterion']) analysis.setMaxIterations(int(params['optimizer_max_iterations'])) elif current_class == 'MuscleAnalysis': analysis = osim.MuscleAnalysis(model) analysis.setComputeMoments(params['compute_moments']) elif current_class == 'JointReaction': # construct joint reaction analysis analysis = osim.JointReaction(model) # analysis.setForcesFileName( # f"{Path(self.muscle_forces_dir, trial.stem).resolve()}_StaticOptimization_force.sto" # ) joint = osim.ArrayStr() joint.append(params['joint_names'].replace(' ', '')) analysis.setJointNames(joint) body = osim.ArrayStr() body.append(params['apply_on_bodies'].replace(' ', '')) analysis.setOnBody(body) frame = osim.ArrayStr() frame.append(params['express_in_frame'].replace(' ', '')) analysis.setInFrame(frame) else: raise ValueError('AnalyzeTool must be called from a child class') analysis.setModel(model) analysis.setName(current_class) analysis.setOn(params['on']) analysis.setStepInterval(int(params['step_interval'])) analysis.setInDegrees(params['in_degrees']) analysis.setStartTime(first_time) analysis.setEndTime(last_time) model.addAnalysis(analysis) # analysis tool analyze_tool = osim.AnalyzeTool(model) analyze_tool.setName(trial.stem) analyze_tool.setModel(model) analyze_tool.setModelFilename(Path(self.model_input).stem) if self.xml_actuators: force_set = osim.ArrayStr() force_set.append(self.xml_actuators) analyze_tool.setForceSetFiles(force_set) analyze_tool.updateModelForces(model, self.xml_actuators) analyze_tool.setInitialTime(first_time) analyze_tool.setFinalTime(last_time) if self.low_pass: analyze_tool.setLowpassCutoffFrequency(self.low_pass) analyze_tool.setCoordinatesFileName(f'{trial.resolve()}') analyze_tool.setExternalLoadsFileName(f'{temp_xml}') analyze_tool.setLoadModelAndInput(True) analyze_tool.setResultsDir(f'{self.sto_output}') analyze_tool.run() if self.xml_forces: temp_xml.unlink() # delete temporary xml file if self.remove_empty_files: self._remove_empty_files(directory=self.sto_output)
#Set output filename idTool[ii-startInd][tt].setOutputGenForceFileName(dynamicFiles[tt].split('.')[0]+'_id.sto') #Print and run tool idTool[ii-startInd][tt].printToXML(dynamicFiles[tt].split('.')[0]+'_setupID.xml') idTool[ii-startInd][tt].run() ##### NOTE: filter ID results given lack of CoP noise #Print confirmation print('ID complete for '+dynamicFiles[tt].split('.')[0]) #Run analysis to extract body kinematics #Initialise analysis tool anTool[ii-startInd].append(osim.AnalyzeTool()) #Set the model anTool[ii-startInd][tt].setModelFilename(subList[ii]+'_scaledModelAdjusted_sensors.osim') #Set times anTool[ii-startInd][tt].setStartTime(startTime) anTool[ii-startInd][tt].setFinalTime(endTime) #Set external loads file anTool[ii-startInd][tt].setExternalLoadsFileName(dynamicFiles[tt].split('.')[0]+'_grf'+'.xml') #Set kinematics anTool[ii-startInd][tt].setCoordinatesFileName(dynamicFiles[tt].split('.')[0]+'_ik.mot') #Set lowpass filter frequency for kinematics (10Hz)
def perform_jra(model_file, ik_file, grf_file, grf_xml, reserve_actuators, muscle_forces_file, results_dir, prefix, joint_names, apply_on_bodies, express_in_frame): """Performs Static Optimization using OpenSim. Parameters ---------- model_file: str OpenSim model (.osim) ik_file: str kinematics calculated from Inverse Kinematics grf_file: str the ground reaction forces grf_xml: str xml description containing how to apply the GRF forces reserve_actuators: str path to the reserve actuator .xml file muscle_forces_file: str path to the file containing the muscle forces from SO results_dir: str directory to store the results prefix: str prefix of the resultant joint reaction loads joint_names: list joint names of interest apply_on_bodies: list apply on child or parent express_in_frame: list frame to express results """ assert (len(joint_names) == len(apply_on_bodies) == len(express_in_frame)) # model model = opensim.Model(model_file) # prepare external forces xml file name = os.path.basename(grf_file)[:-8] # external_loads = opensim.ExternalLoads(model, grf_xml) # external_loads.setExternalLoadsModelKinematicsFileName(ik_file) # external_loads.setDataFileName(grf_file) # external_loads.setLowpassCutoffFrequencyForLoadKinematics(6) # external_loads.printToXML(results_dir + name + '.xml') # construct joint reaction analysis motion = opensim.Storage(ik_file) joint_reaction = opensim.JointReaction(model) joint_reaction.setName('JointReaction') joint_reaction.setStartTime(motion.getFirstTime()) joint_reaction.setEndTime(motion.getLastTime()) joint_reaction.setForcesFileName(muscle_forces_file) joint_names_arr = opensim.ArrayStr() apply_on_bodies_arr = opensim.ArrayStr() express_in_frame_arr = opensim.ArrayStr() for j, b, f in zip(joint_names, apply_on_bodies, express_in_frame): joint_names_arr.append(j) print(j) apply_on_bodies_arr.append(b) express_in_frame_arr.append(f) joint_reaction.setJointNames(joint_names_arr) joint_reaction.setOnBody(apply_on_bodies_arr) joint_reaction.setInFrame(express_in_frame_arr) model.addAnalysis(joint_reaction) model.initSystem() # analysis analysis = opensim.AnalyzeTool(model) analysis.setName(prefix + name) analysis.setModel(model) analysis.setModelFilename(model_file) analysis.setInitialTime(motion.getFirstTime()) analysis.setFinalTime(motion.getLastTime()) analysis.setLowpassCutoffFrequency(6) analysis.setCoordinatesFileName(ik_file) analysis.setExternalLoadsFileName(results_dir + name + '.xml') analysis.setLoadModelAndInput(True) analysis.setResultsDir(results_dir) analysis.run() jra_file = results_dir + name + '_JointReaction_ReactionLoads.sto' return jra_file
model.getForceSet().append(pelvis_Mz_torque_actuator) # Add point actuators pelvis_Fx_point_actuator = createPointActuator('pelvis', (-0.034, 0.0, 0), (1, 0, 0), 'pelvis_FX') pelvis_Fy_point_actuator = createPointActuator('pelvis', (-0.034, 0.0, 0), (0, 1, 0), 'pelvis_Fy') pelvis_Fz_point_actuator = createPointActuator('pelvis', (-0.034, 0.0, 0), (0, 0, 1), 'pelvis_Fz') model.getForceSet().append(pelvis_Fx_point_actuator) model.getForceSet().append(pelvis_Fy_point_actuator) model.getForceSet().append(pelvis_Fz_point_actuator) #Analyze / SO tool analyze_tool = opensim.AnalyzeTool( os.path.join(location_XMLs, so_analyze_file), False) analyze_tool.setModel(model) # analyzeTool.setModelFilename(osimModel.getDocumentFileName()); analyze_tool.setInitialTime(so_start_time) analyze_tool.setFinalTime(so_end_time) analyze_tool.setLowpassCutoffFrequency(kinematic_filter_frequency) analyze_tool.setCoordinatesFileName( os.path.join(location_motion_data, save_ik_name)) analyze_tool.setExternalLoadsFileName( os.path.join(location_motion_data, save_external_loads_name)) analyze_tool.setLoadModelAndInput(True) analyze_tool.setResultsDir(location_motion_data) # These are parameters that can be used to programatically alter the optimization parameters # analyze_tool.setReplaceForceSet(False) # analyze_tool.setOutputPrecision(6)