【MUJOCO官方文档中文翻译】概述篇

MUJOCO官方文档中文翻译概述篇目录


前言

部分物理学名词无法准确翻译
以在python使用mujoco仿真外骨骼和机器蛇为学习目标,概述篇之后会先跳过计算篇和c++编程篇

官方文档链接:https://mujoco.readthedocs.io/en/latest/overview.html


一、介绍

MuJoCo 是 Multi-Joint dynamics with Contact 的缩写。它是一个通用物理引擎,旨在促进机器人学、生物力学、图形和动画、机器学习以及其他需要快速、准确模拟铰接结构与环境交互的领域的研究和开发。该引擎最初由 Roboti LLC 开发,2021 年 10 月被 DeepMind 收购并免费提供,2022 年 5 月开源。MuJoCo 代码库位于 GitHub 上的 deepmind/mujoco 代码库中。

MuJoCo 是一个带有 C API 的 C/C++ 库,面向研究人员和开发人员。runtime 模拟模块经过调整,以最大限度地提高性能,并在低级数据结构上运行,这些数据结构由内置的 XML 解析器和编译器预先分配。用户可使用本地 MJCF 场景描述语言定义模型,该语言是一种 XML 文件格式,旨在尽可能方便用户阅读和编辑。也可以加载 URDF 模型文件。该库包括一个以 OpenGL 渲染的本地 GUI 交互式可视化。MuJoCo 还提供了大量用于计算物理相关量的实用功能。

MuJoCo 可用于实现基于模型的计算,如控制合成、状态估计、系统识别、机构设计、通过逆动力学进行数据分析,以及用于机器学习应用的并行采样。它还可用作更传统的模拟器,包括游戏和交互式虚拟环境。

1.关键特征

MuJoCo 拥有众多功能。在此,我们将概述其中最显著的特点。

广义坐标与现代接触动力学相结合

物理引擎传统上分为两类。机器人和生物力学引擎在广义坐标或关节坐标中使用高效、精确的递归算法。不过,它们要么不使用接触动力学,要么依赖于需要很小时间步长的早期弹簧阻尼方法。游戏引擎则采用更现代的方法,通过求解优化问题找到接触力。不过,它们通常采用过度约束的笛卡尔表示法,在这种表示法中,关节约束条件是以数值方式施加的,当涉及复杂的运动结构时,会造成不准确和不稳定。MuJoCo 是第一个将广义坐标仿真和基于优化的接触动力学结合起来的通用引擎。最近,其他模拟器也采用了 MuJoCo 的方法,但通常无法兼容其所有功能,因为这些模拟器并非从一开始就设计成这样。习惯于游戏引擎的用户一开始可能会发现广义坐标与直觉相悖;请参阅下文的 "说明 "部分。

软、凸和解析可逆接触动力学

在现代接触动力学方法中,摩擦接触所产生的力或脉冲通常被定义为线性或非线性互补问题(LCP 或 NCP)的解,而这两种问题都是 NP 难题。MuJoCo 基于对接触物理学的不同表述,可简化为一个凸优化问题,详见 "计算 "一章。我们的模型允许软接触和其他约束条件,并具有唯一定义的逆,便于数据分析和控制应用。有多种优化算法可供选择,包括可处理椭圆摩擦锥的投影Gauss-Seidel法的广义算法。求解器统一处理摩擦接触,包括扭转和滚动摩擦、无摩擦接触、关节和肌腱限制、关节和肌腱中的干摩擦,以及各种相等约束。

肌腱的几何形状

MuJoCo 可以为肌腱的三维几何建模,肌腱是最小路径长度的字符串,服从缠绕和通点约束。该机制与 OpenSim 中的机制类似,但实施了一套更受限制的封闭式缠绕选项,以加快计算速度。它还提供机器人专用结构,如滑轮和耦合自由度。肌腱可用于驱动,也可用于对肌腱长度施加不等式或等式约束。

通用执行模型

在使用与模型无关的应用程序接口(API)的同时,设计一个足够丰富的执行模型是一项挑战。MuJoCo 通过采用一个抽象的可驱动模型来实现这一目标,该模型可以有不同类型的传动、力的产生和内部动力学(即使整体动力学达到三阶的状态变量)。这些组件可以实例化,从而以统一的方式模拟电机、气动和液压缸、PD 控制器、生物肌肉和许多其他驱动器。

可重新配置的计算管道

MuJoCo 有一个顶级步进函数 mj_step,用于运行整个前向动力学并推进仿真状态。不过,在许多仿真以外的应用中,能够运行计算流水线的选定部分也是有益的。为此,MuJoCo 提供了大量可任意组合设置的标志,允许用户根据需要重新配置管道,而不仅仅是通过选项选择算法和算法参数。此外,许多底层函数可以直接调用。用户定义的回调可以实现自定义力场、驱动器、碰撞例程和反馈控制器。

模型编译

如上所述,用户以一种名为 MJCF 的 XML 文件格式定义一个 MuJoCo 模型。然后,该模型会被内置编译器编译成底层数据结构 mjModel,该结构经过交叉索引和优化,可用于runtime计算。编译后的模型也可以保存为二进制 MJB 文件。

模型与数据分离

MuJoCo 在运行时将仿真参数分离成两个数据结构(C 结构):

mjModel 包含预计将保持不变的模型描述。其中嵌入的其他结构包含仿真和可视化选项,这些选项需要偶尔更改,但更改由用户完成。

mjData 包含所有动态变量和中间结果。所有函数都在这里读取输入并写入输出,这些输出将成为仿真流水线后续阶段的输入。它还包含一个预分配和内部管理的堆栈,因此 runtime 模块无需在模型初始化后调用内存分配函数。

mjModel 由编译器构建,而 mjData 则在运行时根据 mjModel 构建。这种分离使模拟多个模型以及每个模型的多个状态和控制变得容易,反过来又促进了采样和有限差分的多线程运行。顶层应用程序接口函数反映了这种基本分离,其格式为:

