沉下心来学鲁班头像
具身智能实战:让机器鸭爬梯子——双策略交接与接触力控制的深度解读封面图

具身智能实战:让机器鸭爬梯子——双策略交接与接触力控制的深度解读

教一只四足机器人爬梯子,比教它走路难在哪里?本文从 Datawhale 具身智能组队学习的第 6 课出发,用大白话拆解"梯面攀爬"任务中的两个核心工程难点:双策略交接和接触力控制。

一、这节课到底在讲什么?

1.1 任务目标

一句话总结:训练一只叫 MicroDuck 的四足机器人,从地面沿着带横档的斜梯爬上去,翻到桌面上,然后站稳。

整个过程分两个阶段:

阶段1(攀爬):用脚一级一级踩上横档,像攀岩一样往上爬
阶段2(起身):翻到桌面后,从趴着的状态站起来,保持平衡

先来看最终效果——下面是 MicroDuck 从地面到桌面的完整攀爬序列(12 帧抽帧):
在这里插入图片描述

完整攀爬序列(12 帧)

从上到下、从左到右,展示了 MicroDuck 从地面到桌面的完整过程:

  • 第 1-3 帧:鸭子从地面接近梯子,开始用前脚踩上第一根横档
  • 第 4-6 帧:交替踩横档,身体逐渐升高,重心前移
  • 第 7-9 帧:接近梯子顶部,身体开始翻向桌面
  • 第 10 帧:前脚已经踩到桌面边缘,后脚还在梯子上
  • 第 11 帧:身体翻到桌面上,但还在趴着(这是 climber → getup 的交接点)
  • 第 12 帧:getup 策略接管,鸭子站起来,稳稳站在桌面上

关键观察:第 10-11 帧之间发生了策略交接。注意鸭子的姿态变化——从"攀爬姿态"(身体前倾)变成"趴着"(身体贴桌面),然后 getup 把它拉起来。

看完效果,你可能好奇:这是怎么做到的?接下来我们一步步拆解。

1.2 为什么这个任务有挑战性?

和之前学过的平地走路、篮球平衡、高跷行走相比,爬梯子有三个本质区别:

维度平地走路爬梯子
支撑面连续地面,踩哪都行离散横档,必须踩准(间距约 5cm)
力的方向主要靠垂直支撑力需要摩擦力防止滑下去,需要法向力防止掉下去
失败后果摔倒,重新走从梯子上掉下来,可能卡住或翻车

通俗比喻:平地走路像在操场上走,爬梯子像在攀岩墙上爬——每一步都要精确控制脚的位置和力度。

1.3 整体流程

环境配置 → 加载攀爬策略(climber) → 接触力仿真 → 
策略交接(handoff) → 加载起身策略(getup) → 站稳验证 → ONNX导出 → BPU部署

Notebook 共 8 个步骤,从模型检查到板端部署,形成一条完整的可复用流程。


二、需要理解的名词概念

在深入技术细节之前,先统一"语言":

概念大白话解释在本文中的角色
策略(Policy)AI 的"大脑",输入当前状态(61个数字),输出动作(14个关节角度)攀爬和起身各有一个策略
ONNX一种通用的模型文件格式,让 AI 模型能在不同平台运行把训练好的策略打包成可部署格式
HBM“Hardware Binary Model”——给 RDK 开发板用的编译后模型相当于把 Python 编译成机器码
BPU“Brain Processing Unit”——RDK 开发板上的 AI 专用芯片专门跑神经网络推理的小芯片
MuJoCo物理仿真引擎,模拟重力、碰撞、摩擦等物理效果充当机器人的"身体"和"世界"
接触力(Contact Force)脚和梯子横档之间的力法向力=支撑力,切向力=摩擦力
策略交接(Handoff)climber 爬到顶后,自动切换到 getup 的过程本文核心机制之一
闭环(In-the-loop)每个控制周期:读观测→AI推理→执行动作→物理更新→下一周期真实反馈循环
61维观测AI 每次"看到"的信息:身体姿态、速度、关节角度等 61 个数字策略的输入
14维动作AI 每次"做出"的决策:14 个关节的目标角度策略的输出
MDP“Markov Decision Process”——马尔可夫决策过程,强化学习的数学框架定义状态、动作、奖励
奖励函数(Reward)告诉 AI "什么行为是好的"的评分机制本文核心机制之一
课程训练(Curriculum)先学简单的,再学难的,循序渐进从有支撑板到无支撑板

