机器人情绪与动作系统设计最佳实践
综合自:reachy-mini-conversation-app(Pollen Robotics)
问题描述
如何为社交机器人设计情绪和动作系统,使其:
- 在交互时表现自然
- 在空闲时保持鲜活感
- 支持多种情绪/动作的无缝切换
- 与语音同步产生有机的运动
核心设计原则
1. 永不静止(Always Alive)
原则:机器人永远不应该完全静止。
实现:
- 空闲 0.3 秒后自动进入呼吸动画
- 呼吸参数:5mm Z 轴浮动 + 天线交替摆动
- 频率接近人类呼吸(6 次/分钟)
理由:静止的机器人显得机械和"死亡",持续的微运动创造亲和感。
2. 双层融合架构
架构:
┌─────────────────────────────────────┐
│ 最终姿态输出(100Hz) │
├─────────────────────────────────────┤
│ 主要动作(互斥) + 次要偏移(叠加) │
│ ├─ 情绪 ├─ 语音摆动 │
│ ├─ 舞蹈 └─ 人脸追踪 │
│ ├─ Goto 定位 │
│ └─ 呼吸 │
└─────────────────────────────────────┘
理由:
- 主要动作互斥避免冲突
- 次要偏移叠加增加自然感
- 单一控制点确保一致性
3. 音频驱动自然运动
原则:说话时的运动应该由音频实时驱动。
关键参数:
| 参数 | 值 | 作用 |
|---|---|---|
| 延迟补偿 | 200ms | 对齐音频与机械延迟 |
| VAD 开启阈值 | -35 dB | 检测语音开始 |
| VAD 关闭阈值 | -45 dB | 滞后避免抖动 |
| 振荡轴数 | 6 轴 | pitch/yaw/roll/x/y/z |
理由:
- 多轴独立振荡避免机械感
- 响度驱动幅度保持动态
- 随机初始相位增加有机感
方案比较
动作触发方式
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| LLM 工具调用 | 上下文相关、智能选择 | 延迟较高 | 交互式情绪表达 |
| 随机触发 | 简单、不可预测 | 缺乏意图 | 空闲时的自发行为 |
| 时间触发 | 可预测、可控 | 机械感 | 定期演示 |
| 音频驱动 | 自然同步 | 需要音频输入 | 说话时的辅助运动 |
推荐:组合使用 - LLM 决定"做什么",音频驱动"怎么做",随机增加"变化"。
呼吸状态设计
| 参数 | 保守值 | 活跃值 | 推荐 |
|---|---|---|---|
| Z 轴浮动 | 3mm | 10mm | 5mm |
| 呼吸频率 | 0.08 Hz | 0.15 Hz | 0.1 Hz |
| 天线摆动 | 10° | 20° | 15° |
| 天线频率 | 0.3 Hz | 0.7 Hz | 0.5 Hz |
推荐:使用保守值作为基础,在特定人格或情绪状态下调整。
决策矩阵
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 用户说话时 | 语音摆动 + 天线冻结 | 避免干扰监听 |
| 机器人说话时 | 语音摆动 + 情绪动作 | 增强表达力 |
| 短暂空闲(<15s) | 呼吸动画 | 保持鲜活感 |
| 长时间空闲(>15s) | LLM 触发创意动作 | 主动吸引注意 |
| 情绪切换 | 插值过渡(1s) | 避免突变 |
推荐最佳实践
设计层面
-
分层设计:将情绪、舞蹈、呼吸作为独立的 Move 对象,通过队列顺序执行
-
单一控制点:所有运动通过统一的
set_target输出,避免并发冲突 -
线程安全:控制循环独占状态,外部通过消息队列通信
-
时间对齐:使用单调时钟,避免系统时间跳跃影响动画
参数层面
-
呼吸优先:任何空闲状态都应该回到呼吸,而不是完全静止
-
天线异步:两天线使用相反方向摆动,打破对称感
-
相位随机:每次会话使用不同的初始相位,避免重复感
-
响度映射:运动幅度应该与音量正相关,使用 gamma 曲线调整
时长与调用层面
-
时长协议:所有 Move 必须实现
duration属性,控制循环依赖它判断完成 -
复合时长:多个子动作组成的复合动作,总时长 = Σ 子动作时长
-
即时响应:收到完整工具参数后立即执行,异步返回结果给 LLM
-
空闲区分:空闲触发的工具调用不生成语音回复,避免打扰