void mj_step(const mjModel* m, mjData* d);

交互式模拟和可视化

本地三维可视化器提供网格和几何基元、纹理、反射、阴影、雾、透明度、线框、天空盒、立体可视化(在支持四缓冲 OpenGL 的显卡上)的渲染。该功能用于生成三维渲染,帮助用户深入了解物理仿真,包括自动生成的模型骨架、等效惯性盒、接触位置和法线、可分为法线和切向分量的接触力、外部扰动力、局部框架、关节和致动器轴以及文本标签等可视化辅助工具。可视化器要求使用带有 OpenGL 渲染上下文的通用窗口,从而允许用户采用自己选择的图形用户界面库。随 MuJoCo 一起发布的 simulate.cc 代码示例展示了如何使用 GLFW 库实现这一功能。一个相关的可用性功能是可以 "进入 "模拟,推动物体并查看物理响应。用户选择要施加外力和扭矩的物体,就能看到扰动及其动态结果的实时渲染。这可用于对模型进行可视化调试,测试反馈控制器的响应,或将模型配置为所需的姿势。

强大而直观的建模语言

MuJoCo 拥有自己的建模语言 MJCF。MJCF 的目标是提供对 MuJoCo 所有计算功能的访问,同时使用户能够快速开发新模型并进行实验。这一目标的实现在很大程度上要归功于广泛的默认设置机制,该机制类似于 HTML 中内嵌的层叠样式表(CSS)。虽然 MJCF 有许多元素和属性,但在任何给定模型中,用户需要设置的元素和属性却少得惊人。这使得 MJCF 文件比许多其他格式更简短、更易读。

自动生成复合柔性对象

MuJoCo 的软约束可用于为绳索、布料和可变形三维物体建模。这需要大量的规则体、关节、筋腱和约束一起工作。建模语言具有高级宏,可由模型编译器自动扩展为必要的标准模型元素集合。重要的是,这些灵活的对象能够与模拟的其他部分完全交互。

2.模型实例

MuJoCo 中有几个实体称为 “模型”。用户在以 MJCF 或 URDF 编写的 XML 文件中定义模型。然后,软件可以在不同介质(文件或内存)和不同描述级别(高或低)上创建同一模型的多个实例。如下表所示,所有组合都是可能的:
在这里插入图片描述
所有 runtime 计算都通过 mjModel 进行,而 mjModel 太复杂,无法手动创建。这就是为什么我们有两个层次的模型。高层次建模是为了方便用户:其唯一目的是编译成低层次模型,并在此基础上进行计算。生成的 mjModel 可以加载并保存为二进制文件 (MJB),但这些文件是特定版本的,无法反编译,因此模型应始终保持为 XML 文件。

内部C++ 类 mjCModel 与 MJCF 文件格式大致一一对应。XML 解析器可解释 MJCF 或 URDF 文件并创建相应的 mjCModel。原则上,用户可以通过编程创建 mjCModel,然后将其保存到 MJCF 或进行编译。然而,由于 C++ API 无法从独立于编译器的库中导出,因此该功能尚未公开。我们计划围绕它开发一个 C 语言包装器,但目前解析器和编译器总是一起调用,而且模型只能以 XML 创建。

下图显示了获取 mjModel 的不同路径(同样,第二点还不可用):

(文本编辑器)→MJCF/URDF 文件→(MuJoCo 解析器→mjCModel→MuJoCo 编译器)→mjModel

(用户代码)→ mjCModel→(MuJoCo 编译器)→ mjModel

MJB 文件→(MuJoCo 加载器)→ mjModel

3.例子

下面是一个用 MuJoCo 的 MJCF 格式制作的简单模型。它定义了一个固定于世界的平面、一束用于更好地照亮物体和投射阴影的光线,以及一个具有 6 个 DOF 的浮动框(这就是 "free "关节的作用)。

<mujoco>
  <worldbody>
    <light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
    <geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
    <body pos="0 0 1">
      <joint type="free"/>
      <geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
    </body>
  </worldbody>
</mujoco>

内置的 OpenGL 可视化器将该模型渲染为
在这里插入图片描述如果对该模型进行模拟,箱子会掉在地上。下面给出了不进行渲染的被动动力学基本模拟代码。

#include "mujoco.h"
#include "stdio.h"

char error[1000];
mjModel* m;
mjData* d;

int main(void)
{
   // load model from file and check for errors
   m = mj_loadXML("hello.xml", NULL, error, 1000);
   if( !m )
   {
      printf("%s\n", error);
      return 1;
   }

   // make data corresponding to model
   d = mj_makeData(m);

   // run simulation for 10 seconds
   while( d->time<10 )
      mj_step(m, d);

   // free model and data
   mj_deleteData(d);
   mj_deleteModel(m);

   return 0;
}

从技术上讲,这是一个 C 文件,但它也是一个合法的 C++ 文件。事实上,MuJoCo 应用程序接口与 C 和 C++ 都兼容。通常情况下,用户代码会用 C++ 编写,因为这样既方便,又不会牺牲效率,因为计算瓶颈在模拟器中,而模拟器已经进行了高度优化。

函数 mj_step 是顶层函数,它将模拟状态推进一个时间步。当然,这个例子只是一个被动的动力系统。当用户指定控制或施加力并开始与系统交互时,情况就会变得更加有趣。

接下来,我们将提供一个更详细的示例来说明 MJCF 的若干功能。请看下面的示例:

