摘要

在将强化学习策略部署到真实机器人硬件的过程中,仿真与现实之间的差距(sim-to-real gap)是制约迁移效果的核心瓶颈之一。其中,执行器(关节电机)的非线性动力学特性——包括摩擦、延迟、弹性形变,齿间间隙等是仿真模型最难精确刻画的部分。本文介绍了一套面向双足人形机器人的执行器网络(Actuator Network)真机系统辨识与数据采集流程,旨在通过采集真实关节响应数据,训练一个神经网络来替代传统的理想化执行器模型,从而在仿真中更真实地还原电机行为,缩小 sim-to-real gap。

注: 本篇 blog 持续更新中。当前方法的可靠性尚未经过充分验证,部分结论可能随实验推进而修正或完善,仅供参考。


一、背景与动机

1.1 Sim-to-Real Gap 问题

基于强化学习的运动控制策略通常在仿真环境(如 MuJoCo、Isaac Gym)中训练,然后直接迁移到真实机器人上。然而,仿真器默认使用的执行器模型过于理想化:

  • 无延迟:命令立刻生效,而真实电机控制环有通信延迟和计算延迟(通常 1-3 个控制周期)。
  • 无摩擦:仿真关节不考虑齿轮摩擦、轴承摩擦,而真实电机的摩擦力矩非线性且依赖速度方向。
  • 线性力矩-位置关系:仿真中 PD 控制器输出扭矩 ,但真实电机受饱和、温升、反电动势等影响,这一关系并不线性。

这些差异导致策略在真机上表现可能并不稳定,尤其是面对复杂的任务时。

1.2 Actuator Network 方案

解决思路是用神经网络来学习真实执行器的动力学模型。训练好的 Actuator Network 在仿真中替代简单 PD 控制器,使仿真行为更接近真实机器人,从而提升策略迁移成功率。

Actuator Network 的基本形式为:

其中 是待训练的神经网络,输入为关节状态和控制指令,输出为实际输出力矩(或对 PD 输出的残差修正,类似论文ASAP中的方法)。

1.3 目标机器人:X2 双足人形机器人

本项目基于 X2 双足人形机器人,腿部共有 12 个自由度

关节名 关节类型
Left left_hip_yaw_joint 髋偏航
Left left_hip_roll_joint 髋横滚
Left left_hip_pitch_joint 髋俯仰
Left left_knee_joint 膝关节
Left left_ankle_pitch_joint 踝俯仰
Left left_ankle_roll_joint 踝横滚
Right right_hip_yaw_joint 髋偏航
Right right_hip_roll_joint 髋横滚
Right right_hip_pitch_joint 髋俯仰
Right right_knee_joint 膝关节
Right right_ankle_pitch_joint 踝俯仰
Right right_ankle_roll_joint 踝横滚

二、数据采集方案设计

2.1 单关节逐个激励策略

系统辨识最关键的设计决策是如何施加激励信号。我们采用单关节逐个激励(Single-Joint Sequential Excitation)方案:每次仅激励一个关节,其余关节保持零位(或安全姿态),逐一对 12 个关节进行系统辨识。

选择这一方案的原因:

  1. 避免多关节耦合干扰:同时激励多个关节时,关节间的力学耦合(尤其是足底接触力的变化)会影响每个关节的实际输出力矩,使得辨识到的模型掺入了耦合效应,而非单纯的执行器特性。
  2. 安全性可控:机器人处于悬挂或支撑状态,单关节运动幅度有限,便于人工监控。
  3. 数据标注清晰:每段数据明确对应某一关节的某一激励条件,后处理简单。

2.2 多频域正弦激励

激励信号选用正弦轨迹,原因如下:

  • 频谱成分明确,便于分析频域特性;
  • 幅值和频率可精确控制;
  • 关节位移连续可微,避免阶跃指令对电机造成冲击。

我们设计了渐进式多频域激励方案:频率范围从 0.1 Hz 起步,以 0.05 Hz 为步进逐步增加至 1 Hz,共覆盖 19 个频率点,对应激励周期从 10 s 到 1 s:

频率范围 对应周期范围 动态特性
0.1 Hz – 0.2 Hz 5 s – 10 s 准静态低频区,考察低速摩擦与弹性形变特性
0.25 Hz – 0.5 Hz 2 s – 4 s 中频区,覆盖正常行走步频(~0.3–0.5 Hz)
0.5 Hz – 1.0 Hz 1 s – 2 s 高频区,考察电机动态响应延迟与带宽极限

渐进式采集的优势:

  1. 系统性覆盖:均匀分布的频率点避免了特定频段的盲区,使训练数据的频域覆盖更完整;
  2. 频率依赖效应可见:通过逐步扫频可以清晰观察到误差随频率单调增大的趋势,便于定位电机带宽边界;
  3. 低频先行:从低频开始采集,电机运动缓慢,操作人员有充足时间观察关节状态,确认安全后再逐步提高频率。

每个关节在每个频率点下采集至少 3 个完整正弦周期的数据,确保稳态响应被充分记录。

2.3 基于 Soft Limit 的自适应幅值策略

不同关节的运动范围差异显著(例如髋俯仰关节范围远大于髋偏航关节)。若使用固定幅值,小范围关节可能超限,大范围关节则激励不充分。

我们设计了基于 soft limit 的相对幅值策略

Step 1:从 URDF 读取关节原始限位

1
2
3
4
5
6
7
8
9
10
# get_limit.py
SOFT_RATIO = 0.9

def compute_soft_limits(lower: float, upper: float, soft_ratio: float = 0.9):
center = 0.5 * (lower + upper)
half_range = 0.5 * (upper - lower)
soft_half_range = soft_ratio * half_range
soft_lower = center - soft_half_range
soft_upper = center + soft_half_range
return soft_lower, soft_upper

首先将 URDF 中的硬限位(hard limit)缩小 10%(即 soft_ratio = 0.9),得到 soft limit,为关节提供一层安全缓冲。

Step 2:基于 soft limit 计算激励幅值

激励幅值按 soft limit 可用范围的比例计算:

我们采用渐进式幅值扫描方案:幅值比例 从 10% 起步,以 10% 为步进逐步增加至 100%(即完整 soft limit 范围),共 10 档:

幅值档位 特性描述
10% – 30% 0.10 – 0.30 小幅线性区,近似线性摩擦,适合辨识弹性刚度
40% – 60% 0.40 – 0.60 中等幅值,覆盖正常行走时的典型关节摆动范围
70% – 90% 0.70 – 0.90 大幅非线性区,摩擦非线性显著,激励边界动力学
100% 1.00 全幅值,覆盖 soft limit 全范围,测试极端工况响应

渐进式幅值扫描的优势:

  • 从小幅值开始,确认电机响应正常后再增大激励,降低真机测试风险;
  • 系统性地采集从线性区到非线性区的过渡特性,使 actuator network 能学习完整的非线性映射;
  • 每个幅值档位与频率维度组合,形成 10 × 19 = 190 种激励条件的二维网格,充分覆盖工作空间。

left_hip_pitch_joint 为例(假设 URDF 限位为 [-0.8, 1.2] rad):

激励轨迹为:

这一策略保证了不同关节数据覆盖的一致性,同时自动适应各关节的物理约束。在全幅值(100%)条件下,soft limit 裁剪机制仍作为最后一道防线保障安全。

2.4 采集数据字段

每个控制周期(通常 500 Hz 或 1 kHz)记录以下字段:

字段名 含义 单位
timestamp 时间戳 s
joint_name 关节名称 -
desired_position 目标位置 rad
actual_position 实际位置 rad
actual_velocity 实际速度 rad/s
actual_effort 实际输出力矩 Nm
kp 位置增益 Nm/rad
kd 阻尼增益 Nm·s/rad
period 激励周期 s
amplitude_ratio 幅值比例 -

所有数据汇总为一个 CSV 文件(actuator_data.csv),格式如下:

