Mujoco 学习系列(一)安装与部署

这个系列文章用来记录 Google DeepMind 发布的 Mujoco 仿真平台的使用过程,Mujoco 是具身智能领域中非常知名的仿真平台,以简单易用的API和精准的物理引擎而著称(PS:原来Google能写好API文档啊),也是我平时使用最多的仿真平台,相比较于Gazebo、Isaac Sim 等仿真器而言至少对我来说非常高效,能够在初期快速验证模型性能以及配置文件,下面是几个我常用的仿真平台对比:

仿真平台开发公司渲染物理引擎主要优势典型用途
MuJoCoDeepMind (原Roboti)MuJoCo精确的物理建模、速度快、适合优化强化学习、控制算法研究
GazeboOpen RoboticsODE, Bullet 等与 ROS 深度集成、功能丰富机器人系统集成、SLAM、导航
Isaac SimNVIDIAPhysX(GPU支持)高保真渲染、多传感器仿真、数字孪生机器人感知、数字孪生建模
Isaac GymNVIDIAPhysX(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

运行后会弹出仿真器,此时你需要确认以下几点是可用的:

  1. 小人在没有干预的情况下逐渐躺到在地面;
  2. 右侧打开 Control 面板拖动控制条,小人对应的关节是可动的;

在这里插入图片描述


3. 使用 URDF 文件

如果你有机器人的开发经验,特别是在ROS平台上,那么通常用得最多的是 urdfxacro,但 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 页面中选择合适的版本下载。
在这里插入图片描述

打开软件后直接按照下面的步骤操作:

  1. File -> Import Mesh..
  2. File -> Export Mesh As..
  3. 在弹出的对话框中选择 .stl 格式并保存;

在这里插入图片描述

【Note】:因为 mujoco 在使用mesh文件时紧支持表面不超过 200000 个渲染面的文件,如果你在后面运行时出现了相关报错还可以按照下面的步骤减少渲染面个数:

  1. Filters -> Remeshing, Simplication and Reconstruction -> Simplication: Quadric Edge Collaspe Decimation
  2. 在弹出的界面中将渲染面改到合适的范围;

在这里插入图片描述

在这里插入图片描述

3.3 修改 urdf 文件

然后编辑 kinova.urdf 文件,总共需要做2步操作:

  1. mesh file 的搜索路径改为相对路径;
  2. 修改 .dae 文件后缀为 .stl
  3. 添加 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?

有两种可能性:

  1. 不能直接通过修改文件后缀的方式,跳回到 3.2.3 老老实实用最稳妥的方式一个一个手动转化吧;
  2. 文件的 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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ai学习之openai api

一、什么是openai api 大家对特斯拉的马斯克应该是不陌生的&#xff0c;openai 就是马斯克投资的一家研究人工智能的公司&#xff0c;它就致力于推动人工智能技术的发展&#xff0c;目标是确保人工智能对人类有益&#xff0c;并实现安全且通用的人工智能。 此后&#xff0c;O…

leetcode 合并区间 java

用 ArrayList<int[]> merged new ArrayList<>();来定义数组的list将数组进行排序 Arrays.sort(intervals,(a,b) -> Integer.compare(a[0],b[0]));如果前面的末尾>后面的初始&#xff0c;那么新的currentInterval的末尾这两个数组末尾的最大值&#xff0c;即…

std::vector<>.emplace_back

emplace_back() 详解&#xff1a;C 就地构造的效率革命 emplace_back() 是 C11 引入的容器成员函数&#xff0c;用于在容器尾部就地构造&#xff08;而非拷贝或移动&#xff09;元素。这一特性显著提升了复杂对象的插入效率&#xff0c;尤其适用于构造代价较高的类型。 一、核…

Dify实战案例《AI面试官》更新,支持语音交互+智能知识库+随机题库+敏感词过滤等...

大模型应用课又更新了&#xff0c;除了之前已经完结的两门课&#xff08;视频图文&#xff09;&#xff1a; 《Spring AI 从入门到精通》《LangChain4j 从入门到精通》 还有目前正在更新的 《Dify 从入门到实战》 本周也迎来了一大波内容更新&#xff0c;其中就包括今天要介绍…

AGI大模型(29):LangChain Model模型

1 LangChain支持的模型有三大类 大语言模型(LLM) ,也叫Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。聊天模型(Chat Model),主要代表Open AI的ChatGPT系列模型。这些模型通常由语言模型支持,但它们的API更加结构化。具体来说,这些模型将聊天消…

动态IP技术在跨境电商中的创新应用与战略价值解析

在全球化4.0时代&#xff0c;跨境电商正经历从"流量红利"向"技术红利"的深度转型。动态IP技术作为网络基础设施的关键组件&#xff0c;正在重塑跨境贸易的运营逻辑。本文将从技术架构、应用场景、创新实践三个维度&#xff0c;揭示动态IP如何成为跨境电商突…

android双屏之副屏待机显示图片

摘要&#xff1a;android原生有双屏的机制&#xff0c;但需要芯片厂商适配框架后在底层实现。本文在基于芯发8766已实现底层适配的基础上&#xff0c;仅针对上层Launcher部分对系统进行改造&#xff0c;从而实现在开机后副屏显示一张待机图片。 副屏布局 由于仅显示一张图片&…

STM32之中断

一、提高程序实时性的架构方案 轮询式 指的是在程序运行时&#xff0c;首先对所有的硬件进行初始化&#xff0c;然后在主程序中写一个死循环&#xff0c;需要运行的功能按照顺序进行执行&#xff0c;轮询系统是一种简单可靠的方式&#xff0c;一般适用于在只需要按照顺序执行…

LLM应用开发平台资料

课程和代码资料 放下面了&#xff0c;自取&#xff1a; https://pan.quark.cn/s/57a9d22d61e9

硬盘健康检测与性能测试的实践指南

在日常使用 Windows 系统的过程中&#xff0c;我们常常需要借助各种工具来优化性能、排查问题或管理文件。针对windows工具箱进行实测解析&#xff0c;发现它整合了多种实用功能&#xff0c;能够帮助用户更高效地管理计算机。 以下为测试发现的功能特性&#xff1a; 硬件信息查…

正则表达式进阶(三):递归模式与条件匹配的艺术

在正则表达式的高级应用中&#xff0c;递归模式和条件匹配是处理复杂嵌套结构和动态模式的利器。它们突破了传统正则表达式的线性匹配局限&#xff0c;能够应对嵌套括号、HTML标签、上下文依赖等复杂场景。本文将详细介绍递归模式&#xff08;(?>...)、 (?R) 等&#xff0…

从零开始创建React项目及制作页面

一、React 介绍 React 是一个由 Meta&#xff08;原Facebook&#xff09; 开发和维护的 开源JavaScript库&#xff0c;主要用于构建用户界面&#xff08;User Interface, UI&#xff09;。它是前端开发中最流行的工具之一&#xff0c;广泛应用于单页应用程序&#xff08;SPA&a…

【前端部署】通过 Nginx 让局域网用户访问你的纯前端应用

在日常前端开发中&#xff0c;我们常常需要快速将本地的应用展示给局域网内的同事或测试人员&#xff0c;而传统的共享方式往往效率不高。本文将指导你轻松地将你的纯前端应用&#xff08;无论是 Vue, React, Angular 或原生项目&#xff09;部署到本地&#xff0c;并配置局域网…

【Python装饰器深潜】从语法糖到元编程的艺术

目录 🌟 前言🏗️ 技术背景与价值🩹 当前技术痛点🛠️ 解决方案概述👥 目标读者说明🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选型对比🛠️ 二、实战演示⚙️ 环境配置要求💻 核心代码实现案例1:基础计时装饰器案…

mbed驱动st7789屏幕-硬件选择及连接(1)

目录 1.整体介绍 2. 硬件选择 2.1 mbed L432KC 2.2 ST7789 240*240 1.3寸 3. mbed与st7789的硬件连接 4. 总结 1.整体介绍 我们在使用单片机做一些项目的时候,交互性是最重要的因素。那么对于使用者而言,交互最直接的体现无非就是视觉感知,那么我们希望将项目通过视觉…

SpringBoot集成Jasypt对数据库连接密码进行加密、解密

引入依赖 <!--配置密码加密--><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.3</version></dependency><plugin><groupId>c…

分类器引导的条件生成模型

分类器引导的条件生成模型 分类器引导的条件生成模型1. **基本概念**2. **核心思想**3. **实现步骤&#xff08;以扩散模型为例&#xff09;**4. **优点**5. **挑战与注意事项**6. **应用场景**7. **数学推导**总结 分类器引导的条件生成模型 分类器引导的条件生成模型是一种通…

WPF中的ObjectDataProvider:用于数据绑定的数据源之一

ObjectDataProvider是WPF(Windows Presentation Foundation)中一种强大而灵活的数据绑定源&#xff0c;它允许我们将对象实例、方法结果甚至是构造函数的返回值用作数据源。通过本文&#xff0c;我将深入探讨ObjectDataProvider的工作原理、使用场景以及如何在实际应用中发挥其…

lasticsearch 报错 Document contains at least one immense term 的解决方案

一、问题背景 在使用 Elasticsearch 存储较大字段数据时&#xff0c;出现如下异常&#xff1a; ElasticsearchStatusException: Elasticsearch exception [typeillegal_argument_exception, reasonDocument contains at least one immense term in field"fieldZgbpka"…

[目标检测] YOLO系列算法讲解

前言 目标检测就是做到给模型输入一张图片或者视频&#xff0c;模型可以迅速判断出视频和图片里面感兴趣的目标所有的位置和它 的类别&#xff0c;而当前最热门的目标检测的模型也就是YOLO系列了。 YOLO系列的模型的提出&#xff0c;是为了解决当时目标检测的模型帧率太低而提…