<mujoco model="example">
  <default>
    <geom rgba=".8 .6 .4 1"/>
  </default>

  <asset>
    <texture type="skybox" builtin="gradient" rgb1="1 1 1" rgb2=".6 .8 1" width="256" height="256"/>
  </asset>

  <worldbody>
    <light pos="0 1 1" dir="0 -1 -1" diffuse="1 1 1"/>
    <body pos="0 0 1">
      <joint type="ball"/>
      <geom type="capsule" size="0.06" fromto="0 0 0  0 0 -.4"/>
      <body pos="0 0 -0.4">
        <joint axis="0 1 0"/>
        <joint axis="1 0 0"/>
        <geom type="capsule" size="0.04" fromto="0 0 0  .3 0 0"/>
        <body pos=".3 0 0">
          <joint axis="0 1 0"/>
          <joint axis="0 0 1"/>
          <geom pos=".1 0 0" size="0.1 0.08 0.02" type="ellipsoid"/>
          <site name="end1" pos="0.2 0 0" size="0.01"/>
        </body>
      </body>
    </body>

    <body pos="0.3 0 0.1">
      <joint type="free"/>
      <geom size="0.07 0.1" type="cylinder"/>
      <site name="end2" pos="0 0 0.1" size="0.01"/>
    </body>
  </worldbody>

  <tendon>
    <spatial limited="true" range="0 0.6" width="0.005">
      <site site="end1"/>
      <site site="end2"/>
    </spatial>
  </tendon>
</mujoco>

在这里插入图片描述

该模型是一个 7 自由度的手臂,"握 "着一根绳子,绳子的另一端连接着一个圆柱体。绳子的长度是有限制的。肩部有球形关节,肘部和腕部有一对铰链关节。圆柱体内的方框表示自由 “关节”。XML 中的外部body元素是所需的世界体。请注意,在两个body之间使用多关节并不需要创建虚拟体。

MJCF 文件包含指定模型所需的最少信息。腔体由空间中的线段定义–在这种情况下只需要腔体的半径。body框架的位置和方向由所属的几何体推断。惯性特性是根据均匀密度假设下的几何体形状推断出来的。命名这两点是因为肌腱定义需要参考它们,但没有命名其他任何东西。仅为铰链关节定义了关节轴,但没有为球关节定义关节轴。碰撞规则是自动定义的。摩擦属性、重力、模拟时间步长等均设置为默认值。顶部指定的默认几何体颜色适用于所有几何体。

除了以二进制 MJB 格式保存编译后的模型外,我们还可以将其保存为 MJCF 格式或人类可读文本格式;分别参见 example_saved.xml 和 example_saved.txt。XML 版本与原始版本类似,而文本版本则包含 mjModel 的所有信息。比较文本版本和 XML 版本可以看出模型编译器为我们做了多少工作。

二、模型要素

本节简要介绍了可以包含在 MuJoCo 模型中的所有元素。稍后,我们将更详细地解释底层计算、MJCF 中指定元素的方式以及它们在 mjModel 中的表示。

1.选项(Options)

每个模型都有以下三套选件。它们总是包含在内。如果 XML 文件中没有指定它们的值,则使用默认值。用户可以在每个模拟时间步之前更改这些选项的值。但在一个时间步长内,所有选项均不得更改。

mjOption

此结构包含影响物理模拟的所有选项。它用于选择算法并设置其参数,启用或禁用模拟管道的不同部分,以及调整重力等系统级物理属性。

mjVisual

此结构包含所有可视化选项。还有其他 OpenGL 渲染选项,但这些选项取决于会话,不属于模型的一部分。

mjStatistic

此结构包含由编译器计算的有关模型的统计数据:平均body质量、模型的空间范围等。包含该结构的目的是为了提供信息,同时也因为可视化程序使用它来进行自动缩放。

2.资产(Assets)

资产本身并不是模型元素。模型元素可以引用它们,在这种情况下,资产会以某种方式改变引用元素的属性。一个资产可以被多个模型元素引用。由于包含资产的唯一目的是对其进行引用,而引用只能通过名称来完成,因此每个资产都有一个名称(使用时可从文件名中推断)。相反,常规元素的名称可以不定义。

网格(Mesh)
MuJoCo 可以从 OBJ 文件和二进制 STL 中加载三角网格。MeshLab 等软件可用于转换其他格式。任何三角形集合都可以作为网格加载和可视化,碰撞检测器则使用凸壳。编译时有缩放网格和拟合原始几何形状的选项。网格还可用于自动推断惯性属性–将其视为三角形金字塔的结合体,并结合其质量和惯性。需要注意的是,网格没有颜色,而是使用参照几何体的材料属性对网格进行着色。相反,所有空间属性都由网格数据决定。MuJoCo 支持 OBJ 和自定义二进制文件格式的法线和纹理坐标。网格也可以直接嵌入到 XML 中。

蒙皮(Skin)
蒙皮网格(或称蒙皮)是指其形状可在运行时变形的网格。它们的顶点与刚体(此处称为骨骼)相连,每个顶点可以属于多个骨骼,从而使蒙皮产生平滑变形。皮肤是纯粹的可视化对象,不会影响物理特性,但可以显著增强视觉真实感。皮肤可以从自定义二进制文件中加载,也可以直接嵌入 XML 中,与网格类似。在自动生成复合柔性对象时,模型编译器也会为这些对象生成皮肤。

高度字段(Field)
高度字段可从 PNG 文件(内部转换为灰度)或稍后描述的自定义二进制格式文件中加载。高度字段是海拔数据的矩形网格。编译器会将数据归一化为 [0-1] 范围。然后,高度域的实际空间范围由引用 geom 的尺寸参数决定。高度字段只能从连接到世界体的 geom 引用。出于渲染和碰撞检测的目的,网格矩形会自动进行三角化处理,因此高度场会被视为三角棱镜的结合体。与这种复合物体的碰撞检测原则上可以为单个几何体对生成大量接触点。如果出现这种情况,则只保留前 64 个接触点。这样做的理由是,高度场应用于地形图建模,与模拟中的其他对象相比,高度场的空间特征较大,因此对于设计良好的模型来说,接触点的数量较少。

