URLab Bridge

URLab Bridge 是同一 GitHub 组织下的独立配套仓库(urlab_bridge)。它在外部系统和 URLab 的 MuJoCo 仿真之间提供 Python 侧的中间件,通过 ZMQ 进行通信,用于强化学习策略部署、远程遥操作、数据记录、传感器监控和自定义控制流程。

功能

  • 双向 ZMQ 通信:从 Unreal 接收关节状态、传感器数据、基座状态和相机图像;向 Unreal 发送执行器指令和 PD 增益
  • 远程控制:从 Python 脚本、Jupyter notebook、ROS 2 节点或任何支持 ZMQ 的系统驱动机器人
  • 策略部署:针对 Unreal 仿真运行预训练的强化学习策略(运动、动作模仿、四足步态)
  • 传感器监控:实时仪表盘(DearPyGui),用于可视化关节状态、传感器读数和相机画面
  • 自动处理关节发现、关节映射和执行器 ID 解析
  • 提供用于身体位置计算的正向运动学
  • 面向多关节机构场景的前缀式消息过滤机制
  • 同时支持位置目标(适用于位置执行器)与力矩目标(适用于运动 + PD 控制)。

架构

┌─────────────────────────────────┐     ZMQ      ┌──────────────────┐
│  Python (URLab Bridge)          │◄────────────►│  Unreal (URLab)  │
│                                 │              │                  │
│  Your Control System            │  joint state │  MuJoCo physics  │
│    ├─ RL Policy (RoboJuDo)      │◄─────────────│  ZMQ Broadcaster │
│    ├─ Custom Controller         │              │                  │
│    └─ Teleoperation             │  ctrl targets│  ZMQ Subscriber  │
│                                 │─────────────►│  → d->ctrl       │
└─────────────────────────────────┘              └──────────────────┘         

安装

该桥接模块是一个独立的代码仓库—— https://github.com/URLab-Sim/urlab_bridge 。您可以将其克隆到任何位置;它无需与 URLab 插件放在同一仓库中。它使用 uv 进行 Python 环境管理;需要 Python 3.11 或更高版本。

git clone https://github.com/URLab-Sim/urlab_bridge.git
cd urlab_bridge

最低安装要求(核心仪表盘 + ZMQ — 无策略):

uv sync

这会创建一个 .venv/ 目录,强制 Python 版本为 3.11 或更高,并安装 pyzmqnumpyopencv-pythondearpygui

为了支持强化学习策略(添加 torchonnxruntimemujoco 等):

uv sync --extra policy
uv pip install -e ./RoboJuDo

如果 RoboJuDo 安装卡住(这是 uv/setuptools 动态依赖解析方面的一个已知问题),请使用 --no-deps,因为它所需的一切都已包含在策略policy附加文件中,然后添加它特有的两个依赖项:

uv pip install --no-deps -e ./RoboJuDo
uv pip install pygame pynput

依赖 PHC 的策略还需要:

cd RoboJuDo && git submodule update --init --recursive

ZMQ 协议

有关 ZMQ 协议的详细信息、主题格式和消息结构,请参阅 ZMQ 网络文档。(zmq_networking.md).

直接使用 Bridge

无需 RoboJuDo 的自定义控制器示例:

from urlab_policy.unreal_env import ZmqLink
import struct, time, numpy as np

zmq = ZmqLink("tcp://127.0.0.1:5555", "tcp://127.0.0.1:5556")
time.sleep(1)  # 等待连接

# 读取状态
messages = zmq.drain()
for topic, payload in messages.items():
    if "/joint/" in topic and len(payload) == 16:
        jid, pos, vel, acc = struct.unpack("<Ifff", payload)
        print(f"Joint {jid}: pos={pos:.3f}")

# 发送控制 (12 执行器,全部归零)
targets = np.zeros(12)
zmq.send_control("my_robot_prefix", targets)

zmq.close()

RoboJuDo 集成

为了运行预训练的 RL 策略,该 bridge 将RoboJuDo封装为策略运行时。

GUI(图形界面):

.venv\Scripts\activate
$env:PYTHONPATH = "src"
python src\urlab_policy\policy_gui.py

CLI(命令行):

python src/run.py --policy unitree --prefix g1

可用策略在policy_registry.py中注册。每个条目定义了策略配置类、环境配置、自由度数量和控制器类型。

Go2 Walk-These-Ways 策略

12 自由度的四足策略,支持步态调节。提供预设步态:Trot(小跑)、Pronk(跳跃)、Bound(弹跳)和 Pace(侧对步)。需要下载检查点文件(详见文件 RoboJuDo/checkpoints/ README).

运动执行器 vs 位置执行器

方式 MJCF 执行器 控制信号 PD 位置
Position <position kp="100" kv="5"> 位置目标(弧度) MuJoCo 内部
Motor + PD <motor forcerange="-88 88"> 位置目标(弧度 ) C++ UMjPDController

位置执行器更简单、更稳定。运动+PD 方式与训练动力学完全匹配,但需要配置增益。使用 GUI 中的复选框进行切换。

配置

env_config.py中的关键设置:

字段 默认值 必须匹配
sim_dt 0.002 Unreal 管理器时间步长
sim_decimation 10 策略频率 = 1/(sim_dt * decimation)
state_endpoint tcp://127.0.0.1:5555 ZmqSensorBroadcaster 端点 (PUB)
control_endpoint tcp://127.0.0.1:5556 ZmqControlSubscriber 端点 (SUB)

所有套接字在虚幻引擎端进行绑定,Python 桥接端负责连接。话题格式与端口分配详见ZMQ Networking

强制速度覆盖

策略 GUI 提供了强制速度覆盖功能,允许您直接发送手动速度指令(vx, vy, yaw_rate),绕过键盘操作输入。适用于脚本化运动或在 Unreal 中无需操作铰链即可进行测试。

多铰链场景

ZMQ 话题采用前缀匹配过滤机制(如<prefix>/joint/..., <prefix>/control,等)。在多铰链设备场景中,每个设备均以自身专属前缀进行消息的发布与订阅;Python 端会根据该前缀对接收的消息进行过滤,将状态数据路由至对应的策略实例。

网格处理

在导入之前,使用 Scripts/clean_meshes.py 将网格转换为 GLB 格式并解决文件名冲突。

调试工具

脚本 用途
zmq_visualizer_gui.py 独立的 ZMQ 状态查看器,带滑块
policy_gui.py 完整的策略运行器,带可视化
test_native_mujoco.py 在原生 MuJoCo 查看器中运行策略(真实情况对比)
test_compare_targets.py 记录原生与 Unreal 的目标值以便比较