当前位置: 首页 > news >正文

人工智能训练物理模拟器 MuJoCo入门教程 常用函数介绍及测试用例

一、MuJoCo 简介

MuJoCo(Multi-Joint dynamics with Contact)即多关节接触动力学,是一款免费开源的物理引擎,旨在助力机器人、生物力学、图形动画等领域的研究与开发。它将速度、精度和建模能力独特融合,专为基于模型的优化,尤其是通过接触进行的优化而设计。其具备以下关键特性:
广义坐标与现代接触动力学结合:融合机器人学、生物力学引擎在广义坐标上的高效递归算法,以及游戏引擎基于优化求解接触力的现代方法。
接触动力学处理:通过凸优化问题求解接触力,支持软接触、多种约束,能统一处理摩擦接触、关节限制等情况。
丰富的建模支持:可模拟肌腱几何结构、提供通用驱动模型、拥有可重构计算流水线,还支持模型编译以优化运行时计算。

二、安装环境

1 安装 Anaconda

从Anaconda 官方网站下载对应操作系统的安装包,按向导提示完成安装。

2 创建 Conda 环境

打开 Anaconda Prompt(Windows)或终端(Linux/Mac),执行以下命令创建新环境

conda create -n mujoco_env python=3.8

其中,mujoco_env为环境名,可自行修改;python=3.9指定 Python 版本。

3 激活环境

创建好环境后,执行以下命令激活:

conda activate mujoco_env
4 安装环境

在激活的 Conda 环境中,执行以下命令安装:

pip install mujoco numpy imageio glfw

三 常用函数简介

MuJoCo提供了丰富的API和函数,用于创建、模拟和可视化物理模型。以下是一些常用API和函数的介绍及用法:

模型加载与初始化
mujoco.MjModel.from_xml_path
  • 功能:从XML文件中加载MuJoCo模型。
  • 用法示例
# 从指定路径的XML文件加载模型
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
mujoco.MjData
  • 功能:创建一个与模型对应的MjData对象,用于存储模型在模拟过程中的各种数据,如关节位置、速度、力等。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
# 创建MjData对象
data = mujoco.MjData(model)
模拟控制
mujoco.mj_step
  • 功能:执行一次模拟步骤,更新模型的状态(如位置、速度等)。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 执行一次模拟步骤
mujoco.mj_step(model, data)
data.ctrl
  • 功能:用于设置模型的控制输入,例如关节的驱动力矩。
  • 用法示例
import numpy as np
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 设置控制输入,这里假设控制输入是一个长度为3的数组
control_input = np.array([1.0, 2.0, 3.0])
data.ctrl[:] = control_input
获取模型信息
data.qpos
  • 功能:获取模型中所有关节的位置(广义坐标)。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 获取关节位置
joint_positions = data.qpos
print(joint_positions)
data.qvel
  • 功能:获取模型中所有关节的速度(广义速度)。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 获取关节速度
joint_velocities = data.qvel
print(joint_velocities)
data.geom('geom_name').xpos
  • 功能:获取指定几何体的位置。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 获取名为'my_geom'的几何体的位置
geom_position = data.geom('my_geom').xpos
print(geom_position)
可视化相关
mujoco.MjvScene
  • 功能:创建一个用于存储要渲染的场景信息的对象。
  • 用法示例
import mujoco

model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 创建MjvScene对象
scene = mujoco.MjvScene(model, maxgeom=10000)
mujoco.mjv_updateScene
  • 功能:根据模型和数据的当前状态更新场景中的几何体、光照等信息。
  • 用法示例
import mujoco
import glfw
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)
scene = mujoco.MjvScene(model, maxgeom=10000)
opt = mujoco.MjvOption()
perturb = mujoco.MjvPerturb()
cam = mujoco.MjvCamera()
mujoco.mjv_defaultCamera(cam)

# 初始化GLFW并创建窗口等操作...

# 更新场景信息
mujoco.mjv_updateScene(model, data, opt, perturb, cam, mujoco.mjtCatBit.mjCAT_ALL, scene)
mujoco.mjr_render
  • 功能:将更新后的场景信息渲染到指定的视口区域。
  • 用法示例
import mujoco
import glfw

model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)
scene = mujoco.MjvScene(model, maxgeom=10000)
opt = mujoco.MjvOption()
perturb = mujoco.MjvPerturb()
cam = mujoco.MjvCamera()
mujoco.mjv_defaultCamera(cam)