纹理(Texture)
纹理可以从 PNG 文件加载,也可以由编译器根据用户定义的程序参数合成。还可以在创建模型时将纹理留空,然后在 runtime 时进行更改,以便在 MuJoCo 仿真中渲染视频或创建其他动态效果。可视化器支持两种纹理映射类型:2D 和立方体。2D 贴图适用于平面和高度场。立方体贴图适用于将纹理 "收缩 "到三维物体周围,而无需指定纹理坐标。它还可用于创建天空盒。立方体贴图的六个面可以从单独的图像文件中加载,也可以从一个合成图像文件中加载,或者通过重复相同的图像生成。与直接从模型元素中引用的所有其他资产不同,纹理只能从另一个资产(即材质)中引用,然后再从模型元素中引用。

材料(Material)
材料用于控制 geoms, sites 和 tendons的外观。这是通过引用相应模型元素中的材质来实现的。外观包括纹理映射以及与以下 OpenGL 灯光交互的其他属性: RGBA、镜面反射、光泽度和发射。材质还可用于使物体反射。目前,反射只在平面和方框的 Z+ 面上渲染。请注意,模型元素也可以使用本地 RGBA 参数设置颜色。如果同时指定了材质和本地 RGBA,则本地定义优先。

3.运动学树(Kinematic tree)

MuJoCo 通常模拟受到约束的刚体集合的动力学运动。系统状态以关节坐标表示,bodies被明确组织成运动学树。除顶层的 "世界 "体外,每个体都有一个唯一的父体。不允许运动学循环;如果需要循环关节,则应使用相等约束对其进行建模。因此,MuJoCo 模型的主干是一棵或几棵由嵌套体定义形成的运动树;一个孤立的浮动体也算一棵树。下面列出的其他几个元素都是在体中定义的,并属于该体。这与后面列出的独立元素形成鲜明对比,后者不能与单个体关联。

Body
物体具有质量和惯性属性,但不具有任何几何属性。几何图形(或几何体)被附加到物体上。每个物体都有两个坐标系:一个是用于定义物体以及定位相对于物体的其他元素的坐标系,另一个是以物体质量中心为中心并与其惯性主轴对齐的惯性系。因此,物体惯性矩阵在该框架中是对角线。在每个时间步中,MuJoCo 都会递归计算前向运动学,以全局笛卡尔坐标得出所有物体位置和方向。这为所有后续计算提供了基础。

Joint
关节是在体内部定义的。它们在主体与其父体之间创建运动自由度 (DOFs)。在没有关节的情况下,主体与其父体是焊接在一起的。这与使用过度完整笛卡尔坐标的游戏引擎正好相反,在游戏引擎中,关节会移除而不是增加自由度。有四种类型的关节:球形关节、滑动关节、铰链关节和 “自由关节”,"自由关节 "可创建浮动体。一个体可以有多个关节。这样就可以自动创建复合关节,而无需定义假体。球关节和自由关节的方向分量用单位四元数表示,MuJoCo 中的所有计算都遵循四元数的属性。

Joint reference
参考点是存储在 mjModel.qpos0 中的关节位置向量。它与模型处于初始配置时的关节数值相对应。在我们前面的例子中,肘部是以 90° 角弯曲配置创建的。但 MuJoCo 并不知道什么是肘部,因此默认情况下会将此关节配置视为数值为 0。我们可以覆盖默认行为,使用关节的 ref 属性指定初始配置对应于 90°。所有关节的参考值都会汇总到向量 mjModel.qpos0 中。每次重置模拟时,关节配置 mjData.qpos 都会设置为 mjModel.qpos0。运行时,关节位置矢量相对于参考点进行解释。具体来说,关节应用的空间变换量为 mjData.qpos - mjModel.qpos0。这种变换是对存储在 mjModel 主体元素中的父子平移和旋转偏移的补充。ref 属性只适用于标量关节(滑动和铰链)。对于球形关节,mjModel.qpos0 中保存的四元数始终为 (1,0,0,0),对应于空旋转。对于自由关节,浮动体的全局 3D 位置和四元数都保存在 mjModel.qpos0 中。

Spring reference
这是所有关节和肌腱弹簧达到静止长度的姿势。当关节配置偏离弹簧参考姿势时会产生弹簧力,弹簧力与偏离量呈线性关系。弹簧参考姿势保存在 mjModel.qpos_spring 中。对于滑动和铰链关节,弹簧参考由属性 springref 指定。对于球关节和自由关节,弹簧参考与初始模型配置相对应。

DOF
自由度与关节密切相关,但并非一一对应,因为球关节和自由关节具有多个 DOF。将关节视为指定位置信息,将自由度视为指定速度和力信息。更正式地说,关节位置是系统配置流形上的坐标,而关节速度则是当前位置处该流形切线空间上的坐标。DOF 具有与速度相关的特性,如摩擦损失、阻尼、电枢惯性。作用在系统上的所有广义力都用 DOF 空间表示。相反,关节具有与位置相关的特性,如极限和弹簧刚度。DOF 并非由用户直接指定。相反,它们是由给定关节的编译器创建的。

Geom
Geoms 是刚性连接到物体的三维形状。同一个物体可以连接多个 Geom。鉴于 MuJoCo 只支持凸形几何体之间的碰撞,而创建非凸形物体的唯一方法是将它们表示为凸形几何体的结合体,因此这一点特别有用。除了碰撞检测和随后的接触力计算外,几何体还用于渲染,以及在省略体质量和惯性时自动推断体质量和惯性。MuJoCo 支持几种原始几何形状:平面、球面、腔体、椭圆体、圆柱体、盒体。一个几何体也可以是一个网格或一个高度场;这可以通过引用相应的资产来实现。几何体具有许多影响模拟和可视化的材料属性。

Site
点本质上是轻型几何体。它们代表了物体框架内感兴趣的位置。点不参与碰撞检测或惯性属性的自动计算,但可用于指定传感器、肌腱路径和滑块-曲柄端点等其他物体的空间属性。

Camera
一个模型中可以定义多个摄像机。在交互式可视化界面中,总是有一个默认的摄像机,用户可以用鼠标自由移动。不过,定义额外的摄像机也很方便,这些摄像机可以固定在世界中,也可以附着在某个物体上并随其移动。除了摄像机的位置和方向外,用户还可以调整垂直视场和瞳孔间距以进行立体渲染,以及创建立体虚拟环境所需的斜投影。在使用不完善的光学系统对真实摄像机进行建模时,可以为水平和垂直方向指定不同的焦距,并指定一个非居中的主点。

