Mujoco使用记录
Mujoco python Cpp踩坑全记录
适用于Mujoco 3.2 及以上版本
简介
mujoco是一个物理仿真引擎,用于模拟机器人、物体等的运动。
其支持C++、Python等多种语言,并支持Unity plugin、ROS等平台。
支持并行计算,支持多线程,速度十分可观。
提供了高度的自定义性,可以通过xml文件定义模型、场景等。提供丰富的sensor、actuator等。
人称小blender(bushi)
缺点: 仅为仿真引擎,如果需要pid控制等功能需要自己实现
安装
使用
mujoco
用于控制整体环境,包括模型、数据、渲染器等。
1
2
3
4
import mujoco as mj
mj.mj_resetData(model, data) # 重置数据
mj.mj_defaultCamera(camera) # 设置默认相机
重要的类
MjModel
模型类,包含了模型(或模型的集合)所需的所有数据,如质量、惯性、几何形状、关节、约束等。
- 初始化
MjModel结构体 Cpp源码: MjModel source: https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h#L588 注意:其Cpp中的成员是可在Python中直接访问的,如
model.ngeom
,model.geom(0)
等。
由于MjModel
类是一个C++类,使用bindings库生成的Python类,因此无法直接使用MjModel()
来创建对象。
1
2
3
4
5
import mujoco
model = mujoco.MjModel.from_xml_path("path/to/xml") # 从xml路径加载模型
model = mujoco.MjModel.from_xml_string(xml_string) # 从xml字符串加载模型
- 获取信息
1
2
3
4
5
6
model.ngeom # 几何体数量
model.geom(0) # 获取第一个几何体
model.geom("geom_name") # 获取名为"geom_name"的几何体
model.geom(0).pos # 获取第一个几何体的位置
- 修改环境参数
具体可以参考MjModel的Cpp源码
1
2
3
4
5
6
7
8
model.opt # 修改相关物理参数 struct mjOption_: https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h#L431
model.opt.gravity = [0, 0, -9.81] # 修改重力
model.opt.timestep = 0.01 # 修改时间步长
model.opt.wind = [0, 0, 0] # 修改风力
model.opt.density = 1.225 # 修改空气密度
model.vis # 修改可视化参数 struct mjVisual_: https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h#L478
model.vis.scale.forcewidth = 0.1 # 修改力的宽度
MjData
MjData结构体 Cpp源码
数据类,包含模拟过程中的状态(位置、速度、加速度等)和控制(关节力、关节位置等)。
- 初始化
1
data = mujoco.MjData(model) # 从模型创建数据
- 获取状态
1
2
3
4
5
6
7
8
9
data.qpos # 位置
data.qvel # 速度
data.time # 时间
data.sensordata # 传感器数据
data.geom_xpos # 所有几何体的位置
# 同时也支持类似于`model.geom(0)`的访问方式:
data.geom("geoname").xpos # 获取名为"geoname"的几何体的位置
data.geom(0).xpos # 获取第一个几何体的位置
- 控制
1
2
3
4
5
6
data.ctrl # 控制, 例如data.ctrl[0]表示第一个关节的控制力
data.ctrl = [1, 2, 3, 4] # 设置控制力, 例如四旋翼的四个电机
data.qfrc_applied # 施加generalized force, 例如data.qfrc_applied[0]表示施加到第一个关节的力
data.qfrc_applied[0] = 1 # 施加笛卡尔力
data.eq_active # 约束是否激活
Renderer
- 初始化
1
renderer = mujoco.Renderer(model, height=480, width=640) # 从模型创建渲染器
- 渲染
1
2
3
4
5
6
7
8
with mujoco.Renderer(model) as renderer:
mujoco.mj_forward(model, data) # 更新数据, 注意需要手动更新时间 model.time 或者使用model.mj_step()
renderer.update_scene(data, camera, vis_option) # 更新场景
# 注意: camera可以为序号(int),也可以为MjCamera对象,也可以是相机名(str)
# 相机可以是通过MjvCamera()创建的对象,也可以XML里定义的相机名
img = renderer.render() # 返回一个numpy数组
MjvOption & MjCamera
MjvOption
类用于设置可视化参数,MjCamera
类用于设置相机参数。
1
2
3
4
5
6
vis_option = mujoco.MjvOption()
vis_option.flags[mujoco.mjtVisFlag.mjVIS_JOINT] = True # 显示关节
camera = mujoco.MjCamera() # 创建相机
mujoco.mjv_defaultFreeCamera(model, camera) # 设置默认相机
camera.distance = 1 # 设置相机距离
MjCamera
用于创建相机并设置相机参数
1
2
3
4
5
6
7
camera = mujoco.MjvCamera() # 创建相机
mujoco.mjv_defaultCamera(camera) # 设置为默认相机
camera.distance = 1 # 设置相机距离
camera.azimuth = 0 # 设置方位角
camera.elevation = 0 # 设置仰角
camera.lookat = [x, y, z] # 设置始终看向[x, y, z]
MjSpec
可以用于修改model
关于修改场景
Mujoco 使用xml文件定义并修改场景
示例可以参考这里
坑
- 使用pybinging11使用Cpp接口时,参数的传入为引用!!!,如
MjData
中的参数都为引用,要十分注意,建议使用deepcopy使用。
本文由作者按照 CC BY 4.0 进行授权