Beispiel #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
Beispiel #2
0
def create_opensim_storage(time, data, column_names):
    """Creates a OpenSim::Storage.

    Parameters
    ----------
    time: SimTK::Vector

    data: SimTK::Matrix

    column_names: list of strings

    Returns
    -------
    sto: OpenSim::Storage

    """
    sto = opensim.Storage()
    sto.setColumnLabels(list_to_osim_array_str(['time'] + column_names))
    for i in range(data.nrow()):
        row = opensim.ArrayDouble()
        for j in range(data.ncol()):
            row.append(data.getElt(i, j))

        sto.append(time[i], row)

    return sto
Beispiel #3
0
def read_from_storage(file_name, to_filter=False):
    """Read OpenSim.Storage files.

    Parameters
    ----------
    file_name: (string) path to file

    Returns
    -------
    tuple: (labels, time, data)
    """
    sto = opensim.Storage(file_name)
    sto.resampleLinear(0.01)
    if to_filter:
        sto.lowpassFIR(4, 6)

    labels = osim_array_to_list(sto.getColumnLabels())
    time = opensim.ArrayDouble()
    sto.getTimeColumn(time)
    time = np.round(osim_array_to_list(time), 3)
    data = []
    for i in range(sto.getSize()):
        temp = osim_array_to_list(sto.getStateVector(i).getData())
        temp.insert(0, time[i])
        data.append(temp)

    df = pd.DataFrame(data, columns=labels)
    df.index = df.time
    return df
Beispiel #4
0
def read_from_storage(model_file, file_name):
    """Read OpenSim.Storage files.
    Parameters
    ----------
    file_name: (string) path to file
    Returns
    -------
    tuple: (labels, time, data)
    """
    sto = opensim.Storage(file_name)
    if sto.isInDegrees():
        model = opensim.Model(model_file)
        model.initSystem()
        model.getSimbodyEngine().convertDegreesToRadians(sto)

    # sto.resampleLinear(sampling_interval)

    labels = osim_array_to_list(sto.getColumnLabels())
    time = opensim.ArrayDouble()
    sto.getTimeColumn(time)
    time = osim_array_to_list(time)
    data = []
    for i in range(sto.getSize()):
        temp = osim_array_to_list(sto.getStateVector(i).getData())
        temp.insert(0, time[i])
        data.append(temp)

    df = pd.DataFrame(data, columns=labels)
    df.index = df.time
    return df
Beispiel #5
0
def read_from_storage(file_name, sampling_interval=0.01, to_filter=False):
    """Read OpenSim.Storage files.

    Parameters
    ----------
    file_name: (string) path to file

    sampling_interval: resample the data with a given interval (0.01)

    to_filter: use low pass 4th order FIR filter with 6Hz cut off
    frequency

    Returns
    -------
    df: pandas data frame

    """
    sto = opensim.Storage(file_name)
    sto.resampleLinear(sampling_interval)
    if to_filter:
        sto.lowpassFIR(4, 6)

    labels = osim_array_to_list(sto.getColumnLabels())
    time = opensim.ArrayDouble()
    sto.getTimeColumn(time)
    time = osim_array_to_list(time)
    data = []
    for i in range(sto.getSize()):
        temp = osim_array_to_list(sto.getStateVector(i).getData())
        temp.insert(0, time[i])
        data.append(temp)

    df = pd.DataFrame(data, columns=labels)
    df.index = df.time
    return df
Beispiel #6
0
def test_StorageToPieceWiseLinearFunction():

    sto = osim.Storage(os.path.join(this_file_dir, 'storage.sto'))
    column_name = 'column1'
    scale_factor = 2.5

    time = osim.ArrayDouble()
    sto.getTimeColumn(time)

    state_index = sto.getStateIndex(column_name)

    if type(scale_factor) == float:
        sto.multiplyColumn(state_index, scale_factor)
    elif scale_factor == None:
        pass
    else:
        raise Exception('scale_factor, if specified, must be a float.')

    ordinate = osim.ArrayDouble()
    sto.getDataColumn(state_index, ordinate)

    fcn = osim.PiecewiseLinearFunction()
    for idx in range(time.getSize()):
        fcn.addPoint(time.get(idx), ordinate.get(idx))

    fcnName = os.path.join(this_file_dir, 'piecewiseLinearFunction.xml')
    fcn.printToXML(fcnName)

    assert (open(fcnName).readlines() ==
            open(fcnName.replace('.xml', '_desired.xml')).readlines())

    os.remove(fcnName)