Light
灯光可以固定在世界体上,也可以连接到运动体上。可视化器可以访问 OpenGL(固定函数)中的全部照明模型,包括环境、漫反射和镜面反射组件、衰减和截止、位置和方向照明以及雾。灯光,或者说被灯光照亮的物体,也可以投射阴影。不过,与材质反射类似,每个投射阴影的灯光都会增加一次渲染,因此应谨慎使用这一功能。详细记录照明模型超出了本章的范围;请参阅 OpenGL 文档。请注意,除了用户在运动树中定义的灯光外,还有一个默认的头灯会随着摄像机移动。其属性可通过 mjVisual 选项进行调整。

4.独立式(Stand-alone)

在这里,我们描述的是不属于单个机构的模型元素,因此是在运动学树之外描述的。

Tendon
肌腱是标量长度元素,可用于驱动、施加限制和平等约束,或产生弹簧阻尼和摩擦损耗。肌腱有两种类型:固定肌腱和空间肌腱。固定肌腱是(标量)关节位置的线性组合。它们可用于模拟机械耦合。空间肌腱的定义是通过一系列指定点(或通路点)或环绕指定几何体的最短路径。仅支持球体和圆柱体作为包裹几何体,圆柱体在包裹时被视为无限长。为避免肌腱从包裹几何体的一侧突然跳到另一侧,用户还可以指定首选的一侧。如果肌腱路径中有多个包裹几何体,它们必须被点分开,以避免需要使用迭代求解器。空间肌腱也可以使用滑轮分割成多个分支。

Actuator
MuJoCo 提供了一个灵活的致动器模型,其中有三个可独立指定的组件。它们共同决定了致动器的工作方式。通过以协调的方式指定这些组件,可获得常见的致动器类型。这三个组件分别是传动、激活动力学和力的产生。传动装置规定了执行器与系统其他部分的连接方式;可供选择的类型包括关节、腱和滑块-曲柄。激活动力学可用于模拟气动或液压缸以及生物肌肉的内部激活状态;使用此类致动器可使整个系统的动力学达到三阶。力的产生机制决定了作为致动器输入的标量控制信号如何被映射为标量力,而标量力又如何被从传动装置中推断出的力矩臂映射为广义力。

Sensor
MuJoCo 可以生成模拟传感器数据,并将其保存在全局数组 mjData.sensordata 中。该结果不会用于任何内部计算,而是提供给用户用于自定义计算或数据分析。可用的传感器类型包括触摸传感器、惯性测量单元(IMU)、力矩传感器、关节和肌腱位置及速度传感器、致动器位置、速度和力传感器、运动捕捉标记位置和四元数以及磁力计。其中有些需要额外的计算,有些则是从 mjData 的相应字段复制而来。还有一个用户传感器,允许用户代码在传感器数据数组中插入任何其他感兴趣的量。MuJoCo 还具有离屏渲染功能,可以直接模拟彩色和深度摄像头传感器。这并不包括在标准传感器模型中,而是必须通过编程完成,如 simulate.cc 示例代码所示。

Equality
等效约束可以在运动学树结构和其中定义的关节/DOFs 已施加的约束之外再施加额外的约束。它们可用于创建环形关节或一般的机械耦合模型。执行这些约束的内力与所有其他约束力一起计算。可用的等效约束类型包括:在一个点上连接两个物体(在运动树外创建一个球形关节);将两个物体焊接在一起;固定一个关节或肌腱的位置;通过三次多项式耦合两个关节或两条肌腱的位置;将挠性体(即可变形网格)的边缘约束为初始长度。

Flex
Flexes 是在 MuJoCo 3.0 中添加的。它们表示可变形的网格,可以是一维、二维或三维网格(因此其元素可以是腔体、三角形或四面体)。与固定连接在单个物体上的静态形状的几何体不同,柔性网格的元素是可变形的:它们是通过连接多个物体构建而成,因此物体的位置和方向决定了运行时柔性网格元素的形状。这些可变形元素支持碰撞和接触力,还能产生被动力和约束力,从而保持可变形实体的形状。该系统提供了自动化功能,可从文件中加载网格,构建与网格顶点相对应的体,构建与网格面(或线或四面体,取决于维度)相对应的柔性元素,并获得相应的可变形网格。

Contact pair
MuJoCo 中的接触生成是一个复杂的过程。检查是否有接触对有两个来源:自动邻近性测试和其他统称为 "动态 "的过滤器,以及模型中提供的明确几何对列表。后者是一种单独的模型元素。由于接触涉及两个几何要素的组合,明确的规范允许用户以动态机制无法实现的方式定义接触参数。这对于微调接触模型也很有用,特别是添加被主动过滤方案删除的接触对。现在,接触机制已扩展到柔性元素,可以在两个以上的物体之间创建接触互动。不过,这种碰撞是自动发生的,无法使用接触对进行微调。

Contact exclude
这与 "接触对 "相反:它指定了应从候选接触对中排除的体对(而不是几何体)。它适用于禁用几何体之间的接触,因为这些几何体会导致不理想的永久接触。请注意,MuJoCo 有其他机制来处理这种情况(特别是如果几何体属于同一个体或属于父体和子体,它们就不能发生碰撞),但有时这些自动机制并不足够,明确的排除就变得很有必要。

Custom numeric
在 MuJoCo 模拟中输入自定义数字有三种方法。首先,可以在 XML 中定义全局数字字段。它们有一个名称和一个实数值数组。其次,可以通过特定元素的自定义数组来扩展某些模型元素的定义。这可以通过在 XML 元素大小中设置属性 nuser_XXX 来实现。第三,数组 mjData.userdata 不用于任何 MuJoCo 计算。用户可以在这里存储自定义计算的结果;请记住,所有随时间变化的内容都应存储在 mjData 中,而不是 mjModel 中。

