强化学习最强仿真平台--MuJoCo官方文档解读-Introduction

链接
2021年10月18日DeepMind收购并开源了MuJoCo软件(之前都是收费的,最早由Roboti LLC开发),MuJoCo:Multi-Joint dynamics with Contact

一、Overview

1.1 介绍

MuJoCo是一个带有C API的C/C库,面向研究人员和开发人员。运行时模拟模块被调优为最大限度地提高性能,并对由内置XML解析器和编译器预先分配的低级数据结构进行操作。用户使用原生的MJCF场景描述语言定义模型–这是一种设计为尽可能具有人类可读性和可编辑性的XML文件格式。也可以加载URDF模型文件。该库包括带有原生GUI的交互式可视化,在OpenGL中渲染。MuJoCo进一步公开了大量用于计算与物理相关的量的效用函数。
MuJoCo可用于实现基于模型的计算,如控制综合、状态估计、系统辨识、机构设计、通过逆动力学进行数据分析,以及用于机器学习应用的并行采样。它还可以用作更传统的模拟器,包括游戏和交互式虚拟环境。

1.1.1 主要特点

  • 广义坐标与现代接触动力学的结合
  • 软接触、凸接触和解析可逆接触动力学
  • 肌腱几何学
  • 通用驱动模型
  • 可重构计算流水线
  • 模型编译
  • 模型和数据的分离
    MuJoCo在运行时将模拟参数分成两个数据结构(C结构):
    mjModel:包含模型描述,并且应该保持不变。它还嵌入了包含模拟和可视化选项的其他结构,这些选项需要偶尔更改,但这是由用户完成的。
    MjData:包含所有动态变量和中间结果。它被用作暂存区,所有函数在这里读取它们的输入并写入它们的输出-然后这些输出变成模拟流水线中后续阶段的输入。它还包含一个预分配和内部管理的堆栈,因此运 行时模块不需要在模型初始化后调用内存分配函数。
    mjModel由编译器构造。给定mjModel,mjData在运行时构造。这种分离使得模拟多个模型以及每个模型的多个状态和控件变得容易,进而促进了采样和有限差分的多线程。顶层API函数反映了这种基本分离, 其格式为:
void mj_step(const mjModel*m,mjData*d);
  • 交互式仿真和可视化
    本机3D可视化工具提供网格和几何图元、纹理、反射、阴影、雾、透明度、线框、天框、立体可视化(在支持四缓冲OpenGL的视频卡上)的渲染。此功能用于生成3D渲染,帮助用户深入了解物理仿真,包括可视化辅助工具,例如自动生成的模型骨架、等效惯性框、接触位置和法线、可分为法向和切向分量的接触力、外部扰动力、局部框架、关节和执行机构轴以及文本标签。可视化工具期望一个具有OpenGL渲染上下文的通用窗口,从而允许用户采用他们选择的GUI库。MuJoCo随附的代码样例Simulation ate.cc展示了如何使用GLFW库实现这一点。一个相关的可用性特性是能够“接触”模拟,推动对象,并查看物理响应。用户选择将施加外力和扭矩的物体,并查看扰动及其动态结果的实时渲染。这可用于直观地调试模型、测试反馈控制器的响应或将模型配置为所需的姿势。

  • 强大而直观的建模语言
    独创的MJCF建模语言(类似于URDF,都是XML格式文件),但是可阅读性更强。

  • 复合柔性对象的自动生成等等

1.1.2 模型示例

在MuJoCo中有几个被称为“模型”的实体。用户在用MJCF或URDF编写的XML文件中定义模型。然后,该软件可以在不同的介质(文件或内存)和不同的描述级别(高或低)上创建同一模型的多个实例。所有组合都有可能,如下表所示:

- High level Low level
File MJCF/URDF(XML) MJB(binary)
Memory mjCModel(C++ class) mjModel(C struct)