Beispiel #7
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
    def run_id_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}')

            # initialize inverse dynamic tool from setup file
            model = osim.Model(self.model_input)
            id_tool = osim.InverseDynamicsTool(self.xml_input)
            id_tool.setModel(model)

            # get starting and ending time
            motion = osim.Storage(f'{trial.resolve()}')
            start = motion.getFirstTime()
            end = motion.getLastTime()

            # inverse dynamics tool
            id_tool.setStartTime(start)
            id_tool.setEndTime(end)
            id_tool.setCoordinatesFileName(f'{trial.resolve()}')

            if self.low_pass:
                id_tool.setLowpassCutoffFrequency(self.low_pass)

            # set name of input (mot) file and output (sto)
            filename = f'{trial.stem}'
            id_tool.setName(filename)
            id_tool.setOutputGenForceFileName('inverse_dynamic_output.sto')
            id_tool.setResultsDir(f'{self.sto_output}')

            # external loads file
            if self.forces_dir:
                loads = osim.ExternalLoads(self.xml_forces, True)
                if self.prefix:
                    loads.setDataFileName(
                        f"{Path(self.forces_dir, trial.stem.replace(f'{self.prefix}_', '')).resolve()}.sto"
                    )
                else:
                    loads.setDataFileName(
                        f"{Path(self.forces_dir, trial.stem).resolve()}.sto")
                loads.setExternalLoadsModelKinematicsFileName(
                    f'{trial.resolve()}')

                temp_xml = Path(f'{trial.stem}_temp.xml')
                loads.printToXML(f'{temp_xml.resolve()}')  # temporary xml file
                id_tool.setExternalLoadsFileName(f'{temp_xml}')
            else:
                id_tool.setExternalLoadsFileName(self.xml_forces)
            id_tool.printToXML(self.xml_output)
            id_tool.run()

            if self.forces_dir:
                temp_xml.unlink()  # delete temporary xml file
Beispiel #9
0
 def test_states_storage_optional_arguments(self):
     # Try all combinations of optional arguments, just to ensure the
     # wrapping works.
     model = osim.Model(
         os.path.join(test_dir, "gait10dof18musc_subject01.osim"))
     sto = osim.Storage(self.states_sto_fname)
     states = osim.StatesTrajectory.createFromStatesStorage(model, sto)
     states = osim.StatesTrajectory.createFromStatesStorage(
         model, sto, False, False)
     states = osim.StatesTrajectory.createFromStatesStorage(
         model, sto, False, True)
     states = osim.StatesTrajectory.createFromStatesStorage(
         model, sto, True, False)
     states = osim.StatesTrajectory.createFromStatesStorage(
         model, sto, True, True)
Beispiel #10
0
def read_from_storage(file_name):
    """Read OpenSim.Storage files. """
    sto = opensim.Storage(file_name)

    labels = osim_array_to_list(sto.getColumnLabels())
    time = opensim.ArrayDouble()
    sto.getTimeColumn(time)
    time = osim_array_to_list(time)
    data = []
    for i in range(sto.getSize()):
        temp = osim_array_to_list(sto.getStateVector(i).getData())
        temp.insert(0, time[i])
        data.append(temp)

    df = pd.DataFrame(data, columns=labels)
    df.index = df.time
    return df