Custom text
自定义文本字段可以保存在模型中。它们可用于自定义计算–指定关键字命令或提供其他文本信息。但不要将它们用于注释;在编译后的模型中保存注释没有任何好处。XML 有自己的注释机制(被 MuJoCo 的解析器和编译器忽略),这更合适。

Custom tuple
自定义元组是 MuJoCo 模型元素的列表,可能包括其他元组。模拟器不会使用它们,但可用于指定用户代码所需的元素组。例如,可以使用图元来定义用于自定义接触处理的体对。

Keyframe
关键帧是模拟状态变量的快照。它包含关节位置矢量、关节速度矢量、执行器激活(如有)矢量和模拟时间矢量。模型可以包含一个关键帧库。这些关键帧可用于将系统状态重置为某个感兴趣的点。需要注意的是,关键帧并非用于在模型中存储轨迹数据,而应使用外部文件。

三、说明

读者很可能具有使用其他物理模拟器和相关惯例的经验,以及与 MuJoCo 不一致的一般编程实践。这有可能造成混淆。本节的目的是预先澄清最有可能引起混淆的方面;它介于常见问题解答和选定主题教程之间。我们需要参考后面文档中涉及的材料,但下面的文字尽可能是自成一体的介绍性文字。

1.分歧

当状态元素迅速趋于无穷大时,模拟就会出现发散。在 MuJoCo 中,这通常表现为 mjWARN_BADQACC 警告。发散是所有物理仿真的通病,并不一定说明模型有问题或仿真器有错误,而是暗示对于给定的积分器选择来说,时间步长过大。在物理仿真中,速度(大时间步长)和稳定性(小时间步长)之间总是存在矛盾。一个对速度进行了良好调整的模型,其最大可能的时间步长是不发散的,这通常意味着它可以在极端条件下发散。从这个意义上说,罕见的发散情况实际上可以说明模型调试良好。在任何情况下,都可以通过减少时间步长和/或改用更稳定的积分器来防止发散。如果这种方法失败,罪魁祸首就不同了。例如,在物体初始化为穿透的模型中,巨大的排斥力可能会将它们推开并导致发散。

2.单位不详

MuJoCo 不指定基本物理单位。用户可以根据自己的选择来解释单位系统,只要前后一致即可。为了理解这一点,请看一个例子:重量为 1 千克、使用 1 牛顿推进器的 1 米宇宙飞船,与重量为 1 克、使用 1 达因推进器的 1 厘米宇宙飞船的动力学原理是一样的。这是因为 MKS 和 CGS 都是一致的单位系统。这一特性允许用户随意缩放模型,这在模拟非常小或非常大的物体时非常有用,可以改善模拟的数值特性。

尽管如此,我们还是鼓励用户使用 MKS,因为 MuJoCo 在两个地方使用了类似 MKS 的默认值:

重力的默认值是(0, 0, -9.81),相当于 MKS 中的地球表面重力。请注意,这并没有真正指定 MKS 单位系统,因为我们可能会在Enceladus使用 CGS。

几何密度(用于推断物体质量和惯性)的默认值是 1000,相当于 MKS 中水的密度。

一旦选择了一致的基本单位(长度、质量、时间)系统,所有衍生单位都将与这一系统相对应,就像在维度分析中一样。例如,如果我们的模型被解释为 MKS,那么力和扭矩就分别以牛顿和牛顿-米为单位。

角度: 虽然在 MJCF 中可以用度来指定角度(事实上度也是默认值),但 mjModel 和 mjData 中的所有角度量都是用弧度表示的。因此,举例来说,如果我们使用 MKS,陀螺仪报告的角速度将以弧度/秒为单位,而铰链接头的刚度将以牛米/弧度为单位。

3.出人意料的碰撞

默认情况下,MuJoCo 会排除属于有直接父子关系的主体对的 geoms 之间的碰撞。例如,请看上面 "示例 "部分中的手臂模型:即使腔体 geoms 相互穿透,在 "肘部 "也不会发生碰撞,因为前臂是上臂的直接子体。

但是,如果父体是一个静态体,即世界体,或者是一个相对于世界体没有任何自由度的体,那么这种排除就不适用。碰撞检测部分记录的这一行为可以防止物体从地板上坠落或穿过墙壁。然而,这种行为往往会导致以下情况:

用户注释掉浮动基体模型的根关节,也许是为了防止它坠落;现在基体被视为静态,出现了之前没有的新碰撞,用户感到困惑。有两种简单的方法可以避免这个问题:

不要移除根关节。也许只需禁用重力,并在可能的情况下添加一些流体粘度,就能防止模型过度移动。

通过设置相关的 contype 和 conaffinity 属性,或使用接触排除指令,使用碰撞过滤明确禁用不需要的碰撞。

4.非面向对象

面向对象编程是一个非常有用的抽象概念,它建立在数据结构与对数据结构进行操作的函数这一更基本(也更接近硬件)的概念之上。对象是数据结构和函数的集合,这些数据结构和函数与一个语义实体相对应,因此它们之间的依赖性比与应用程序其他部分的依赖性更强。我们之所以不在这里使用对象,是因为我们的依赖结构是这样的:自然实体是整个物理模拟器。与对象不同,我们有少量数据结构和大量对其进行操作的函数。

我们仍然使用一种分组方式,但与面向对象的方法不同。我们将模型(mjModel)与数据(mjData)分开。它们都是数据结构。模型包含描述被建模物理系统恒定属性所需的一切,而数据则包含时变状态和内部计算的可重用中间结果。所有顶级函数的参数都是指向 mjModel 和 mjData 的指针。通过这种方式,我们避免了全局变量对工作区的污染和对多线程的干扰,但我们这样做的方式与面向对象编程实现相同效果的方式不同。

5.柔软性和防滑性