所有运行时计算都是使用mjModel执行的,mjModel太复杂了,无法手动创建。这就是为什么我们有两个层次的建模。高层的存在是为了方便用户:其唯一目的是将其编译成可在其上执行计算的低级模型。生成的mjModel可以加载并保存到二进制文件(MJB)中,但是这些文件是特定于版本的,不能反编译,因此应该始终将模型作为XML文件进行维护。(低级的存在是为了能让计算机识别并直接运行,类似于C/C++语言的链接和编译器,把.c/.cpp代码链接编译成二进制代码.o从而可以直接用计算机运行的。
(内部)C++类mjCModel与MJCF文件格式大致一一对应。XML解析器解释MJCF或URDF文件并创建相应的mjCModel。原则上,用户可以通过编程方式创建mjCModel,然后将其保存到MJCF或编译。但是,该功能尚未公开,因为C++ API不能从独立于编译器的库导出。有一个围绕它开发C包装器的计划,但目前解析器和编译器总是一起调用,并且只能用XML创建模型。(后期可能会使用C++类来开发模型,但是现在还没有实现)
获取mjModel的路径一般如下(3种方法):

  1. 文本编辑器–>MJCF/URDF文件–>(MuJoCo解析器–>mjCModel–>MuJoCo编译器)–>mjModel
  2. 用户代码(C++代码)–>mjCModel–>(MuJoCo编译器)–>mjModel (该功能正在开发中)
  3. MJB文件–>(MuJoCo装载器)–>mjModel

1.1.3 例子

下面是MuJoCo的MJCF格式的一个简单模型。它定义了固定到世界的平面、更好地照亮对象和投射阴影的灯光,以及具有6个自由度的浮动长方体(这就是“自由”关节的作用)。
helloj.xml

<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>

如果对这个模型进行模拟,盒子就会掉到地上。下面给出了没有渲染被动动力学的基本仿真代码。
hello.c

#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 API与C和C++都兼容。通常情况下,用户代码将用C++语言编写,因为它增加了方便性,并且不会因为计算瓶颈在已经高度优化的模拟器中而牺牲效率。
函数mj_step是将模拟状态推进一个时间步长的顶层函数。当然,这个例子只是一个被动动力系统。当用户指定控制或施加力并开始与系统交互时,事情会变得更加有趣。

接下来,我们提供一个更详细的示例,说明MJCF的几个特性。
example.xml

<mujoco model="example">
    <compiler coordinate="global"/>
    <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>
            <geom type="capsule" fromto="0 0 1  0 0 0.6" size="0.06"/>
            <joint type="ball" pos="0 0 1"/>
            <body>
                <geom type="capsule" fromto="0 0 0.6  0.3 0 0.6" size="0.04"/>
                <joint type="hinge" pos="0 0 0.6" axis="0 1 0"/>
                <joint type="hinge" pos="0 0 0.6" axis="1 0 0"/>
                <body>
                    <geom type="ellipsoid" pos="0.4 0 0.6" size="0.1 0.08 0.02"/>
                    <site name="end1" pos="0.5 0 0.6" type="sphere" size="0.01"/>
                    <joint type="hinge" pos="0.3 0 0.6" axis="0 1 0"/>
                    <joint type="hinge" pos="0.3 0 0.6" axis="0 0 1"/>
                body>
            body>
        body>
        <body>
            <geom type="cylinder" fromto="0.5 0 0.2  0.5 0 0" size="0.07"/>
            <site name="end2" pos="0.5 0 0.2" type="sphere" size="0.01"/>
            <joint type="free"/>
        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元素是必需的WorldBody。请注意,在两个实体之间使用多个关节不需要创建虚拟实体。
强化学习最强仿真平台--MuJoCo官方文档解读-Introduction_第1张图片

MJCF文件包含指定模型所需的最少信息。胶囊是由空间中的线段定义的-在这种情况下,只需要胶囊的半径。车身骨架的位置和方向是从它们所属的几何图形推断出来的。惯性特性是在均匀密度假设下从几何形状中推断出来的。之所以命名这两个位置,是因为腱定义需要引用它们,但没有命名其他位置。仅为铰链关节定义关节轴,而不为球关节定义关节轴。碰撞规则是自动定义的。摩擦属性、重力、模拟时间步长等设置为其默认值。顶部指定的默认几何图形颜色适用于所有几何图形。
除了将编译后的模型保存为二进制MJB格式外,我们还可以将其保存为MJCF或人类可读的文本;请分别参阅examplesave.xml和exampleaved.txt。XML版本与原始版本类似,而文本版本包含来自mjModel的所有信息。将文本版本与XML版本进行比较,可以看出模型编译器为我们做了多少工作。

1.2 模型相关元素

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

1.2.1 选项(options)

每种模型都有下面列出的三组选项。他们总是被包括在内。如果未在XML文件中指定它们的值,则使用默认值。这些选项的设计使得用户可以在每个模拟时间步长之前更改它们的值。但是,在时间步长内,所有选项都不应更改。
mjOption:此结构包含影响物理模拟的所有选项。它用于选择算法并设置其参数,启用和禁用模拟管道的不同部分,以及调整系统级物理属性(如重力,模拟失重的环境,或者物体浮力和重力平衡的环境)。
mjVisual:此结构包含所有可视化选项。还有其他OpenGL渲染选项,但这些选项与会话相关,不是模型的一部分。
mjStatistic:此结构包含由编译器计算的有关模型的统计信息:平均体重、模型的空间范围等。包含该结构是为了提供信息,还因为可视化工具将其用于自动缩放。

1.2.2 资产(Assets)

资产本身并不是模型元素。模型图元可以参照它们,在这种情况下,资源会以某种方式修改参照图元的属性。一个资源可以被多个模型元素引用。由于包含资产的唯一目的是引用它,并且只能按名称进行引用,因此每个资产都有一个名称(如果适用,可以从文件名推断出名称)。相反,常规元素的名称可以保留为未定义。

  • mesh(网格):
    MuJoCo可以从二进制STL文件加载三角化网格。诸如MeshLab之类的软件可用于从其他格式进行转换。虽然可以加载任何三角形集合并将其可视化为网格,但碰撞检测器使用凸面外壳。有一些编译时选项可用于缩放网格,以及将基本体几何形状拟合到网格。该网格还可以用来自动推断惯性特性–将其视为三角金字塔的联合,并将它们的质量和惯性组合在一起。请注意,STL格式不支持颜色;一些软件包在未使用的字段中写入颜色信息,但这并不一致。而是使用参考几何的材质属性对网格进行着色。相反,所有空间属性都由网格数据确定。MuJoCo支持自定义二进制文件格式,该格式还可以指定法线和纹理坐标。网格也可以直接嵌入到XML中。
  • skin(皮肤)
  • Height field(高度场)
  • Testure(质地)
  • Material(材料)

1.2.3 运动学相关(Kinematic tree)

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

  • Body
    Body具有质量和惯性属性,但没有任何几何属性。取而代之的是将几何形状(或几何图形)附加上去。每个Body都有两个坐标框架:用于定义它以及相对于它定位其他元素的框架,以及以body质心为中心并与其主惯性轴对齐的惯性框架。因此,在这个框架中,body惯性矩阵是对角线。在每个时间步,MuJoCo递归计算正向运动学,生成全局笛卡尔坐标中的所有body位置和方向。这为所有后续计算提供了基础。
  • Joint(关节)
    Joint(关节)在body内定义。它们在body与其父body之间创建运动自由度(DOF)。在没有关节的情况下,body将焊接到其父body。这与使用过完整笛卡尔坐标的游戏引擎相反,在游戏引擎中,关节移除自由度而不是添加自由度。有四种类型的关节:球关节、滑动关节、铰链关节和创建浮体的“自由关节”。单个body可以有多个关节。这样,可以自动创建组合关节,而不必定义虚拟body。球和自由运动类型的方向分量用单位四元数表示,MuJoCo中的所有计算都考虑四元数的特性。
  • DOF(自由度)
    自由度与关节密切相关,但不是一一对应的,因为球关节和自由关节有多个自由度。可以将运动类型视为指定位置信息,将自由度视为指定速度和力信息。更正式地说,关节位置是系统配置流形上的坐标,而关节速度是当前位置处该流形切线空间上的坐标。自由度具有与速度相关的特性,如摩擦损失、阻尼、电枢惯性。作用在系统上的所有广义力都表示在自由度空间中。相比之下,运动类型具有与位置相关的特性,例如极限和弹簧刚度。自由度不是由用户直接指定的。相反,它们是由给定关节的编译器创建的。
  • Geom(几何)
  • Site(位置)
  • Camera(相机)
  • Light(灯光)
    灯光可以固定在世界实体上,也可以附加到移动的实体上。可视化工具提供对OpenGL中完整照明模型的访问(固定功能),包括环境光、漫反射和镜面反射组件、衰减和截止、位置和定向照明、雾。灯光,或者更确切地说,由灯光照亮的对象也可以投射阴影。但是,与材质反射类似,每个阴影投射灯光都会添加一个渲染过程,因此应谨慎使用此功能。请注意,除了在运动学树中由用户定义的灯光外,还有一个默认的前照灯随相机移动。其属性通过mjVisual选项进行调整。

1.2.4 独立元素(stand-alone elements)

在这里,我们描述了不属于单个实体的模型元素,因此在运动学树之外进行了描述。

  • Reference pose
    参考姿势是存储在 mjModel.qpos0 中的关节位置向量。当模型处于初始配置时,它对应于关节的数值。
  • Spring reference pose
    这是所有关节和肌腱弹簧达到其静止长度的姿势。
  • Tendon(肌腱)
    肌腱是标量长度元素,可用于驱动、施加限制和等式约束,或创建弹簧阻尼器和摩擦损失
  • Actuator
    MuJoCo提供了一种灵活的执行器模型,具有三个可以独立指定的组件。它们共同决定了执行器的工作方式。通过以协调的方式指定这些组件,可以获得常见的执行器类型。这三个部分是传递(transmission)、激活动力学(activation dynamics)和力的产生(force generation)。
  • Sensor
    MuJoCo可以生成模拟传感器数据,该数据保存在全局数组mjData.ensordata中。结果不在任何内部计算中使用;相反,提供结果是因为用户可能需要它来进行自定义计算或数据分析。可用的传感器类型包括触摸传感器、惯性测量单元(IMU)、力-扭矩传感器、关节和肌腱位置和速度传感器、执行器位置、速度和力传感器、运动捕捉标记位置和四元数以及磁强计。其中一些需要额外的计算,而另一些则是从mjData的相应字段复制的。还有一个用户传感器,允许用户代码在传感器数据数组中插入任何其他感兴趣的量。MuJoCo还具有屏幕外渲染功能,可以直接模拟颜色和深度相机传感器。这不包括在标准传感器模型中,而必须以编程方式完成,如代码样例simate.cc所示(官网给的代码)。
  • Equality
    除了运动学树结构和其中定义的运动类型/自由度已经施加的约束之外,相等约束还可以施加其他约束。
  • Contact pair
  • Contact exclude
  • Custom numeric
    在MuJoCo模拟中输入自定义数据有三种方式。首先,可以在XML中定义全局数值字段。它们有一个名称和一个实值数组。其次,某些模型元素的定义可以使用特定于元素的自定义数组进行扩展。这是通过在XML元素大小中设置属性nuser_XXX来实现的。第三,有一个数组mjData.userdata,它没有被任何MuJoCo计算使用。用户可以将自定义计算的结果存储在那里;回想一下,随时间变化的所有内容都应该存储在mjData中,而不是存储在mjModel中。
  • Custom text
    自定义文本字段可以保存在模型中。它们可以在自定义计算中使用-或者用于指定关键字命令,或者用于提供一些其他文本信息。
  • Custom tuple
    自定义元组是MuJoCo模型元素的列表,可能包括其他元组。
  • Keyframe(关键帧)
    关键帧是模拟状态变量的快照。它包含关节位置、关节速度、执行器激活(如果存在)和模拟时间的向量。该模型可以包含关键帧库。它们对于将系统状态重置为关注点非常有用。请注意,关键帧不用于在模型中存储轨迹数据;应使用外部文件来实现此目的。

1.3 澄清

读者可能有其他物理模拟器和相关约定的经验,以及与MuJoCo不一致的一般编程实践。这有可能造成混乱。本节的目标是先发制人地澄清最容易混淆的方面;它介于常见问题解答和有关选定主题的教程之间。我们将需要参考文档后面介绍的材料,但是下面的文本尽可能自成体系,具有介绍性。

  • Not object-oriented
  • Softness and slip
  • Type, names, ids
  • Bodies, geoms, sites
  • Joint coordinates
  • Floating objects

你可能感兴趣的:(Mujoco学习,xml,roboto,仿真器,deepmind)