JSON 指令操控机械臂
前置知识
什么是 JSON?
JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种结构化数据格式,通过{"键":值}对组织指令参数,例如目标位置、动作类型和运动速度。
为什么用 JSON 指令控制机械臂?
JSON 指令可以用统一的数据格式描述机械臂控制参数,便于通过 Web、HTTP、串口等方式发送同一类控制命令。
发送 JSON 指令的方式
Web 端发送指令
在 Web 端使用界面中,预留有指令输入框,可以发送 JSON 指令对机械臂进行设置或控制等操作。部分 JSON 指令的反馈内容较长,可能无法在界面中完整显示。
- 根据入门教程连接机械臂的 WiFi,并打开 Web 端使用界面
- 在 Web 端使用界面中,找到 "FEEDBACK INFOMATION" 下的输入框
- 在此处输入对应的 JSON 指令与机械臂进行通信
- 点击 "SEND" 发送后,JSON 指令反馈的信息会在输入框上方显示
Web 端中已经准备好每个功能对应的 JSON 代码,点击 INPUT 按钮,即可复制到输入框,以便直接发送和二次修改。

Python-HTTP 请求通信
前置知识
HTTP 请求是一种常见的网络通信方式。机械臂接入同一局域网后,可通过 Python 程序向机械臂 Web 服务发送 JSON 指令,并读取返回信息。
Python 虚拟环境用于隔离项目依赖,避免不同项目的 Python 库版本互相影响。虚拟环境配置完成后,后续使用时进入例程目录并激活该环境即可。
-
检查电脑已安装 Python。
-
下载并解压 RoArm-M3 配套的 Python 文件包。

-
打开命令行工具,进入解压后的文件夹路径。
-
创建虚拟环境:
python -m venv roarmpython-env -
激活虚拟环境。Windows 中执行:
.\roarmpython-env\Scripts\activateLinux 中执行:
source roarmpython-env/bin/activate -
安装项目依赖:
pip install -r requirements.txt -
检查依赖是否安装完成:
pip list
确认机械臂当前 IP 地址:
- AP 模式下,默认访问地址为
192.168.4.1。 - STA 或 AP+STA 模式下,OLED 屏幕会显示路由器分配给机械臂的 IP 地址。
运行 HTTP 请求通信程序:
python http_simple_ctrl.py <机械臂 IP 地址>
运行脚本的设备需要与机械臂处于同一个局域网内。
Python-串口通信
Python 串口通信通过驱动板序号 9 的 Type-C USB 接口与 ESP32 串口通信。该接口可用于发送 JSON 指令和读取机械臂反馈。

Windows 串口通信
-
使用 USB 线连接 PC 与机械臂驱动板序号 9 的 Type-C USB 接口。
-
在设备管理器中查看新出现的 COM 口。下图示例为
COM20,实际端口号以电脑显示为准。
-
若没有显示新的 COM 口,先确认 USB 线连接的是序号 9 的 Type-C USB 接口;若“其它设备”中出现名称带 CP2102 的未识别设备,安装 CP2102 串口驱动。
-
运行串口通信程序:
python serial_simple_ctrl.py COM20
Linux 串口通信
-
使用 USB 线连接 Linux 主机与机械臂驱动板序号 9 的 Type-C USB 接口。
-
查看串口设备名:
ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null -
常见串口设备名为
/dev/ttyUSB0或/dev/ttyACM0。按实际设备名运行串口通信程序:python serial_simple_ctrl.py /dev/ttyUSB0
运行完成后,可在终端中查看机械臂初始化后的返回信息,并继续发送 JSON 指令。