正如我们将在 "计算 "一章中详细解释的那样,MuJoCo 基于接触物理学和其他约束条件的数学模型。该模型本质上是软模型,即对约束条件施加更大的推力总会导致更大的加速度,因此可以唯一定义逆动力学。这是可取的,因为它能产生一个凸优化问题,并能进行依赖于逆动力学的分析,此外,我们在实践中需要模拟的大多数接触都具有一定的软性。然而,一旦我们允许软约束,我们实际上就创造了一种新的动力学类型,即变形动力学,现在我们必须明确这些动力学的行为方式。这就需要对接触和其他约束条件进行详细的参数化,其中涉及可根据约束条件设置的属性 solref 和 solimp,稍后将对其进行描述。

这种软模型经常令人困惑的一点是,无法避免逐渐的接触滑移。同样,摩擦接头也会在重力作用下逐渐屈服。这并不是因为求解器无法防止滑移(达到摩擦锥或摩擦损失极限),而是因为它一开始就没有试图防止滑移。回想一下,在给定约束条件下,较大的力必然导致较大的加速度。如果要完全抑制滑移,就必须违反这一关键特性。因此,如果你在模拟中看到逐渐滑移,直观的解释可能是摩擦力不足,但在 MuJoCo 中很少出现这种情况。相反,需要调整 solref 和 solimp 参数向量,以减少这种影响。增加约束阻抗(solimp 的前两个元素)以及全局 mjModel.opt.impratio 设置尤其有效。这种调整通常需要更小的时间步长来保持仿真稳定,因为它们会使非线性动力学更难进行数值积分。牛顿求解器也可以减少滑动,因为牛顿求解器一般更为精确。

在需要完全抑制滑动的情况下,可在主求解器之后运行第二个无滑动求解器。它通过忽略约束软度来更新摩擦维度的接触力。然而,当使用该选项时,MuJoCo 不再求解其设计用于求解的凸优化问题,模拟的鲁棒性可能会降低。因此,建议使用牛顿求解器、椭圆摩擦锥和较大的摩擦系数值来减少滑移。

6.类型、名称、ID

如前所述,MuJoCo 支持大量模型元素。每种元素类型在 mjModel 中都有相应的部分列出其各种属性。例如,关节极限数据在数组

mjtNum* jnt_range;             // joint limits       (njnt x 2)

mjModel 中还给出了每个数组(本例中为 njnt)的大小。第一个关节点的极限首先包括在内,然后是第二个关节点的极限等。这种排序反映了 MuJoCo 中的所有矩阵都是行主格式。

可用的元素类型在 mjmodel.h 的枚举类型 mjtObj 中定义。这些枚举大多在内部使用。一个例外是 MuJoCo API 中的函数 mj_name2id 和 mj_id2name,它们将元素名称映射为整数 id,反之亦然。这些函数将元素类型作为输入。

在 XML 中命名模型元素是可选的。同一类型的两个元素(如两个关节)不能有相同的名称。只有在模型中其他地方需要引用给定元素时,才需要命名;XML 中的引用只能通过名称来完成。模型编译完成后,为方便用户使用,名称仍会存储在 mjModel 中,但不会对模拟产生进一步影响。名称对于查找相应的整数 id 以及渲染都很有用:例如,如果启用关节标签,每个关节旁边都会显示一个字符串(名称未定义的元素会被标记为 “关节 N”,其中 N 是 id)。

元素的整数 id 对 MuJoCo 数据数组的索引至关重要。按照 C 语言的习惯,id 以 0 为基础。要打印名为 "肘 "的关节的范围,请执行以下操作

int jntid = mj_name2id(m, mjOBJ_JOINT, "elbow");
if( jntid>=0 )
   printf("(%f, %f)\n", m->jnt_range[2*jntid], m->jnt_range[2*jntid+1]);

如果未找到名称,函数将返回-1,这就是为什么要始终检查 id>=0 的原因。

7.物体、几何、点

物体、几何体和点是 MuJoCo 的元素,它们大致对应于物理世界中的刚体。那么为什么要把它们分开呢?这里将解释语义和计算方面的原因。

首先是相似性。物体、几何体和点都有与之相连的空间框架(尽管物体也有第二个框架,它以物体的质量中心为中心,并与惯性主轴对齐)。这些框架的位置和方向是在每个时间步长通过前向运动学从 mjData.qpos 计算得出的。正向运动学的结果在 mjData 中以 xpos、xquat 和 xmat 的形式表示体,以 geom_xpos 和 geom_xmat 的形式表示几何体,以 site_xpos 和 site_xmat 的形式表示点。

现在是不同之处。体用于构建运动树,是其他元素(包括几何体和点)的容器。体具有空间框架和惯性属性,但没有与外观或碰撞几何相关的属性。这是因为这些属性并不影响物理特性(当然接触除外,但这些属性会单独处理)。如果你在机器人学教科书中看到过运动树的图解,那么这些物体通常被画成无定形的形状–以表明它们的实际形状与物理无关。

几何体(geom,geometric primitive 的缩写)用于指定外观和碰撞几何形状。每个几何体都属于一个物体,并与该物体刚性连接。同一个物体可以连接多个几何体。考虑到 MuJoCo 的碰撞检测器假定所有几何体都是凸面(如果网格不是凸面,它会在内部用其凸面体替换网格),这一点尤其有用。因此,如果要对一个非凸形状进行建模,就必须将其分解为凸几何体的联合体,并将所有几何体附加到同一个体上。在 XML 模型中,几何体也可以有质量和惯性(或者说是用于计算质量和惯性的材料密度),但这在模型编译器中只用于计算体的质量和惯性。在实际模拟的 mjModel 中,几何体没有惯性属性。

点是轻几何体。它们具有相同的外观属性,但不能参与碰撞,也不能用于推断物体质量。另一方面,点可以做几何体不能做的事情:它们可以指定触摸传感器的体积、IMU 传感器的附件、空间筋腱的路线、滑块-曲柄执行器的端点。这些都是空间量,但它们并不对应于应该具有质量或与其他实体发生碰撞的实体–这就是点元素产生的原因。点还可以用来指定用户感兴趣的点(或者说框架)。

