Sim-to-Real 迁移
3we 平台的核心目标之一是使 sim-to-real 迁移可靠且可量化。本指南介绍了噪声模型、域随机化,以及在将策略部署到硬件之前应通过的五项验证测试。
3we 仿真器并非像素级精确的数字孪生。相反,它经过校准,使得在仿真中训练的策略部署到真实机器人时能达到仿真性能的至少 85%。我们通过以下方式实现这一目标:
- 从硬件录制数据校准的真实传感器噪声模型
- 对物理参数进行域随机化
- 一套标准化的迁移验证测试
仿真器注入噪声以匹配真实世界的传感器特性:
| 传感器 | 噪声类型 | 参数 |
|---|---|---|
| LiDAR | 高斯距离噪声 | sigma = 0.01 m |
| LiDAR | 随机丢点 | 每次扫描 2% 的射线 |
| IMU(加速度计) | 白噪声 + 偏置 | sigma = 0.02 m/s^2,偏置漂移 = 0.001 m/s^2/s |
| IMU(陀螺仪) | 白噪声 + 偏置 | sigma = 0.005 rad/s,偏置漂移 = 0.0001 rad/s/s |
| 相机 | 高斯像素噪声 | sigma = 3.0(每通道,uint8) |
| 里程计 | 滑移模型 | 每步 5% 随机车轮滑移 |
| 电机响应 | 一阶滞后 | tau = 50 ms |
在环境中启用或禁用噪声:
env = gym.make("3we/Navigation-v1", sensor_noise=True)SensorNoiseModel
Section titled “SensorNoiseModel”SDK 提供了一个可配置的 SensorNoiseModel,您可以根据自己的具体硬件进行调优:
from threewe.sim.noise import SensorNoiseModel
noise = SensorNoiseModel( lidar_gaussian_stddev=0.02, # 2cm noise on LiDAR imu_accel_stddev=0.01, # m/s^2 imu_gyro_stddev=0.005, # rad/s camera_gaussian_stddev=5.0, # pixel intensity noise odometry_slip_factor=0.05, # 5% wheel slip)在训练过程中,随机化这些参数以构建鲁棒的策略:
from threewe.sim.domain_randomization import DomainRandomization
dr = DomainRandomization()params = dr.sample()# {# "mass_scale": 1.05, # 0.9-1.1x robot mass# "friction_scale": 0.92, # 0.8-1.2x floor friction# "motor_torque_noise": 0.02, # Gaussian noise on motor output# "gravity_noise": -0.003, # Slight gravity variation# "lighting_intensity": 1.2, # 0.5-1.5x scene lighting# "color_jitter": 0.05, # Random color shift# "lidar_noise_scale": 1.3, # 0.5-2.0x LiDAR noise# "imu_noise_scale": 0.8, # 0.5-2.0x IMU noise# "camera_noise_scale": 1.1, # 0.5-2.0x camera noise# "odometry_slip_scale": 1.4, # 0.5-2.0x wheel slip# }物理随机化:
- 质量缩放(0.9x 到 1.1x)— 考虑载荷变化
- 摩擦缩放(0.8x 到 1.2x)— 不同地面表面
- 电机扭矩噪声 — 执行器不精确性
- 重力噪声 — 传感器安装角度变化
视觉随机化:
- 光照强度(0.5x 到 1.5x)— 不同时间段
- 纹理随机化 — 不同的墙壁/地板外观
- 阴影随机化 — 不同光源位置
- 颜色抖动 — 相机白平衡变化
传感器随机化:
- LiDAR 噪声缩放 — 考虑真实世界反射率变化
- IMU 噪声缩放 — 温度漂移、振动效应
- 相机噪声缩放 — 不同照明质量
- 里程计滑移缩放 — 车轮与地面接触变化
在 Gymnasium 环境中使用域随机化
Section titled “在 Gymnasium 环境中使用域随机化”import gymnasium as gymfrom threewe.sim.domain_randomization import DomainRandomization
dr = DomainRandomization(seed=42)env = gym.make("3we/Navigation-v1")
for episode in range(1000): params = dr.sample() obs, info = env.reset(options={"domain_randomization": params}) done = False while not done: action = policy(obs) obs, reward, terminated, truncated, info = env.step(action) done = terminated or truncated自定义随机化配置
Section titled “自定义随机化配置”创建 YAML 文件来自定义范围:
physics: mass_scale_range: [0.85, 1.15] friction_scale_range: [0.7, 1.3] motor_torque_noise_stddev: 0.08
visual: randomize_textures: true randomize_lighting: true lighting_intensity_range: [0.3, 1.8] color_jitter: 0.15
sensor: lidar_noise_scale_range: [0.3, 2.5] imu_noise_scale_range: [0.5, 2.0] camera_noise_scale_range: [0.5, 2.5] odometry_slip_scale_range: [0.5, 2.5]五项验证测试
Section titled “五项验证测试”在部署到硬件之前,运行迁移验证套件。SDK 包含一个正式的验证协议,具有 5 项标准迁移测试:
| 测试 | 指标 | 通过条件 | 描述 |
|---|---|---|---|
straight_walk_5m | 终点误差 (m) | real < sim x 2.0 | 前行 5m,测量位置误差 |
rotation_360 | 角度误差 (deg) | real < 1.0(绝对值) | 旋转 360 度,测量最终航向误差 |
obstacle_avoidance_3 | 成功率 | real > sim x 0.7 | 绕过 3 个障碍物导航 |
pointnav_10m | SPL | real > sim x 0.6 | 导航 10m,计算最优路径比率 |
dynamic_obstacle | 碰撞率 | real < sim x 1.5 | 在移动障碍物中导航 |
# Sim-only validation (CI-friendly, no hardware needed)threewe test sim2real --backend gazebo --scene office_v2
# Full sim2real comparison (requires hardware)threewe sim2real report --backend gazebo --scene office_v2 --trials 5import asynciofrom threewe.benchmark.sim2real import Sim2RealValidator
async def validate(): validator = Sim2RealValidator()
report = await validator.validate( sim_backend="gazebo", real_backend="real", num_trials=5, )
print(f"Overall: {'PASS' if report.overall_passed else 'FAIL'}") print(f"Pass rate: {report.pass_rate:.0%}")
for result in report.results: status = "PASS" if result.passed else "FAIL" print(f" [{status}] {result.test_name}: " f"sim={result.sim_value:.3f}, " f"real={result.real_value:.3f}, " f"ratio={result.transfer_ratio:.2f}")
asyncio.run(validate())在仿真和真实环境中分别运行测试后,计算迁移比率:
transfer_ratio = real_score / sim_score成功率的迁移比率高于 0.85 表明您的策略非常适合部署。比率在 0.6 到 0.85 之间可在监控下进行初步部署。比率低于 0.6 则表明需要额外的域随机化或在真实数据上进行微调。
改善迁移的建议
Section titled “改善迁移的建议”- 从训练一开始就启用域随机化,而非作为微调步骤。
- 使用动作平滑包装器(
threewe.wrappers.ActionSmoothing)来避免在真实硬件上会放大的抖动动作。 - 收集 10 分钟的真实世界驾驶数据,将传感器分布与仿真进行比较。如果偏差显著,则调整噪声参数。
- 初始迁移时优先使用 LiDAR 而非相机输入的策略 — LiDAR 的 sim-to-real 差距更小。
- 校准的电机模型使用从实际 JGA25-370 电机测量的响应曲线(150ms 上升时间,稳态精度在 5% 以内)。