Mujoco xml模型

发布于:2025-04-14 ⋅ 阅读:(28) ⋅ 点赞:(0)

XML主要分为以下三个部分:

  • < asset> : 用 tag导入STL文件;
  • < worldbody>:用tag定义了所有的模拟器组件,包括灯光、地板以及你的机器人;
  • < acutator>:定义可以执行运动的关节。定义的顺序需要按照运动学顺序来,比如多关节串联机器人以工具坐标附近的最后一个关节为joint0,依此类推。

一个例子

mujoco官方文档给了xml文件能写的内容
XML Reference

<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

<mesh name="base_link" file="base_link.obj"/>

<!--使用上-->
<geom type="mesh" mesh="base_link"/>  <!-- 使用该网格 -->

default

基本使用

< default> 定义的属性模板通过 ​​class 属性​​ 在后续的 < body>, < joint>, < geom> 等元素中引用。

基本引用规则​​:

  • ​​class="模板名"​​:在元素中添加该属性即可继承模板中定义的所有属性。
  • 继承逻辑​​:子类会继承父类的所有属性,同名属性会被子类覆盖,显式写了属性就会覆盖类的属性。
<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>

根类使用

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

<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"属性。

显式覆盖

<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,除非它们也被显式设置。

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

<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 名称必须唯一。

<default>
	<default class="a">...</default>
	<default class="b">...</default>  <!-- 允许,不同名 -->
	<default class="a">...</default>   <!-- 错误!与第一个 "a" 冲突 -->
</default>

子类只是会继承父类的属性,并不是嵌套使用的关系,body能直接使用aa和bb,所以aa和bb不能同名

<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> 内部​​。
​​默认行为​​:若无关节,子刚体会与父刚体​​刚性固定​​。
​​关节作用​​:添加关节后,子刚体可​​相对父刚体运动​​(旋转或平移)。

<!--定义父刚体​​-->
<body name="parent_body" pos="0 0 0">
  <!-- 父刚体的几何、惯性等属性 -->
</body>
<!--在父刚体内嵌套子刚体​​-->
<body name="parent_body">
  <body name="child_body" pos="0 0 0.1"> <!-- 初始位置偏移 -->
    <!-- 子刚体的关节、几何等 -->
  </body>
</body>
<!--在子刚体中添加关节​​-->
<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

<!-- 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(自由关节)

geom