Beispiel #11
0
def stoToDF(fileName, sampleInterval=None, filterFreq=None):
    """
    
    Parameters
    ----------
    fileName: filename of opensim .mot or .sto file

    Returns
    -------
    df: pandas data frame
    
    """

    #Load file
    osimSto = osim.Storage(fileName)

    #Resample
    if sampleInterval != None:
        osimSto.resampleLinear(sampleInterval)

    #Filter
    if filterFreq != None:
        osimSto.lowpassFIR(4, int(filterFreq))

    #Get column labels
    labels = osimToList(osimSto.getColumnLabels())

    #Set time values
    time = osim.ArrayDouble()
    osimSto.getTimeColumn(time)
    time = osimToList(time)

    #Allocate space for data
    data = []
    #Loop through columns and get data
    for i in range(osimSto.getSize()):
        temp = osimToList(osimSto.getStateVector(i).getData())
        temp.insert(0, time[i])
        data.append(temp)

    #Convert to dataframe
    df = pd.DataFrame(data, columns=labels)

    return df
    def finalize_model(self, mot, filter_param=None):
        self.state = self.model.initSystem()

        # get some reference that will be modified during the optimization (for speed sake)
        self.n_dof = self.state.getQ().size()
        self.actuators = self.model.getForceSet()
        self.n_actuators = self.actuators.getSize()
        self.muscle_actuators = self.model.getMuscles()
        self.n_muscles = self.muscle_actuators.getSize()

        self._data_storage = osim.Storage(mot)
        self.filter_param = filter_param

        self.__dispatch_kinematics()

        force_set = self.model.getForceSet()
        for i in range(force_set.getSize()):
            coord = osim.CoordinateActuator.safeDownCast(force_set.get(i))
            if coord:
                coord.overrideActuation(self.state, True)
Beispiel #13
0
    def test_StorageToPieceWiseLinearFunction(self):

        sto = osim.Storage(os.path.join(test_dir, 'storage.sto'))
        column_name = 'column1'
        scale_factor = 2.5

        time = osim.ArrayDouble()
        sto.getTimeColumn(time)

        state_index = sto.getStateIndex(column_name)

        if type(scale_factor) == float:
            sto.multiplyColumn(state_index, scale_factor)
        elif scale_factor == None:
            pass
        else:
            raise Exception('scale_factor, if specified, must be a float.')

        ordinate = osim.ArrayDouble()
        sto.getDataColumn(state_index, ordinate)

        fcn = osim.PiecewiseLinearFunction()
        for idx in range(time.getSize()):
            fcn.addPoint(time.get(idx), ordinate.get(idx))

        fcnName = os.path.join(test_dir, 'piecewiseLinearFunction.xml')
        fcn.printToXML(fcnName)

        assert fcn.getX(0) == 0
        assert_almost_equal(fcn.getX(1), 0.01)
        assert_almost_equal(fcn.getX(2), 0.02)
        assert_almost_equal(fcn.getX(3), 0.03)
        assert_almost_equal(fcn.getX(4), 0.04)
        assert_almost_equal(fcn.getY(0), 3.75)
        assert_almost_equal(fcn.getY(1), 23.025)
        assert_almost_equal(fcn.getY(2), 13.5575)

        os.remove(fcnName)