# 初始化GLFW并创建窗口等操作...

viewport = mujoco.MjrRect(0, 0, 1200, 900)  # 假设视口大小为1200x900
context = mujoco.MjrContext(model, mujoco.mjtFontScale.mjFONTSCALE_150)

# 渲染场景
mujoco.mjr_render(viewport, scene, context)
传感器相关

data.sensordata

  • 功能:获取模型中所有传感器的数据。
  • 用法示例
model = mujoco.MjModel.from_xml_path('path/to/your/model.xml')
data = mujoco.MjData(model)

# 执行模拟步骤以更新传感器数据
mujoco.mj_step(model, data)

# 获取传感器数据
sensor_data = data.sensordata
print(sensor_data)

以上只是MuJoCo中一些常用API和函数的介绍,MuJoCo还有许多其他功能强大的API可以用于更复杂的模拟和分析任务。你可以参考MuJoCo官方文档以获取更详细的信息。

四 示例

1 创建模型配置文件

创xml文件:model1.xml

<mujoco>
    <worldbody>
        <!-- 机械臂底座 -->
        <body name="base" pos="0 0 0">
            <joint name="joint1" type="hinge" axis="0 1 0"/>
            <geom name="base_geom" type="cylinder" size="0.1 0.1"/>
            <body name="arm1" pos="0 0.1 0">
                <joint name="joint2" type="hinge" axis="0 1 0"/>
                <geom name="arm1_geom" type="cylinder" size="0.05 0.5"/>
                <body name="arm2" pos="0 0.5 0">
                    <joint name="joint3" type="hinge" axis="0 1 0"/>
                    <geom name="arm2_geom" type="cylinder" size="0.05 0.3"/>
                    <body name="end_effector" pos="0 0.3 0">
                        <geom name="ee_geom" type="sphere" size="0.05"/>
                    </body>
                </body>
            </body>
        </body>
        <!-- 小球 -->
        <body name="ball" pos="0.5 0 0.5">
            <geom name="ball_geom" type="sphere" size="0.03" rgba="1 0 0 1"/>
        </body>
    </worldbody>
    <actuator>
        <!-- 为每个关节添加一个执行器 -->
        <motor joint="joint1" ctrlrange="-1 1"/>
        <motor joint="joint2" ctrlrange="-1 1"/>
        <motor joint="joint3" ctrlrange="-1 1"/>
    </actuator>
</mujoco>
2 编写python脚本
# 导入 mujoco 库,用于进行物理模拟和模型加载等操作
import mujoco
# 导入 numpy 库,用于处理数值计算,例如数组操作等
import numpy as np
# 导入 glfw 库,用于创建窗口和处理图形渲染的上下文等
import glfw

# 加载模型,从指定的 XML 文件 'model1.xml' 中读取模型信息
model = mujoco.MjModel.from_xml_path('model1.xml')
# 创建与模型对应的 MjData 对象,用于存储模型在模拟过程中的各种数据
data = mujoco.MjData(model)

# 定义模拟的总时间,单位为秒
sim_time = 20.0
# 定义控制频率,即每秒进行控制计算的次数
control_freq = 100

# 计算控制周期,控制周期是控制频率的倒数,单位为秒
control_period = 1.0 / control_freq

# 定义目标位置,这是机械臂末端要到达的目标点,用三维数组表示
target_pos = np.array([0.5, 0, 0.5])

# 定义比例系数,用于计算控制力矩,在比例控制算法中使用
kp = 10.0

# 初始化 GLFW 库,GLFW 用于创建窗口和管理图形上下文
if not glfw.init():
    # 如果初始化失败,抛出异常并给出提示信息
    raise Exception("GLFW could not be initialized")

# 创建一个 GLFW 窗口,指定窗口的宽度为 1200 像素,高度为 900 像素,窗口标题为 "MuJoCo Simulation"
window = glfw.create_window(1200, 900, "MuJoCo Simulation", None, None)
if not window:
    # 如果窗口创建失败,终止 GLFW 并抛出异常给出提示信息
    glfw.terminate()
    raise Exception("GLFW window could not be created")

# 将当前的 OpenGL 上下文设置为刚刚创建的窗口的上下文
glfw.make_context_current(window)

# 创建一个 MjvScene 对象,用于存储要渲染的场景信息,maxgeom 参数指定场景中最大的几何体数量
scene = mujoco.MjvScene(model, maxgeom=10000)
# 创建一个 MjvPerturb 对象,用于处理场景中的扰动信息,例如外力等
perturb = mujoco.MjvPerturb()
# 创建一个 MjvOption 对象,用于设置场景渲染的各种选项
opt = mujoco.MjvOption()

