diff --git a/main.py b/main.py index 5e9bd34d..32b35d38 100644 --- a/main.py +++ b/main.py @@ -590,7 +590,7 @@ def main(sessionName, trialName, trial_id, cameras_to_use=['all'], # Run IK tool. logging.info('Running Inverse Kinematics') try: - pathOutputIK = runIKTool( + pathOutputIK, pathModelIK = runIKTool( pathGenericSetupFile4IK, pathScaledModel, pathTRCFile4IK, outputIKDir) except Exception as e: @@ -608,7 +608,7 @@ def main(sessionName, trialName, trial_id, cameras_to_use=['all'], os.makedirs(outputJsonVisDir,exist_ok=True) outputJsonVisPath = os.path.join(outputJsonVisDir, trialName + '.json') - generateVisualizerJson(pathScaledModel, pathOutputIK, + generateVisualizerJson(pathModelIK, pathOutputIK, outputJsonVisPath, vertical_offset=vertical_offset) diff --git a/utilsOpenSim.py b/utilsOpenSim.py index 18fa62b9..338b0986 100644 --- a/utilsOpenSim.py +++ b/utilsOpenSim.py @@ -163,11 +163,44 @@ def runIKTool(pathGenericSetupFile, pathScaledModel, pathTRCFile, pathOutputSetup = os.path.join( pathOutputFolder, 'Setup_IK_' + IKFileName + '.xml') - # Setup IK tool. + # To make IK faster, we remove the patellas and their constraints from the + # model. Constraints make the IK problem more difficult, and the patellas + # are not used in the IK solution for this particular model. Since muscles + # are attached to the patellas, we also remove all muscles. opensim.Logger.setLevelString('error') + model = opensim.Model(pathScaledModel) + # Remove all actuators. + forceSet = model.getForceSet() + forceSet.setSize(0) + # Remove patellofemoral constraints. + constraintSet = model.getConstraintSet() + patellofemoral_constraints = [ + 'patellofemoral_knee_angle_r_con', 'patellofemoral_knee_angle_l_con'] + for patellofemoral_constraint in patellofemoral_constraints: + i = constraintSet.getIndex(patellofemoral_constraint, 0) + constraintSet.remove(i) + # Remove patella bodies. + bodySet = model.getBodySet() + patella_bodies = ['patella_r', 'patella_l'] + for patella in patella_bodies: + i = bodySet.getIndex(patella, 0) + bodySet.remove(i) + # Remove patellofemoral joints. + jointSet = model.getJointSet() + patellofemoral_joints = ['patellofemoral_r', 'patellofemoral_l'] + for patellofemoral in patellofemoral_joints: + i = jointSet.getIndex(patellofemoral, 0) + jointSet.remove(i) + # Print the model to a new file. + model.finalizeConnections + model.initSystem() + pathScaledModelWithoutPatella = pathScaledModel.replace('.osim', '_no_patella.osim') + model.printToXML(pathScaledModelWithoutPatella) + + # Setup IK tool. IKTool = opensim.InverseKinematicsTool(pathGenericSetupFile) IKTool.setName(IKFileName) - IKTool.set_model_file(pathScaledModel) + IKTool.set_model_file(pathScaledModelWithoutPatella) IKTool.set_marker_file(pathTRCFile) if timeRange: IKTool.set_time_range(0, timeRange[0]) @@ -180,7 +213,7 @@ def runIKTool(pathGenericSetupFile, pathScaledModel, pathTRCFile, command = 'opensim-cmd -o error' + ' run-tool ' + pathOutputSetup os.system(command) - return pathOutputMotion + return pathOutputMotion, pathScaledModelWithoutPatella # %% This function will look for a time window, of a minimum duration specified