def get_open_sim_model(prob):
    if prob in runningOpenSimModels:
        return runningOpenSimModels[prob][0], runningOpenSimModels[prob][
            1], runningOpenSimModels[prob][2], runningOpenSimModels[prob][
                3], runningOpenSimModels[prob][4]
    else:
        runningOpenSimModels[prob] = [
            osim.Model(subject_model), get_open_sim_model.idx
        ]
        runningOpenSimModels[prob].append(
            runningOpenSimModels[prob][0].initSystem())

        data_storage = osim.Storage(
            f'{PROJECT_PATH}/{subject}/1_inverse_kinematic/{mot_file}')

        model = runningOpenSimModels[prob][0]
        model.getSimbodyEngine().convertDegreesToRadians(data_storage)
        data_storage.lowpassFIR(2, 6)
        gen_coord_function = osim.GCVSplineSet(5, data_storage)
        runningOpenSimModels[prob].append(list())
        for frame in range(data_storage.getSize()):
            q = list()
            for idx_q in range(data_storage.getStateVector(frame).getSize()):
                q.append(
                    gen_coord_function.evaluate(
                        idx_q, 0,
                        data_storage.getStateVector(frame).getTime()))
            runningOpenSimModels[prob][3].append(osim.Vector(q))
        runningOpenSimModels[prob].append(
            np.linspace(data_storage.getFirstTime(),
                        data_storage.getLastTime(),
                        num=data_storage.getSize()))

        get_open_sim_model.idx += 1
        return runningOpenSimModels[prob][0], runningOpenSimModels[prob][
            1], runningOpenSimModels[prob][2], runningOpenSimModels[prob][
                3], runningOpenSimModels[prob][4]
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)
def calculate_muscle_data(model_file, ik_file):
    """This function calculates the moment arm and maximum muscle force provided an
    OpenSim model and a motion from inverse kinematics.

    Parameters
    ----------
    model_file: string
        OpenSim .osim file
    ik_file: string
        .mot from inverse kinematics

    Returns
    -------
    tuple:
        (moment arm[time x coordinates x muscles], max_force[time x muscles])
    """
    model = opensim.Model(model_file)
    state = model.initSystem()

    # model coordinates dictionary
    model_coordinates = {}
    for i in range(0, model.getNumCoordinates()):
        model_coordinates[model.getCoordinateSet().get(i).getName()] = i

    # model muscles dictionary
    model_muscles = {}
    for i in range(0, model.getNumControls()):
        model_muscles[model.getMuscles().get(i).getName()] = i

    # process the motion
    motion = opensim.Storage(ik_file)
    labels = motion.getColumnLabels()
    isInDeg = motion.isInDegrees()

    # calculate moment arm and max force
    max_force = np.empty([motion.getSize(), len(model_muscles)], float)
    moment_arm = np.empty(
        [motion.getSize(),
         len(model_coordinates),
         len(model_muscles)], float)
    for t in tqdm(range(0, motion.getSize())):
        state_vector = motion.getStateVector(t)
        state_data = state_vector.getData()

        # update model pose
        for j in range(0, state_data.getSize()):
            coordinate = model_coordinates[labels.get(j + 1)]  # time is 0
            if isInDeg:
                value = np.deg2rad(state_data.get(j))
            else:
                value = state_data.get(j)

            model.updCoordinateSet().get(coordinate).setValue(state, value)

        model.realizePosition(state)

        # calculate muscle moment arm
        for coordinate_index in model_coordinates.values():
            for muscle_index in model_muscles.values():
                coordinate = model.getCoordinateSet().get(coordinate_index)
                muscle = model.getMuscles().get(muscle_index)
                ma = muscle.computeMomentArm(state, coordinate)
                moment_arm[t, coordinate_index, muscle_index] = ma

        # calculate max force (TODO use force-length/velocity relations)
        for muscle_index in model_muscles.values():
            muscle = model.getMuscles().get(muscle_index)
            max_force[t, muscle_index] = muscle.getMaxIsometricForce()

    return (moment_arm, max_force)
Beispiel #18
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
Beispiel #19
0
    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)
 c3d = osim.C3DFileAdapter()
 trc = osim.TRCFileAdapter()
 
 #Get markers
 static = c3d.read(staticFile[0])
 markersStatic = c3d.getMarkersTable(static)
 
 #Write static data to file
 trc.write(markersStatic, staticFile[0].split('.')[0]+'.trc')
 
 #Set variable for static trial trc
 staticTrial_trc = staticFile[0].split('.')[0]+'.trc'
 
 #Set scale time range
 scaleTimeRange = osim.ArrayDouble()
 scaleTimeRange.set(0,osim.Storage(staticTrial_trc).getFirstTime())
 scaleTimeRange.set(1,osim.Storage(staticTrial_trc).getFirstTime()+0.5)
 
 #Set-up scale tool    
 scaleTool.append(osim.ScaleTool())
 
 #Set mass in scale tool
 scaleTool[ii-startInd].setSubjectMass(mass)
 
 #Set generic model file
 scaleTool[ii-startInd].getGenericModelMaker().setModelFileName(genModelFileName)
 
 #Set the measurement set
 scaleTool[ii-startInd].getModelScaler().setMeasurementSet(measurementSet)
 
 #Set scale tasks
