主页 > IT业界  > 

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

人工智能训练物理模拟器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()

如果环境正确,即可看到下面的演示窗口和数据

标签:

人工智能训练物理模拟器MuJoCo入门教程常用函数介绍及测试用例由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“人工智能训练物理模拟器MuJoCo入门教程常用函数介绍及测试用例