def list_to_osim_array_str(list_str): """Convert Python list of strings to OpenSim::Array<string>.""" arr = opensim.ArrayStr() for element in list_str: arr.append(element) return arr
def calc_net_generalized_forces(model, motion): model.initSystem() net_joint_moments = None import tempfile with tempfile.TemporaryDirectory() as tmpdirname: id_tool = osim.InverseDynamicsTool() modelID = osim.Model(model) id_tool.setModel(modelID) if type(motion) == osim.Storage: id_tool.setLowpassCutoffFrequency(6) storage = motion else: table = motion.exportToStatesTable() labels = list(table.getColumnLabels()) import re for ilabel in range(len(labels)): labels[ilabel] = labels[ilabel].replace('/value', '') labels[ilabel] = re.sub('/jointset/(.*?)/', '', labels[ilabel]) table.setColumnLabels(labels) storage = osim.convertTableToStorage(table) # TODO: There's a bug in converting column labels in # convertTableToStorage(). stolabels = osim.ArrayStr() stolabels.append('time') for label in labels: stolabels.append(label) storage.setColumnLabels(stolabels) id_tool.setCoordinateValues(storage) # id_tool.setExternalLoadsFileName(extloads_fpath) excludedForces = osim.ArrayStr() excludedForces.append('ACTUATORS') id_tool.setExcludedForces(excludedForces) id_result = 'joint_moment_breakdown_residuals.sto' id_tool.setResultsDir(tmpdirname) id_tool.setOutputGenForceFileName(id_result) # TODO: Remove muscles from the model? id_tool.run() net_joint_moments = osim.TimeSeriesTable( os.path.join(tmpdirname, id_result)) return net_joint_moments
def setup_ID_xml(trial: str, model: str, directory: str, time_range: list, cut_off_freq: np.float64): ''' Rewrites the ID 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 cuf_off_frequency: low pass cut-off frequency ''' # Create an instance of the inverse dynamics tool ID_tool = osim.InverseDynamicsTool() # Set tool name ID_tool.setName(model) # Set the opensim model name ID_tool.setModelFileName(directory + "\\" + model + "\\" + model + ".osim") # Set excluded forces excluded_forces = osim.ArrayStr() excluded_forces.setitem(0, 'Muscles') ID_tool.setExcludedForces(excluded_forces) # Set low pass cut-off frequency, NOTE: Must be a double (np.float64) ID_tool.setLowpassCutoffFrequency(np.float64(cut_off_freq)) # Set the input and results directory ID_tool.setResultsDir(directory + "\\" + model + "\\" + trial) ID_tool.setInputsDir(directory + "\\" + model + "\\" + trial) # Set the time range, NOTE: Must be a double (np.float64) ID_tool.setStartTime(np.float64(time_range[0])) ID_tool.setEndTime(np.float64(time_range[-1])) # Set the external loads file external_loads_file = directory + "\\" + model + "\\" + trial + "\\" + trial + 'ExternalLoads.xml' ID_tool.setExternalLoadsFileName(external_loads_file) # Set the coordinates file coordindate_file = directory + "\\" + model + "\\" + trial + "\\" + trial + 'IKResults.mot' ID_tool.setCoordinatesFileName(coordindate_file) # Set the output file output_file_name = trial + "IDResults.sto" ID_tool.setOutputGenForceFileName(output_file_name) ''' Write changes to an XML setup file ''' xml_setup_path = directory + "\\" + model + "\\" + trial + "\\" + trial + "IDSetup.xml" ID_tool.printToXML(xml_setup_path)
print("Vsualization is enabled .... ") viz = pendulumDF.updVisualizer().updSimbodyVisualizer() viz.setBackgroundType(viz.SolidColor) viz.setBackgroundType(osim.SimTKVisualizer.GroundAndSky) viz.setShowFrameNumber(True) viz.setGroundHeight(-2) else: print("Vsualization is disabled .... ") # Create the force reporter for obtaining the forces applied to the model # during a forward simulation fReporter = osim.ForceReporter(pendulumDF) sReporter = osim.StatesReporter(pendulumDF) bKinematics = osim.BodyKinematics(pendulumDF, True) bodiesToRecord = osim.ArrayStr() bKinematics.setModel(pendulumDF) bKinematics.setBodiesToRecord(bodiesToRecord) pendulumDF.addAnalysis(fReporter) pendulumDF.addAnalysis(sReporter) pendulumDF.addAnalysis(bKinematics) manager = osim.Manager(pendulumDF) manager.setIntegratorMethod( osim.Manager.IntegratorMethod_RungeKuttaFeldberg) manager.setIntegratorAccuracy(1.0e-12) manager.setIntegratorMaximumStepSize(stepSize) # print simulation information # pendulumDF.printDetailedInfo(si , sys.stdout);
def plot_passive_joint_moments(model, coord_table, coord_paths, muscle_paths=None): model.initSystem() # for muscle in model.getMuscleList(): # muscle.set_ignore_tendon_compliance(True) # model.initSystem() num_coords = len(coord_paths) if not muscle_paths: muscle_paths = list() for muscle in model.getMuscleList(): muscle_paths.append(muscle.getAbsolutePathString()) num_muscles = len(muscle_paths) labels = list(coord_table.getColumnLabels()) import re for ilabel in range(len(labels)): labels[ilabel] = labels[ilabel].replace('/value', '') labels[ilabel] = re.sub('/jointset/(.*?)/', '', labels[ilabel]) coord_table.setColumnLabels(labels) storage = osim.convertTableToStorage(coord_table) # TODO: There's a bug in converting column labels in # convertTableToStorage(). stolabels = osim.ArrayStr() stolabels.append('time') for label in labels: stolabels.append(label) storage.setColumnLabels(stolabels) net_joint_moments = None import tempfile with tempfile.TemporaryDirectory() as tmpdirname: id_tool = osim.InverseDynamicsTool() modelID = osim.Model(model) id_tool.setModel(modelID) id_tool.setCoordinateValues(storage) id_tool.setLowpassCutoffFrequency(6) # id_tool.setExternalLoadsFileName(extloads_fpath) excludedForces = osim.ArrayStr() excludedForces.append('ACTUATORS') id_tool.setExcludedForces(excludedForces) id_result = 'joint_moment_breakdown_residuals.sto' id_tool.setResultsDir(tmpdirname) id_tool.setOutputGenForceFileName(id_result) # TODO: Remove muscles from the model? id_tool.run() net_joint_moments = osim.TimeSeriesTable( os.path.join(tmpdirname, id_result)) time = coord_table.getIndependentColumn() states_traj = osim.StatesTrajectory.createFromStatesStorage(model, storage, True, True, True) # TODO for models without activation dynamics, we must prescribeControlsToModel(). fig = pl.figure(figsize=(8.5, 11)) tendon_forces = np.empty((len(time), num_muscles)) for imusc, muscle_path in enumerate(muscle_paths): muscle = model.getComponent(muscle_path) for itime in range(len(time)): state = states_traj.get(itime) state.updU().setToZero() muscle.setActivation(state, 0.01) model.realizeVelocity(state) muscle.computeEquilibrium(state) model.realizeDynamics(state) tendon_forces[itime, imusc] = muscle.getTendonForce(state) for icoord, coord_path in enumerate(coord_paths): coord = model.getComponent(coord_path) label = os.path.split(coord_path)[-1] + '_moment' net_moment = toarray(net_joint_moments.getDependentColumn(label)) moment_arms = np.empty((len(time), num_muscles)) for imusc, muscle_path in enumerate(muscle_paths): muscle = model.getComponent(muscle_path) for itime in range(len(time)): state = states_traj.get(itime) moment_arms[itime, imusc] = \ muscle.computeMomentArm(state, coord) ax = fig.add_subplot(num_coords, 1, icoord + 1) # net_integ = np.trapz(np.abs(net_moment), x=time) sum_actuators_shown = np.zeros_like(time) for imusc, muscle_path in enumerate(muscle_paths): if np.any(moment_arms[:, imusc]) > 0.00001: this_moment = tendon_forces[:, imusc] * moment_arms[:, imusc] mom_integ = np.trapz(np.abs(this_moment), time) if mom_integ > 0.5: ax.plot(time, this_moment, label=muscle_path) sum_actuators_shown += this_moment ax.plot(time, sum_actuators_shown, label='sum actuators shown', color='gray', linewidth=2) time_net = np.array(net_joint_moments.getIndependentColumn()) filter = (time_net > time[0]) & (time_net < time[-1]) # ax.plot(time_net[filter], net_moment[filter], # label='net', color='black', linewidth=2) ax.set_title(coord_path) ax.set_ylabel('moment (N-m)') ax.legend(frameon=False, bbox_to_anchor=(1, 1), loc='upper left', ncol=2) ax.tick_params(axis='both') ax.set_xlim([time[0], time[-1]]) ax.set_xlabel('time (% gait cycle)') fig.tight_layout() return fig
jointX = osim.SliderJoint('tx', model.getGround(), massless) coordX = jointX.updCoordinate(osim.SliderJoint.Coord_TranslationX) coordX.setName('tx') model.addJoint(jointX) # The joint's x axis must point in the global "+y" direction. jointY = osim.SliderJoint('ty', massless, osim.Vec3(0), osim.Vec3(0, 0, 0.5 * np.pi), body, osim.Vec3(0), osim.Vec3(0, 0, 0.5 * np.pi)) coordY = jointY.updCoordinate(osim.SliderJoint.Coord_TranslationX) coordY.setName('ty') model.addJoint(jointY) # Add the kinematic constraint ty = tx^2. constraint = osim.CoordinateCouplerConstraint() independentCoords = osim.ArrayStr() independentCoords.append('tx') constraint.setIndependentCoordinateNames(independentCoords) constraint.setDependentCoordinateName('ty') coefficients = osim.Vector(3, 0) # 3 elements initialized to 0. # The polynomial is c0*tx^2 + c1*tx + c2; set c0 = 1, c1 = c2 = 0. coefficients.set(0, 1) constraint.setFunction(osim.PolynomialFunction(coefficients)) model.addConstraint(constraint) study = osim.MocoStudy() problem = study.updProblem() problem.setModel(model) phase0 = problem.getPhase(0) # Setting stricter bounds for the speeds improves convergence.
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 setup_scale_xml(scale_filename: str, trial: str, model: str, output_directory: str, input_directory: str): ''' Rewrites the scale setup xml file for a new trial Inputs: scale_filename: full filename for the template inverse kinematics setup xml file trial: trial name, e.g., "_12Mar_ss_12ms_01" model: model name, e.g., "AB08" directory: output directory name References: Megan Schroeder, 11/01/2014 ''' # Static trc filename static_trc = input_directory + "\\" + model + trial + "_Static.trc" # Create marker_data object to read starting and ending times from trc file marker_data = osim.MarkerData(static_trc) time_range = osim.ArrayDouble() time_range.setitem(0, marker_data.getStartFrameTime()) time_range.setitem(1, marker_data.getLastFrameTime()) # Create scale_tool object scale_tool = osim.ScaleTool(scale_filename) scale_tool.setName(model) # Modify top-level properties # TODO, get height (optional), age (optional) and mass (required) of subject scale_tool.setPathToSubject(model) #scale_tool.setSubjectMass() #scale_tool.setSubjectHeight() #scale_tool.setSubjectAge # Update generic_model_maker generic_model_marker = scale_tool.getGenericModelMaker() generic_model_marker.setModelFileName(model + ".osim") generic_model_marker.setMarkerSetFileName(model + '_Scale_MarkerSet.xml') # Update model_scaler model_scaler = scale_tool.getModelScaler() model_scaler.setApply(True) scale_order = osim.ArrayStr() scale_order.setitem(0, 'Measurements') model_scaler.setScalingOrder(scale_order) measurements_set = model_scaler.getMeasurementSet() measurements_set.assign( osim.MeasurementSet().makeObjectFromFile(model + '_Scale_MarkerSet.xml')) model_scaler.setMarkerFileName(static_trc) model_scaler.setTimeRange(time_range) model_scaler.setPreserveMassDist(True) output_filename = trial + 'TempScaled.osim' model_scaler.setOutputModelFileName(output_filename) ouput_scale_filename = trial + '_ScaleSet.xml' model_scaler.setOutputScaleFileName(ouput_scale_filename)
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) for sub in subjectList: for mot in motList: for exf in exforceList:
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)
def create_scale_setup(self, file_dep, target): # EDIT THESE FIELDS IN PARTICULAR. # -------------------------------- time_range = osm.ArrayDouble() time_range.append(self.init_time) time_range.append(self.final_time) tool = osm.ScaleTool() tool.setName('%s_%s' % (self.study.name, self.subject.name)) tool.setSubjectMass(self.subject.mass) # GenericModelMaker # ================= gmm = tool.getGenericModelMaker() gmm.setModelFileName(os.path.relpath(file_dep['generic_model'], self.results_scale_path)) gmm.setMarkerSetFileName(os.path.relpath(self.prescale_markerset_fname)) # ModelScaler # =========== scaler = tool.getModelScaler() scaler.setPreserveMassDist(True) marker_traj_rel_fpath = os.path.relpath(file_dep['marker_traj'], self.results_scale_path) scaler.setMarkerFileName(marker_traj_rel_fpath) scale_order_str = osm.ArrayStr() scale_order_str.append('manualScale') scale_order_str.append('measurements') scaler.setScalingOrder(scale_order_str) scaler.setTimeRange(time_range) mset = scaler.getMeasurementSet() # Manual scalings # --------------- sset = scaler.getScaleSet() # MarkerPlacer # ============ placer = tool.getMarkerPlacer() placer.setStaticPoseFileName(marker_traj_rel_fpath) placer.setTimeRange(time_range) placer.setOutputModelFileName(os.path.relpath( self.output_model_fpath, self.results_scale_path)) placer.setOutputMotionFileName(os.path.relpath( self.output_motion_fpath, self.results_scale_path)) placer.setOutputMarkerFileName(os.path.relpath( self.output_markerset_fpath, self.results_scale_path)) ikts = util.IKTaskSet(placer.getIKTaskSet()) self.edit_setup_function(util, mset, sset, ikts) # Validate Scales # =============== model = osm.Model(file_dep['generic_model']) bset = model.getBodySet() for iscale in range(sset.getSize()): segment_name = sset.get(iscale).getSegmentName() if not bset.contains(segment_name): raise Exception("You specified a Scale for " "body %s but it's not in the model." % segment_name) if not os.path.exists(self.results_scale_path): os.makedirs(self.results_scale_path) tool.printToXML(target['setup'])
#Set generic model file genModelFileName = genModelPath+'\\LaiArnold2017_refined_Fukuchi2017-running.osim' #Add model geometry to search paths osim.ModelVisualizer.addDirToGeometrySearchPaths(genModelPath+'\\Geometry') #Create the measurement set object for later use measurementSetObject = osim.OpenSimObject.makeObjectFromFile('..\\OpensimModel\\scaleMeasurementSet_Fukuchi2017-running.xml') measurementSet = osim.MeasurementSet.safeDownCast(measurementSetObject) #Set the scale task set scaleTaskSet = osim.IKTaskSet('..\\OpensimModel\\scaleTasks_Fukuchi2017-running.xml') #Set scale order scaleOrder = osim.ArrayStr() scaleOrder.set(0,'measurements') #Set IK task set ikTaskSet = osim.IKTaskSet('..\\OpensimModel\\ikTasks_Fukuchi2017-running.xml') #Set up a list of markers once flattened to keep #This mainly gets rid of the random ASY markers markersFlatList = ['L.ASIS_1','L.ASIS_2','L.ASIS_3', 'L.Heel.Bottom_1','L.Heel.Bottom_2','L.Heel.Bottom_3', 'L.Heel.Lateral_1','L.Heel.Lateral_2','L.Heel.Lateral_3', 'L.Heel.Top_1','L.Heel.Top_2','L.Heel.Top_3', 'L.Iliac.Crest_1','L.Iliac.Crest_2','L.Iliac.Crest_3', 'L.MT1_1','L.MT1_2','L.MT1_3', 'L.MT5_1','L.MT5_2','L.MT5_3', 'L.PSIS_1','L.PSIS_2','L.PSIS_3',
TimeArray.set(1,final_time) # Scale Tool scaleTool = osim.ScaleTool(XML_generic_ST_path) scaleTool.setName('Subject') # Name of the subject scaleTool.setSubjectMass(70) # Mass of the subject scaleTool.setSubjectHeight(-1) # Only for information (not used by scaling) scaleTool.setSubjectAge(-1) # Only for information (not used by scaling) # Generic Model Maker scaleTool.getGenericModelMaker().setModelFileName('Rajagopal2015.osim') scaleTool.getGenericModelMaker().setMarkerSetFileName(XML_markers_path) # Model Scaler scaleTool.getModelScaler().setApply(1) scaleTool.getModelScaler().setScalingOrder(osim.ArrayStr('measurements', 1)) scaleTool.getModelScaler().setMarkerFileName(TRC_file) scaleTool.getModelScaler().setTimeRange(TimeArray) scaleTool.getModelScaler().setPreserveMassDist(1) scaleTool.getModelScaler().setOutputModelFileName(scaled_MM_path) scaleTool.getModelScaler().setOutputScaleFileName(XML_SF_file) # The scale factor information concern the pair of marker that will be used # to scale each body in your model to make it more specific to your subject. # The scale factor are computed with the distance the virtual markers and between your experimental markers # Create a Marker Pair Set fo each body measurementTemp = osim.Measurement() bodyScaleTemp = osim.BodyScale() markerPairTemp = osim.MarkerPair()
taskSet = osim.IKTaskSet('scaleTasks.xml') for k in range(0,taskSet.getSize()-1): scaleTool.getMarkerPlacer().getIKTaskSet().adoptAndAppend(taskSet.get(k)) #Set marker file #Add the virtual markers and create a new .trc file to use in scaling osimHelper.addVirtualMarkersStatic('static.trc','staticVirtualMarkers.trc') #Place in scale tool scaleTool.getMarkerPlacer().setMarkerFileName('staticVirtualMarkers.trc') scaleTool.getModelScaler().setMarkerFileName('staticVirtualMarkers.trc') #Set options scaleTool.getModelScaler().setPreserveMassDist(True) scaleOrder = osim.ArrayStr(); scaleOrder.set(0,'measurements') scaleTool.getModelScaler().setScalingOrder(scaleOrder) #Set time ranges timeRange = osim.ArrayDouble() timeRange.set(0,0.5); timeRange.set(1,1.5) scaleTool.getMarkerPlacer().setTimeRange(timeRange) scaleTool.getModelScaler().setTimeRange(timeRange) #Set output files scaleTool.getModelScaler().setOutputModelFileName('scaledModel.osim') scaleTool.getModelScaler().setOutputScaleFileName('scaleSet.xml') #Set marker adjuster parameters scaleTool.getMarkerPlacer().setOutputMotionFileName('static_motion.mot') scaleTool.getMarkerPlacer().setOutputModelFileName('scaledModelAdjusted.osim')
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
external_loads.printToXML( os.path.join(location_motion_data, save_external_loads_name)) #perform ID id_tool = opensim.InverseDynamicsTool() id_tool.setModel(model) # id_tool.setModelFileName() id_tool.setCoordinatesFileName(os.path.join(location_motion_data, save_ik_name)) id_tool.setLowpassCutoffFrequency(kinematic_filter_frequency) id_tool.setResultsDir(location_motion_data) id_tool.setOutputGenForceFileName(save_id_name) id_tool.setStartTime(id_start_time) id_tool.setEndTime(id_end_time) excludedForces = opensim.ArrayStr() excludedForces.append('Muscles') id_tool.setExcludedForces(excludedForces) id_tool.setExternalLoadsFileName( os.path.join(location_motion_data, save_external_loads_name)) id_tool.printToXML(os.path.join(location_motion_data, save_id_settings_name)) id_tool.run() #Re-Load Model #This was added to re-initiate the model so that it wouldnt have multiple sets of external loads associated with it. model = opensim.Model(os.path.join(location_motion_data, scaled_model_filename)) model.updateMarkerSet(markerset) model.initSystem() state = model.initSystem()