下面的示例说明了可以将多个点和几何体连接到同一个体上:在本例中,两个点和两个几何体连接到一个体上。

<mujoco>
  <worldbody>
    <body pos="0 0 0">
      <geom type="sphere" size=".1" rgba=".9 .9 .1 1"/>
      <geom type="capsule" pos="0 0 .1" size=".05 .1" rgba=".9 .9 .1 1"/>
      <site type="box" pos="0 -.1 .3" size=".02 .02 .02" rgba=".9 .1 .9 1"/>
      <site type="ellipsoid" pos="0 .1 .3" size=".02 .03 .04" rgba=".9 .1 .9 1"/>
    </body>
  </worldbody>
</mujoco>

该模型由 OpenGL 可视化器渲染为
在这里插入图片描述

请注意红色方框。这是身体惯性属性的等效惯性盒渲染,由 MuJoCo 内部生成。方框位于几何体上方,但不在点上方。这是因为只有几何体被用来(自动)推断物体的惯性属性。如果我们碰巧知道后者,当然可以直接指定。但通常更方便的做法是,让模型编译器利用均匀密度假设(几何体密度可以在 XML 中指定;默认值为水的密度),从附着在几何体上的几何体推断出这些体的属性。

8.关节坐标

MuJoCo 与游戏引擎(如 ODE、Bullet、Havoc、PhysX)之间的一个主要区别是,MuJoCo 采用广义或联合坐标,而游戏引擎采用笛卡尔坐标,尽管 Bullet 现在支持广义坐标。这两种方法的区别可归纳如下:

关节坐标:

最适合机器人等精细运动结构;

关节增加了默认情况下焊接在一起的体之间的自由度;

关节约束隐含在表示中,不会被违反;

模拟体的位置和方向是通过正向运动学从广义坐标中获得的,不能直接操作(根体除外)。

笛卡尔坐标:

最适合许多相互弹跳的体,如分子动力学和箱体堆叠;

关节消除了默认情况下自由浮动体之间的自由度;

关节约束以数值方式执行,可以违反;

明确表示模拟体的位置和方向,并可直接操作,但这可能会进一步违反联合约束。

如果模型中的自由浮动体也包含运动学树,那么在处理这些自由浮动体时,关节坐标可能会特别 容易混淆。下文将对此进行说明。

9.漂浮物

在使用关节坐标工作时,你不能简单地将任意物体的位置和方向设置为你想要的任何位置和方向。要达到这种效果,你必须实现某种形式的逆运动学,计算出一组(不一定唯一的)关节坐标,在此坐标下,正向运动学将物体放置到你想要的位置。

浮动体的情况则不同,即通过自由关节与世界相连的物体。这类物体的位置和方向以及线速度和角速度都在 mjData.qpos 和 mjData.qvel 中明确表示,因此可以直接操作。一般的方法是在 qpos 和 qvel 中找到体数据所在的地址。当然,qpos 和 qvel 代表的是关节而不是身体,因此需要相应的关节地址。假设在 XML 中,主体被命名为 “myfloatingbody”。必要的地址可以通过以下方式获得

int bodyid = mj_name2id(m, mjOBJ_BODY, "myfloatingbody");
int qposadr = -1, qveladr = -1;

// make sure we have a floating body: it has a single free joint
if( bodyid>=0 && m->body_jntnum[bodyid]==1 && m->jnt_type[m->body_jntadr[bodyid]]==mjJNT_FREE ) {
  // extract the addresses from the joint specification
  qposadr = m->jnt_qposadr[m->body_jntadr[bodyid]];
  qveladr = m->jnt_dofadr[m->body_jntadr[bodyid]];
}

如果一切顺利(即 "myfloatingbody "确实是一个浮动体),那么 qposadr 和 qveladr 就是浮动体/关节数据所在的 qpos 和 qvel 地址。位置数据是 7 个数字(三维位置和单位四元数),速度数据是 6 个数字(三维线速度和三维角速度)。现在可以将这些数字设置为所需的身体姿态和速度。

自由关节的语义如下。自由关节的线性位置和线性速度都在全局帧中。自由关节的方向(四元数)也在全局帧中。然而,自由关节的旋转速度是在局部体框架中。这与其说是一个设计决定,不如说是对四元数拓扑结构的正确使用。角速度存在于四元数切线空间中,而四元数切线空间是为某个方向局部定义的,因此帧局部角速度是一种自然的参数化。加速度与相应的速度定义在同一空间。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Mujoco Hopper是一种基于物理仿真的机器人模型。它的设计灵感来自草原上跳跃的动作,模拟了机器人在地面上跳跃的运动。这个模型具有简单却又非常灵活的结构,使得它能够通过强大的运动能力来完成各种任务。 Mujoco Hopper的外观是一个由连接起来的几个关节和连杆组成的结构。每个关节都有特定的运动范围和运动速度,使得机器人能够复杂地移动和跳跃。通过改变关节的运动角度和速度,我们可以控制机器人的动作,让它实现各种跳跃动作和运动模式。 Mujoco Hopper的仿真需要使用Mujoco物理仿真引擎,它能够准确地模拟机器人和环境之间的物理交互。通过在仿真环境中测试不同的控制算法和参数设置,我们可以优化机器人的运动能力和稳定性。这些优化方法包括使用强化学习算法来训练机器人自主学习跳跃动作,并通过反馈调整机器人的控制参数。 Mujoco Hopper广泛应用于机器人领域的研究和开发中。通过使用这个模型,我们可以探索机器人在跳跃运动中的稳定性、能量损耗和灵活性等特性。同时,Mujoco Hopper也为机器人控制算法的优化提供了一个可靠的仿真平台,可以加速机器人设计和开发的过程。 总之,Mujoco Hopper是一个基于物理仿真的机器人模型,它通过跳跃动作展示了机器人的运动能力和灵活性。它为机器人研究和控制算法的开发提供了一个重要的工具和平台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值