コード例 #1
0
def solveMocoInverse():

    #Construct the MocoInverse tool.
    inverse = osim.MocoInverse()
    inverse.setName('inverseTorqueTracking')

    #Construct a ModelProcessor and set it on the tool. The muscles are removed
    #and reserve actuators added to generate a torque driven solution
    modelProcessor = osim.ModelProcessor('scaledModelMuscle.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('Jog05_grf.xml'))
    modelProcessor.append(osim.ModOpRemoveMuscles())
    modelProcessor.append(osim.ModOpAddReserves(300))
    inverse.setModel(modelProcessor)
    
    #Construct a TableProcessor of the coordinate data and pass it to the
    #inverse tool. TableProcessors can be used in the same way as
    #ModelProcessors by appending TableOperators to modify the base table.
    #A TableProcessor with no operators, as we have here, simply returns the
    #base table.
    inverse.setKinematics(osim.TableProcessor('ikResults_states.sto'))

    # Initial time, final time, and mesh interval.
    inverse.set_initial_time(osim.Storage('ikResults_states.sto').getFirstTime())
    inverse.set_final_time(osim.Storage('ikResults_states.sto').getLastTime())
    inverse.set_mesh_interval(0.02)

    # By default, Moco gives an error if the kinematics contains extra columns.
    # Here, we tell Moco to allow (and ignore) those extra columns.
    inverse.set_kinematics_allow_extra_columns(True)

    # Solve the problem and write the solution to a Storage file.
    solution = inverse.solve()
    
    #Return the solution as an object that we can use
    return solution
コード例 #2
0
def solveMocoInverse():

    # Construct the MocoInverse tool.
    inverse = osim.MocoInverse()

    # Construct a ModelProcessor and set it on the tool. The default
    # muscles in the model are replaced with optimization-friendly
    # DeGrooteFregly2016Muscles, and adjustments are made to the default muscle
    # parameters.
    modelProcessor = osim.ModelProcessor('subject_walk_armless.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('grf_walk.xml'))
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    # Only valid for DeGrooteFregly2016Muscles.
    modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    # Only valid for DeGrooteFregly2016Muscles.
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    modelProcessor.append(osim.ModOpAddReserves(1.0))
    inverse.setModel(modelProcessor)

    # Construct a TableProcessor of the coordinate data and pass it to the
    # inverse tool. TableProcessors can be used in the same way as
    # ModelProcessors by appending TableOperators to modify the base table.
    # A TableProcessor with no operators, as we have here, simply returns the
    # base table.
    inverse.setKinematics(osim.TableProcessor('coordinates.sto'))

    # Initial time, final time, and mesh interval.
    inverse.set_initial_time(0.81)
    inverse.set_final_time(1.79)
    inverse.set_mesh_interval(0.02)

    # By default, Moco gives an error if the kinematics contains extra columns.
    # Here, we tell Moco to allow (and ignore) those extra columns.
    inverse.set_kinematics_allow_extra_columns(True)

    # Solve the problem and write the solution to a Storage file.
    solution = inverse.solve()
    solution.getMocoSolution().write(
        'example3DWalking_MocoInverse_solution.sto')

    # Generate a PDF with plots for the solution trajectory.
    model = modelProcessor.process()
    report = osim.report.Report(model,
                                'example3DWalking_MocoInverse_solution.sto',
                                bilateral=True)
    # The PDF is saved to the working directory.
    report.generate()
コード例 #3
0
def getWalkingModel():

    # Load the 19 DOF, 18 muscle model from file.
    model = osim.Model('subject_walk_armless_18musc.osim');

    # Add actuators representing the pelvis residual actuators and lumbar
    # torques. These actuators are only as strong as they need to be for the
    # problem to converge.
    addCoordinateActuator(model, 'pelvis_tx', 60)
    addCoordinateActuator(model, 'pelvis_ty', 300)
    addCoordinateActuator(model, 'pelvis_tz', 35)
    addCoordinateActuator(model, 'pelvis_tilt', 60)
    addCoordinateActuator(model, 'pelvis_list', 35)
    addCoordinateActuator(model, 'pelvis_rotation', 25)
    addCoordinateActuator(model, 'lumbar_bending', 40)
    addCoordinateActuator(model, 'lumbar_extension', 40)
    addCoordinateActuator(model, 'lumbar_rotation', 25)

    # We need additional actuators for hip rotation and hip adduction since the
    # existing muscle act primarily in the sagittal plane.
    addCoordinateActuator(model, 'hip_rotation_r', 100)
    addCoordinateActuator(model, 'hip_rotation_l', 100)
    addCoordinateActuator(model, 'hip_adduction_r', 100)
    addCoordinateActuator(model, 'hip_adduction_l', 100)

    # Create a ModelProcessor to make additional modifications to the model.
    modelProcessor = osim.ModelProcessor(model)
    # Weld the subtalar and toe joints.
    jointsToWeld = osim.StdVectorString()
    jointsToWeld.append('subtalar_r')
    jointsToWeld.append('subtalar_l')
    jointsToWeld.append('mtp_r')
    jointsToWeld.append('mtp_l')
    modelProcessor.append(osim.ModOpReplaceJointsWithWelds(jointsToWeld))
    # Apply the ground reaction forces to the model.
    modelProcessor.append(osim.ModOpAddExternalLoads('external_loads.xml'))
    # Update the muscles: ignore tendon compliance and passive forces, replace
    # muscle types with the DeGrooteFregly2016Muscle type, and scale the width
    # of the active force length curve.
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    # Add a set a weak reserves to the sagittal-plane joints in the model.
    modelProcessor.append(osim.ModOpAddReserves(1.0))

    return modelProcessor
コード例 #4
0
def solveMocoInverseMuscle():

    #Construct the MocoInverse tool.
    inverse = osim.MocoInverse()
    inverse.setName('inverseMuscleTracking')

    #Construct a ModelProcessor and set it on the tool.
    #Currently the coordinate actuators for the pelvis, along with the reserve
    #actuators are fairly generally set, and not weighted at all in cost function.
    #These actuators could be more carefully considered to generate an appropriate
    #muscle driven simulation. For example, if they max and min control to 1 - the 
    #pelvis actuators may not produce enough torque.
    modelProcessor = osim.ModelProcessor('scaledModelMuscle.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('Jog05_grf.xml'))
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    # Only valid for DeGrooteFregly2016Muscles.
    # modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    # Only valid for DeGrooteFregly2016Muscles.
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    modelProcessor.append(osim.ModOpAddReserves(2))
    inverse.setModel(modelProcessor)
    
    #Construct a TableProcessor of the coordinate data and pass it to the
    #inverse tool. TableProcessors can be used in the same way as
    #ModelProcessors by appending TableOperators to modify the base table.
    #A TableProcessor with no operators, as we have here, simply returns the
    #base table.
    inverse.setKinematics(osim.TableProcessor('ikResults_states.sto'))

    #Initial time, final time, and mesh interval.
    inverse.set_initial_time(osim.Storage('ikResults_states.sto').getFirstTime())
    inverse.set_final_time(osim.Storage('ikResults_states.sto').getLastTime())
    inverse.set_mesh_interval(0.02)

    # By default, Moco gives an error if the kinematics contains extra columns.
    # Here, we tell Moco to allow (and ignore) those extra columns.
    inverse.set_kinematics_allow_extra_columns(True)

    # Solve the problem and write the solution to a Storage file.
    solution = inverse.solve()
    
    #Return the solution as an object that we can use
    return solution
コード例 #5
0
def torqueDrivenMarkerTracking():

    # Create and name an instance of the MocoTrack tool.
    track = osim.MocoTrack()
    track.setName("torque_driven_marker_tracking")

    # Construct a ModelProcessor and add it to the tool. ModelProcessors
    # accept a base model and allow you to easily modify the model by appending
    # ModelOperators. Operations are performed in the order that they are
    # appended to the model.
    # Create the base Model by passing in the model file.
    modelProcessor = osim.ModelProcessor("subject_walk_armless.osim")
    # Add ground reaction external loads in lieu of a ground-contact model.
    modelProcessor.append(osim.ModOpAddExternalLoads("grf_walk.xml"))
    # Remove all the muscles in the model's ForceSet.
    modelProcessor.append(osim.ModOpRemoveMuscles())
    # Add CoordinateActuators to the model degrees-of-freedom. This ignores the
    # pelvis coordinates which already have residual CoordinateActuators.
    modelProcessor.append(osim.ModOpAddReserves(250))
    track.setModel(modelProcessor)

    # Use this convenience function to set the MocoTrack markers reference
    # directly from a TRC file. By default, the markers data is filtered at
    # 6 Hz and if in millimeters, converted to meters.
    track.setMarkersReferenceFromTRC("marker_trajectories.trc")

    # There is marker data in the 'marker_trajectories.trc' associated with
    # model markers that no longer exists (i.e. markers on the arms). Set this
    # flag to avoid an exception from being thrown.
    track.set_allow_unused_references(True)

    # Increase the global marker tracking weight, which is the weight
    # associated with the internal MocoMarkerTrackingCost term.
    track.set_markers_global_tracking_weight(10)

    # Increase the tracking weights for individual markers in the data set
    # placed on bony landmarks compared to markers located on soft tissue.
    markerWeights = osim.MocoWeightSet()
    markerWeights.cloneAndAppend(osim.MocoWeight("R.ASIS", 20))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.ASIS", 20))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.PSIS", 20))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.PSIS", 20))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.Knee", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.Ankle", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.Heel", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.MT5", 5))
    markerWeights.cloneAndAppend(osim.MocoWeight("R.Toe", 2))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.Knee", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.Ankle", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.Heel", 10))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.MT5", 5))
    markerWeights.cloneAndAppend(osim.MocoWeight("L.Toe", 2))
    track.set_markers_weight_set(markerWeights)

    # Initial time, final time, and mesh interval. The number of mesh points
    # used to discretize the problem is computed internally using these values.
    track.set_initial_time(0.81)
    track.set_final_time(1.65)
    track.set_mesh_interval(0.05)

    # Solve! Use track.solve() to skip visualizing.
    solution = track.solveAndVisualize()
