基于云端OpenClaw的情绪互动机器人系统-Milk-V Duo S + 机器人 端开发(7)
上一周我完成了 11-前进招手 的设计,把普通挥手动作扩展成了一个包含前进步态、左右招手和回正过程的复杂动作组。本周继续进行机器人端复杂动作库建设,重点调试另外两个新的手脚协同动作组:12-鞠躬谢谢、13-下蹲保护。
这个动作组的目标是让机器人在表达“感谢”“回应表扬”“礼貌结束互动”等场景时,不只是简单挥手,而是通过身体前倾、手臂配合和腿部支撑形成类似“鞠躬致谢”的动作。它看起来比前进招手短,但技术上并不简单,因为鞠躬动作要求上半身前倾时下肢稳定,手臂姿态要同时表达“谢谢”,不能让机器人出现前倾失衡。
复杂手脚协同动作组设计:鞠躬谢谢动作组
一、动作语义设计
在情绪互动机器人中,“谢谢”是一种非常重要的正向情绪表达。用户输入:
谢谢你陪我聊天。
或者:
你今天表现得真棒!
机器人如果只是站立不动,交互会显得冷淡;如果只是挥手,又不够礼貌。因此我设计了“鞠躬谢谢”动作组,让机器人用身体动作表达回应和感谢。
这个动作组主要对应以下语义:
| 用户语义 | 机器人动作 |
|---|---|
| 感谢 | 鞠躬 |
| 被夸奖 | 点头式身体前倾 |
| 礼貌结束 | 鞠躬后回正 |
| 温和正面情绪 | 慢速致谢动作 |
| 演示结尾 | 谢幕动作 |
二、动作组文件结构
本周设计的鞠躬谢谢动作组 一共包含 9 个动作关键帧,总执行时间约为 7.6 秒。相比 11-前进招手.xml 的 32 帧,这个动作组更短,但是每一帧都承担了明确的姿态功能。
整体可以分为四个阶段:
| 阶段 | 步骤 | 作用 |
|---|---|---|
| 初始站立 | 第 1 步 | 保持标准站立姿态 |
| 手臂致谢预备 | 第 2 步 | 手臂和腿部进入感谢姿态 |
| 鞠躬循环 | 第 3-8 步 | 身体反复前倾和回正 |
| 归位结束 | 第 9 步 | 恢复标准站立 |
| 步骤 | 动作描述 |
|---|---|
| 1 | 机器人以标准站立姿态静止,准备鞠躬。 |
| 2 | 双臂向前伸出(#21 P660,#22 P1240,#26 P1760,#27 P2340),身体直立,做鞠躬准备姿势。 |
| 3 | 腿部弯曲(#4、#5、#10、#11 调整),身体向前弯腰,完成第一次鞠躬。 |
| 4 | 腿部伸直,身体恢复直立,手臂仍保持前伸。 |
| 5 | 腿部再次弯曲,身体第二次弯腰鞠躬。 |
| 6 | 腿部再次伸直,身体直起恢复直立。 |
| 7 | 腿部第三次弯曲,身体第三次弯腰鞠躬。 |
| 8 | 腿部第三次伸直,身体恢复直立,手臂仍前伸。 |
| 9 | 手臂收回至站立姿态,所有关节恢复初始站立位,鞠躬动作结束。 |
三、第 1 步:标准站立作为安全起点
第 1 步仍然使用标准站立姿态:
#3 P1895 #4 P1919 #5 P2151 #6 P1570
#7 P1477 #8 P1523 #9 P1430 #10 P826
#11 P1081 #12 P1105
#21 P1477 #22 P1000 #23 P500
#24 P1500 #25 P2500 #26 P2000 #27 P1500
我在设计所有复杂动作组时都会保留这个原则:复杂动作开始前先站稳。因为机器人执行上一个动作后,可能处于挥手、下蹲或者后退的姿态。如果直接进入鞠躬,身体重心可能还没有回到中间位置,容易导致动作不自然甚至失衡。
技术理解:标准站立不是“多余动作”,而是复杂动作组之间的同步点。它相当于机器人动作系统中的 reset 状态,可以清除前一个动作残留的姿态误差。
四、第 2 步:手臂和腿部进入致谢姿态
第 2 步中,动作组开始改变上肢和下肢姿态:
#21 P660 #22 P1240
#26 P1760 #27 P2340
其中 21、22 号舵机主要用于左侧手臂姿态调整,26、27 号舵机配合身体和腿部姿态稳定。这个步骤不是鞠躬本身,而是“致谢预备动作”。
我这样设计的原因是:如果机器人一开始就直接前倾,用户看到的只是身体突然下压;加入手臂预备后,动作语义会更清楚,像是在先做出“我要表达感谢”的准备姿态。
五、第 3、5、7 步:身体前倾形成鞠躬
真正的鞠躬动作出现在第 3、5、7 步,这几步的关键变化包括:
#4 P1440
#5 P1860
#10 P1140
#11 P1560
这些舵机主要参与身体前倾和腿部支撑调整。原始站立时,4 号舵机为 P1919,5 号舵机为 P2151,而在鞠躬帧中它们分别变化到 P1440、P1860。这个差值让机器人上半身产生明显前倾效果。
技术理解:鞠躬动作不能只改“腰部”或“上半身”某一个舵机。因为机器人身体前倾后,重心会向前移动。如果腿部和脚掌没有配合,机器人就可能向前倒。因此我同时调整 10、11 号舵机,让下肢承担补偿作用,使前倾动作看起来更稳。
六、第 4、6、8 步:回正但不完全归位
第 4、6、8 步使用了接近站立的身体姿态,但手臂仍保持致谢状态:
#4 P1919
#5 P2151
#10 P826
#11 P1081
#21 P660
#22 P1240
#26 P1760
#27 P2340
这样设计是为了形成“鞠躬—抬起—再鞠躬”的循环,而不是每次都完全恢复站立。它相当于保留了感谢动作的上下文,让机器人连续鞠躬三次,看起来更像一个完整的礼貌动作。
如果每次都回到标准站立,动作会变成“鞠躬—站立—鞠躬—站立”,节奏会显得断裂。而现在的设计是“鞠躬—半回正—鞠躬—半回正”,视觉上更加连贯。
七、第 9 步:最终归位
第 9 步用 T500 回到标准站立姿态:
#21 P1477 #22 P1000
#26 P2000 #27 P1500
这个步骤虽然时间只有 500 ms,但非常关键。因为机器人在结束感谢动作后,必须回到后续动作序列可以安全接续的姿态。比如云端生成的动作序列可能是:
[12, 1, 0]
表示先鞠躬谢谢,再挥手,最后站立。如果 12-鞠躬谢谢 结束后没有回正,后面的挥手动作就会在非标准姿态下开始,容易出现动作错位。
八、Duo S 端执行时的动作编号校验
在 Duo S 端,我把 12-鞠躬谢谢.xml 加入动作编号映射:
ACTION_MAP = {
11: "11-前进招手",
12: "12-鞠躬谢谢",
13: "13-下蹲保护",
16: "16-左招手",
17: "17-右招手",
}
同时在执行前加入动作编号校验:
def get_action_file(action_id):
if action_id not in ACTION_MAP:
print("未知动作编号:", action_id)
return None
return ACTION_MAP[action_id]
技术理解:云端 OpenClaw Agent 生成动作序列时,虽然有动作白名单和 normalize 兜底校验,但 Duo S 端仍然需要再做一层保护。因为端侧是真正控制舵机的最后一环,一旦执行了不存在或错误的动作文件,轻则机器人无响应,重则可能造成舵机动作异常。因此端侧动作编号校验是安全控制链路中不可省略的一层。
九、与情绪语义的结合
12-鞠躬谢谢 最适合出现在以下动作序列中:
[12, 0]
表示感谢后回到站立;
[1, 12, 0]
表示先挥手打招呼,再鞠躬致谢;
[11, 12, 0]
表示先前进招手,再鞠躬谢谢,适合演示开场或故事结尾。
技术理解:动作组不是孤立存在的。OpenClaw 生成的是动作序列,而 Duo S 端执行的是本地 XML 动作库。一个好的动作组不仅自身要稳定,还要能和其他动作组自然衔接。鞠躬谢谢这种动作尤其适合作为一段互动的收尾,因为它有明确的礼貌语义和稳定的回正过程。
复杂手脚协同动作组设计:下蹲保护动作组
一、为什么要设计“下蹲保护”
在情绪互动机器人系统中,我们不只需要开心、感谢、打招呼等正向动作,也需要能够表达害怕、紧张、退缩、保护自己的动作。比如用户输入:
我有点害怕,想躲起来。
或者故事中出现:
突然传来一声巨响,小机器人吓得蹲了下来。
如果机器人只是执行普通下蹲,情绪表达会比较单薄。因此我设计了“下蹲保护”动作组,让机器人在下蹲的同时加入手臂收拢和身体保护姿态,使动作更像是在“保护自己”。
二、动作组整体结构
本周设计的第二个动作组-下蹲保护一共包含 8 个动作关键帧,总执行时间约为 8 秒。每一步都使用 T1000,也就是每个关键帧持续 1 秒。
这个动作组可以分为四个阶段:
| 阶段 | 步骤 | 动作功能 |
|---|---|---|
| 初始站立 | 第 1 步 | 标准站立,准备进入保护动作 |
| 下蹲成型 | 第 2 步 | 双腿弯曲,身体重心下降 |
| 手臂保护 | 第 3-6 步 | 双臂收拢并摆动,形成保护姿态 |
| 缓冲回正 | 第 7-8 步 | 从低重心姿态恢复到站立 |
| 步骤 | 动作描述 |
|---|---|
| 1 | 机器人以标准站立姿态就位。 |
| 2 | 双腿急速弯曲下蹲(#4、#5 大幅降至 P780、P760,#10、#11 推至极限),身体重心快速下沉至最低位,做出紧急下蹲保护姿态。 |
| 3 | 双臂向前环抱(#21、#22 收至胸前,#23、#26、#27 推至高位),头部居中,形成抱头防护姿势。 |
| 4 | 头部(#24)向左偏转至 P1060,模拟观察左侧危险。 |
| 5 | 头部向右偏转至 P1980,模拟观察右侧危险。 |
| 6 | 头部回中至 P1500,保持下蹲保护姿态。 |
| 7 | 手臂开始回收放松(#21-#27 向站立姿态恢复),身体准备直立。 |
| 8 | 所有关节恢复至初始站立姿态,下蹲保护动作结束。 |
三、第 1 步:标准站立姿态
第 1 步仍然是标准站立姿态:
#3 P1895 #4 P1919 #5 P2151 #6 P1570
#7 P1477 #8 P1523 #9 P1430 #10 P826
#11 P1081 #12 P1105
#21 P1477 #22 P1000 #23 P500
#24 P1500 #25 P2500 #26 P2000 #27 P1500
这是所有复杂动作组的统一起点。对于“下蹲保护”来说,标准站立尤其重要,因为下蹲动作会大幅改变腿部角度。如果起点不一致,可能导致一条腿先下压、另一条腿还没跟上,从而造成机器人左右晃动。
技术理解:越是涉及重心变化的动作,越需要统一起点。站立帧相当于把机器人重新校准到一个可预测的姿态,再开始执行高风险动作。
四、第 2 步:腿部下蹲,重心降低
第 2 步是下蹲保护的核心姿态之一,主要变化集中在腿部舵机:
#4 P780
#5 P760
#6 P1140
#9 P1860
#10 P2240
#11 P2220
可以看到,4、5、6 号和 9、10、11 号舵机都发生了大幅变化。这说明动作不是单腿弯曲,而是左右腿同时进入下蹲状态。
技术理解:真正稳定的下蹲必须左右腿协同。如果只改变一侧腿部舵机,机器人会向一边塌陷;如果腿部变化太快,重心下降瞬间会造成冲击。因此我在这个动作组中把每一步都设置为 T1000,让机器人有足够时间完成关节移动。
五、第 3-6 步:手臂进入保护姿态
第 3 步开始,上肢加入保护动作:
#21 P900
#22 P860
#23 P2100
#25 P900
#26 P2140
#27 P2100
这里的 21、22、23 号舵机和 25、26、27 号舵机都发生明显变化,形成双臂向身体前方或两侧收拢的效果。
第 4、5、6 步中,24 号舵机又发生了变化:
#24 P1060
#24 P1980
#24 P1500
这让保护动作不只是静态抱住身体,而是有一个“左右护住—回到中间”的动态过程。视觉上,机器人像是先蹲下,再用手臂挡在身体前方,表达害怕或自我保护。
技术理解:情绪动作不能只是姿态静止。害怕、紧张这类情绪往往伴随收缩、躲避、遮挡等动作趋势。因此我在下蹲基础上加入了手臂摆动,让动作更符合情绪表达。
六、第 7 步:缓冲回正,不直接站立
第 7 步不是直接恢复站立,而是先进入一个缓冲姿态:
#21 P1480
#22 P1280
#23 P1260
#25 P1740
#26 P1720
#27 P1520
这一帧的作用是让手臂和腿部先从保护姿态中松开,但身体还没有完全恢复到标准站立。这样设计的原因是,如果第 6 步之后直接回到站立,机器人会从低重心快速拉起,容易出现晃动。
技术理解:复杂动作的结束不能只看“最后是否站稳”,还要看“从上一帧到最后一帧的过渡是否平滑”。第 7 步就是一个缓冲帧,用来减少低重心到站立之间的冲击。
七、第 8 步:恢复标准站立
第 8 步最终恢复到标准站立姿态:
#3 P1895 #4 P1919 #5 P2151 #6 P1570
#7 P1477 #8 P1523 #9 P1430 #10 P826
#11 P1081 #12 P1105
#21 P1477 #22 P1000 #23 P500
#24 P1500 #25 P2500 #26 P2000 #27 P1500
这样设计保证了动作组结束后,后续动作可以安全接续。例如云端生成:
[13, 0]
表示下蹲保护后站立;
[13, 12, 0]
表示先害怕下蹲,再鞠躬谢谢,适合故事中从紧张到缓和的情绪变化;
[13, 11, 0]
表示先保护自己,再前进招手,适合故事中“害怕之后重新鼓起勇气”的情节表达。
八、Duo S 端的安全执行策略
这个动作组让我意识到,Duo S 端不能只是机械地执行云端发来的动作编号,还需要对高风险动作进行安全控制。像 13-下蹲保护 这种涉及低重心和大幅腿部变化的动作,最好加入执行锁和状态判断。
我在端侧设计中可以加入类似的控制逻辑:
is_running = False
def safe_run_sequence(sequence):
global is_running
if is_running:
print("当前已有动作正在执行,忽略新的动作序列")
return
is_running = True
try:
for action_id in sequence:
action_file = get_action_file(action_id)
if action_file is None:
continue
run_action_group(action_file)
run_action_group("站立.xml")
except Exception as e:
print("动作执行异常:", e)
run_action_group("站立.xml")
finally:
is_running = False
技术理解:机器人执行动作时最怕的是两个动作序列同时进入串口。如果一个线程正在让机器人下蹲,另一个线程又让机器人挥手,舵机指令会交错,姿态可能变得不可控。因此 Duo S 端必须使用执行锁或状态变量,保证同一时间只有一个动作序列在执行。
九、动作组异常时的回正机制
除了执行锁,我还加入了一个重要思路:无论动作是否正常执行完成,都尽量让机器人回到站立姿态。
try:
run_action_group("13-下蹲保护.xml")
except Exception as e:
print("下蹲保护执行失败:", e)
finally:
run_action_group("站立.xml")
技术理解:在机器人系统中,“异常后停在哪里”非常重要。如果程序报错时机器人刚好处于下蹲或半抬腿姿态,长时间保持这个姿态可能会让舵机持续受力。因此端侧异常处理不只是打印日志,还要尽量执行安全回正动作。
十、与云端 OpenClaw 的语义配合
13-下蹲保护 可以作为害怕、紧张、回避等语义的动作基础。云端 OpenClaw Agent 在生成动作序列时,可以根据文本情绪强度选择是否调用这个动作:
| 文本情绪 | 建议动作序列 |
|---|---|
| 有点紧张 | [13, 0] |
| 害怕后被安慰 | [13, 12, 0] |
| 先害怕再鼓起勇气 | [13, 11, 0] |
| 故事情节出现危险 | [13, 0] |
| 演示机器人自我保护 | [13, 0] |
这样一来,机器人不仅能表达开心、感谢,也能表达害怕和自我保护,情绪动作库更加完整。
十一、本周总结
本周先是完成了复杂手脚协同动作组 12-鞠躬谢谢 的设计和调试。这个动作组虽然只有 9 个关键帧,但它体现了几个重要的技术点:
- 使用标准站立作为动作起点;
- 通过上肢预备动作增强感谢语义;
- 通过身体前倾和下肢补偿实现稳定鞠躬;
- 通过半回正帧形成连续鞠躬节奏;
- 通过最终归位保证后续动作序列可安全接续;
- 在 Duo S 端加入动作编号映射和校验,保证云端动作序列可以稳定落地执行。
这次调试让我进一步理解到,机器人动作设计不仅是“让舵机转到某个角度”,而是要考虑动作背后的情绪语义、身体平衡、时间节奏和系统接口。只有云端语义理解和端侧动作库都足够可靠,机器人才能真正从一个机械执行器变成一个能表达情绪的互动终端。
同时还完成了第三个复杂手脚协同动作组 13-下蹲保护 的设计。这个动作组的重点不只是“蹲下”,而是通过腿部下蹲、手臂收拢、动态保护和缓冲回正,表达出害怕或自我保护的情绪。
主要收获包括:
- 掌握了低重心动作的设计方法;
- 理解了腿部对称变化对机器人稳定性的影响;
- 在下蹲基础上加入手臂保护,使动作更有情绪表达;
- 通过缓冲帧避免从低姿态直接站起造成晃动;
- 在 Duo S 端设计执行锁、异常回正和动作编号校验,提高动作执行安全性;
- 让机器人动作库从正向情绪扩展到紧张、害怕、自我保护等复杂情绪。
到这里,三个新的复杂动作组已经基本完成:11-前进招手、12-鞠躬谢谢、13-下蹲保护。它们相比基础动作更能体现本项目的技术难度:不只是云端生成动作编号,而是 Duo S 端能够稳定解析、调度和执行复杂的手脚协同动作。最终,机器人才能真正把大模型理解到的情绪,转换成可见、可感知、有节奏的身体表达。
更多推荐



所有评论(0)