三、攀爬和起身,这两个动作分别是如何学会的?

3.1 不是"一个策略包打天下"

很多人会想:为什么不训练一个策略,让它既能爬梯子又能站起来?

答案是:两个任务的物理状态差异太大。

  • 攀爬时:鸭子身体前倾,重心在梯子方向,脚在横档上交替踩踏
  • 起身时:鸭子身体从趴着变成直立,重心从低到高,脚从悬空到踩实桌面

如果让一个策略同时学这两件事,它会在两种状态之间"精神分裂"——既学不会爬,也学不会站。

工程上的做法:拆成两个独立策略,各学各的,然后在合适的时机交接。

3.2 攀爬策略(climber)是怎么训练的?

数据来源:社区开源项目 HannesVonEssen/microduck-climb,提供了完整的训练代码、checkpoint 和 ONNX 模型。

训练框架:基于 PPO(Proximal Policy Optimization)算法,在 MuJoCo 仿真环境中训练。

关键参数:

参数值说明
观测维度61身体姿态、速度、关节角度等
动作维度1414 个可控关节的目标角度
控制频率50 Hz每秒做 50 次决策
仿真频率200 Hz每秒推进 200 步物理仿真
并行环境数6464 个仿真环境同时训练
训练迭代4000+每轮采样 + 策略优化

训练过程:

初始化策略(随机动作)
    ↓
在 64 个并行环境中同时试错
    ↓
每步计算奖励(爬得越高越好、脚踩得越准越好)
    ↓
PPO 算法更新策略参数
    ↓
重复 4000+ 轮,直到策略稳定
    ↓
导出 ONNX 模型

3.3 起身策略(getup)是怎么训练的?

训练起点不同:getup 不是从零开始学的,而是用预训练 checkpoint 续训。

预训练 checkpoint(已经学会基本站立)
    ↓
在"翻到桌面后趴着"的初始状态下续训
    ↓
奖励函数:身体直立 + 双脚踩实 + 不滑动
    ↓
训练到稳定起身
    ↓
导出 ONNX 模型

为什么用预训练? 因为从零学"从趴着到站立"太难了——初始状态离目标状态太远,随机探索几乎不可能碰巧学会。用预训练 checkpoint 相当于"站在巨人的肩膀上",只需要微调就能学会。

3.4 两个策略的接口完全一致

虽然功能不同,但 climber 和 getup 的输入输出完全一样:

输入:obs[1, 61]  →  61 维观测向量
输出:action[1, 14]  →  14 维关节目标角度

这意味着切换策略时,不需要改变仿真环境的接口——只需要把推理的模型从 climber.onnx 换成 getup.onnx 就行。


四、接触力控制是如何做到的?

4.1 核心原则:不直接控制力,而是引导 AI 学会正确的接触方式

这是很多人容易误解的地方。代码里没有一行代码直接设置"脚和横档之间应该有多大的力"。

取而代之的是:通过奖励函数引导 AI 自己学会正确的接触方式。

4.2 五个奖励函数,五个"老师"

老师 1:路径进度奖励(ladder_path_progress)
# 伪代码
progress = 0.75 × 水平进度 + 0.25 × 垂直进度
reward = 当前progress - 上次progress

大白话:鸭子每往前/往上移动一点,就给奖励。75% 看水平进度,25% 看垂直进度。

效果:鼓励鸭子沿着梯子方向前进,而不是原地打转或往回走。

老师 2:高度进度奖励(ladder_height_progress)
# 伪代码
height_progress = (当前高度 - 起始高度) / (桌面高度 - 起始高度)
reward = 当前progress - 上次progress

大白话:专门奖励"往上爬"。鸭子每升高一点,就给奖励。

效果:和路径进度配合,确保鸭子既往前又往上,而不是只往前不往上(比如沿着地面跑)。

老师 3:脚部对齐奖励(ladder_foot_alignment)——接触控制的核心

这是最复杂也最重要的一个奖励函数:

# 伪代码
# 1. 计算每只脚到最近横档的距离
rung_error = sqrt((沿梯子方向偏差)² + (垂直方向偏差)²)

# 2. 计算三个维度的得分
score = exp(-(横向偏差/0.045)²)      # 脚不能偏出梯子两侧(4.5cm以内)
      × exp(-(左右偏差/梯宽)²)        # 脚不能超出梯子宽度
      × exp(-(rung_error/0.065)²)     # 脚必须靠近某个横档(6.5cm以内)

# 3. 加一个"门控":只有进入梯子区域才生效
score *= gate  # 梯子入口前=0,梯子上=1,桌面后=0

大白话:

这个函数在告诉 AI:“你的脚应该踩在横档上”。怎么判断?

  • 横向偏差:脚不能偏出梯子两侧(左右 4.5cm 以内)
  • 纵向偏差:脚必须靠近某个横档(6.5cm 以内)
  • 门控机制:只有鸭子真正进入梯子区域,这个奖励才生效

效果:AI 通过几万次试错,最终学会"把脚放到横档上"。一旦脚放对了,MuJoCo 物理引擎自然算出正确的接触力。

老师 4:脚部滑动惩罚(foot_slip)
cfg.rewards["foot_slip"].weight = -0.2

大白话:脚在接触面上滑动,扣分。

效果:鼓励 AI 学会"踩稳",而不是"脚底打滑"。

老师 5:脚部离地惩罚(foot_clearance)
cfg.rewards["foot_clearance"].weight = -0.5

大白话:脚抬太高,扣分。

效果:鼓励 AI 学会"贴着横档走",而不是"高抬腿"浪费能量。

4.3 物理引擎的角色

MuJoCo 负责:

  • 计算脚和横档之间的真实碰撞(法向力、摩擦力)
  • 判断是否滑落(摩擦力不够时自然滑落)
  • 判断是否卡住(脚卡在两根横档之间)

AI 负责:

  • 输出 14 个关节的目标角度
  • 通过奖励函数引导,学会"把脚放到正确位置"

两者配合:

AI 输出动作 → MuJoCo 算物理 → 反馈新的状态 → AI 再输出
     ↑                                              ↓
     └──────────────── 闭环循环 ────────────────────┘

这就是"闭环"——AI 不是在一开始就知道所有答案,而是在和物理世界的持续互动中,不断调整自己的行为。

4.4 梯子几何的真实建模

V2 版本按参考视频中的空间关系重做了梯子几何:

组件描述碰撞属性
两根斜梁矩形截面,沿斜面布置真实碰撞几何
14 根横档密集排列,间距约 5cm真实碰撞几何
顶部平台(桌面)四条腿支撑真实碰撞几何
梯脚落地木块防止梯子看起来像浮在空中真实碰撞几何
桌后方的椅子视觉装饰,不影响物理不参与碰撞

关键设计:所有梯梁、横档、桌面和梯脚都是真实 MuJoCo 碰撞几何,不是"看起来像"的视觉模型。这意味着 AI 在训练中感受到的物理反馈,和真实世界中是一样的。


五、双策略交接是如何做到的?

5.1 为什么需要交接?

想象你爬梯子到桌面后:

  • climber(攀爬策略):擅长一级一级往上踩,但它的"世界观"里只有梯子,不知道到了桌面该怎么办
  • getup(起身策略):擅长从趴着变成站着,但它不会爬梯子

所以必须两个策略接力:climber 爬到顶 → 切换 → getup 把鸭子拉起来站稳。

5.2 交接的触发条件

代码里有一个叫 foot_desktop_eligible 的函数,它判断"是否可以交棒了"。条件有三个,必须同时满足:

条件1:脚碰到了桌面
条件2:身体已经在桌面范围内
条件3:持续了至少 1 个控制步(约 0.02 秒)
条件1:脚碰到了桌面

用 MuJoCo 的物理引擎检测:鸭子的左脚或右脚,是否和桌面(tread_31/desktop)发生了真实碰撞(距离 ≤ 0)。

不是"差不多到了",是物理引擎真的算出脚和桌面接触了。

条件2:身体已经在桌面范围内

鸭子的身体重心,必须在桌面的矩形范围内(前后左右都算),而且高度要超过 0.66(说明已经翻上来了,不是还在梯子上)。