Beispiel #21
0
    def _populate_references(self):
        # Initialize objects needed to populate the references.
        coord_functions = opensim.FunctionSet()
        marker_weights = opensim.SetMarkerWeights()

        # Load coordinate data, if available.
        if self.coordinate_file and (self.coordinate_file != ""
                                     and self.coordinate_file != "Unassigned"):
            coordinate_values = opensim.Storage(self.coordinate_file)
            # Convert to radians, if in degrees.
            if not coordinate_values.isInDegrees():
                self.model.getSimbodyEngine().convertDegreesToRadians(
                    coordinate_values)
            coord_functions = opensim.GCVSplineSet(5, coordinate_values)

        index = 0
        for i in range(0, self.ik_task_set.getSize()):
            if not self.ik_task_set.get(i).getApply():
                continue
            if opensim.IKCoordinateTask.safeDownCast(self.ik_task_set.get(i)):
                # NOTE: Opposed to C++, a variable cannot be declared in the above if statement, so do it now.
                coord_task = opensim.IKCoordinateTask.safeDownCast(
                    self.ik_task_set.get(i))
                coord_ref = opensim.CoordinateReference()
                if coord_task.getValueType(
                ) == opensim.IKCoordinateTask.FromFile:
                    if not coord_functions:
                        raise Exception(
                            "InverseKinematicsTool: value for coordinate " +
                            coord_task.getName() + " not found.")

                    index = coord_functions.getIndex(coord_task.getName(),
                                                     index)
                    if index >= 0:
                        coord_ref = opensim.CoordinateReference(
                            coord_task.getName(), coord_functions.get(index))
                elif coord_task.getValueType(
                ) == opensim.IKCoordinateTask.ManualValue:
                    reference = opensim.Constant(
                        opensim.Constant(coord_task.getValue()))
                    coord_ref = opensim.CoordinateReference(
                        coord_task.getName(), reference)
                else:  # Assume it should be held at its default value
                    value = self.model.getCoordinateSet().get(
                        coord_task.getName()).getDefaultValue()
                    reference = opensim.Constant(value)
                    coord_ref = opensim.CoordinateReference(
                        coord_task.getName(), reference)

                if not coord_ref:
                    raise Exception(
                        "InverseKinematicsTool: value for coordinate " +
                        coord_task.getName() + " not found.")
                else:
                    coord_ref.setWeight(coord_task.getWeight())

                self.coordinate_references.push_back(coord_ref)

            elif opensim.IKMarkerTask.safeDownCast(self.ik_task_set.get(i)):
                # NOTE: Opposed to C++, a variable cannot be declared in the above if statement, so do it now.
                marker_task = opensim.IKMarkerTask.safeDownCast(
                    self.ik_task_set.get(i))
                if marker_task.getApply():
                    # Only track markers that have a task and it is "applied"
                    marker_weights.cloneAndAppend(
                        opensim.MarkerWeight(marker_task.getName(),
                                             marker_task.getWeight()))

        self.markers_reference.initializeFromMarkersFile(
            self.marker_file, marker_weights)
Beispiel #22
0
# Musculoskeletal model
osimModel = osim.Model(scaled_MM_Moved_path)
state = osimModel.initSystem()

MOT_file = MOT_files[0]
PFF_MOT_file = PFF_MOT_files[0]

path, filename = os.path.split(MOT_file)
filename, ext = os.path.splitext(filename)

