机器人
返回首页

MuJoCo键盘控制球体移动教程:实时记录位姿附代码

2026-03-27 来源:EEWorld 论坛

MuJoCo键盘控制球体移动教程:实时记录位姿附代码

本文将介绍如何在MuJoCo仿真环境中添加一个球体,并通过键盘方向键控制其x、y、z方向移动,同时实时记录球体的位置和姿态。教程包含完整的XML场景描述和Python代码实现,适合初学者学习MuJoCo基础操作和交互控制。

一、场景设置:XML描述

首先,创建一个MuJoCo XML文件,定义场景中的地面和球体。球体通过自由关节(freejoint)连接,允许在三维空间中自由移动。以下为XML代码:

<mujoco>
  <visual>
    <headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0"/>
    <rgba haze="0.15 0.25 0.35 1"/>
    <global azimuth="140" elevation="-30"/>
  </visual>

  <asset>
    <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
    <texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3"
      markrgb="0.8 0.8 0.8" width="300" height="300"/>
    <material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
  </asset>

  <worldbody>
    <geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
    
    <body name="ball" pos="0 0 1">
      <freejoint name="free_joint"/>
      <geom type="sphere" size="0.2" rgba="1 0 0 1" mass="1"/>
    </body>
  </worldbody>
</mujoco>

该代码创建了一个带纹理的地面和一个红色球体,初始位置在(0,0,1)。

二、键盘控制:使用pynput库

通过Python的pynput库监听键盘事件,实现上下左右方向键控制球体x、y移动,Alt左键和Alt右键控制z移动。代码如下:

from pynput import keyboard

key_states = {
    keyboard.Key.up: False,
    keyboard.Key.down: False,
    keyboard.Key.left: False,
    keyboard.Key.right: False,
    keyboard.Key.alt_l: False,
    keyboard.Key.alt_r: False,
}

def on_press(key):
    if key in key_states:
        key_states[key] = True

def on_release(key):
    if key in key_states:
        key_states[key] = False

listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()

三、完整代码:整合MuJoCo仿真与键盘控制

将XML场景和键盘控制结合,使用MuJoCo的Python接口进行仿真循环。在循环中,根据按键状态更新球体位置,并打印实时位姿。注意,需要关闭重力以防止球体下落。完整代码如下:

import mujoco
import mujoco.viewer
import numpy as np
from pynput import keyboard

key_states = {
    keyboard.Key.up: False,
    keyboard.Key.down: False,
    keyboard.Key.left: False,
    keyboard.Key.right: False,
    keyboard.Key.alt_l: False,
    keyboard.Key.alt_r: False,
}

def on_press(key):
    if key in key_states:
        key_states[key] = True

def on_release(key):
    if key in key_states:
        key_states[key] = False

listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()

XML = """
<mujoco>
  <visual>
    <headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0"/>
    <rgba haze="0.15 0.25 0.35 1"/>
    <global azimuth="140" elevation="-30"/>
  </visual>

  <asset>
    <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
    <texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3"
      markrgb="0.8 0.8 0.8" width="300" height="300"/>
    <material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
  </asset>

  <worldbody>
    <geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
    
    <body name="ball" pos="0 0 1">
      <freejoint name="free_joint"/>
      <geom type="sphere" size="0.2" rgba="1 0 0 1" mass="1"/>
    </body>
  </worldbody>
</mujoco>
"""

model = mujoco.MjModel.from_xml_string(XML)
model.opt.gravity = (0, 0, 0)
data = mujoco.MjData(model)

class CustomViewer:
    def __init__(self, model, data):
        self.handle = mujoco.viewer.launch_passive(model, data)
        self.pos = 0.0001

    def is_running(self):
        return self.handle.is_running()

    def sync(self):
        self.handle.sync()

    @property
    def cam(self):
        return self.handle.cam

    @property
    def viewport(self):
        return self.handle.viewport
    
    def run_loop(self):
        while self.is_running():
            ball_body_name = "ball"
            pos = data.body(ball_body_name).xpos
            quat = data.body(ball_body_name).xquat
            print(f"Position: {pos}, Orientation: {quat}")

            if key_states[keyboard.Key.up]:
                data.qpos[0] += self.pos
            if key_states[keyboard.Key.down]:
                data.qpos[0] -= self.pos
            if key_states[keyboard.Key.left]:
                data.qpos[1] += self.pos
            if key_states[keyboard.Key.right]:
                data.qpos[1] -= self.pos
            if key_states[keyboard.Key.alt_l]:
                data.qpos[2] += self.pos
            if key_states[keyboard.Key.alt_r]:
                data.qpos[2] -= self.pos

            mujoco.mj_step(model, data)
            self.sync()


viewer = CustomViewer(model, data)
viewer.cam.distance = 3
viewer.cam.azimuth = 0
viewer.cam.elevation = -30
viewer.run_loop()

四、常见问题:为什么Alt R无法控制z方向运动?

在默认情况下,MuJoCo开启重力(z轴方向),球体会自然下落。要解决此问题,需将重力设置为零,代码中添加:model.opt.gravity = (0, 0, 0)。这样,键盘控制即可在z轴生效。

五、总结

本教程演示了MuJoCo中球体的创建、键盘交互控制和位姿实时记录。通过此基础示例,可扩展用于机器人仿真、运动控制等场景。如需查看原帖详细内容(含视频和图片),请访问:MuJoCo 可视化键盘控制球体及位姿实时记录,附代码!

原帖子内容来源:https://bbs.eeworld.com.cn/thread-1310774-1-1.html



进入机器人查看更多内容>>
相关视频
  • 直播回放: 如何使用MPLAB® Mindi™软件进行模拟电路仿真

  • 直播回放: 开启 SDV 的未来:集成 TI 的远程控制边缘节点解决方案

  • 直播回放: 2026 是德科技XR8新品发布: 一段跨越70年的示波器创新之旅

  • 直播回放: 使用RUHMI模型转换器部署BYOM模型并进行MINST模型部署

  • 直播回放: 使用Reality AI Tools 基于数据创建微小型AI模型以及进行拉弧检测开发实践

  • 直播回放: MPS 赋能人形机器人 - 因为没有运动,机器人只是一尊雕塑

精选电路图
  • 设计汽车集群电源

  • 6晶体管H桥

  • USB自供电声卡

  • AVR LCD温度计—LM35

  • AVR PC步进电机驱动器

  • AVR温度计TCN75

    相关电子头条文章