Mujoco xml模型
XML主要分为以下三个部分:
- < asset> : 用 tag导入STL文件;
- < worldbody>:用tag定义了所有的模拟器组件,包括灯光、地板以及你的机器人;
- < acutator>:定义可以执行运动的关节。定义的顺序需要按照运动学顺序来,比如多关节串联机器人以工具坐标附近的最后一个关节为joint0,依此类推。
一个例子
mujoco官方文档给了xml文件能写的内容
XML Reference
xml
<mujoco model="example">
<!-- set some defaults for units and lighting -->
<compiler angle="radian" meshdir="meshes"/>
<!-- 导入STL文件 -->
<asset>
<mesh file="base.STL" />
<mesh file="link1.STL" />
<mesh file="link2.STL" />
</asset>
<!-- 定义所有模拟器组件 -->
<worldbody>
<!-- 灯光 -->
<light directional="true" pos="-0.5 0.5 3" dir="0 0 -1" />
<!-- 添加地板,这样我们就不会凝视深渊 -->
<geom name="floor" pos="0 0 0" size="1 1 1" type="plane" rgba="1 0.83 0.61 0.5"/>
<!-- the ABR Control Mujoco interface expects a hand mocap -->
<body name="hand" pos="0 0 0" mocap="true">
<geom type="box" size=".01 .02 .03" rgba="0 .9 0 .5" contype="2"/>
</body>
<!-- 构建串联机器人 -->
<body name="base" pos="0 0 0">
<geom name="link0" type="mesh" mesh="base" pos="0 0 0"/>
<inertial pos="0 0 0" mass="0" diaginertia="0 0 0"/>
<!-- nest each child piece inside the parent body tags -->
<body name="link1" pos="0 0 1">
<!-- this joint connects link1 to the base -->
<joint name="joint0" axis="0 0 1" pos="0 0 0"/>
<geom name="link1" type="mesh" mesh="link1" pos="0 0 0" euler="0 3.14 0"/>
<inertial pos="0 0 0" mass="0.75" diaginertia="1 1 1"/>
<body name="link2" pos="0 0 1">
<!-- this joint connects link2 to link1 -->
<joint name="joint1" axis="0 0 1" pos="0 0 0"/>
<geom name="link2" type="mesh" mesh="link2" pos="0 0 0" euler="0 3.14 0"/>
<inertial pos="0 0 0" mass="0.75" diaginertia="1 1 1"/>
<!-- the ABR Control Mujoco interface uses the EE body to -->
<!-- identify the end-effector point to control with OSC-->
<body name="EE" pos="0 0.2 0.2">
<inertial pos="0 0 0" mass="0" diaginertia="0 0 0" />
</body>
</body>
</body>
</body>
</worldbody>
<!-- 定义关节上的执行器 -->
<actuator>
<motor name="joint0_motor" joint="joint0"/>
<motor name="joint1_motor" joint="joint1"/>
</actuator>
</mujoco>
compiler
option
asset
mesh
xml
<mesh name="base_link" file="base_link.obj"/>
<!--使用上-->
<geom type="mesh" mesh="base_link"/> <!-- 使用该网格 -->
default
基本使用
< default> 定义的属性模板通过 class 属性 在后续的 < body>, < joint>, < geom> 等元素中引用。
基本引用规则:
- class="模板名":在元素中添加该属性即可继承模板中定义的所有属性。
- 继承逻辑:子类会继承父类的所有属性,同名属性会被子类覆盖,显式写了属性就会覆盖类的属性。
xml
<default>
<!-- 根默认类 -->
<default class="robot"> <!-- 主模板 -->
<geom friction="0.6" margin="0.001"/> <!-- 所有几何体默认摩擦系数 -->
<joint damping="2"/> <!-- 所有关节默认阻尼 -->
<motor ctrlrange="-23.7 23.7"/> <!-- 所有电机默认控制范围 -->
<!-- 子类:髋关节模板 -->
<default class="abduction"> <!-- 继承自 robot -->
<joint axis="1 0 0" range="-1.0472 1.0472"/> <!-- 覆盖 axis 和 range -->
</default>
<!-- 子类:膝关节模板 -->
<default class="knee"> <!-- 继承自 robot -->
<joint range="-2.7227 -0.83776"/> <!-- 覆盖 range -->
<motor ctrlrange="-45.43 45.43"/> <!-- 覆盖电机的控制范围 -->
</default>
</default>
</default>
根类使用
xml
<body name="base" childclass="robot"> <!-- 所有子元素默认继承robot类 -->
<geom type="box" size="0.1 0.1 0.1"/> <!-- 自动应用 friction="0.6" -->
<joint name="free_joint"/> <!-- 自动应用 damping="2" -->
</body>
子类abduction使用
xml
<body name="FL_hip">
<joint name="FL_hip_joint" class="abduction"/> <!-- 继承以下属性:
axis="1 0 0"
range="-1.0472 1.0472"
damping="2" (从父类robot继承) -->
</body>
所以也就是说使用了 < joint class="abduction">的,有damping="2"属性,也有axis="1 0 0" range="-1.0472 1.0472"属性。
显式覆盖
xml
<default>
<default class="aa">
<geom rgba="1 0 0 1" friction="0.8"/> <!-- 红色+高摩擦 -->
<joint damping="3"/> <!-- 高阻尼 -->
</default>
</default>
<body name="parent" childclass="aa">
<!-- 子刚体自动继承类 aa -->
<body name="child1">
<geom type="box"/> <!-- 自动应用 rgba="1 0 0 1" 和 friction="0.8" -->
<joint type="hinge"/> <!-- 自动应用 damping="3" -->
</body>
<!-- 子刚体显式覆盖属性 -->
<body name="child2">
<geom type="sphere" rgba="0 1 0 1"/> <!-- 覆盖为绿色 -->
<joint type="slide" damping="1"/> <!-- 覆盖阻尼 -->
</body>
</body>
childclass与class
childclass 的作用范围仅作用于 < body> 标签内直接嵌套的子 < body>,当前刚体不使用这个属性,子刚体的子刚体(孙子级)不会自动继承该 childclass,除非它们也被显式设置。
xml
<body name="parent" childclass="aa">
<geom/> <!-- 不会应用 aa 的 geom 默认属性 -->
<!-- 子刚体(直接继承 aa) -->
<body name="child1">
<geom/> <!-- 自动应用 aa 的 geom 默认属性 -->
<!-- 孙子刚体(不继承 aa,除非 child1 也设置 childclass) -->
<body name="grandchild">
<geom/> <!-- 不使用 aa 的属性 -->
</body>
</body>
</body>
<!-- 逐层传递 -->
<body name="parent" childclass="aa">
<body name="child1" childclass="aa"> <!-- 显式传递 -->
<body name="grandchild">
<geom/> <!-- 现在继承 aa -->
</body>
</body>
</body>
class仅作用于当前 < body> 自身,不会自动传递给任何子刚体,子刚体若需继承,必须显式设置自己的 class 或 childclass。
xml
<default>
<default class="robot_part">
<geom rgba="1 0 0 1"/>
<joint damping="5"/>
</default>
</default>
<body name="parent" class="robot_part">
<!-- 当前body继承robot_part的属性 -->
<geom type="box"/> <!-- 红色方块 -->
<body name="child">
<!-- 子刚体不受影响!使用全局默认属性 -->
<geom type="sphere"/> <!-- 默认颜色 -->
</body>
</body>
多个class
类名是要唯一的
同级 < default> 类名不能重复:在相同嵌套层级下,class 名称必须唯一。
xml
<default>
<default class="a">...</default>
<default class="b">...</default> <!-- 允许,不同名 -->
<default class="a">...</default> <!-- 错误!与第一个 "a" 冲突 -->
</default>
子类只是会继承父类的属性,并不是嵌套使用的关系,body能直接使用aa和bb,所以aa和bb不能同名
xml
<default class="a"> <!-- 父类 -->
<default class="aa">...</default> <!-- 子类,继承 "a" 的属性 -->
</default>
<default class="b">
<default class="bb">...</default> <!-- 子类,继承 "b" 的属性 -->
</default>
worldbody
body关系
跟urdf的link和joint写法不一样,但是逻辑是一样的。
两个 < body>(刚体)通过 关节(< joint>) 实现物理连接,关节定义了它们之间的运动约束关系。
父子结构:子 < body> 必须嵌套在父 < body> 内,嵌套关系表达了父子关节,joint就不用写父子关节了。
关节定义位置:关节 < joint> 必须定义在 子 < body> 内部。
默认行为:若无关节,子刚体会与父刚体刚性固定。
关节作用:添加关节后,子刚体可相对父刚体运动(旋转或平移)。
xml
<!--定义父刚体-->
<body name="parent_body" pos="0 0 0">
<!-- 父刚体的几何、惯性等属性 -->
</body>
xml
<!--在父刚体内嵌套子刚体-->
<body name="parent_body">
<body name="child_body" pos="0 0 0.1"> <!-- 初始位置偏移 -->
<!-- 子刚体的关节、几何等 -->
</body>
</body>
xml
<!--在子刚体中添加关节-->
<body name="parent_body">
<body name="child_body" pos="0 0 0.1">
<joint name="child_joint" type="hinge" axis="0 1 0"/>
<geom type="box" size="0.1 0.1 0.1"/>
</body>
</body>
类似下面的urdf
xml
<!-- URDF 的链式结构(明确指定父子关系) -->
<link name="parent_link"/>
<joint name="child_joint" type="revolute">
<parent link="parent_link"/>
<child link="child_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="child_link"/>
特性 | URDF | MuJoCo |
---|---|---|
连接方式 | 显式通过 < parent> 和 标签 | 隐式通过 < body> 嵌套层级 |
关节位置 | 独立于 < link> 之外 | 必须定义在子 < body> 内部 |
初始偏移 | 在 < joint> 的 中定义 | 在子 < body> 的 pos 属性中定义 |
几何体定义 | 在 < link> 内通过 < visual>/< collision> | 直接在 < body> 内通过 < geom> |
inertial
joint
能写的属性
属性 | 类型 | 描述 |
---|---|---|
name | 字符串 | 关节的唯一标识符。 |
type | 字符串 | 关节的类型(如hinge、slide、ball等),决定了关节的运动方式。 |
pos | 数组 | 关节相对于其父体的位置,默认为(0,0,0)。 |
axis | 数组 | 运动轴向量,对于hinge和slide关节类型,这是旋转或滑动发生的方向。 |
range | 数组 | 关节运动的范围,通常为一个最小值和一个最大值的数组。限制了关节可以达到的最小和最大位置。 |
damping | 浮点数 | 关节的阻尼系数,用于模拟运动中的能量损失。 |
stiffness | 浮点数 | 关节的刚度,用于模拟弹簧效果,影响关节回到初始位置的力度。 |
armature | 浮点数 | 附加到关节轴上的虚拟质量,用于稳定仿真。可以认为是增加关节惯性的一种方式,有助于防止数值问题。 |
limited | 布尔值 | 指示关节是否受到range属性定义的范围限制。默认为true,表示受限。 |
关节类型:Hinge(铰链关节),Slide(滑动关节),Ball(球形关节),free(自由关节)