1
2
3
4
timestamp,joint_name,desired_position,actual_position,actual_velocity,actual_effort,kp,kd,period,amplitude_ratio
1234567890.001,left_hip_pitch_joint,0.218,0.201,0.032,12.5,80.0,2.0,2.0,0.20
1234567890.003,left_hip_pitch_joint,0.221,0.204,0.038,13.1,80.0,2.0,2.0,0.20
...

三、安全机制设计

真机实验的首要原则是安全。我们将多层安全限制融入采集程序中:

3.1 位置限幅(Soft Limit Clipping)

在每次发送关节指令前,将目标位置裁剪到 soft limit 范围内:

1
q_cmd = np.clip(q_desired, soft_lower[joint], soft_upper[joint])

即使激励信号因计算误差略微超出范围,也能保证实际指令安全。

3.2 最大力矩限制(Effort Limit)

从 URDF 读取每个关节的最大力矩 effort_limit,并在电机驱动器层面设置扭矩上限,防止电机过热或关节损坏:

1
2
effort_limit = joint_limits[joint_name]["effort"]  # 从 URDF 读取
# 发送给驱动器的力矩命令不超过 effort_limit

3.3 最大速度限制(Velocity Limit)

类似地,设置速度阈值。如果关节实测速度超过安全阈值(通常取 URDF velocity limit 的 80%),自动停止当前激励,切换到保持当前位置模式:

1
2
if abs(actual_velocity) > 0.8 * velocity_limit[joint]:
emergency_stop()

3.4 人工急停

采集程序实现键盘急停(Ctrl+C 或专用按键),任何异常情况下可立即停止所有关节运动,恢复到零位姿态。


四、数据可视化与质量分析

4.1 单关节时序可视化

采集完成后,对每个关节的时序数据进行四图联排可视化:

1
2
3
4
5
6
7
8
9
10
11
12
13
def plot_single_joint(df, joint_name, outdir):
# 子图1:desired vs actual position
ax1.plot(t, joint_df["desired_position"], label="desired_position")
ax1.plot(t, joint_df["actual_position"], label="actual_position")

# 子图2:tracking error = desired - actual
ax2.plot(t, joint_df["error"])

# 子图3:actual velocity
ax3.plot(t, joint_df["actual_velocity"])

# 子图4:actual effort (torque)
ax4.plot(t, joint_df["actual_effort"])

四图联排能直观展示:

  • 跟踪滞后:actual_position 与 desired_position 的相位差,体现电机延迟
  • 跟踪误差:量化 PD 控制器的稳态和动态误差
  • 速度响应:实际速度的幅值和相位
  • 力矩饱和:力矩是否出现裁剪,反映激励幅值是否过大

4.2 跨关节统计对比

对所有 12 个关节计算统计指标并绘制柱状图:

1
2
3
4
stats = df.groupby("joint_name").agg(
error_rms = ("error", lambda x: (x**2).mean()**0.5),
effort_mean = ("actual_effort", lambda x: x.abs().mean()),
)

RMS 误差柱状图joint_error_rms.png)帮助识别哪些关节的 PD 追踪效果最差,这些关节往往是 actuator network 建模收益最大的关节。

平均绝对力矩柱状图joint_effort_mean_abs.png)反映各关节的负载水平,可以指导 PD 增益调整。

4.3 激励条件分析(Period vs. Amplitude)

针对不同激励周期和幅值比例的组合,分析 RMS 误差的变化趋势:

1
2
3
cond_stats = df.groupby(["joint_name", "period", "amplitude_ratio"]).agg(
error_rms = ("error", lambda x: (x**2).mean()**0.5),
)

生成每个关节的”RMS Error vs Period”折线图({joint_name}_error_vs_period.png),每条线对应一种幅值比例。

典型观察规律:

  • 高频(1 Hz 周期)下 RMS 误差通常更大,因为电机动态响应跟不上快速变化的指令
  • 大幅值(100% ratio)的误差通常高于小幅值(10% ratio),反映非线性摩擦的影响
  • 踝关节(ankle)误差一般高于髋关节(hip),因为踝关节传动比更大、摩擦更显著