# 创建一个 MjvCamera 对象,用于控制场景的视角
cam = mujoco.MjvCamera()
# 使用默认设置初始化相机对象
mujoco.mjv_defaultCamera(cam)

# 开始模拟循环,只要模拟时间未达到总时间且窗口没有被关闭,就继续循环
while data.time < sim_time and not glfw.window_should_close(window):
    # 计算机械臂末端当前位置与目标位置之间的误差,用向量表示
    error = target_pos - data.geom('ee_geom').xpos

    # 根据误差和比例系数计算控制力矩,这里使用简单的比例控制算法
    control_torque = kp * error

    # 将计算得到的控制力矩应用到模型的控制输入中,控制机械臂的运动
    data.ctrl[:] = control_torque

    # 在每个控制周期内,执行多次模拟步骤,确保模拟的精度
    for _ in range(int(control_period / model.opt.timestep)):
        # 执行一次模拟步骤,更新模型的状态
        mujoco.mj_step(model, data)

    # 获取当前窗口的帧缓冲区大小,即窗口的实际渲染区域大小
    viewport_width, viewport_height = glfw.get_framebuffer_size(window)
    # 创建一个 MjrRect 对象,用于定义渲染的视口区域,左上角坐标为 (0, 0),宽度和高度为窗口的大小
    viewport = mujoco.MjrRect(0, 0, viewport_width, viewport_height)

    # 更新场景信息,根据模型和数据的当前状态更新场景中的几何体、光照等信息
    mujoco.mjv_updateScene(model, data, opt, perturb, cam, mujoco.mjtCatBit.mjCAT_ALL, scene)

    # 创建一个 MjrContext 对象,用于管理渲染上下文,指定字体缩放比例
    context = mujoco.MjrContext(model, mujoco.mjtFontScale.mjFONTSCALE_150)

    # 渲染场景,将更新后的场景信息渲染到指定的视口区域
    mujoco.mjr_render(viewport, scene, context)

    # 交换前后缓冲区,将渲染好的图像显示到窗口上
    glfw.swap_buffers(window)
    # 处理窗口的事件,例如鼠标点击、键盘输入等
    glfw.poll_events()

    # 每 0.1 秒打印一次当前的模拟时间和机械臂末端的位置
    if data.time % 0.1 < 0.001:
        print(f'time: {data.time:.2f}, end effector pos: {data.geom("ee_geom").xpos}')

#模拟结束后,终止 GLFW 库,释放相关资源
glfw.terminate()

如果环境正确,即可看到下面的演示窗口和数据
请添加图片描述

相关文章:

  • 基于 DataEase 的企业数据分析实践
  • centos7操作系统下安装docker,及查看docker进程是否启动
  • 如何用 DeepSeek 和 ChatGPT 打造智能搜索与问答体验
  • 残差收缩模块
  • 大数据测试中,数据仓库表类型有哪些?
  • 深度学习中关于超参数的解释
  • vm+centos虚拟机
  • Kotlin中RxJava用法
  • SQL 中为什么参数多了not in 比 in 慢多了,怎么优化
  • JavaScript系列05-现代JavaScript新特性
  • .NET10 - 预览版1新功能体验(一)
  • Generalized Sparse Additive Model with Unknown Link Function
  • vue全局注册组件
  • Y3学习打卡
  • 【3-3】springcloud
  • 【每日学点HarmonyOS Next知识】网络请求回调toast问题、Popup问题、禁止弹窗返回、navigation折叠屏不显示返回键、响应式布局
  • Deepseek:物理神经网络PINN入门教程
  • element-push el-date-picker日期时间选择器,禁用可选中的时间 精确到分钟
  • OpenCV计算摄影学(11)色调映射算法类cv::TonemapDrago
  • 【量化策略】网格交易策略
  • 央行最新报告:积极落地5月推出的一揽子金融政策,促进经济供需平衡、物价合理回升
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元
  • 陕西永寿4岁女童被蜜蜂蜇伤致死,当地镇政府介入处理
  • 中国驻美国大使馆发言人就中美经贸高层会谈答记者问
  • 国铁集团:铁路五一假期运输收官,多项运输指标创历史新高
  • 驱逐行动再加码?特朗普或向利比亚和卢旺达遣送非法移民