把“会聊天还会跳舞”的千问桌面机器人做出来
你桌上放个小机器人,平时当语音助手,叫它还能扭一段。
这种东西的快乐点很简单:
- 你加班回家,喊一句“我回来了”,它能回你一句人话。
- 你说“来段舞”,它真的动起来。
- 你走到桌前,它能“看见你”,自动打招呼。
不少现成机器人接了千问(Qwen)后,聊天和动作都挺丝滑。槽点也很明显:没摄像头。少了视觉,桌面机器人就像“耳朵很灵但眼神不好”。
这篇就按“能照着做”的路线,带你搭一个:
- ✅ 千问对话(文本/语音)
- ✅ 舞蹈动作(舵机/灯效/音效)
- ✅ 可选:加摄像头,做人脸/手势/物体互动
你要做的机器人,结构长这样
把它想成三层:
- 大脑:千问
- 负责理解你在说啥、该回什么、要不要触发动作
- 耳朵和嘴:ASR + TTS
- ASR 把你说的话转文字
- TTS 把回复变成语音
- 身体:舵机/灯带/屏幕
- “跳舞”本质是动作序列
- “情绪”可以用灯效/屏幕表情来补
加摄像头后,多一层:
- 眼睛:摄像头 + 视觉模型/算法(OpenCV 或 Qwen-VL)
硬件怎么选:省心方案 vs 折腾方案
省心方案(推荐)
- 树莓派 4/5 或 任何迷你主机(N100):跑 Python 很舒服
- USB 麦克风:收音稳定
- 小音箱:别用树莓派板载输出,容易糊
- 舵机 x2~6:机器人头/手/身体摆动
- 舵机驱动板(PCA9685):别硬怼 GPIO,稳很多
- (可选)USB 摄像头:30fps 够用
折腾方案(更便宜)
- ESP32 做舵机控制 + 主机负责 AI
- 好处是实时控制很稳
- 坏处是通信要自己处理(串口/UDP/MQTT)
小建议:别一上来就做人形全身。桌面机器人“头+两只手”已经很有戏了。
软件栈:照着拼就能跑
你可以用 Python 把整条链路串起来:
- 对话:Qwen API(或你自建推理)
- 语音转文字:Whisper / 讯飞 / 阿里云等
- 文字转语音:Edge TTS / 火山 / 阿里云等
- 动作控制:PCA9685 / Arduino
- 视觉:OpenCV + 人脸检测 或 Qwen-VL
如果你不想做复杂工程,记住一句话:
让千问只做“决策”,动作用你写死的动作库来执行。
这样更稳定,也更像“玩具机器人”的真实体验。
关键设计:让千问决定“说什么”和“做什么”
机器人最容易翻车的点:
- 模型输出太自由
- 你没法稳定解析
- 舵机一会儿跳一会儿不跳
解决办法:给模型一个固定输出格式。
让千问输出 JSON(强烈建议)
让它每次回复都带两个字段:
speech:要说的话action:要执行的动作名(可为空)
示例提示词(system):
你是桌面机器人。你必须只输出 JSON。
字段:speech(string), action(string)。
action 只能从以下列表选择:
- idle
- wave
- dance_happy
- nod
- shake_head
- light_party
如果不需要动作,action 输出 idle。
禁止输出多余文字。
用户说:“来段舞”。 模型输出就该是:
{"speech":"好嘞!给你整一段。","action":"dance_happy"}
你解析 JSON,动作就稳了。
代码骨架:一条链路跑通(Python 示例)
下面是“能跑通思路”的骨架。你按自己用的 SDK 改接口就行。
import json
# 伪代码:你替换成真实的 Qwen 调用
def call_qwen(messages):
# return '{"speech":"好嘞!","action":"dance_happy"}'
raise NotImplementedError
# 动作库:把动作名字映射到具体执行函数
class Actuator:
def idle(self):
pass
def wave(self):
print("[动作] 挥手")
def dance_happy(self):
print("[动作] 快乐舞")
# 这里写舵机序列:角度+时间
def nod(self):
print("[动作] 点头")
def shake_head(self):
print("[动作] 摇头")
def light_party(self):
print("[动作] 灯光派对")
def run(self, action_name: str):
fn = getattr(self, action_name, None)
if not fn:
return self.idle()
return fn()
def robot_turn(user_text: str, actuator: Actuator):
messages = [
{"role": "system", "content": "你是桌面机器人...(省略,见上文)"},
{"role": "user", "content": user_text}
]
raw = call_qwen(messages)
data = json.loads(raw)
speech = data.get("speech", "")
action = data.get("action", "idle")
# 1) 说话:接你的 TTS
print("[说]", speech)
# 2) 动作:执行动作库
actuator.run(action)
if __name__ == "__main__":
act = Actuator()
robot_turn("来段舞", act)
你会发现:模型再聪明,也只是输出一个动作名。真正“跳舞”的确定性来自你的动作库。
“跳舞”怎么写:动作序列比你想的简单
舵机舞蹈本质是:
- 角度 A -> 角度 B
- 中间停多少毫秒
- 再来一组
一个最小可用的动作结构:
import time
def move_servo(channel, angle):
# 这里替换为 PCA9685/Arduino 的真实控制
pass
DANCE = [
# (舵机通道, 角度, 持续秒)
(0, 60, 0.15),
(1, 120, 0.15),
(0, 120, 0.15),
(1, 60, 0.15),
]
def dance_happy():
for ch, angle, dur in DANCE:
move_servo(ch, angle)
time.sleep(dur)
想更像“跳舞”?加两个小技巧:
- 节拍对齐:动作间隔固定成 0.12/0.15/0.2 秒一类
- 动作回弹:每次摆到极限后回一点点,立刻“活”起来
没摄像头也能玩出花:用“声音场景”补视觉
没摄像头时,照样能很有互动感。
几个特别讨巧的玩法:
- 叫它“看时间”:它报时,同时做点头动作
- 你说“我累了”:它安慰你,然后灯光变柔和
- 你说“庆祝一下”:它放音乐 + light_party
甚至可以做“桌面陪伴模式”:
- 每隔 30 分钟提醒你喝水
- 你回应“好”,它挥手
桌面机器人要的就是这种小细节。🙂
加摄像头后,体验会直接起飞
有摄像头,你能解锁三类高频场景:
1) 人来了就打招呼
- 检测到人脸
- 触发
speech: “嗨,你回来了”+action: wave
2) 跟随你的位置
- 人脸在画面左边:头转左
- 在右边:头转右
- 像真的“看着你说话”
3) 手势触发
- 竖大拇指:它开心跳舞
- 摇手:它挥手回应
用 OpenCV 做轻量视觉(够用、便宜)
你不一定要上视觉大模型。
- 人脸检测:Haar/MediaPipe
- 手势:MediaPipe Hands
这套优势是:
- 低延迟
- 不花模型钱
- 体验很稳定
用 Qwen-VL 做“看图说话”(更聪明)
你想让机器人“看见桌面有什么”再聊天,比如:
- “我桌上这是什么?”
- “我拿的这本书叫啥?”
这种就交给 Qwen-VL 一类视觉语言模型。
建议用法:
- 视觉模型只负责产出一句“观察结论”
- 再把结论丢给对话模型做最终回复和动作决策
这样成本和延迟都更可控。
一个实战流程:摄像头 + 千问联动
你可以这么走:
- 摄像头每隔 0.5 秒做一次检测
- 检测到人脸就生成一个事件:
event=face_detected - 发给千问:让它决定说什么、做什么
事件提示词示例(user):
事件:face_detected
人物位置:偏左
环境:办公室桌面
请输出 JSON:speech + action
动作可以设计成:
- 偏左 ->
action: look_left - 偏右 ->
action: look_right - 居中 ->
action: nod
你的机器人立刻“有灵魂”。
避坑清单(血泪版)
- 别让模型直接输出舵机角度:一次输出错,舵机就抽风。动作名映射动作库,最稳。
- 电源别省:舵机单独供电。USB 供电不够就会抖、重启。
- 麦克风离音箱远点:不然自激,机器人会跟自己吵起来。
- JSON 一定要强约束:不加约束,模型会给你写小作文,你解析直接炸。
- 摄像头权限/隐私要想清楚:本地处理就本地处理,别默认把画面上传。
- 动作幅度别太大:桌面机器人最怕“用力过猛”,一抖就像癫痫发作。
你可以从这个最小版本开干
想尽快体验到“会聊天+会动”的爽感,按这个清单做:
- 树莓派 + USB 麦克风 + 小音箱
- 两个舵机 + PCA9685
- 千问:只负责输出
speech/action - 你写 6 个动作:
idle/wave/nod/shake_head/dance_happy/light_party
等你玩嗨了,再加摄像头。
如果你愿意,把你现在用的硬件型号(主控、舵机数量、有没有屏幕)发我,我可以按你的配置把动作库结构和接口一起理顺,让你少踩一堆坑。