WiFi 配置
前置知识
RoArm-M3 支持 AP、STA 和 AP+STA 三种 WiFi 工作模式。
- AP 模式:驱动板建立热点,手机或电脑连接该热点后访问 Web 端。AP-only 模式下默认访问地址为
192.168.4.1。 - STA 模式:驱动板连接到已有路由器,由路由器分配 IP 地址。
- AP+STA 模式:驱动板保留自身热点,同时连接到已有路由器。OLED 屏幕会显示热点名称和路由器分配的 IP 地址。
出厂默认 WiFi 模式为 AP。需要切换模式或保存开机默认配置时,可发送下列 JSON 指令。
CMD_WIFI_ON_BOOT - 设置默认 WiFi 模式
{"T":401,"cmd":3}
设置开机后 WiFi 的默认工作模式。
cmd:默认工作模式代号,0为关闭,1为 AP,2为 STA,3为 AP+STA。
CMD_SET_AP - 设置 AP 模式
{"T":402,"ssid":"RoArm-M3","password":"12345678"}
设置 WiFi 为 AP 模式,建立 WiFi 热点。
ssid:AP 模式下 WiFi 的名称(SSID),最大长度 32 个字符。password:AP 模式下 WiFi 的密码,最大长度 64 个字符。
CMD_SET_STA - 设置 STA 模式
{"T":403,"ssid":"yourWiFiName","password":"yourWiFiPassword"}
设置 WiFi 为 STA 模式,连接到现有的 WiFi 网络。
ssid:STA 模式下要连接的 WiFi 网络名称(SSID),最大长度 32 个字符。password:STA 模式下要连接的 WiFi 网络密码,最大长度 64 个字符。
首次设置 STA 模式时,机械臂会自动切换为 AP+STA 模式;若约 15 秒后仍未连接到现有 WiFi,设备会自动切回 AP 模式,便于继续通过默认热点进行配置。
CMD_WIFI_APSTA - 设置 AP+STA 模式
{"T":404,"ap_ssid":"RoArm-M3","ap_password":"12345678","sta_ssid":"yourWiFiName","sta_password":"yourWiFiPassword"}
设置 WiFi 为 AP+STA 模式,同时连接到现有的 WiFi 网络。
ap_ssid:AP 模式下 WiFi 的名称(SSID),最大长度 32 个字符。ap_password:AP 模式下 WiFi 的密码,最大长度 64 个字符。sta_ssid:STA 模式下要连接的 WiFi 网络名称(SSID),最大长度 32 个字符。sta_password:STA 模式下要连接的 WiFi 网络密码,最大长度 64 个字符。
使用该指令后,机械臂会连接到现有 WiFi 网络,同时建立一个名为 RoArm-M3 的热点。此模式下,OLED 屏幕第一行会显示 AP 的 WiFi 名称,第二行会显示无线网络分配的 IP 地址。
CMD_WIFI_INFO - 查看当前 WiFi 信息
{"T":405}
查看机械臂当前 WiFi 信息。 返回值如下:
{"ip":"192.168.10.90","rssi":-50,"wifi_mode_on_boot":3,"sta_ssid":"yourWiFiName","sta_password":"yourWiFiPassword","ap_ssid":"RoArm-M3","ap_password":"12345678"}
ip:STA 或 AP+STA 模式下由路由器分配的 IP 地址。AP-only 模式下,该字段可能为0.0.0.0,Web/HTTP 默认访问地址仍为192.168.4.1。rssi:当前 STA 连接的 WiFi 信号强度;未连接到上级 WiFi 网络时通常为 0。wifi_mode_on_boot:当前连接的 WiFi 模式,0为关闭,1为 AP,2为 STA,3为 AP+STA。sta_ssid:STA 模式下要连接的 WiFi 网络名称(SSID)。sta_password:STA 模式下要连接的 WiFi 网络密码。ap_ssid:AP 模式下 WiFi 的名称(SSID)。ap_password:AP 模式下 WiFi 的密码。
WiFi 配置保存在机械臂 Flash 文件系统的 wifiConfig.json 文件中,文件内容示例如下:
{"wifi_mode_on_boot":3,"sta_ssid":"JSBZY-2.4G","sta_password":"waveshare0755","ap_ssid":"RoArm-M3","ap_password":"12345678"}
CMD_WIFI_CONFIG_CREATE_BY_STATUS - 根据当前 WiFi 状态生成配置文件
{"T":406}
根据当前 WiFi 状态生成 WiFi 配置的 wifiConfig.json 文件。
使用该指令后,机械臂会根据当前 WiFi 状态生成 wifiConfig.json 文件。若文件不存在,则创建该文件;若文件已存在,则覆盖原文件。
CMD_WIFI_CONFIG_CREATE_BY_INPUT - 根据输入信息生成配置文件
{"T":407,"mode":3,"ap_ssid":"RoArm-M3","ap_password":"12345678","sta_ssid":"JSBZY-2.4G","sta_password":"waveshare0755"}
将输入的信息写入 flash 内存中的 wifiConfig.json 文件中。
mode:WiFi 模式代号,0为关闭,1为 AP,2为 STA,3为 AP+STA。
CMD_WIFI_STOP - 关闭 WiFi 连接
{"T":408}
关闭 WiFi 连接。
机械臂运动控制(MOVING CTRL)

这部分介绍 Web 端 MOVING CTRL 模块中的 JSON 指令。指令主要分为关节角度控制和三维直角坐标控制:关节角度控制可使用弧度制或角度制,三维直角坐标控制用于控制机械臂末端点的位置和姿态。
前置知识
阻塞与非阻塞
阻塞指令发送后,控制程序会等待当前动作执行到一定阶段,再继续处理后续指令。常见表现是机械臂运动过程中,后续指令需要等待一段时间才生效。
非阻塞指令发送后,控制程序不会等待机械臂完成运动,后续指令可能很快被继续处理。连续发送非阻塞运动指令时,相邻目标点的变化不宜过大,并且要随时观察机械臂是否接近障碍物或机械限位。
复位
CMD_MOVE_INIT - 运动到初始位置
{"T":100}
让机械臂所有关节转动到初始位置。正常情况下,机械臂开机时会自动转动到初始位置;需要重新回到初始姿态时,可发送该指令。
该指令会引起进程阻塞。机械臂运动到初始位置前,后续指令可能需要等待。
关节角度控制
CMD_SINGLE_JOINT_CTRL - 单独关节控制(弧度制)
{"T":101,"joint":0,"rad":0,"spd":0,"acc":10}
以弧度制形式控制某个关节转动到指定角度。
joint:关节序号。上方模板中的joint值需要在发送前改为实际关节编号。
| 序号 | 关节名称 | 中文说明 |
|---|---|---|
| 1 | BASE_JOINT | 基础关节 |
| 2 | SHOULDER_JOINT | 肩关节 |
| 3 | ELBOW_JOINT | 肘关节 |
| 4 | WRIST_JOINT | 手腕关节 1 |
| 5 | ROLL_JOINT | 手腕关节 2 |
| 6 | EOAT_JOINT | 夹爪关节 |