五、Actuator Network 评估:PD vs. NN

在模型训练完成后,需要在真机上评估 Actuator Network 相对于纯 PD 控制的提升效果。

5.1 评估指标

对每个关节计算三项指标:

指标 含义
RMSE Root Mean Square Error(均方根误差),综合反映跟踪精度
MAE Mean Absolute Error(平均绝对误差),对异常值不敏感
决定系数,反映模型拟合质量(越接近 1 越好)

5.2 评估结果(Locomotion-like 激励)

评估方法为:在真机上执行真实行走轨迹激励(哪怕是乱动的情况),同步记录真实关节力矩作为 ground truth,然后分别用 PD 模型和 Actuator Network 对相同输入进行力矩预测,计算各自与真机力矩的误差。

以下是 12 个腿部关节的对比结果(误差单位:Nm):

关节 PD RMSE PD MAE PD R² NN RMSE NN MAE NN R²
left_ankle_pitch 0.470 0.359 0.314 0.221 0.097 0.848
left_ankle_roll 0.179 0.142 0.571 0.058 0.045 0.956
left_hip_pitch 5.739 4.603 0.816 0.926 0.543 0.995
left_hip_roll 0.283 0.226 0.957 0.216 0.174 0.975
left_hip_yaw 3.848 3.049 -6.807 0.588 0.365 0.817
left_knee 1.428 1.131 0.295 0.327 0.242 0.963
right_ankle_pitch 0.400 0.322 0.424 0.109 0.084 0.958
right_ankle_roll 0.179 0.144 0.794 0.073 0.057 0.966
right_hip_pitch 5.451 4.419 0.837 0.601 0.393 0.998
right_hip_roll 0.259 0.209 0.960 0.157 0.128 0.985
right_hip_yaw 3.537 2.848 -7.960 0.378 0.266 0.898
right_knee 1.285 1.039 0.398 0.254 0.198 0.977

结果分析:

从数值上看,Actuator Network 在 全部 12 个关节 上的 RMSE、MAE 均显著低于纯 PD 模型,R² 也全面提升,部分关节提升幅度极为突出:

  • hip_pitch / hip_yaw:PD 的 R² 为负值(-6.8 / -8.0),说明纯 PD 模型在这两个关节上的预测甚至不如均值基线,而 NN 将 R² 提升至 0.82–0.90,RMSE 降低约 85%–90%,是改善最显著的关节。这两个关节的传动链摩擦和非线性特性较强,PD 的线性假设失效最为明显。
  • hip_roll / ankle:PD 已有较好基线(R² 0.57–0.96),NN 在此基础上进一步将 RMSE 降至不足 PD 的 1/3–1/2,R² 普遍达到 0.95 以上。
  • knee:PD R² 仅约 0.30–0.40,反映膝关节在运动中存在较大非线性;NN 将 R² 提升至 0.96–0.98,精度大幅改善。

这一结果有力证明了 Actuator Network 方法的有效性:通过真机数据驱动建模,神经网络能够捕捉 PD 控制器无法描述的非线性摩擦、延迟和传动耦合效应,在力矩预测精度上全面超越理想 PD 模型。

然而,在实际闭环部署中,策略层面的改善并不明显,这一现象值得深入理解:

原因一:X2 机器人的 PD 参数本身已经调校得较好

X2 的电机驱动器经过厂商仔细调优,PD 增益在正常行走范围内已能实现较小的跟踪误差。尽管力矩预测精度有显著提升,但在当前任务下这一差距未能转化为可观察的行走质量改善。这与文献中 actuator network 效果显著的场景(通常是 PD 效果较差、摩擦较大的低成本电机)存在本质差异。

原因二:测试任务的动力学复杂度相对有限

