這個系列文章用來記錄 Google DeepMind 發布的 Mujoco
仿真平臺的使用過程,Mujoco 是具身智能領域中非常知名的仿真平臺,以簡單易用的API和精準的物理引擎而著稱(PS:原來Google能寫好API文檔啊),也是我平時使用最多的仿真平臺,相比較于Gazebo、Isaac Sim 等仿真器而言至少對我來說非常高效,能夠在初期快速驗證模型性能以及配置文件,下面是幾個我常用的仿真平臺對比:
仿真平臺 | 開發公司 | 渲染 | 物理引擎 | 主要優勢 | 典型用途 |
---|---|---|---|---|---|
MuJoCo | DeepMind (原Roboti) | 中 | MuJoCo | 精確的物理建模、速度快、適合優化 | 強化學習、控制算法研究 |
Gazebo | Open Robotics | 中 | ODE, Bullet 等 | 與 ROS 深度集成、功能豐富 | 機器人系統集成、SLAM、導航 |
Isaac Sim | NVIDIA | 強 | PhysX(GPU支持) | 高保真渲染、多傳感器仿真、數字孿生 | 機器人感知、數字孿生建模 |
Isaac Gym | NVIDIA | 弱 | PhysX(GPU加速) | 多環境并行、用于大規模RL訓練 | 強化學習 |
作為系列文章的第一篇是安裝與部署,整個系列將聚焦仿真這一方向,在部署到真機前實現模型驗證。
1. 前期準備工作
前期準備工作主要是檢查你的硬件條件,雖然官方文檔中提到了對OpenGL的需求,但如果你的OS內核沒有過于古老的情況下是不用理會的。
- Github 倉庫:https://github.com/google-deepmind/mujoco
- 官方文檔:https://mujoco.readthedocs.io/en/stable/overview.html
這里以我個人的平臺為例,具體配置如下:
- OS:Ubuntu 20.04 Desktop
- CPU:12th Gen Intel? Core? i7-12700K
- Memory:Sumsung DDR4 32*2 GB
- GPU:NVIDIA GeForce RTX 3060 Super 12 GB
- CUDA Version:12.2
- GPU Driver:535.183.01
- Mujoco Version:3.3.2
后續會在GPU服務器上部署仿真平臺并訓練模型,如果沒有特殊說明的情況下都是以上述配置進行實驗。
雖然官方沒有說明有關仿真平臺的硬件要求,但我個人建議CPU使用12代及其以上型號、內存不低于32GB、顯卡在3060及其以上,因為后面會有博客教你如何在Mujoco上使用模型進行推理,如果你的顯卡顯存不夠的話幾個經典模型是跑不起來的。
2. 編譯與部署
Mujoco 提供了Release和source兩種部署方式,支持 Windows、MacOS、Linux 三大平臺,自己編譯與直接拉取二進制文件效果一樣,兩種方式二選一。
2.1 源碼編譯
- 官方提供的編譯文檔:Building from source
拉取源碼
$ git clone git@github.com:google-deepmind/mujoco.git
因為編譯過程中會使用到 cmake 的 FetchContent
從網上拉取需要的組件,所以需要你確保梯子可用。
編譯源碼
$ cd mujoco
$ mkdir build && cd build
$ cmake .....
-- Looking for IceConnectionNumber in ICE
-- Looking for IceConnectionNumber in ICE - found
-- mujoco::FindOrFetch: Using FetchContent to retrieve `glfw3` - Done
-- mujoco::FindOrFetch: checking for targets in package `mujoco`
-- mujoco::FindOrFetch: checking for targets in package `mujoco` - found
-- mujoco::FindOrFetch: checking for targets in package `glfw3`
-- mujoco::FindOrFetch: checking for targets in package `glfw3` - found
-- Configuring done
-- Generating done
-- Build files have been written to: /home/gaohao/Downloads/mujoco/build
上面的操作沒有報錯的可以繼續執行編譯命令:
$ cmake --build . # 【不推薦】官方編譯命令
$ make -j$(nproc) # 【推薦】多線程編譯
$ make install```
2.2 下載二進制文件
直接在官方 Github 倉庫的 Release 中下載即可:
下載好后直接解壓:
$ tar -zxvf mujoco-3.3.2-linux-x86_64.tar.gz
然后在 ~/.bashrc
文件的末尾添加以下內容:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/Downloads/mujoco-3.3.2/bin
2.3 安裝 python 庫
這里建議使用conda管理python環境,根據官網介紹需要使用 3.8 及其以上版本,我這里使用 3.10:
$ conda create --name mujoco python=3.10
$ pip install mujoco
2.4 驗證安裝效果
新建一個python腳本并添加下面的內容用來加載mujoco自帶的一個xml模型文件 humanoid.xml
,在安裝/編譯位置的 model
文件夾中
import mujoco# 你的實際安裝路徑
model_path = '~/Downloads/mujoco-3.3.2/model/humanoid/humanoid.xml'
model = mujoco.MjModel.from_xml_path(model_path)
data = mujoco.MjData(model)
print(data)
# 調用計時API確保其他組件正常安裝
for _ in range(1000): mujoco.mj_step(model, data)print("Test done.")
運行示例:
(mujoco) $ python test.py<mujoco._structs.MjData object at 0x7ff67c1471b0>
Test done.
能夠正確打印 data 的數據類型則說明安裝成功。
2.5 驗證仿真器 simulate
在確保上面的API驗證沒有報錯的前提下需要驗證仿真器是否能夠正常運行:
$ cd mujoco/bin
$ ./simulate ../model/humanoid/humaniod.xml
運行后會彈出仿真器,此時你需要確認以下幾點是可用的:
- 小人在沒有干預的情況下逐漸躺到在地面;
- 右側打開
Control
面板拖動控制條,小人對應的關節是可動的;
3. 使用 URDF 文件
如果你有機器人的開發經驗,特別是在ROS平臺上,那么通常用得最多的是 urdf
或 xacro
,但 mujoco 原生并不支持 urdf
格式的文件,需要將其轉換為 xml
后使用。
3.1 獲取機器人 urdf 文件
這里推薦一個 Github 倉庫 Awesome Robot Descriptions
里面有很多開源的機器人模型文件。
- Github 倉庫鏈接:Awesome Robot Descriptions
這里以 Gen2
這個機械臂模型為例,直接點擊 URDF
進入對應的倉庫:
你可以將整個倉庫下載下來也可以用瀏覽器插件下載一部分,這里為了方便我直接將 example-robot-data/robots/kinova_description
這個文件夾拷貝了一份到 mujoco-3.3.2
目錄下,當前文件結構如下:
$ cd ~/Downloads/mujoco-3.3.2
$ tree -L 1
.
├── bin
├── demo.py
├── include
├── kinova_description # 從 example-robot-data/robots/ 拷貝過來的文件夾
├── lib
├── model
├── MUJOCO_LOG.TXT
├── sample
├── simulate
└── THIRD_PARTY_NOTICES
進入kinova_description/robots
檢查一下 kinova.urdf
文件的link樹是否完整:
$ cd kinova_description/robots
$ check_urdf kinova.urdfrobot name is: kinova
---------- Successfully Parsed XML ---------------
root Link: base has 1 child(ren)child(1): j2s6s200_link_basechild(1): j2s6s200_link_1child(1): j2s6s200_link_2child(1): j2s6s200_link_3child(1): j2s6s200_link_4child(1): j2s6s200_link_5child(1): j2s6s200_link_6child(1): j2s6s200_end_effectorchild(2): j2s6s200_link_finger_1child(1): j2s6s200_link_finger_tip_1child(3): j2s6s200_link_finger_2child(1): j2s6s200_link_finger_tip_2
只要沒有報錯則說明文件 urdf 的link樹是正確的,那么就可以進行后續操作。
【Note】:這一步一定要去做,因為后面有些問題就是由于link樹沒有正確連接導致的,但urdf 文件本身排查起來很累,所以在使用前就檢查連接合法性是最合適的。
3.2 [可選] 轉換 mesh 文件
如果你的機器人模型文件引用的 mesh 文件是 stl
格式,則可以直接跳過這一段,這里為了更全面的演示我特意找的是 dae
格式的文件。
將 dae
文件轉換為 stl
有很多種方法,我常用的方法有以下三種,前兩種是可能的偷懶方法,其中第三種是一定可行的,之所以說是可能的偷懶方法是因為這兩種轉化方式的成功與否完全取決于廠商是否規范和運氣。但無論如何都需要對原始文件進行備份:
$ cp -r meshes/ meshes_mujoco/
對于偷懶方法而言,使用后直接跳到 3.3
小節完成 urdf 文件修改后即可執行 3.4
小節驗證是否可用,如果不可用則跳回來在剩下兩個方法中再選一個嘗試。
3.2.1 可能的偷懶方法一
第一種可能的偷懶方法是直接修改文件后綴名,使用下面的命令可以直接將 dae
后綴修改為 stl
后綴:
$ cd meshes_mujoco
$ for file in *.dae; do mv "$file" "${file%.dae}.stl"; done
3.3.2 可能的偷懶方法二
第二種可能的偷懶方法是用python腳本批量修改,需要安裝依賴庫:
$ pip install trimesh pyglet
我這里提供了一個python腳本:
import os
import sys
import trimeshdef convert_dae_to_stl(folder_path):if not os.path.isdir(folder_path):print(f"路徑無效:{folder_path}")return# 獲取所有 .dae 文件dae_files = [f for f in os.listdir(folder_path) if f.lower().endswith('.dae')]if not dae_files:print("未找到 .dae 文件。")returnfor dae_file in dae_files:dae_path = os.path.join(folder_path, dae_file)stl_path = os.path.join(folder_path, os.path.splitext(dae_file)[0] + '.stl')try:mesh = trimesh.load(dae_path)if mesh.is_empty:print(f"跳過空模型:{dae_file}")continuemesh.export(stl_path)print(f"轉換成功:{dae_file} -> {os.path.basename(stl_path)}")except Exception as e:print(f"轉換失敗:{dae_file},錯誤信息:{e}")if __name__ == '__main__':if len(sys.argv) < 2:print("用法:python convert.py <文件夾路徑>")else:convert_dae_to_stl(sys.argv[1])
通過下面的命令使用,運行后會在 meshes_mujoco/
文件夾下生成同名但格式不同的mesh文件:
$ cd meshes_mujoco/
$ python conv.py ./
3.2.3 絕對可行的方法
最保險和穩妥的方法是使用第三方工具將文件轉換成 stl
格式并保存,這里推薦使用開源工具 meshlab
,這個方式比較麻煩的點在于需要一個一個手動轉換后保存:
- Meshlab 官網鏈接:https://www.meshlab.net
進入后在 Download
頁面中選擇合適的版本下載。
打開軟件后直接按照下面的步驟操作:
File
->Import Mesh..
;File
->Export Mesh As..
;- 在彈出的對話框中選擇
.stl
格式并保存;
【Note】:因為 mujoco 在使用mesh文件時緊支持表面不超過 200000
個渲染面的文件,如果你在后面運行時出現了相關報錯還可以按照下面的步驟減少渲染面個數:
Filters
->Remeshing, Simplication and Reconstruction
->Simplication: Quadric Edge Collaspe Decimation
;- 在彈出的界面中將渲染面改到合適的范圍;
3.3 修改 urdf 文件
然后編輯 kinova.urdf
文件,總共需要做2步操作:
- 將
mesh
file 的搜索路徑改為相對路徑; - 修改
.dae
文件后綴為.stl
; - 添加 mujoco 的 mesh 文件搜索路徑;
3.2.1 修改 mesh file 的搜索路徑
打開urdf文件后將里面的 package://example-robot-data/robots/kinova_description/meshes
批量替換成 ../meshes_mujoco
:
3.2.2 修改 .dae 文件后綴為 .stl
如果你的urdf文件本身用的就是 stl
后綴就不用執行這一步;如果是跟著我的示例就需要執行,同樣是批量查找并替換:
3.2.3 添加 mujoco mesh 重定向信息
在文件末尾處添加以下字段以讓mujoco能夠找到 mesh 文件:
【Note】:添加的部分一定要在 <robot>...</robot>
標簽內。
<robot>...<mujoco><compiler balanceinertia="true" discardvisual="false" meshdir="../meshes_mujoco"/></mujoco>
</robot>
3.4 運行 urdf 轉換命令
此時你的kinova_description
文件結構如下:
$ cd mujoco-3.3.2/kinova_description/
$ tree -L 1.
├── meshes # 原始的dae文件夾
├── meshes_mujoco # 轉換成stl的文件夾
├── README.md
├── robots
└── srdf
運行轉換命令:
(mujoco) $ cd ../
(mujoco) $ ./bin/compile kinova_description/robots/kinova.urdf kinova_description/robots/kinova.xml...
WARNING: Geom with duplicate name '' encountered in URDF, creating an unnamed geom.
WARNING: Geom with duplicate name '' encountered in URDF, creating an unnamed geom.
WARNING: Geom with duplicate name '' encountered in URDF, creating an unnamed geom.
WARNING: Geom with duplicate name '' encountered in URDF, creating an unnamed geom.
Done.
First compile: 0.1349s
Second compile: 0.02025s
輸出上面的樣子則表明轉換成功。
3.4.1 可能的報錯一:
如果運行后發現有以下報錯:
Error: number of faces should be between 1 and 200000 in STL file 'kinova_description/robots/../meshes_mujoco/base.stl'; perhaps this is an ASCII file?
有兩種可能性:
- 不能直接通過修改文件后綴的方式,跳回到
3.2.3
老老實實用最穩妥的方式一個一個手動轉化吧; - 文件的 mesh 渲染面體太多了,跳回到
3.2.3
中修改渲染面的個數;
3.4.2 可能的報錯二:
如果運行后發現有以下報錯:
Error: Error opening file 'kinova_description/robots/base.stl': No such file or directory
通常是應為沒有執行 3.2.3
步導致的,在urdf中添加字段讓 mujoco 完成重定向。
3.4.3 可能的報錯三:
如果運行后發現有以下報錯:
...
Plugins registered by library 'libelasticity.so':mujoco.elasticity.cablemujoco.elasticity.shell
ERROR: could not initialize GLFW
通常是因為沒有使用虛擬環境導致的,使用正確的conda環境,在我這里是mujoco
:
$ conda activate mujoco
如果仍然是這個報錯,檢測你的命令是否輸錯了:
$ ./bin/simulate # 錯誤
$ ./bin/compile # 正確
3.5 打開仿真器 simulate
在確保轉換成功后就可以打開仿真器查看機器人模型了,仿真器使用的是 xml
格式的文件,如果打開的是 urdf
則會報錯。
$ cd mujoco-3.3.2
$ ./bin/simulate kinova_description/robots/kinova.xml