MocoInverse接口使用教程

MocoInverse通过Direct Collocation方式的轨迹优化解决了冗余执行器问题,进行执行器的控制,以实现精确规定的目标运动,以控制扭矩的平方或其他成本为最小化目标。

MocoInverse和MocoTrack用于解决标准问题,需要以模型和运动学数据作为输入,并产生控制和执行器状态作为输出,但两者解决的是不同的最优控制问题。

我们首先讨论MocoInverse的求解问题,使用肌肉骨骼模型,求解肌肉行为中的激活强度问题,并以提供的API脚本进行使用方法的演示。

MocoInverse的官方python脚本没有可视化动画界面,而MocoTrack有可视化动画界面。

在个示例中,我们将学习如何使用MocoInverse工具依据指定的运动,计算步行过程中的肌肉激活程度。这个示例分为两部分:第一部分不依赖于肌电(Electromyography, EMG)数据为cost,而第二部分则对一部分肌肉的肌肉行为进行了EMG数据的惩罚。

示例中,使用了osim.report可以自动生成所有状态和控制轨迹的PDF报告。这种自动化报告生成对于分析和展示模拟或优化结果非常有用,可以快速地将关键数据可视化并整合到一个易于分享的文档中。

import opensim as osim

def solveMocoInverse():

    # MocoInverse实例化
    inverse = osim.MocoInverse()
    #使用ModelProcessor加载.osim肌肉骨骼模型
    modelProcessor = osim.ModelProcessor('subject_walk_scaled.osim')
    #将地反力数据添加到模型中
    modelProcessor.append(osim.ModOpAddExternalLoads('grf_walk.xml'))
    #关闭模型中所有肌肉的肌腱顺应性
    modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
    #模型上肌肉使用DeGrooteFregly2016
    modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
    # 关闭模型中DeGrooteFregly2016Muscles的被动纤维力
    modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
    # 缩放模型中所有DeGrooteFregly2016Muscle的纤维力曲线宽度
    modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
    # 使用基于函数的表示肌肉路径,该设置可以加快收敛速度,
    # 要了解如何为模型创建一组基于函数的路径,请参阅示例“examplePolynomialPathFitter.py”。
    modelProcessor.append(osim.ModOpReplacePathsWithFunctionBasedPaths(
        "subject_walk_scaled_FunctionBasedPathSet.xml"))
    # 将备用执行器添加到模型中
    modelProcessor.append(osim.ModOpAddReserves(1.0))
    #将配置完成的模型选项给到MocoInverse实例中
    inverse.setModel(modelProcessor)
    # 构造一个坐标数据的TableProcessor,并将其传递给mocoinverse。
    # 可以通过向基础表添加 TableOperator 来以与 ModelProcessor 相同的方式使用 TableProcessor。
    # 如我们这里的 TableProcessor 没有任何操作符,则简单地返回基础表。
    #将运动学数据输入给mocoiverse
    inverse.setKinematics(osim.TableProcessor('coordinates.sto'))

    # 初始时间0.48s,终止时间1.61s,间隔为0.02s.
    inverse.set_initial_time(0.48)
    inverse.set_final_time(1.61)
    inverse.set_mesh_interval(0.02)

    # 默认情况下,运动学数据包含额外的列,Moco会报错。
    # # 在这里,我们告诉Moco允许(并忽略)这些额外的列。
    inverse.set_kinematics_allow_extra_columns(True)

    # 求解配置好的问题,并将结果进行保存
    solution = inverse.solve()
    # 将求解的结果进行保存
    solution.getMocoSolution().write('example3DWalking_MocoInverse_solution.sto')

    # 处理并获取模型
    model = modelProcessor.process()
    # 生成包含数据结果的PDF文件,包含模型和求解数据结果
    report = osim.report.Report(model,
                                'example3DWalking_MocoInverse_solution.sto',
                                bilateral=True)
    # 生成报告文件
    report.generate()

def solveMocoInverseWithEMG():

    # 初始化部分与上述相同
    inverse = osim.MocoInverse()
    #使用ModelProcessor加载.osim肌肉骨骼模型
    modelProcessor = osim.ModelProcessor('subject_walk_scaled.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.ModOpReplacePathsWithFunctionBasedPaths(
        "subject_walk_scaled_FunctionBasedPathSet.xml"))
    modelProcessor.append(osim.ModOpAddReserves(1.0))
    inverse.setModel(modelProcessor)
    #将运动学数据加载到mocoiverse
    inverse.setKinematics(osim.TableProcessor('coordinates.sto'))
    inverse.set_initial_time(0.48)
    inverse.set_final_time(1.61)
    inverse.set_mesh_interval(0.02)
    inverse.set_kinematics_allow_extra_columns(True)
    # inverse初始化
    study = inverse.initialize()
    # 构建problem,upd:update更新
    problem = study.updProblem()

    # 以肌电平方差添加到损失函数
    emgTracking = osim.MocoControlTrackingGoal('emg_tracking')
    #设置权重
    emgTracking.setWeight(50.0)
    # 加载归一化的肌电数据
    controlsRef = osim.TimeSeriesTable('electromyography.sto')
    # 根据峰值水平缩放三块肌肉的活动
    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))
    #将模型中的执行器与肌电图中的列相关联
    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)

    # 求解配置好的问题,并将结果进行保存
    solution = study.solve()
    solution.write('example3DWalking_MocoInverseWithEMG_solution.sto')

    # 将参考数据和求解的数据进行对比
    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')

    # 生成一份报告,对比有无EMG的MocoInverse结果
    model = modelProcessor.process()
    output = 'example3DWalking_MocoInverseWithEMG_report.pdf'
    ref_files = [
        'controls_reference.sto',
        'example3DWalking_MocoInverseWithEMG_solution.sto']
    report = osim.report.Report(model,
                                'example3DWalking_MocoInverse_solution.sto',
                                output=output, bilateral=True,
                                ref_files=ref_files,
                                colors=['black', 'blue', 'red'])
    # 生成报告文件
    report.generate()


# 求解基本问题,不使用EMG数据
solveMocoInverse()

# 求解基本问题,使用EMG数据
solveMocoInverseWithEMG()

相关推荐

  1. MocoInverse接口使用教程

    2024-07-14 07:54:04       33 阅读
  2. 很详细!接口使用教程(二)

    2024-07-14 07:54:04       24 阅读
  3. 【金融数据接口】wind数据python使用教程

    2024-07-14 07:54:04       19 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 07:54:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 07:54:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 07:54:04       58 阅读
  4. Python语言-面向对象

    2024-07-14 07:54:04       69 阅读

热门阅读

  1. python datetime库与时间戳timestamp的转换

    2024-07-14 07:54:04       22 阅读
  2. zookeeper在哪里能用到

    2024-07-14 07:54:04       20 阅读
  3. 开源科学工程技术软件

    2024-07-14 07:54:04       17 阅读
  4. 2060:【例1.1】计算机输出

    2024-07-14 07:54:04       25 阅读
  5. Debian ip6tables allow IPv6 traffic on TCP port 18917

    2024-07-14 07:54:04       26 阅读
  6. ubuntu 物理内存爆炸而不使用虚拟内存的问题

    2024-07-14 07:54:04       21 阅读
  7. Unity宏和编辑器

    2024-07-14 07:54:04       21 阅读