STO_file = filename + '.sto'  # Path to the output .MOT file that will be created and contain the IK results
XML_ID_file = dir_path + 'XML\\' + filename + '_ID.xml'  # Path to the ID XML file that will be created
XML_External_Load_ID_file = dir_path + 'XML\\' + filename + '_External_Load_ID.xml'  # Path to the External Load ID XML file that will be created

# Mot Data
motData = osim.Storage(MOT_file)
initial_time = motData.getFirstTime()
final_time = motData.getLastTime()

# ID tool
idTool = osim.InverseDynamicsTool(XML_generic_ID_path)
idTool.setResultsDir(dir_path + '\\STO\\')
idTool.setName(filename)
idTool.setModel(osimModel)
idTool.setCoordinatesFileName(MOT_file)
idTool.setStartTime(initial_time)
idTool.setEndTime(final_time)
idTool.setOutputGenForceFileName(STO_file)

# External Load File
externalLoads = osim.ExternalLoads(osimModel,
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:
            motionFilename = sub + ".mot"
            exforceFilename = sub + "_" + str(mot) + "_" + str(exf) + ".xml"
            outputFilename = sub + "_" + str(mot) + "_" + str(exf)

            motData = osim.Storage(motionFilename)

            ##Get the time of Start and End
            initial_time = motData.getFirstTime()
            final_time = motData.getLastTime()

            aTool.setName(outputFilename)
            ##Calculation start time
            aTool.setInitialTime(initial_time)
            ##Calculation finish time
            aTool.setFinalTime(final_time)
            ##Output precision
            aTool.setOutputPrecision(8)
            aTool.setLowpassCutoffFrequency(6.0)
            aTool.setSolveForEquilibrium(False)
            ##Set the model
Beispiel #24
0
# base table.
track.setStatesReference(osim.TableProcessor("coordinates.sto"))
track.set_states_global_tracking_weight(5)

# 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.
# The IK data doesn't match the GRF data, so specific times need ti be taken from this
track.set_initial_time(osim.Storage('coordinates.sto').getFirstTime())
track.set_final_time(osim.Storage('coordinates.sto').getLastTime())
# track.set_mesh_interval(0.05)

# 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"))

# 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
Beispiel #25
0
    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)
Beispiel #26
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
def kinematicsToStates(kinematicsFileName = None, osimModelFileName = None,
                       outputFileName = 'coordinates.sto',
                       inDegrees = True, outDegrees = False):
    
    # Convenience function for scaling muscle strength based on height/mass relationship.
    # The scaling is based on the Handsfield et al. equations, and this function
    # is adapted from that which comes with the Rajagopal et al. model
    #
    # Input:    kinematicsFileName - file containing kinematic data. Header should only be coordinates name, rather than path to state
    #           osimModelFileName - opensim model filename that corresponds to kinematic data
    #           outputFileName - optional filename to output to (defaults to coordinates.sto)
    #           inDegrees - set to true if kinematics file is in degrees (defaults to True)
    #           outDegrees - set to true if desired output is in degrees (defaults to False)

    if kinematicsFileName is None:
        raise ValueError('Filename for kinematics is required')
    if osimModelFileName is None:
        raise ValueError('OpenSim model filename is required')

    #Load in the kinematic data
    kinematicsStorage = osim.Storage(kinematicsFileName)
    
    #Create a copy of the kinematics data to alter the column labels in
    statesStorage = osim.Storage(kinematicsFileName)
    
    #Resample the data points linearly to avoid any later issues with matching
    #time points. Use a time stamp for 250 Hz
    kinematicsStorage.resampleLinear(1/250)
    statesStorage.resampleLinear(1/250)
    
    #Get the column headers for the storage file
    angleNames = kinematicsStorage.getColumnLabels()
    
    #Get the corresponding full paths from the model to rename the
    #angles in the kinematics file
    kinematicModel = osim.Model(osimModelFileName)
    for ii in range(0,angleNames.getSize()-1):
        currAngle = angleNames.get(ii)
        if currAngle != 'time':
            #Get full path to coordinate
            fullPath = kinematicModel.updCoordinateSet().get(currAngle).getAbsolutePathString()+'/value'
            #Set angle name appropriately using full path
            angleNames.set(ii,fullPath)
    
    #Set the states storage object to have the updated column labels
    statesStorage.setColumnLabels(angleNames)
    
    #Appropriately set output in degrees or radians
    if inDegrees and not outDegrees:
        #Convert degrees values to radians for consistency with the current
        #file label (defaults back to inDegrees=no). Radians seem to work
        #better with the Moco process as well.
        kinematicModel.initSystem()
        kinematicModel.getSimbodyEngine().convertDegreesToRadians(statesStorage)
    elif inDegrees and outDegrees:
        #Change the storage label back to specifying indegrees=yes
        statesStorage.setInDegrees(True)
    elif not inDegrees and outDegrees:
        #Convert radians to degrees
        kinematicModel.initSystem()
        kinematicModel.getSimbodyEngine().convertRadiansToDegrees(statesStorage)
        #Reset labeling for degrees
        statesStorage.setInDegrees(True)
    
    #Write the states storage object to file
    statesStorage.printToXML(outputFileName)