コード例 #6
0
    trackingSolution.write('trackingSolution.sto')
    study.visualize(trackingSolution)

## Part 3: Compare Predictive and Tracking Solutions
# This is a convenience function provided for you. See mocoPlotTrajectory.m
plot.mocoPlotTrajectory('predictSolution.sto', 'trackingSolution.sto',
                        'predict', 'track')

## Part 4: Muscle-driven Inverse Problem
# Create a MocoInverse tool instance.
inverse = osim.MocoInverse()

# Part 4a: Provide the model via a ModelProcessor. Similar to the TableProcessor,
# you can add operators to modify the base model.
modelProcessor = osim.ModelProcessor(muscleDrivenModel)
modelProcessor.append(osim.ModOpAddReserves(2))
inverse.setModel(modelProcessor)

# Part 4b: Set the reference kinematics using the same TableProcessor we used
# in the tracking problem.
inverse.setKinematics(tableProcessor)

# Part 4c: Set the time range, mesh interval, and convergence tolerance.
inverse.set_initial_time(0)
inverse.set_final_time(1)
inverse.set_mesh_interval(0.05)
inverse.set_convergence_tolerance(1e-4)
inverse.set_constraint_tolerance(1e-4)

# Allow extra (unused) columns in the kinematics and minimize activations.
inverse.set_kinematics_allow_extra_columns(True)
コード例 #7
0
def solveMocoInverseWithEMG():

    # This initial block of code is identical to the code above.
    inverse = osim.MocoInverse()
    modelProcessor = osim.ModelProcessor('subject_walk_armless.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('grf_walk.xml'))
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    modelProcessor.append(osim.ModOpAddReserves(1.0))
    inverse.setModel(modelProcessor)
    inverse.setKinematics(osim.TableProcessor('coordinates.sto'))
    inverse.set_initial_time(0.81)
    inverse.set_final_time(1.79)
    inverse.set_mesh_interval(0.02)
    inverse.set_kinematics_allow_extra_columns(True)

    study = inverse.initialize()
    problem = study.updProblem()

    # Add electromyography tracking.
    emgTracking = osim.MocoControlTrackingGoal('emg_tracking')
    emgTracking.setWeight(50.0)
    # Each column in electromyography.sto is normalized so the maximum value in
    # each column is 1.0.
    controlsRef = osim.TimeSeriesTable('electromyography.sto')
    # Scale the tracked muscle activity based on peak levels from
    # "Gait Analysis: Normal and Pathological Function" by
    # Perry and Burnfield, 2010 (digitized by Carmichael Ong).
    soleus = controlsRef.updDependentColumn('soleus')
    gasmed = controlsRef.updDependentColumn('gastrocnemius')
    tibant = controlsRef.updDependentColumn('tibialis_anterior')
    for t in range(0, controlsRef.getNumRows()):
        soleus[t] = 0.77 * soleus[t]
        gasmed[t] = 0.87 * gasmed[t]
        tibant[t] = 0.37 * tibant[t]
    emgTracking.setReference(osim.TableProcessor(controlsRef))
    # Associate actuators in the model with columns in electromyography.sto.
    emgTracking.setReferenceLabel('/forceset/soleus_r', 'soleus')
    emgTracking.setReferenceLabel('/forceset/gasmed_r', 'gastrocnemius')
    emgTracking.setReferenceLabel('/forceset/gaslat_r', 'gastrocnemius')
    emgTracking.setReferenceLabel('/forceset/tibant_r', 'tibialis_anterior')
    problem.addGoal(emgTracking)

    # Solve the problem and write the solution to a Storage file.
    solution = study.solve()
    solution.write('example3DWalking_MocoInverseWithEMG_solution.sto')

    # Write the reference data in a way that's easy to compare to the solution.
    controlsRef.removeColumn('medial_hamstrings')
    controlsRef.removeColumn('biceps_femoris')
    controlsRef.removeColumn('vastus_lateralis')
    controlsRef.removeColumn('vastus_medius')
    controlsRef.removeColumn('rectus_femoris')
    controlsRef.removeColumn('gluteus_maximus')
    controlsRef.removeColumn('gluteus_medius')
    controlsRef.setColumnLabels(
        ['/forceset/soleus_r', '/forceset/gasmed_r', '/forceset/tibant_r'])
    controlsRef.appendColumn('/forceset/gaslat_r', gasmed)
    osim.STOFileAdapter.write(controlsRef, 'controls_reference.sto')

    # Generate a report comparing MocoInverse solutions without and with EMG
    # tracking.
    model = modelProcessor.process()
    output = 'example3DWalking_MocoInverseWithEMG_report.pdf'
    ref_files = [
        'example3DWalking_MocoInverseWithEMG_solution.sto',
        'controls_reference.sto'
    ]
    report = osim.report.Report(model,
                                'example3DWalking_MocoInverse_solution.sto',
                                output=output,
                                bilateral=True,
                                ref_files=ref_files)
    # The PDF is saved to the working directory.
    report.generate()
コード例 #8
0
    def create_model_processor(self, root_dir):

        # Create base model without reserves.
        model = osim.Model(os.path.join(root_dir,
                'resources/Rajagopal2016/'
                'subject_walk_contact_bounded_80musc.osim'))

        forceSet = model.getForceSet()
        numContacts = 0
        for i in np.arange(forceSet.getSize()):
            forceName = forceSet.get(int(i)).getName()
            if 'contact' in forceName: numContacts += 1

        print('Removing contact force elements from model...')
        contactsRemoved = 0
        while contactsRemoved < numContacts:
            for i in np.arange(forceSet.getSize()):
                forceName = forceSet.get(int(i)).getName()
                if 'contact' in forceName: 
                    print('  --> removed', forceSet.get(int(i)).getName())
                    forceSet.remove(int(i))
                    contactsRemoved += 1
                    break

        modelProcessor = osim.ModelProcessor(model)
        modelProcessor.append(osim.ModOpReplaceJointsWithWelds(
            ['subtalar_r', 'mtp_r', 'subtalar_l', 'mtp_l', 'radius_hand_r',
             'radius_hand_l']))
        modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
        modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
        modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
        modelProcessor.append(osim.ModOpFiberDampingDGF(0))
        baseModel = modelProcessor.process()

        # Create model for CMC
        modelProcessorCMC = osim.ModelProcessor(baseModel)
        modelProcessorCMC.append(osim.ModOpAddReserves(1))
        cmcModel = modelProcessorCMC.process()

        tasks = osim.CMC_TaskSet()
        for coord in cmcModel.getCoordinateSet():
            cname = coord.getName()
            if cname.endswith('_beta'):
                continue
            task = osim.CMC_Joint()
            task.setName(cname)
            task.setCoordinateName(cname)
            task.setKP(100, 1, 1)
            task.setKV(20, 1, 1)
            task.setActive(True, False, False)
            tasks.cloneAndAppend(task)
        tasks.printToXML(
            os.path.join(root_dir, 'code',
                         'motion_prescribed_walking_cmc_tasks.xml'))

        cmcModel.printToXML(os.path.join(root_dir, 'resources/Rajagopal2016/'
                                         'subject_walk_for_cmc.osim'))

        # Create direct collocation model:
        #   - TODO reserves
        #   - implicit tendon compliance mode
        #   - add external loads
        def add_reserve(model, coord, max_control):
            actu = osim.CoordinateActuator(coord)
            if coord.startswith('lumbar'):
                prefix = 'torque_'
            elif coord.startswith('pelvis'):
                prefix = 'residual_'
            else:
                prefix = 'reserve_'
            actu.setName(prefix + coord)
            actu.setMinControl(-1)
            actu.setMaxControl(1)
            actu.setOptimalForce(max_control)
            model.addForce(actu)
        add_reserve(baseModel, 'lumbar_extension', 50)
        add_reserve(baseModel, 'lumbar_bending', 50)
        add_reserve(baseModel, 'lumbar_rotation', 20)
        for side in ['_l', '_r']:
            add_reserve(baseModel, f'arm_flex{side}', 15)
            add_reserve(baseModel, f'arm_add{side}', 15)
            add_reserve(baseModel, f'arm_rot{side}', 5)
            add_reserve(baseModel, f'elbow_flex{side}', 5)
            add_reserve(baseModel, f'pro_sup{side}', 1)
            add_reserve(baseModel, f'hip_rotation{side}', 0.5)

        add_reserve(baseModel, 'pelvis_tilt', 60)
        add_reserve(baseModel, 'pelvis_list', 30)
        add_reserve(baseModel, 'pelvis_rotation', 15)
        add_reserve(baseModel, 'pelvis_tx', 100)
        add_reserve(baseModel, 'pelvis_ty', 200)
        add_reserve(baseModel, 'pelvis_tz', 35)
        baseModel.initSystem()
        muscles = baseModel.updMuscles()
        for imusc in np.arange(muscles.getSize()):
            muscle = muscles.get(int(imusc))
            if 'gas' in muscle.getName() or 'soleus' in muscle.getName():
                muscle.set_ignore_tendon_compliance(False)

        modelProcessorDC = osim.ModelProcessor(baseModel)
        modelProcessorDC.append(osim.ModOpFiberDampingDGF(0.01))
        modelProcessorDC.append(osim.ModOpAddReserves(1, 2.5, True))
        modelProcessorDC.append(
            osim.ModOpTendonComplianceDynamicsModeDGF('implicit'))

        ext_loads_xml = os.path.join(root_dir,
                                     "resources/Rajagopal2016/grf_walk.xml")
        modelProcessorDC.append(osim.ModOpAddExternalLoads(ext_loads_xml))

        return modelProcessorDC
コード例 #9
0
def muscleDrivenStateTracking():

    #Create and name an instance of the MocoTrack tool.
    track = osim.MocoTrack()
    track.setName('muscleDrivenStateTracking')

    #Construct a ModelProcessor and set it on the tool.
    #Currently the coordinate actuators for the pelvis, along with the reserve
    #actuators are fairly generally set, and not weighted at all in cost function.
    #These actuators could be more carefully considered to generate an appropriate
    #muscle driven simulation. For example, if they max and min control to 1 - the 
    #pelvis actuators may not produce enough torque.
    modelProcessor = osim.ModelProcessor('scaledModelMuscle.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('Jog05_grf.xml'))
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    # Only valid for DeGrooteFregly2016Muscles.
    modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    # Only valid for DeGrooteFregly2016Muscles.
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    modelProcessor.append(osim.ModOpAddReserves(2))
    track.setModel(modelProcessor)

    #Construct a TableProcessor of the coordinate data and pass it to the 
    #tracking tool. TableProcessors can be used in the same way as
    #ModelProcessors by appending TableOperators to modify the base table.
    #A TableProcessor with no operators, as we have here, simply returns the
    #base table.
    track.setStatesReference(osim.TableProcessor('ikResults_states.sto'))
    track.set_states_global_tracking_weight(5)

    ##### TODO: add more specific weights for different state coordinates like in RRA

    #This setting allows extra data columns contained in the states
    #reference that don't correspond to model coordinates.
    track.set_allow_unused_references(True)

    # Since there is only coordinate position data the states references, this
    # setting is enabled to fill in the missing coordinate speed data using
    # the derivative of splined position data.
    track.set_track_reference_position_derivatives(True)

    # Initial time, final time, and mesh interval.
    track.set_initial_time(osim.Storage('ikResults_states.sto').getFirstTime())
    track.set_final_time(osim.Storage('ikResults_states.sto').getLastTime())
    track.set_mesh_interval(0.08)

    #Instead of calling solve(), call initialize() to receive a pre-configured
    #MocoStudy object based on the settings above. Use this to customize the
    #problem beyond the MocoTrack interface.
    study = track.initialize()

    #Get a reference to the MocoControlCost that is added to every MocoTrack
    #problem by default.
    problem = study.updProblem()
    effort = osim.MocoControlGoal.safeDownCast(problem.updGoal('control_effort'))
    effort.setWeight(1)

    # # Put a large weight on the pelvis CoordinateActuators, which act as the
    # # residual, or 'hand-of-god', forces which we would like to keep as small
    # # as possible.
    # model = modelProcessor.process()
    # model.initSystem()
    # forceSet = model.getForceSet()
    # for ii in range(forceSet.getSize()):
    #     forcePath = forceSet.get(ii).getAbsolutePathString()
    #     if 'pelvis' in str(forcePath):
    #         effort.setWeightForControl(forcePath, 10)
            
    #Get solver and set the mesh interval
    solver = study.initCasADiSolver()
    #50 mesh intervals for half gait cycle recommended, keep smaller for now
    #19 will produce the same as inverse solution above
    # solver.set_num_mesh_intervals(19)
    
    #Set solver parameters
    solver.set_optim_constraint_tolerance(1e-3)
    solver.set_optim_convergence_tolerance(1e-3)
    
    # Solve and visualize.
    solution = study.solve()

    #Return the solution as an object that we can use
    return solution
コード例 #10
0
def torqueDrivenStateTracking():

    #Create and name an instance of the MocoTrack tool.
    track = osim.MocoTrack()
    track.setName('torqueDrivenStateTracking')

    #Construct a ModelProcessor and set it on the tool. Remove the muscles and
    #add reserve actuators
    modelProcessor = osim.ModelProcessor('scaledModelMuscle.osim')
    modelProcessor.append(osim.ModOpAddExternalLoads('Jog05_grf.xml'))
    modelProcessor.append(osim.ModOpRemoveMuscles())
    modelProcessor.append(osim.ModOpAddReserves(300))
    track.setModel(modelProcessor)

    #Construct a TableProcessor of the coordinate data and pass it to the 
    #tracking tool. TableProcessors can be used in the same way as
    #ModelProcessors by appending TableOperators to modify the base table.
    #A TableProcessor with no operators, as we have here, simply returns the
    #base table.
    track.setStatesReference(osim.TableProcessor('ikResults_states.sto'))
    track.set_states_global_tracking_weight(5)

    ##### TODO: add more specific weights for different state coordinates like in RRA

    #This setting allows extra data columns contained in the states
    #reference that don't correspond to model coordinates.
    track.set_allow_unused_references(True)

    # Since there is only coordinate position data the states references, this
    # setting is enabled to fill in the missing coordinate speed data using
    # the derivative of splined position data.
    track.set_track_reference_position_derivatives(True)

    # Initial time, final time, and mesh interval.
    track.set_initial_time(osim.Storage('ikResults_states.sto').getFirstTime())
    track.set_final_time(osim.Storage('ikResults_states.sto').getLastTime())
    track.set_mesh_interval(0.08)

    #Instead of calling solve(), call initialize() to receive a pre-configured
    #MocoStudy object based on the settings above. Use this to customize the
    #problem beyond the MocoTrack interface.
    study = track.initialize()

    #Get a reference to the MocoControlCost that is added to every MocoTrack
    #problem by default.
    problem = study.updProblem()
    effort = osim.MocoControlGoal.safeDownCast(problem.updGoal('control_effort'))
    effort.setWeight(1)

    # # Put a large weight on the pelvis CoordinateActuators, which act as the
    # # residual, or 'hand-of-god', forces which we would like to keep as small
    # # as possible.
    # model = modelProcessor.process()
    # model.initSystem()
    # forceSet = model.getForceSet()
    # for ii in range(forceSet.getSize()):
    #     forcePath = forceSet.get(ii).getAbsolutePathString()
    #     if 'pelvis' in str(forcePath):
    #         effort.setWeightForControl(forcePath, 10)
            
    #Get solver and set the mesh interval
    solver = study.initCasADiSolver()
    #50 mesh intervals for half gait cycle recommended, keep smaller for now
    #19 will produce the same as inverse solution above
    # solver.set_num_mesh_intervals(19)
    
    #Set solver parameters
    solver.set_optim_constraint_tolerance(1e-3)
    solver.set_optim_convergence_tolerance(1e-3)
    
    #Set guess from inverse solution using the convenience function to transfer
    #an inverse solution to a solver guess
    osimHelper.inverseSolutionToTrackGuess(guessFile = 'inverseTorqueSolution_fromIK.sto',
                                           mocoSolver = solver)
    
    # Solve and visualize.
    solution = study.solve()

    #Return the solution as an object that we can use
    return solution