locomotion 实际任务中,激励信号可以认为是匀速、中等频率的周期运动,动态变化较为平稳。在这类任务中,线性 PD 控制器已能够较好地近似执行器的输入输出关系,actuator network 建模真实非线性动力学的优势难以体现。若任务包含急停、跳跃、应对外力扰动等高动态工况,非线性建模的收益预计会更为显著。

这不意味着 Actuator Network 没有价值

需要强调的是,上述局限性是与具体硬件平台和任务复杂度密切相关的,而非该方法本身的缺陷:

  • 对于摩擦更大、延迟更显著的执行器(如谐波减速器驱动的关节),actuator network 的建模优势将更加突出;
  • 对于高速跑步、侧向快速移步等高动态任务,PD 的线性假设表现会差一些,而 actuator network 能更好地捕捉非线性区间的行为;
  • 本项目建立的数据采集流程、安全机制、可视化分析工具本身具有通用性,可直接迁移到其他执行器或更复杂任务场景。

因此,本工作的核心贡献不仅在于当前场景下的建模精度,更在于建立了一套可复用的真机系统辨识基础设施,为后续更复杂任务和不同硬件平台上的 actuator network 研究奠定了方法论基础。


六、完整工作流程总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
┌─────────────────────────────────────────────────────────────────┐
│ 数据采集与建模完整流程 │
└─────────────────────────────────────────────────────────────────┘

Step 1: 限位读取
└── get_limit.py
├── 解析 URDF 获取每关节 [lower, upper, effort, velocity]
└── 计算 soft limit(原始范围 × 0.9)

Step 2: 数据采集(ROS2 节点)
└── 对 12 个腿部关节逐一激励
├── 激励信号:正弦波,频率 0.1 Hz – 1.0 Hz(步进 0.05 Hz,共 19 个频率点)
├── 幅值:soft limit 可用范围的 10% – 100%(步进 10%,共 10 档)
├── 安全机制:位置裁剪 + 力矩/速度限制 + 急停
└── 记录:timestamp, joint_name, desired_pos, actual_pos,
velocity, effort, kp, kd, period, amplitude_ratio

Step 3: 数据可视化与质量检验
└── visualize_actuator_data.py
├── 单关节时序图(4 子图)
├── 跨关节 RMS 误差柱状图
├── 跨关节平均力矩柱状图
└── 激励条件分析(period vs. error_rms)

Step 4: Actuator Network 训练
└── 输入特征:[q_d, q, q̇, Kp, Kd, τ_prev, ...]
└── 输出:τ_actual(或 Δτ 残差)
└── 框架:PyTorch MLP / LSTM

Step 5: 模型评估
└── 真机采集 locomotion-like 测试数据
└── 对比 PD vs. NN:RMSE / MAE / R²
└── 可视化散点图与时序对比图

Step 6: 集成回仿真
└── 在 MuJoCo / Isaac Gym 中替换 PD 执行器为 Actuator Network
└── 重新训练运动策略
└── 评估 sim-to-real 迁移效果

七、关键设计决策回顾

设计选择 备选方案 选择理由
单关节逐一激励 多关节同时激励 避免关节间力学耦合污染数据
正弦轨迹激励 阶跃/随机激励 频谱可控,连续可微,电机友好
多频域激励(0.1–1.0 Hz,步进 0.05 Hz) 固定单一频率 均匀覆盖不同动态频段,暴露电机带宽边界
渐进式幅值(10%–100%,步进 10%) 固定单一幅值 系统采集线性区到非线性区的完整过渡特性
URDF 安全裁剪 硬件层限制 软件层额外保护,防止指令越界

八、后续工作方向

  1. 扩充训练数据分布:加入更接近真实行走轨迹的激励信号(如在实际的运行中采集到的关节轨迹),缩小 distribution shift。
  2. 时序模型:将 MLP 替换为 LSTM 或 Transformer,显式建模执行器的时序延迟特性。

参考

  • Hwangbo, J. et al. “Learning Agile and Dynamic Motor Skills for Legged Robots.” Science Robotics, 2019.
  • Kumar, V. et al. “RMA: Rapid Motor Adaptation for Legged Robots.” RSS, 2021.