Beispiel #28
0
#Set the model processor in the problem
problem.setModel(simModel)

#Navigate to guess directory
os.chdir('..\\GuessFiles')

#Set guess path
guessPath = os.getcwd()

#Set time bounds on the problem
##### NOTE: first iteration with end time bounds seemed to try and solve to the
##### the final end time bound (i.e. 1.0) rather than as fast as possible. Test
##### and see whether removing these fixes it.
# Set to a percentage of the final guess time to end
timeLB = 0.9 * osim.Storage(taskName + '_StartingGuess.sto').getLastTime()
timeUB = 1.1 * osim.Storage(taskName + '_StartingGuess.sto').getLastTime()
problem.setTimeBounds(osim.MocoInitialBounds(0.0),
                      osim.MocoFinalBounds(timeLB, timeUB))
# problem.setTimeBounds(0,[])

#Define marker end point goals
osimHelper.addMarkerEndPoints(taskName, problem, simModel)

#Define kinematic task bounds
osimHelper.addTaskBounds(taskName, problem, simModel, taskBoundsElv,
                         taskBoundsRot, taskBoundsAng)

#Add a control cost to the problem
problem.addGoal(osim.MocoControlGoal('effort', 1))
Beispiel #29
0
def write(filename):

    import opensim as osim
    import csv
    import numpy as np
    import directories

    allDir = list(directories.main(directories))
    idResultsDir = allDir[7]
    soResultsDir = allDir[8]
    cmcResultsDir = allDir[10]

    storage = osim.Storage(filename)
    labels = storage.getColumnLabels()
    labelSize = labels.getSize()
    header = []

    for i in range(labelSize):
        header.append(labels.getitem(i))

    nrows = storage.getSize()

    data = []
    dataArray = []

    if header[0] == 'time':
        st = 1
        dataArray.append(osim.ArrayDouble())
        storage.getTimeColumn(dataArray[0])
        column = []
        for j in range(nrows):
            column.append(dataArray[0].getitem(j))

        data.append(column)
    else:
        st = 0

    for i in range(st, labelSize):
        dataArray.append(osim.ArrayDouble())
        storage.getDataColumn(header[i], dataArray[i])
        column = []
        for j in range(nrows):
            column.append(dataArray[i].getitem(j))

        data.append(column)
    dataFixed = np.transpose(data)
    headerFixed = []
    headerFixed.append(header)

    # Writing excel file for plotting
    if filename == idResultsDir + "/" + "subject01_walk1_id.sto":
        with open((idResultsDir + "/" + "idData.csv"), "wb") as fid:
            csvWriter = csv.writer(fid, dialect='excel')
            csvWriter.writerows(headerFixed)
            csvWriter.writerows(dataFixed)

    if filename == soResultsDir + "/" + "subject01_walk1_StaticOptimization_force.sto":
        with open((soResultsDir + "/" + "soData.csv"), "wb") as fid:
            csvWriter = csv.writer(fid, dialect='excel')
            csvWriter.writerows(headerFixed)
            csvWriter.writerows(dataFixed)

    if filename == soResultsDir + "/" + "_Gait2354 Joint RXN_ReactionLoads.sto":
        with open((soResultsDir + "/" + "soJrData.csv"), "wb") as fid:
            csvWriter = csv.writer(fid, dialect='excel')
            csvWriter.writerows(headerFixed)
            csvWriter.writerows(dataFixed)

    if filename == cmcResultsDir + "/" + "_Gait2354 Joint RXN_ReactionLoads.sto":
        with open((cmcResultsDir + "/" + "cmcJrData.csv"), "wb") as fid:
            csvWriter = csv.writer(fid, dialect='excel')
            csvWriter.writerows(headerFixed)
            csvWriter.writerows(dataFixed)
    return ()