条件3:持续了至少 1 个控制步

不能是"一瞬间碰到就切换",必须稳定接触至少 1 步,防止误触发。

5.3 切换的完整流程

关键代码在 OfficialPair.step() 里,用大白话翻译:

# 步骤1:记忆机制
# 把"上一步做了什么动作"塞回输入的 34-48 槽位
observation[34:48] = self.raw
# 这样策略知道"我刚才在干嘛",不会突然懵掉

# 步骤2:状态机切换
self.recovering = self.recovering or eligible
# 一旦 eligible=true,就永久进入 getup 模式
# 不会"切过去又切回来"

# 步骤3:推理
if self.recovering:
    self.raw = self.getup.infer(observation)   # 用 getup 策略
else:
    self.raw = self.climber.infer(observation) # 用 climber 策略

# 步骤4:柔顺过渡
if self.recovering:
    # getup 输出不是直接用的,而是和"上一步的动作"做加权平均
    self.executed = alpha × self.raw + (1-alpha) × self.executed
    # 腿用 alpha=0.7,头颈用 alpha=0.5
    # 这样过渡是平滑的,不会"咔"一下突然换动作

四个关键设计:

设计作用如果不做会怎样
记忆机制让策略知道上一步做了什么切换后策略"失忆",动作不连贯
单向切换一旦切换永不回头可能在两个策略之间反复横跳
柔顺过渡动作平滑过渡突然换动作,鸭子可能摔倒
不同 alpha 值腿 0.7,头颈 0.5头颈过渡太慢影响视觉,腿过渡太快影响平衡

5.4 怎么验证交接成功?

不是"触发了切换"就算成功。代码里还有一个 desktop_standing 函数,要求:

条件阈值大白话
双脚都在桌面上all(feet)两只脚都踩稳了
身体在桌面范围内inside_desktop没掉下去
重力方向朝下gravity_z < -0.82身体是直立的,不是歪的
线速度 < 0.25linear_speed没在滑动
角速度 < 2.5angular_speed没在旋转
稳定持续 ≥ 2 秒stable_seconds >= 2.0不是"碰巧站稳一瞬间"

大白话:必须"双脚踩稳 + 身体直立 + 不滑动 + 不旋转 + 保持 2 秒以上",才算真正成功。


六、总结与启发

6.1 核心设计哲学

机制实现方式设计哲学
双策略交接物理接触检测 + 状态机 + 平滑过渡不硬编码切换时机,让物理世界告诉 AI 何时切换
接触力控制奖励函数引导 + MuJoCo 物理仿真不直接控制力,而是告诉 AI “脚应该在哪”
成功验证多条件组合 + 持续时间不是"触发了"就算成功,必须"稳定保持"

6.2 对工程实践的启发

  1. 拆分比统一好:两个差异大的任务,拆成两个策略比一个策略包打天下更有效
  2. 引导比控制好:用奖励函数引导 AI 学会正确行为,比硬编码规则更灵活
  3. 物理真实性很重要:所有几何体都用真实碰撞模型,仿真结果才能迁移到真实世界
  4. 交接需要平滑:策略切换不是"咔"一下换,而是加权平均的柔顺过渡
  5. 验证要全面:不是"触发了"就算成功,必须多条件组合 + 持续时间

6.3 下一步

如果你想动手试试:

  1. 修改梯子间距:测试不同梯级距离对策略的影响
  2. 添加滑动:模拟湿滑梯面,测试策略的鲁棒性
  3. 对比不同模型:原模型 vs ONNX vs BPU,看精度和速度差异
  4. 部署到真机:如果有 RDK 开发板,尝试板端推理

作者:华仔,39 岁技术人,正在探索 AI 赋能个人工作流的第二曲线。

课程来源:Datawhale 具身智能组队学习 — MicroDuck 运动策略与任务开发专题,第 6 课"梯面攀爬"。

模型来源:HannesVonEssen/microduck-climb — 社区开源的攀爬/起身策略、ONNX、PPO 检查点、训练代码和梯子模型。

如果你对具身智能、AI Agent、个人助手建设感兴趣,欢迎交流。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/xiaojia1001/article/details/169269046

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--