rad:需要转动到的目标弧度。各关节以初始位置为基准,范围和方向如下。
| 关节名称 | 初始值 | 范围 | 转动方向 |
|---|---|---|---|
BASE_JOINT | 0 | -3.14~3.14 | 增加时向左转动,减少时向右转动 |
SHOULDER_JOINT | 0 | -1.57~1.57 | 增加时向前转动,减少时向后转动 |
ELBOW_JOINT | 1.570796 | 0~3.14 | 增加时向下转动,减少时向反方向转动 |
WRIST_JOINT | 0 | -1.57~1.57 | 增加时手腕关节 1 向下转动,减少时向上转动 |
ROLL_JOINT | 0 | -3.14~3.14 | 增加时手腕关节 2 顺时针转动,减少时逆时针转动 |
EOAT_JOINT | 3.141593 | 1.08~3.14 | 减少时夹爪关节张开 |
spd:转动速度,单位为步/秒。舵机转动一圈为 4096 步,数值越大速度越快;数值为 0 时,以最大速度转动。acc:转动开始和结束时的加速度,单位为 100 步/秒^2。数值越小,启停越平缓;可设置为 0~254。设置为 10 时,对应 1000 步/秒^2;设置为 0 时,按照最大加速度运行。
挑战任务
单关节动作回归验证
任务目标
只使用 Web 端 MOVING CTRL 区域中的 CMD_SINGLE_JOINT_CTRL 命令,依次验证基础关节、肩关节、肘关节和手腕关节 1 的单关节控制能力,并让机械臂回到接近初始姿态。
适用场景
- 单关节动作回归测试
- 舵机更换后的基础动作检查
- 关节方向与角度范围确认
- 控制参数调试前的低速验证
操作步骤
Web 端每次点击 CMD_SINGLE_JOINT_CTRL,修改输入框中的 JSON 参数后发送。每次发送后,等待当前关节动作结束,再执行下一步。
1. 基础关节右转
{"T":101,"joint":1,"rad":-1.57,"spd":0.5,"acc":10}
2. 肩关节抬起
{"T":101,"joint":2,"rad":0.785,"spd":0.5,"acc":10}
3. 肘关节弯曲
{"T":101,"joint":3,"rad":1.047,"spd":0.5,"acc":10}
4. 手腕关节 1 向下转动
{"T":101,"joint":4,"rad":1.0,"spd":0.5,"acc":10}
5. 基础关节回中(0 rad)
{"T":101,"joint":1,"rad":0,"spd":0.5,"acc":10}
6. 肩关节落回 0 rad
{"T":101,"joint":2,"rad":0,"spd":0.5,"acc":10}
7. 肘关节伸直回 1.57 rad(初始位置)
{"T":101,"joint":3,"rad":1.57,"spd":0.5,"acc":10}
8. 手腕关节 1 回 0 rad
{"T":101,"joint":4,"rad":0,"spd":0.5,"acc":10}
验证标准
- 每个关节只执行对应关节动作,没有明显联动异常。
- 关节运动方向与上方范围表中的说明一致。
- 回中步骤执行后,机械臂姿态接近测试前的初始姿态。
- 运动过程中没有明显干涉、撞击或异常抖动。
注意事项
- 实际关节运动范围参考上方各关节角度范围表格,必要时调整
rad值。 - 第一次测试建议保持
spd=0.5,确认方向后再调整速度。 - 本任务只验证单关节动作,不用于搬运物体。
若某个关节执行 JSON 指令后无明显动作,可先参考 产品FAQ 中的关节无动作排查方法。
CMD_JOINTS_RAD_CTRL - 全部关节控制(弧度制)
{"T":102,"base":0,"shoulder":0,"elbow":1.57,"wrist":0,"roll":0,"hand":1.57,"spd":0,"acc":10}
以弧度制形式同时控制全部关节转动。
base:基础关节的目标弧度,范围参考CMD_SINGLE_JOINT_CTRL中rad的说明。shoulder:肩关节的目标弧度。elbow:肘关节的目标弧度。wrist:手腕关节 1 的目标弧度。roll:手腕关节 2 的目标弧度。hand:夹爪关节的目标弧度。spd:转动速度,单位为步/秒。舵机转动一圈为 4096 步,数值越大速度越快;数值为 0 时,以最大速度转动。acc:转动开始和结束时的加速度,单位为 100 步/秒^2。数值越小,启停越平缓;可设置为 0~254。
CMD_EOAT_HAND_CTRL - 末端关节控制(弧度制)
{"T":106,"cmd":3.14,"spd":0,"acc":0}
以弧度制形式控制夹爪关节的转动角度。
cmd:夹爪关节需要转动到的目标弧度。EOAT_JOINT初始位置默认角度为 3.141593,转动范围为 1.08~3.14;角度减少时,夹爪关节张开。spd:转动速度,单位为步/秒。舵机转动一圈为 4096 步,数值越大速度越快;数值为 0 时,以最大速度转动。acc:转动开始和结束时的加速度,单位为 100 步/秒^2。数值越小,启停越平缓;可设置为 0~254。
CMD_SINGLE_JOINT_ANGLE - 单独关节控制(角度制)
{"T":121,"joint":1,"angle":0,"spd":10,"acc":10}
以角度制形式控制某个关节转动。
joint:关节序号,含义与CMD_SINGLE_JOINT_CTRL中的joint相同。angle:需要转动到的目标角度。各关节以初始位置为基准,范围和方向如下。
| 关节名称 | 初始值 | 范围 | 转动方向 |
|---|---|---|---|
BASE_JOINT | 0° | -180°~180° | 增加时向左转动,减少时向右转动 |
SHOULDER_JOINT | 0° | -90°~90° | 增加时向前转动,减少时向后转动 |
ELBOW_JOINT | 90° | 0°~180° | 增加时向下转动,减少时向反方向转动 |
WRIST_JOINT | 0° | -90°~90° | 增加时手腕关节 1 向下转动,减少时向上转动 |
ROLL_JOINT | 0° | -180°~180° | 增加时手腕关节 2 顺时针转动,减少时逆时针转动 |
EOAT_JOINT | 180° | 45°~180° | 减少时夹爪关节张开 |
spd:转动速度,单位为 °/s。数值越大速度越快;数值为 0 时,以最大速度转动。acc:转动开始和结束时的加速度,单位为 °/s^2。数值为 0 时,按照最大加速度运行。
CMD_JOINTS_ANGLE_CTRL - 全部关节控制(角度制)
{"T":122,"b":0,"s":0,"e":90,"t":0,"r":0,"h":180,"spd":10,"acc":10}
以角度制形式同时控制全部关节转动。
b:基础关节的目标角度,范围参考CMD_SINGLE_JOINT_ANGLE中angle的说明。s:肩关节的目标角度。e:肘关节的目标角度。t:手腕关节 1 的目标角度。r:手腕关节 2 的目标角度。h:夹爪关节的目标角度。spd:转动速度,单位为 °/s。数值越大速度越快;数值为 0 时,以最大速度转动。acc:转动开始和结束时的加速度,单位为 °/s^2。数值为 0 时,按照最大加速度运行。
CMD_DELAY_MILLIS - 延时等待
{"T":111,"cmd":3000}
暂停 3000 毫秒,常用于多条指令之间的等待。
挑战任务
关节角度与延时流程验证
任务目标
只使用 Web 端 MOVING CTRL 区域中的命令按钮,验证角度制单关节控制、延时等待和夹爪开合能否按顺序执行。
适用场景
- 教学演示中的角度制控制验证
- 关节角度单位切换后的动作检查
- 夹爪开合动作回归检查
操作步骤
Web 端每次选择一个 MOVING CTRL 命令按钮,修改输入框中的 JSON 参数后发送。每次发送运动指令后,等待机械臂动作结束,再执行下一步。
1. 抬起肩关节
点击 CMD_SINGLE_JOINT_ANGLE,将 JSON 改为:
{"T":121,"joint":2,"angle":90,"spd":30,"acc":20}
2. 肩关节回到 0°
点击 CMD_SINGLE_JOINT_ANGLE,将 JSON 改为:
{"T":121,"joint":2,"angle":0,"spd":30,"acc":20}
3. 张开夹爪
点击 CMD_EOAT_HAND_CTRL,将 JSON 改为:
{"T":106,"cmd":1.08,"spd":10,"acc":10}
验证标准
- 肩关节能转到目标角度附近。
- 肩关节能回到 0° 附近。
- 夹爪能完成张开动作。
注意事项
joint=2对应肩关节,角度单位为 °。- 如果肩关节运动幅度过大,可先将
angle改为45进行测试。 - 夹爪张开角度可根据实际夹爪状态调整
cmd值,范围参考CMD_EOAT_HAND_CTRL的说明。 - 本任务只验证动作顺序,不用于夹取物体。
三维直角坐标控制
机械臂的坐标轴定义基于右手定则:机械臂正前方为 X 轴正方向,机械臂前方的左侧为 Y 轴正方向,机械臂竖直正上方为 Z 轴正方向。
CMD_XYZT_DIRECT_CTRL - 机械臂末端点位置控制(逆运动学)
{"T":1041,"x":235,"y":0,"z":234,"t":0,"r":0,"g":3.14}
控制机械臂末端点运动到指定位置,并给定末端姿态。
x、y、z:末端点三维空间坐标,单位为 mm。t:Pitch 角。r:Roll 角。g:夹爪角度,弧度制。
该指令不会引起进程阻塞。由于底层没有插值计算,调用后机械臂会直接运动到目标点,适合连续发送新的相邻目标点。连续发送时,相邻目标点的位置差异不宜过大。目标点变化过大时机械臂动作会很突然。首次测试时只使用 1~2 mm 的位置变化,机械臂周围不要放置物体,手和身体远离机械臂运动范围。
CMD_XYZT_GOAL_CTRL - 机械臂末端点位置控制(逆运动学)
{"T":104,"x":235,"y":0,"z":234,"t":0,"r":0,"g":3.14,"spd":0.25}
控制机械臂末端点运动到指定位置,并给定末端姿态。
x、y、z:末端点三维空间坐标,单位为 mm。t:Pitch 角。r:Roll 角。g:夹爪角度,弧度制。spd:运动速度。数值越大速度越快;该指令底层包含曲线速度控制,实际速度并非恒定值。
该指令会引起进程阻塞。机械臂运动到目标位置前,后续指令可能需要等待。
挑战任务
轻量物料转移流程验证
任务目标
只使用 Web 端 MOVING CTRL 区域中的命令按钮,完成一次短距离夹取、抬起、放下动作,验证坐标控制和夹爪控制能否配合执行。
适用场景
- 小型物料搬运
- 料盘取放
- 教学中的 Pick & Place 演示
- 坐标控制与夹爪控制联合验证
操作步骤
Web 端每次选择一个 MOVING CTRL 命令按钮,修改输入框中的 JSON 参数后发送。每次只发送一条指令,等待机械臂动作结束后,再执行下一步。
1. 移动到物体上方
点击 CMD_XYZT_GOAL_CTRL,将 JSON 改为:
{"T":104,"x":230,"y":0,"z":180,"t":0,"r":0,"g":3.14,"spd":0.15}
2. 下降到夹取高度
点击 CMD_XYZT_GOAL_CTRL,将 JSON 改为:
{"T":104,"x":230,"y":0,"z":145,"t":0,"r":0,"g":3.14,"spd":0.12}
3. 张开夹爪
点击 CMD_EOAT_HAND_CTRL,将 JSON 改为:
{"T":106,"cmd":1.08,"spd":0,"acc":10}
4. 闭合夹爪
点击 CMD_EOAT_HAND_CTRL,将 JSON 改为:
{"T":106,"cmd":3.14,"spd":0,"acc":10}
5. 抬起物体
点击 CMD_XYZT_GOAL_CTRL,将 JSON 改为:
{"T":104,"x":230,"y":0,"z":180,"t":0,"r":0,"g":3.14,"spd":0.15}
6. 张开夹爪释放
点击 CMD_EOAT_HAND_CTRL,将 JSON 改为:
{"T":106,"cmd":1.08,"spd":0,"acc":10}
7. 抬起离开
点击 CMD_XYZT_GOAL_CTRL,将 JSON 改为:
{"T":104,"x":230,"y":0,"z":200,"t":0,"r":0,"g":3.14,"spd":0.15}
验证标准
- 机械臂能在短距离内完成下降、夹爪开合、抬起和释放动作。
- 夹爪张开和闭合动作可观察。
- 轻质物体能被夹起,或夹爪能完成夹取动作。
- 运动过程中没有明显干涉、撞击或异常抖动。
注意事项
- 第一次测试建议使用泡沫块、纸团或轻质塑料件。
- 如果夹爪无法夹住物体,优先调整
z高度和cmd/g夹爪开合值。 CMD_XYZT_GOAL_CTRL中的g也会影响夹爪角度,因此本任务先下降到夹取高度,再单独发送CMD_EOAT_HAND_CTRL控制夹爪。- 如果下降高度不合适,只调整第 2 步的
z值。 - 不要夹取过重、过硬、易碎或危险物体。
CMD_SERVO_RAD_FEEDBACK - 获得机械臂的反馈
{"T":105}
获取机械臂末端点位置、各关节角度、负载、电压和扭矩开关状态。
反馈示例:
{"T":1051,"x":344.9311553,"y":4.762362463,"z":206.9881693,"tit":0.056757289,"b":0.013805827,"s":0,"e":1.61528177,"t":0.012271846,"r":-0.006135923,"g":3.130854788,"tB":-44,"tS":0,"tE":128,"tT":48,"tR":32,"tG":-20,"torswitchB":1,"torswitchS":1,"torswitchE":1,"torswitchT":1,"torswitchR":1,"torswitchG":1,"v":1210}
x、y、z:末端点 X 轴、Y 轴、Z 轴坐标。tit、b、s、e、t、r、g:分别代表末端姿态、基础关节、肩关节、肘关节、手腕关节 1、手腕关节 2、夹爪关节角度,以弧度制显示。tB、tS、tE、tT、tR、tG:分别代表基础关节、肩关节、肘关节、手腕关节 1、手腕关节 2、夹爪关节的负载。torswitchB、torswitchS、torswitchE、torswitchT、torswitchR、torswitchG:分别代表对应关节的扭矩开关状态,0为关闭扭矩锁,1为开启扭矩锁。v:当前电压,单位为 0.01V。
连续运动控制
前置知识
顺运动 vs. 逆运动学
顺运动学(Forward Kinematics, FK) 给出一组关节角度(比如 base=0, shoulder=1.57, elbow=0),用于计算机械臂末端在空间中的位置。
逆运动学(Inverse Kinematics, IK) 给出一个末端目标位置(比如 x=200, y=50, z=150),用于反向求解各关节需要转动的角度。
- 顺运动学:关节角度 → 末端位置。
- 逆运动学:末端位置 → 关节角度。
CMD_CONSTANT_CTRL - 连续运动控制(角度控制 + 逆运动学控制)
{"T":123,"m":0,"axis":0,"cmd":0,"spd":0}
使机械臂各关节或机械臂末端点在输入指令后连续运动,直到收到停止指令或新的控制指令。
m:连续运动控制模式。0:角度控制模式,控制机械臂各关节角度连续转动。1:坐标控制模式,控制机械臂末端点坐标连续移动。
axis:控制对象。不同模式下的含义不同。
m | axis | 控制对象 |
|---|---|---|
| 0 | 1 | BASE 基础关节 |
| 0 | 2 | SHOULDER 肩关节 |
| 0 | 3 | ELBOW 肘关节 |
| 0 | 4 | WRIST 手腕关节 1 |
| 0 | 5 | ROLL 手腕关节 2 |
| 0 | 6 | HAND 夹爪关节 |
| 1 | 1 | X 轴 |
| 1 | 2 | Y 轴 |
| 1 | 3 | Z 轴 |
| 1 | 4 | Pitch 角 |
| 1 | 5 | Roll 角 |
| 1 | 6 | HAND 夹爪 / 手腕关节 |
cmd:运动状态。0:STOP,停止运动。1:INCREASE。角度控制模式下增加角度;坐标控制模式下增加坐标轴值。2:DECREASE。角度控制模式下减少角度;坐标控制模式下减少坐标轴值。
spd:速度系数。数值越大速度越快;由于各关节转速有上限,建议取值范围为 0~20。
挑战任务
连续微调对准验证
任务目标
只使用 Web 端 MOVING CTRL 区域中的命令按钮,模拟工程调试中的人工微调对准流程:通过连续运动指令让机械臂末端缓慢靠近目标点,并用停止指令及时停止。
适用场景
- 工装调试
- 夹取前位置微调
- 末端点对准目标中心
- 坐标点记录前的人工校准
操作步骤
Web 端每次选择一个 MOVING CTRL 命令按钮,修改输入框中的 JSON 参数后发送。执行连续运动时,需要准备下一条停止指令。
1. 移动到安全观察位置
点击 CMD_XYZT_GOAL_CTRL,将 JSON 改为:
{"T":104,"x":230,"y":0,"z":180,"t":0,"r":0,"g":3.14,"spd":0.2}
2. X 轴正方向缓慢连续移动
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":1,"cmd":1,"spd":4}
3. 停止 X 轴运动
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":1,"cmd":0,"spd":4}
4. Y 轴正方向缓慢连续移动
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":2,"cmd":1,"spd":4}
5. 停止 Y 轴运动
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":2,"cmd":0,"spd":4}
6. Z 轴缓慢下降
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":3,"cmd":2,"spd":3}
7. 停止 Z 轴运动
点击 CMD_CONSTANT_CTRL,将 JSON 改为:
{"T":123,"m":1,"axis":3,"cmd":0,"spd":3}
8. 读取对准后的当前位置
点击 CMD_SERVO_RAD_FEEDBACK,保持默认 JSON:
{"T":105}
验证标准
- 连续运动方向与坐标系定义一致。
- 每次发送
cmd=0后,机械臂能及时停止。 - 可通过观察将末端点移动到目标附近。
- 发送
T=105后,能记录当前x/y/z作为后续定位参考。
注意事项
- 连续运动测试时必须随时准备发送
cmd=0停止指令。 - 第一次测试建议
spd使用3~4,不要直接使用高速。 - 如果运动方向与预期不一致,应立即停止并重新核对
axis和cmd。 - 本任务适合训练“人工观察 + 连续微调 + 反馈记录”的调试流程。
FLASH 文件系统操作
前置知识
Flash 文件系统与掉电保存
机械臂运行时的临时变量默认保存在 RAM 中,断电后不会保留。需要在下次上电后继续读取的数据,例如任务文件、WiFi 配置和开机任务,需要写入 Flash 存储器。
核心概念
| 概念 | 说明 |
|---|---|
| Flash | 一种非易失性存储芯片,断电后内容不丢失。常见容量 4MB、16MB 等。 |
| 文件系统 | 一种管理 Flash 上数据的软件层,可通过文件名和读写、删除等操作管理数据。 |
| 写入时机 | 在数据变化后主动调用保存函数,将数据写入 Flash。 |
| 读取时机 | 上电初始化时,从 Flash 中读取文件,恢复到变量中。 |
FLASH 文件操作
CMD_SCAN_FILES - 扫描文件
{"T":200}
扫描当前 Flash 文件系统中的全部文件。 返回每个文件的文件名和文件内的第一行内容。
CMD_CREATE_FILE - 新建文件
{"T":201,"name":"file.txt","content":"inputContentHere."}
新建一个文件。
name:文件名称(需包含完整后缀)content:文件第一行内容
CMD_READ_FILE - 读取文件
{"T":202,"name":"mission_a.mission"}
读取某一个文件的内容,返回内容会标注行号。
name:文件名称(需包含完整后缀)
CMD_DELETE_FILE - 删除文件
{"T":203,"name":"file.txt"}
删除指定文件。
name:文件名称(需包含完整后缀)
CMD_APPEND_LINE - 追加行
{"T":204,"name":"file.txt","content":"inputContentHere."}
在指定文件的末尾增加一行内容。
name:文件名称content:要增加的内容
CMD_INSERT_LINE - 插入行
{"T":205,"name":"file.txt","lineNum":3,"content":"content"}
在指定文件中的指定行数处插入一行内容。
name:文件名称lineNum:插入的行数(第一行为 1)content:要插入的内容
CMD_REPLACE_LINE - 替换行
{"T":206,"name":"file.txt","lineNum":3,"content":"Content"}
替换指定文件中的指定行数的内容。
name:文件名称lineNum:要替换的行数content:替换后的内容
CMD_READ_LINE - 读取行
{"T":207,"name":"file.txt","lineNum":3}
读取指定文件中的指定行数的内容。
name:文件名称lineNum:要读取的行数
CMD_DELETE_LINE - 删除行
{"T":208,"name":"file.txt","lineNum":3}
删除指定文件的指定行数的内容。
name:文件名称lineNum:要删除的行数
文件类型说明
.mission 文件:任务文件,可存储指令用于机械臂批量操作boot.mission:开机自动运行的任务文件(无文件时自动创建)wifiConfig.json:存储 WiFi 相关配置(无文件时自动创建)
返回格式示例
扫描文件返回:
>>>---=== File Name and First line ===---<<<
[file]: [boot.mission]
[first line]:
{"name":"boot","intro":"these cmds run automatically at boot."}
>>>---=== File Name and First line ===---<<<
[file]: [mission_a.mission]
[first line]:
{"name":"mission_a","intro":"test mission created in flash."}
读取文件返回:
---=== File Content ===---
reading file: [mission_a.mission] starts:
[lineNum: 1 ] - {"name":"mission_a","intro":"test mission created in flash."}
[lineNum: 2 ] - {"T":104,"x":235,"y":0,"z":234,"t":0,"r":0,"g":3.14,"spd":0.25}
^^^ ^^^ ^^^ reading file: mission_a.mission ends. ^^^ ^^^ ^^^
步骤录制和重现
在 ESP32 的 Flash 文件系统中存一个 .mission 文件,里面放 JSON 指令,就能批量录制和回放机械臂的动作。
本部分指令与 FLASH 文件系统操作指令的区别在于,本章仅用来对任务文件进行操作,而 FLASH 文件系统操作可以对所有的文件进行操作。
任务文件操作
任务文件操作基于 FLASH 文件系统函数封装,文件名不需要输入".mission"后缀。
CMD_CREATE_MISSION - 新建任务文件
{"T":220,"name":"mission_a","intro":"test mission created in flash."}
用来新建一个任务文件。
name:文件名称intro:文件介绍
CMD_MISSION_CONTENT - 读取任务文件内容
{"T":221,"name":"mission_a"}
用来读取任务文件的具体内容。
name:文件名称 读取到的任务文件为 mission_a.mission,返回值如下:
官方旧版资料中 CMD_MISSION_CONTENT 的 T 值为 221,本教程保留该值。
{"T":221,"name":"mission_a"}
---=== File Content ===---
reading file: [mission_a] starts:
{"name":"mission_a","intro":"test mission created in flash."}
[StepNum: 1 ] - {"T":104,"x":235,"y":0,"z":234,"t":3.14,"spd":0.25}
[StepNum: 2 ] - {"T":104,"x":104.3172406,"y":-112.6415887,"z":65.13450799,"t":0,"r":0,"g":3.14,"spd":0.25}
[StepNum: 3 ] - {"T":114,"led":155}
[StepNum: 4 ] - {"T":104,"x":-163.7763876,"y":-138.2353466,"z":105.0922663,"t":0,"r":0,"g":3.14,"spd":0.5}
[StepNum: 5 ] - {"T":114,"led":0}
[StepNum: 6 ] - {"T":114,"led":255}
[StepNum: 7 ] - {"T":104,"x":156.428798,"y":40.20501586,"z":76.68339473,"t":0,"r":0,"g":3.14,"spd":0.25}
[StepNum: 8 ] - {"T":111,"cmd":3000}
[StepNum: 9 ] - {"T":114,"led":0}
^^^ ^^^ ^^^ reading file: mission_a.mission ends. ^^^ ^^^ ^^^
任务文件的第一行内容为任务文件名称和简要介绍,从第二行起才是需要执行的第一步 JSON 指令。读取结果会标注每个步骤的序号。
实际该任务文件案例的内容如下:
{"name":"mission_a","intro":"test mission created in flash."}
{"T":104,"x":235,"y":0,"z":234,"t":3.14,"spd":0.25}
{"T":104,"x":104.3172406,"y":-112.6415887,"z":65.13450799,"t":0,"r":0,"g":3.14,"spd":0.25}
{"T":114,"led":155}
{"T":104,"x":-163.7763876,"y":-138.2353466,"z":105.0922663,"t":0,"r":0,"g":3.14,"spd":0.5}
{"T":114,"led":0}
{"T":114,"led":255}
{"T":104,"x":156.428798,"y":40.20501586,"z":76.68339473,"t":0,"r":0,"g":3.14,"spd":0.25}
{"T":111,"cmd":3000}
{"T":114,"led":0}
CMD_APPEND_STEP_JSON - 追加 JSON 指令
{"T":222,"name":"mission_a","step":"{\"T\":104,\"x\":235,\"y\":0,\"z\":234,\"t\":3.14,\"r\":0,\"g\":3.14,\"spd\":0.25}"}
用来将一个 JSON 指令追加到指定任务文件中。
name:文件名称step:要添加的 JSON 指令,具体格式参考上面的示例。
CMD_APPEND_STEP_FB - 追加当前位置步骤
{"T":223,"name":"mission_a","spd":0.25}
文件末尾新增运动至当前位置
name:文件名称spd:设置机械臂运动到该目标位置的速度。
CMD_APPEND_DELAY - 追加延迟步骤
{"T":224,"name":"mission_a","delay":3000}
任务文件步骤之间新增延迟指令
name:文件名称delay:延迟时间,单位为毫秒。
CMD_INSERT_STEP_JSON - 插入 JSON 指令
{"T":225,"name":"mission_a","stepNum":3,"step":"{\"T\":114,\"led\":255}"}
任务文件步骤之间新增 JSON 指令到指定序号
name:文件名称stepNum:要插入的步骤序号,从 1 开始计数。step:要插入的 JSON 指令,具体格式参考上面的示例。
本条指令和后续任务文件指令中的 stepNum 表示 JSON 指令执行步数,而不是文件行数。若 stepNum 为 3,则对应任务文件中的第 3 步 JSON 指令。
CMD_INSERT_STEP_FB - 插入当前位置步骤
{"T":226,"name":"mission_a","stepNum":3,"spd":0.25}
任务文件步骤之间新增运动至当前位置到指定序号
name:文件名称stepNum:要插入的步骤序号,从 1 开始计数。spd:设置机械臂运动到该目标位置的速度。
CMD_INSERT_DELAY - 插入延迟步骤
{"T":227,"name":"mission_a","stepNum":3,"spd":3000}
任务文件步骤之间新增延迟指令到指定序号
name:文件名称stepNum:要插入的步骤序号,从 1 开始计数。spd:延迟时间,单位为 ms。该指令沿用官方旧版示例字段名spd,在此处表示延迟时间。
CMD_REPLACE_STEP_JSON - 替换 JSON 指令
{"T":228,"name":"mission_a","stepNum":3,"step":"{\"T\":114,\"led\":255}"}
任务文件步骤之间替换 JSON 指令到指定序号
name:文件名称stepNum:要替换的步骤序号,从 1 开始计数。step:要替换的 JSON 指令,具体格式参考上面的示例。
CMD_REPLACE_STEP_FB - 替换当前位置步骤
{"T":229,"name":"mission_a","stepNum":3,"spd":0.25}
任务文件步骤之间替换运动至当前位置到指定序号
name:文件名称stepNum:要替换的步骤序号,从 1 开始计数。spd:设置机械臂运动到该目标位置的速度。
CMD_REPLACE_DELAY - 替换延迟步骤
{"T":230,"name":"mission_a","stepNum":3,"delay":3000}
任务文件步骤之间替换延迟指令到指定序号
name:文件名称stepNum:要替换的步骤序号,从 1 开始计数。delay:延迟时间,单位为 ms。
CMD_DELETE_STEP - 删除步骤
{"T":231,"name":"mission_a","stepNum":3}
任务文件步骤之间删除指定序号
name:文件名称stepNum:要删除的步骤序号,从 1 开始计数。
CMD_MOVE_TO_STEP - 执行指定步骤
{"T":241,"name":"mission_a","stepNum":3}
执行任务文件中的指定序号命令
name:文件名称stepNum:要执行的步骤序号,从 1 开始计数。
CMD_MISSION_PLAY - 播放任务文件
{"T":242,"name":"mission_a","times":3}
播放任务文件中的所有命令
name:文件名称times:要执行的次数;当值为-1时表示无限循环。
ESP-NOW 控制
前置知识
ESP-NOW 是 ESP32 设备之间的无线通信方式,可在不经过路由器的情况下传输控制数据。RoArm-M3 使用该功能实现广播、单播和组播控制。
机械臂下位机使用固定结构体接收 ESP-NOW 数据:
typedef struct struct_message {
byte devCode; // 设备编号(可忽略,设 0 即可)
float base; // 基座关节弧度
float shoulder; // 肩关节弧度
float elbow; // 肘关节弧度
float hand; // 夹爪/腕关节弧度
byte cmd; // 控制类型(参照各 JSON 指令的 T 值含义)
char message[210]; // 备用字符串,当 cmd==1 时当作 JSON 指令执行
} struct_message;
CMD_BROADCAST_FOLLOWER - 设置广播从动模式
{"T":300,"mode":1}
{"T":300,"mode":0,"mac":"00:00:00:00:00:00"}
设置该设备的广播从动模式。
mode:- 1 - [出厂默认] 该设备可以被其它设备发出的广播信号来控制。
- 0 - 该设备不可以被其它设备发出的广播信号来控制。
mac:在 mode 值为 0 的情况下,唯一 Leader 控制设备的 MAC 地址。给定一个 MAC 地址,则该设备只可以被给定 MAC 地址的设备所发出的 ESP-NOW 信息而控制;如果该设备不需要被任何设备控制,可以输入任意一个编造的 MAC 地址,例如:00:00:00:00:00:00。
CMD_ESP_NOW_CONFIG - 设置 ESP-NOW 工作方式
{"T":301,"mode":3}
设置该设备 ESP-NOW 的工作方式。
mode:ESP-NOW 的工作方式的代号。- 0 - 关闭;
- 1 - 流组播 Leader,持续向 peerList 中的设备发送自己的关节位置信息;
- 2 - 流单播/流广播 Leader,持续向某一 MAC 地址的设备发送自己的关节位置信息,当 MAC 地址设置为 FF:FF:FF:FF:FF:FF 则为流广播控制;
- 3 - [出厂默认] Follower,当机械臂处于这一模式下时,可以接收来自其它 Leader 设备的 ESP-NOW 信息,也可以作为 Leader 设备向其它设备发送 ESP-NOW 信息。
只有在流组播、流单播/流广播模式下,主控制设备会持续向被控制设备发送自己的关节位置信息,手动转动主控制设备,被控制设备才会跟着做出相同的运动动作。
CMD_GET_MAC_ADDRESS - 获取本设备 MAC 地址
{"T":302}
获得本设备的 MAC 地址。
返回值示例:
44:17:93:EE:FD:70
每个设备的 MAC 地址都是独一无二的。使用 ESP-NOW 相关功能时,除广播控制外,都需要获得被控制设备的 MAC 地址。默认情况下,每一台机械臂的 OLED 屏幕上会显示自己的 MAC 地址。
CMD_ESP_NOW_ADD_FOLLOWER - 添加被控制设备到 peerList
{"T":303,"mac":"44:17:93:EE:FD:70"}
将被控制设备的 MAC 地址添加到 peerList 中。peerList 是用来存储 MAC 地址的。
mac:需要添加的被控制设备的 MAC 地址。 peerList 中可以添加十几个 MAC 地址用于组播控制,但是当使用组播控制时,peerList 中不可以存有用于广播控制的 MAC 地址:FF:FF:FF:FF:FF:FF。
CMD_ESP_NOW_REMOVE_FOLLOWER - 从 peerList 删除被控制设备
{"T":304,"mac":"44:17:93:EE:FD:70"}
将被控制设备的 MAC 地址从 peerList 中删除。
mac:需要删除的被控制设备的 MAC 地址。
CMD_ESP_NOW_GROUP_CTRL - 组播控制
{"T":305,"dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
{"T":305,"dev":0,"b":0,"s":0,"e":0,"h":0,"cmd":1,"megs":"{\"T\":114,\"led\":255}"}
使用该指令将信息通过 ESP-NOW 组播发送给 peerList 中的全部设备。 参考 ESP-NOW 通信数据结构体部分的内容,该 JSON 指令中各个键对照结构体变量如下,且含补充部分:
dev:对应变量 devCode。b、s、e、h:分别对应变量 base、shoulder、elbow 和 hand。cmd:ESP-NOW 控制信息类型。- 当
cmd为 0 时,被控制的机械臂会转动到给定的各个关节的角度; - 当
cmd为 1 时,b、s、e、h 无效,在 megs 输入不会引起阻塞的 JSON 指令,机械臂会执行 JSON 指令对应的功能。
- 当
megs:对应变量 message。
CMD_ESP_NOW_SINGLE - 单播/广播控制
{"T":306,"mac":"44:17:93:EE:FD:70","dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
{"T":306,"mac":"FF:FF:FF:FF:FF:FF","dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
使用该指令可以单播或广播控制 peerList 中的设备。
mac:被控制设备的 MAC 地址,当 MAC 地址为 FF:FF:FF:FF:FF:FF 时,该指令为广播信号,会发送给全部设备。 参考 ESP-NOW 通信数据结构体部分的内容,该 JSON 指令中各个键对照结构体变量如下,且含补充部分:dev:对应变量 devCode。b、s、e、h:分别对应变量 base、shoulder、elbow 和 hand。cmd:ESP-NOW 控制信息类型。- 当
cmd为 0 时,被控制的机械臂会转动到给定的各个关节的角度; - 当
cmd为 1 时,b、s、e、h 无效,在 megs 输入不会引起阻塞的 JSON 指令,机械臂会执行 JSON 指令对应的功能。
- 当
megs:对应变量 message。
无论是组播控制,还是单播/广播控制,都需要提前将被控制设备的 MAC 地址添加到 peerList 中。
挑战任务
ESP-NOW 多设备通信验证
任务目标
使用 ESP-NOW 指令验证广播、单播和组播三种通信方式。准备四台机械臂 A、B、C、D,其中 A 作为主控制设备,B、C、D 作为被控制设备。
适用场景
- 多机械臂无线同步控制验证
- ESP-NOW 对端设备配置检查
- 广播、单播、组播通信模式对比
- 多设备联动前的通信链路测试
操作步骤
所有指令都通过机械臂 A 发送。开始前记录机械臂 B、C、D 的 MAC 地址。
1. 添加广播地址到 peerList
{"T":303,"mac":"FF:FF:FF:FF:FF:FF"}
2. 发送广播控制指令
{"T":306,"mac":"FF:FF:FF:FF:FF:FF","dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
3. 添加机械臂 B 的 MAC 地址
将示例中的 MAC 地址替换为机械臂 B 的实际 MAC 地址:
{"T":303,"mac":"44:17:93:EE:FD:70"}
4. 发送单播控制指令
将 mac 字段替换为机械臂 B 的实际 MAC 地址:
{"T":306,"mac":"44:17:93:EE:FD:70","dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
5. 配置组播 peerList
将机械臂 B、C 的 MAC 地址分别添加到 peerList。若 peerList 中存在广播地址,先删除广播地址:
{"T":304,"mac":"FF:FF:FF:FF:FF:FF"}
{"T":303,"mac":"44:17:93:EE:FD:70"}
{"T":303,"mac":"44:17:93:EE:FD:71"}
6. 发送组播控制指令
{"T":305,"dev":0,"b":0,"s":0,"e":1.57,"h":1.57,"cmd":0,"megs":"hello!"}
验证标准
- 广播控制时,处于广播从动模式的设备能接收控制指令。
- 单播控制时,只有指定 MAC 地址的机械臂响应。
- 组播控制时,peerList 中的机械臂响应,未加入 peerList 的设备不响应。
- 若控制失败,可通过 OLED 或反馈信息重新核对 MAC 地址和 ESP-NOW 工作模式。
注意事项
- 广播、单播和组播测试前,先确认各设备供电稳定且周围无障碍物。
- 示例 MAC 地址只用于说明,执行时必须替换为实际设备地址。
- peerList 中不要同时保留广播地址和组播目标地址。
- 本任务只验证 ESP-NOW 通信链路,不用于评估机械臂负载能力。