def inverseDynamics():
    import os
    import re
    import shutil
    import opensim as osim
    import directories

    allDir = list(directories.main(directories))
    parentDir = allDir[0]
    paramsDir = allDir[1]
    subID = allDir[4]
    subResultsDir = allDir[5]
    ikResultsDir = allDir[6]
    idResultsDir = allDir[7]

    # Clear Inverse Dynamics Folder
    if os.path.exists(idResultsDir):
        shutil.rmtree(idResultsDir, ignore_errors=True)
    if not os.path.exists(idResultsDir):
        os.mkdir(idResultsDir)

    # Input data files
    genericExtLoads = paramsDir + "/externalLoads.xml"
    motData = parentDir + "/data/osDemo/subject01_walk1_grf.mot"
    motFileName = "subject01_walk1_grf.mot"
    # saveDir = subResultsDir + "/" + subID + "motionFile.mot"
    ikFileName = "subject01_walk1_ik.mot"
    ikFile = ikResultsDir + "/" + ikFileName

    # Copy GRF File over to Current Directory
    shutil.copy(motData, idResultsDir + "/" + motFileName)

    # Load Inverse Kinematics Model
    aModel = osim.Model(subResultsDir + "/" + subID + ".osim")

    # initialize system
    aModel.initSystem()

    # Initialize External Loads File from Generic File
    extLoads = osim.ExternalLoads(aModel, genericExtLoads)

    # Initialize idTool
    idTool = osim.InverseDynamicsTool()
    idTool.setLowpassCutoffFrequency(6.0)
    idTool.setInputsDir(idResultsDir)
    idTool.setResultsDir(idResultsDir)
    idTool.setModel(aModel)
    idTool.setModelFileName(subResultsDir + "/" + subID + ".osim")
    # Get .mot data to determine time range
    motCoordsData = osim.Storage(ikFile)
    # Get initial and final time
    initial_time = motCoordsData.getFirstTime()
    final_time = motCoordsData.getLastTime()

    # Creat output ID
    idFileName = re.sub('ik.mot', 'id.sto', ikFileName)
    # Customize and save external loads ile
    extLoads.setName(motFileName)
    extLoads.setDataFileName(motData)
    extLoads.setExternalLoadsModelKinematicsFileName(ikFile)
    extLoads.printToXML(idResultsDir + "/" +
                        re.sub('ik.mot', 'extLoads.xml', ikFileName))

    # Setup idTool
    idTool.setName(motFileName)
    idTool.setCoordinatesFileName(ikFile)
    idTool.setStartTime(initial_time)
    idTool.setEndTime(final_time)
    # Must be relative to output directory, not full path!
    idTool.setOutputGenForceFileName(idFileName)
    idTool.setExternalLoadsFileName(
        idResultsDir + "/" + re.sub('ik.mot', 'extLoads.xml', ikFileName))
    # Can comment out if not needed in GUI
    idTool.printToXML(idResultsDir + "/" +
                      re.sub('ik.mot', 'setupID.xml', ikFileName))

    # Run idTool
    idTool.run()
    os.system('cls' if os.name == 'nt' else 'clear')
    return ()