尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

通过OpenClaw接入机械臂,实现自然语言控制机械臂 保姆教程:从skill到STM32的完整链路

通过OpenClaw接入机械臂,实现自然语言控制机械臂 保姆教程:从skill到STM32的完整链路 1. 从一句话到机械臂动作OpenClaw 自然语言控制机械臂到底怎么跑通桌面级六轴机械臂放在工位上最尴尬的不是它不会动而是每次想让它动一下都得改代码、重新编译、再烧录。我手头这台用 STM32 做下位机、USB 转 CH340 串口通信的小臂之前调一个「向左转 30 度」要经历改 C 代码里的角度数组、make、插线、跑 fasong、看它动。一天下来真正想验证的动作没几个时间全花在编译链路上。OpenClaw 这类个人 AI 助手出现之后思路就变了把「自然语言 → 结构化动作参数 → 串口指令」这条链路拆开让模型负责理解意图和生成调用代码让本地已经封装好的 Python 控制器负责真正发指令。你只需要说「让机械臂向左转 20 度然后向下移动 3 厘米夹住东西」OpenClaw 根据你预先写好的 skill 描述生成一段调用dfbot_controller.py里现成函数的脚本执行后机械臂就动了。这套方案适合谁适合已经有一台能通过串口控制的桌面机械臂、下位机固件已经能解析类似{#000P1500T1000!}这种舵机指令、并且愿意花半小时把控制逻辑封装成 Python 模块的人。它不适合完全没有下位机通信基础、指望开箱即用的场景因为机械臂的 DH 参数、关节限位、串口设备名这些必须你自己填对。核心检索词先摆出来OpenClaw 机械臂自然语言控制本质是「LLM 生成控制脚本 本地 Python 控制器执行 STM32 串口驱动舵机」的三段式架构。skill 是中间那层翻译官STM32 是最末端执行者。下面按我实际跑通的顺序从环境、串口、控制器封装、skill 配置到验证排错一步步来。2. 前置准备OpenClaw 安装、TaoToken 模型接入与 STM32 串口环境2.1 OpenClaw 安装与模型 API 配置OpenClaw 的安装走 npm 全局包Ubuntu 20.04 上先确认 Node 版本别太旧node -v npm i -g openclaw openclaw onboardonboard交互里会让你选模型提供方。这里我建议直接用 TaoToken 的兼容接口一个 Key 可以切换不同模型省得每个平台单独注册。先去控制台创建 API Key模型对话入口https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_arm接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_arm拿到 Key 之后在 onboard 里选「Use existing values」或手动填 Base URL 和 Key。Base URL 填https://taotoken.net/apiKey 填你刚创建的。模型 ID 按你实际想用的填比如claude-sonnet-4-20250514或gpt-4o这类具体以文档里的模型列表为准。如果你更想先验证模型通不通可以直接在模型对话页发一句「你好」看返回模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_armonboard 后面几步hooks、渠道选择一路选 No 或跳过最后 Restart。网页端如果 Ubuntu 自带浏览器打不开换个浏览器访问本地地址即可。2.2 STM32 下位机与 CH340 串口驱动我的机械臂是 STM32 做主控接收形如{#000P1500T1000!}的舵机指令每个舵机一条P后面是 PWM 值500–2500 对应 -135° 到 135°T是运动时间毫秒。上位机通过 USB 转 CH340 和 STM32 通信。Ubuntu 下 CH340 驱动一般内核自带插上后ls /dev/ttyUSB*或ls /dev/ttyCH341USB*能看到设备节点。如果报permission denied把当前用户加进 dialout 组sudo usermod -aG dialout $USER然后重新登录。设备名以你实际看到的为准我这里是/dev/ttyCH341USB0串口参数 115200、8N1、无流控。2.3 封装本地 Python 控制器这一步是整个链路的地基。把「角度转 PWM、拼指令、写串口」封装成jiekou.pyimport subprocess def control_arm(angles): if len(angles) ! 6: raise ValueError(角度列表必须包含 6 个值) angle_str [str(a) for a in angles] result subprocess.run( [./fasong] angle_str, checkTrue, textTrue, capture_outputTrue ) print(result.stdout)fasong是编译好的 C 程序负责把 6 个角度转成 PWM 并写入串口。核心映射逻辑int angle_to_pwm(int angle) { if (angle -135) angle -135; if (angle 135) angle 135; float pwm 1500 (angle * (1000.0 / 135.0)); return (int)(pwm 0.5); }串口打开和配置fd open(/dev/ttyCH341USB0, O_WRONLY | O_NOCTTY); cfsetospeed(tty, B115200); cfsetispeed(tty, B115200); tty.c_cflag ~PARENB; tty.c_cflag ~CSTOPB; tty.c_cflag ~CSIZE; tty.c_cflag | CS8; tty.c_cflag ~CRTSCTS; tty.c_iflag ~(IXON | IXOFF | IXANY); tty.c_lflag ~(ICANON | ECHO | ECHOE | ISIG); tty.c_oflag ~OPOST; tcsetattr(fd, TCSANOW, tty);编译gcc fasong.c -o fasong。先手动跑一次./fasong 0 0 0 0 0 0 1000机械臂回到零位就说明串口链路通了。再往上封装dfbot_controller.py用 roboticstoolbox 做正逆运动学把常用动作做成函数move_joint_deg、move_up、move_down、move_left、move_right、rotate_left、rotate_right、gripper_open、gripper_close。每个函数接收state_now返回新的current_state形成状态链。DH 参数按你自己机械臂填我的是DFbot DHRobot([ RevoluteMDH(d0.04145, qlimnp.array([-np.pi*3/4, np.pi*3/4])), RevoluteMDH(alphanp.pi/2, qlimnp.array([-np.pi/2, np.pi/2])), RevoluteMDH(a-0.08285, qlimnp.array([-np.pi*3/4, np.pi*3/4])), RevoluteMDH(a-0.08285, qlimnp.array([-np.pi*3/4, np.pi*3/4])), RevoluteMDH(alpha-np.pi/2, d0.11, qlimnp.array([0, np.pi])), ], nameDFbot)到这一步你已经在虚拟机上能手动控制机械臂了。接下来才是 OpenClaw 的 skill 层。3. 可复制配置OpenClaw skill.md 与 robot-api.md 完整片段OpenClaw 的 skill 目录一般在~/.nvm/versions/node/vXX/lib/node_modules/openclaw/skills/下路径以你实际安装为准。新建目录dfbot-arm-codegen里面放skill.md和references/robot-api.md。3.1 skill.md 配置--- name: dfbot-arm-codegen description: 引导 OpenClaw 生成基于 DFbot 机械臂的控制代码。支持笛卡尔空间位移、关节控制和夹爪操作。 metadata: { openclaw: { emoji: , requires: { bins: [python3] } } } --- ## 功能概览 - 本技能根据用户指令生成 Python 脚本。 - 依赖用户本地的 dfbot_controller.py 模块。 ## 生成代码的硬性规则 (CRITICAL) 1. **指定运行目录** - CRITICAL: 所有生成的 Python 脚本必须明确说明或默认在以下目录下运行 /home/rlk/.nvm/versions/node/v22.22.1/lib/node_modules/openclaw/workspace - 提醒用户确保 dfbot_controller.py 和 jiekou.py 已放置在该目录下。 2. **状态追踪** - 机械臂所有移动函数都必须接收 state_now 并在执行后返回新的 current_state。 - 必须链式更新状态current_state move_up(current_state, ...)。 3. **导入与初始化** - 必须从 dfbot_controller 导入 deg0, state_ready 以及各种 move_* 函数。 - 脚本开头通常先执行 current_state move_joint_deg(deg0) 初始化。 4. **单位规范** - 笛卡尔移动 (move_up/down/smooth) 单位是 **米 (m)**。 - 关节转动 (move_left/right, rotate_left/right) 单位是 **度 (°)**。 - 夹爪开合单位是 **度 (°)** (30度为开0度为关)。 ## 使用本技能生成代码 - 根据用户需求结合 references/robot-api.md 生成完整脚本。 - 生成后告知用户脚本已针对 workspace 路径优化请在该目录下执行 python3 生成的脚本名.py。 ## 参考资料 - 详细 API 见 references/robot-api.md。3.2 references/robot-api.md 配置# DFbot API 速查与最小可运行模板 ## 1. 预设状态与基础控制 python from dfbot_controller import deg0, state_ready, move_joint_deg, move_joint_rad current_state move_joint_deg(deg0, delay2) current_state move_joint_rad(state_ready, delay2)2. 常用动作接口动作类型函数签名说明向上移动move_up(state_now, step0.02, delay1, smoothTrue)笛卡尔Z轴增加单位米向下移动move_down(state_now, step0.02, delay1, smoothTrue)笛卡尔Z轴减少单位米底座向左move_left(state_now, step_deg5, delay1)第1关节左转单位度底座向右move_right(state_now, step_deg5, delay1)第1关节右转单位度末端左旋rotate_left(state_now, step_deg5, delay1)第5关节左旋单位度末端右旋rotate_right(state_now, step_deg5, delay1)第5关节右旋单位度任意平滑move_cartesian_smooth(state_now, dx0, dy0, dz0, steps5, delay0.5)对当前位姿平滑移动3. 夹爪控制from dfbot_controller import gripper_open, gripper_close current_state gripper_open(current_state, gripper_deg30, delay1) current_state gripper_close(current_state, gripper_deg0, delay1)4. 最小可运行模板#!/usr/bin/env python3 import time from dfbot_controller import ( deg0, state_ready, move_joint_deg, move_joint_rad, move_up, move_down, move_left, move_right, rotate_left, rotate_right, gripper_open, gripper_close ) def main(): print( 开始执行 DFbot 控制任务 ) current_state move_joint_deg(deg0, delay2) current_state move_joint_rad(state_ready, delay2) current_state gripper_open(current_state, gripper_deg30, delay1) current_state move_left(current_state, step_deg20, delay1.5) current_state move_down(current_state, step0.03, delay1, smoothTrue) current_state gripper_close(current_state, gripper_deg0, delay1) current_state move_up(current_state, step0.05, delay1.5, smoothTrue) print( 任务完成复位 ) current_state move_joint_deg(deg0, delay2) if __name__ __main__: main()### 3.3 关键参数对照表 | 参数 | 值 | 说明 | |------|------|------| | Base URL | https://taotoken.net/api | TaoToken 兼容接口 | | 串口设备 | /dev/ttyCH341USB0 | 以实际为准 | | 波特率 | 115200 | 8N1 无流控 | | PWM 范围 | 500–2500 | 对应 -135° 到 135° | | 默认运动时间 | 1000ms | 可调 0–9999 | | workspace 路径 | .../openclaw/workspace | 脚本运行目录 | 配置完重启 OpenClawskill 才会被加载。 ## 4. 验证请求从自然语言到机械臂动作的端到端联调 重启 OpenClaw 后在对话里发一句 让机械臂向左转 20 度然后向下移动 3 厘米夹住东西再抬起来 OpenClaw 会读取 dfbot-arm-codegen skill结合 robot-api.md 生成一段 Python 脚本大致长这样 python #!/usr/bin/env python3 from dfbot_controller import ( deg0, state_ready, move_joint_deg, move_joint_rad, move_left, move_down, move_up, gripper_open, gripper_close ) def main(): current_state move_joint_deg(deg0, delay2) current_state move_joint_rad(state_ready, delay2) current_state gripper_open(current_state, gripper_deg30, delay1) current_state move_left(current_state, step_deg20, delay1.5) current_state move_down(current_state, step0.03, delay1, smoothTrue) current_state gripper_close(current_state, gripper_deg0, delay1) current_state move_up(current_state, step0.05, delay1.5, smoothTrue) current_state move_joint_deg(deg0, delay2) if __name__ __main__: main()把脚本保存到 workspace 目录执行cd /home/rlk/.nvm/versions/node/v22.22.1/lib/node_modules/openclaw/workspace python3 arm_task.py终端会打印每一步的关节角、发送给机械臂的指令机械臂依次执行回零、到 ready 位、张开夹爪、底座左转 20 度、下降 3 厘米、闭合夹爪、抬起 5 厘米、回零。整个过程不需要你改一行 C 代码。验证成功的标志终端出现成功写入 XX 字节指令: {#000P...}机械臂动作平滑无抖动回零后位置和初始一致。如果动作方向反了检查convert_deg里的符号映射如果幅度不对检查 DH 参数和angle_to_pwm的线性映射。想验证模型本身是否正常可以先去模型对话页发一句测试模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_arm如果对话正常但生成脚本报错问题就在 skill 配置或本地模块路径不在模型。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth5.1 401 Unauthorized现象OpenClaw 调用模型返回 401。原因通常是 API Key 没填对、Key 过期、或 Base URL 写成了带路径的地址。检查~/.openclaw/config里的baseUrl是否为https://taotoken.net/apiKey 是否和 TaoToken 控制台里创建的一致。重新创建 Key 后要重启 OpenClaw。5.2 local proxy failed现象启动时报local proxy failed或连接被拒。这通常是本地端口被占用或配置里指向了一个不存在的本地服务。检查是否有其他进程占用 OpenClaw 默认端口lsof -i :端口号看一下。如果是 onboard 时选了本地代理模式改回直连模式Base URL 直接填 TaoToken 地址。5.3 reading choices 报错现象模型返回结构解析失败日志里出现reading choices或类似字段缺失。这多半是模型 ID 填错或者接口返回了非预期格式。确认模型 ID 在 TaoToken 文档的模型列表里存在且该模型支持 chat completions 格式。换一个模型 ID 试一次比如从gpt-4o换成claude-sonnet-4-20250514。5.4 OAuth 相关报错现象提示 OAuth token 失效或需要重新授权。如果你用的是 OAuth 方式登录某些模型提供方token 过期后会这样。改用 API Key 方式接入 TaoToken 可以绕开 OAuth 刷新问题Key 长期有效不需要反复授权。5.5 串口 permission denied现象/dev/ttyCH341USB0 permission denied。用户不在 dialout 组。执行sudo usermod -aG dialout $USER后重新登录。临时验证可以用sudo chmod 666 /dev/ttyCH341USB0但不建议长期这样。5.6 脚本导入失败 ModuleNotFoundError现象No module named dfbot_controller。脚本运行目录不对或者dfbot_controller.py和jiekou.py没放在 workspace 目录。skill.md 里已经写死了 workspace 路径确保这两个文件在那里且fasong可执行文件也在同目录或 PATH 里。5.7 机械臂不动但串口有输出现象终端打印了指令但机械臂没反应。检查 STM32 固件是否在正常运行、舵机供电是否足够、串口线是否接对。用./fasong 0 0 0 0 0 0 1000手动测一次如果手动也不动问题在下位机不在 OpenClaw。6. 长期编码与 Agent 场景把这条链路用顺跑通一次之后你会发现真正的价值在于「不用改代码就能试动作」。想验证一个抓取姿态直接说「底座右转 15 度末端左旋 10 度下降 2 厘米」OpenClaw 生成脚本、执行、看结果不对就再调一句。这种迭代速度比改 C 代码快一个数量级。如果你要长期做这类机械臂 Agent 开发建议把模型调用走 Coding Plan额度更稳适合反复生成和调试脚本Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_arm接入文档里对 Base URL、Key、Model ID 三件套有完整说明遇到配置问题先翻文档接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_armAPI Key 管理页可以随时创建和吊销 KeyAPI Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopenclaw_arm我自己的习惯是skill.md 里把单位规范和状态链规则写死robot-api.md 里只放函数签名和最小模板这样模型生成代码时不容易跑偏。每次新增一个动作函数就同步更新 robot-api.md 的表格OpenClaw 下次生成就能用上。机械臂的 DH 参数和关节限位一旦确定就别频繁改改一次要重新验证逆解比较费时间。
返回列表