OpenDuckMini强化学习框架入门教程-传感器配置
纠错,疑问,交流: 请进入讨论区或 请点击进入页面,扫码加入微信群或Q群进行交流
获取最新文章: 扫一扫加入“创客智造”公众号
欢迎加入我们的openduckmini交流群,微信扫描右侧二维码立即进群交流
传感器配置
- 理解传感器及配置,包含传感器配置文件,传感器分类,传感器使用,传感器噪声模拟,接触检测和传感器在常量中的定义等
概述
Open Duck Mini V2 在 MJCF 模型中定义了丰富的传感器系统,用于在仿真中获取机器人的状态信息。这些传感器模拟了真实机器人上可用的传感器(如 IMU),并额外提供了一些仿真专用的"特权"观测。
传感器配置文件
传感器定义在 xmls/sensors.xml 中,通过 XML 的 include 机制合并到主模型:
<sensor>
<!-- IMU 传感器 -->
<gyro site="imu" name="gyro"/>
<velocimeter site="imu" name="local_linvel"/>
<accelerometer site="imu" name="accelerometer"/>
<framezaxis objtype="site" objname="imu" name="upvector"/>
<framexaxis objtype="site" objname="imu" name="forwardvector"/>
<framelinvel objtype="site" objname="imu" name="global_linvel"/>
<frameangvel objtype="site" objname="imu" name="global_angvel"/>
<framepos objtype="site" objname="imu" name="position"/>
<framequat objtype="site" objname="imu" name="orientation"/>
<!-- 足部传感器 -->
<framelinvel objtype="site" objname="right_foot" name="right_foot_global_linvel"/>
<framelinvel objtype="site" objname="left_foot" name="left_foot_global_linvel"/>
<framexaxis objtype="site" objname="left_foot" name="left_foot_upvector"/>
<framexaxis objtype="site" objname="right_foot" name="right_foot_upvector"/>
<framepos objtype="site" objname="left_foot" name="left_foot_pos"/>
<framepos objtype="site" objname="right_foot" name="right_foot_pos"/>
</sensor>
传感器分类
IMU 传感器(躯干安装)
这些传感器模拟真实机器人上的 BNO055 惯性测量单元:
| 传感器名称 | 类型 | IMU site | 维度 | 说明 |
|---|---|---|---|---|
gyro |
gyro |
imu | 3 | 角速度 (rad/s) |
local_linvel |
velocimeter |
imu | 3 | 局部线速度 (m/s) |
accelerometer |
accelerometer |
imu | 3 | 加速度 (m/s²) |
upvector |
framexaxis |
imu | 3 | 重力方向(躯干 Z 轴在世界帧的投影) |
forwardvector |
framexaxis |
imu | 3 | 前进方向 |
global_linvel |
framelinvel |
imu | 3 | 世界帧线速度 |
global_angvel |
frameangvel |
imu | 3 | 世界帧角速度 |
position |
framepos |
imu | 3 | IMU 位置 |
orientation |
framequat |
imu | 4 | IMU 姿态四元数 |
IMU 位置
IMU 位于躯干的前部:
<site name="imu" pos="-0.08 -0.0 0.05"/>
相对于躯干中心前移 8cm,这模拟了 BNO055 在 Open Duck Mini V2 上的实际安装位置。
足部传感器
每只脚上安装的传感器,用于步态分析和接触检测:
| 传感器名称 | 类型 | 位置 | 维度 |
|---|---|---|---|
left_foot_global_linvel |
framelinvel |
左足 | 3 |
right_foot_global_linvel |
framelinvel |
右足 | 3 |
left_foot_upvector |
framexaxis |
左足 | 3 |
right_foot_upvector |
framexaxis |
右足 | 3 |
left_foot_pos |
framepos |
左足 | 3 |
right_foot_pos |
framepos |
右足 | 3 |
足部 site 定义:
<site group="0" name="left_foot" pos="0.0005 -0.036225 0.01955"
quat="0.707107 -0.707107 -0 1.72494e-18"/>
<site group="0" name="right_foot" pos="0.0005 -0.036225 0.01955"
quat="0.707107 -0.707107 -0 1.26645e-25"/>
传感器使用(代码层面)
训练环境中的传感器访问
训练环境(base.py)通过 mjx_env.get_sensor_data() 函数访问传感器:
def get_gravity(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.GRAVITY_SENSOR)
def get_global_linvel(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.GLOBAL_LINVEL_SENSOR)
def get_global_angvel(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.GLOBAL_ANGVEL_SENSOR)
def get_local_linvel(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.LOCAL_LINVEL_SENSOR)
def get_accelerometer(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.ACCELEROMETER_SENSOR)
def get_gyro(self, data):
return mjx_env.get_sensor_data(self.mj_model, data, constants.GYRO_SENSOR)
def get_feet_pos(self, data):
return jp.vstack([
mjx_env.get_sensor_data(self.mj_model, data, sensor_name)
for sensor_name in constants.FEET_POS_SENSOR
])
推理环境中的传感器访问
推理环境(mujoco_infer_base.py)通过传感器数据地址直接访问:
# 初始化时预计算传感器地址
self.gyro_id = mujoco.mj_name2id(model, mjOBJ_SENSOR, "gyro")
self.gyro_addr = model.sensor_adr[self.gyro_id]
self.accelerometer_id = mujoco.mj_name2id(model, mjOBJ_SENSOR, "accelerometer")
self.accelerometer_addr = model.sensor_adr[self.accelerometer_id]
# 运行时通过地址直接读取
def get_gyro(self, data):
return data.sensordata[self.gyro_addr:self.gyro_addr + 3]
def get_accelerometer(self, data):
return data.sensordata[self.accelerometer_addr:self.accelerometer_addr + 3]
传感器噪声模拟
训练过程中,传感器读数会添加模拟噪声以提高策略的鲁棒性:
| 传感器 | 噪声标准差 | 说明 |
|---|---|---|
| 陀螺仪 | 0.1 × 噪声等级 | 模拟 IMU 角速度噪声 |
| 加速度计 | 0.05 × 噪声等级 | 模拟 IMU 加速度噪声 |
| 重力向量 | 0.1 × 噪声等级 | 姿态估计噪声 |
| 关节角度 | 位置相关:髋 0.03, 膝 0.05, 踝 0.08 | 模拟编码器量化误差 |
| 关节速度 | 2.5 × 噪声等级 | 速度估计噪声 |
噪声实现方式:
noisy_gyro = gyro + (2 * uniform() - 1) * noise_level * gyro_scale
接触检测
接触检测不是通过 MJCF 传感器定义的,而是通过碰撞检测实现:
from mujoco_playground._src.collision import geoms_colliding
contact = jp.array([
geoms_colliding(data, foot_geom_id, floor_geom_id)
for foot_geom_id in self._feet_geom_id
])
接触几何体通过 constants.py 配置:
LEFT_FEET_GEOMS = ["left_foot_bottom_tpu"]
RIGHT_FEET_GEOMS = ["right_foot_bottom_tpu"]
FEET_GEOMS = LEFT_FEET_GEOMS + RIGHT_FEET_GEOMS
传感器在常量中的定义
constants.py 定义了传感器名称常量,便于引用:
GRAVITY_SENSOR = "upvector"
GLOBAL_LINVEL_SENSOR = "global_linvel"
GLOBAL_ANGVEL_SENSOR = "global_angvel"
LOCAL_LINVEL_SENSOR = "local_linvel"
ACCELEROMETER_SENSOR = "accelerometer"
GYRO_SENSOR = "gyro"
FEET_POS_SENSOR = ["left_foot_pos", "right_foot_pos"]
纠错,疑问,交流: 请进入讨论区或 请点击进入页面,扫码加入微信群或Q群进行交流
获取最新文章: 扫一扫加入“创客智造”公众号
欢迎加入我们的openduckmini交流群,微信扫描右侧二维码立即进群交流


















