基于 DJI RoboMaster Development Board Type C(大疆 RoboMaster C 型开发板) 的全向移动底盘控制工程,面向 Robocon、RoboMaster和机器人底盘原型开发。
项目支持:
- 三轮 120° 全向轮底盘;
- 四轮 X 型全向轮底盘;
- DJI M3508 电机与 C620 电调;
- DJI DBUS 遥控器;
- CAN 电机反馈与速度闭环;
- FreeRTOS 周期控制任务;
- 遥控器/电机离线保护和首次上电限流。
Important
本工程针对的是 DJI RoboMaster C 型开发板,主控为 STM32F407IGHx,不是普通 STM32F4 最小系统板,也不是 A 型或其他型号 RoboMaster 开发板。工程中的时钟、CAN、DBUS、IMU、LED、FreeRTOS 和引脚初始化均继承自大疆 C 板示例工程。迁移到其他控制板时必须重新配置板级外设和引脚。
Warning
M3508 底盘具备较大的输出力矩。首次通电必须架空车轮、启用调试限流,并准备能够直接切断动力电源的急停方式。离线软件检查不能替代实物接线、轮序、方向和急停测试。
本工程以 DJI C 型开发板示例 17.chassis_task 为底层骨架,保留其成熟的 STM32 HAL、CMSIS-RTOS/FreeRTOS、DBUS、CAN、设备离线检测、PID 和板载传感器支持,在此基础上重新整理底盘运动学和 M3508 控制接口。
原示例的轮速分解固定面向四轮麦克纳姆底盘。本项目将运动学独立为 omni_kinematics.c,使上层只需给出车体速度:
vx:前后平移速度
vy:左右平移速度
wz:底盘旋转角速度
运动学模块会根据配置生成三路或四路轮缘速度,再由各电机速度 PID 计算 C620 所需电流。
| 项目 | 默认值 |
|---|---|
| 控制板 | DJI RoboMaster Development Board Type C |
| MCU | STM32F407IGHx,UFBGA176 |
| 底盘结构 | 四轮 X 型全向轮 |
| 电机/电调 | M3508 + C620 |
| 电机反馈 ID | 0x201~0x204 |
| 电流控制帧 | 0x200 |
| CAN 总线 | CAN1,1 Mbit/s |
| 遥控器 | DJI DBUS,USART3,100000 bit/s,偶校验(沿用 C 板示例配置) |
| 控制周期 | 2 ms / 500 Hz |
| 调试限流 | 开启,最大指令值 2500 |
flowchart LR
RC["DJI 遥控器 / DBUS"] --> Decode["通道解析、死区和低通滤波"]
Decode --> Cmd["车体速度指令 vx / vy / wz"]
Cmd --> IK["三轮或四轮全向运动学逆解"]
IK --> Limit["轮速统一归一化限幅"]
Limit --> PID["4 路 M3508 速度 PID"]
PID --> Safety["遥控与电机离线保护、调试限流"]
Safety --> CAN["CAN1:0x200 电流帧"]
CAN --> ESC["C620 电调"]
ESC --> Motor["M3508 + 全向轮"]
Motor --> Feedback["0x201~0x204 转速/电流/温度反馈"]
Feedback --> PID
Feedback --> FK["运动学正解:估计 vx / vy / wz"]
底盘任务每 2 ms 执行一次:
- 判断遥控器开关对应的底盘模式;
- 更新 M3508 转速反馈和底盘速度估计;
- 将遥控通道转换为
vx、vy、wz; - 通过运动学逆解得到各轮目标速度;
- 对全部车轮统一限速,保持运动方向不变;
- 运行各轮速度 PID;
- 检查 DBUS 和电机在线状态;
- 通过 CAN1 发送四路电流指令。
本项目采用车体坐标系:
+vx:车体向前;+vy:车体向左;+wz:从车体上方向下看,逆时针旋转;- 线速度单位为
m/s,角速度单位为rad/s。
三只全向轮的驱动方向相隔 120°:
| 逻辑轮 | C620 ID | 反馈 ID | 驱动方向 |
|---|---|---|---|
| Wheel 0 | 1 | 0x201 |
0° |
| Wheel 1 | 2 | 0x202 |
120° |
| Wheel 2 | 3 | 0x203 |
240° |
| 第 4 路 | 4 | 0x204 |
不使用,程序强制发送 0 |
这里的角度描述的是轮子的主动滚动方向,不是被动滚子方向。
| 逻辑轮 | 安装位置 | C620 ID | 反馈 ID |
|---|---|---|---|
| Wheel 0 | 前左 | 1 | 0x201 |
| Wheel 1 | 前右 | 2 | 0x202 |
| Wheel 2 | 后右 | 3 | 0x203 |
| Wheel 3 | 后左 | 4 | 0x204 |
实际电机安装朝向可能不同,因此方向不能仅凭线色判断。应在架空测试后,通过 CHASSIS_MOTOR_x_DIRECTION 单独修正每只电机的正负号。
设:
L为底盘中心到轮接地点的距离;v0、v1、v2为三只轮的轮缘线速度;vx、vy、wz为车体速度。
三轮逆解为:
三路旋转项均为 L × wz,因此纯旋转时三只轮具有相同的逻辑速度。物理电机正反方向由方向配置进一步映射。
对应正解为:
四轮逻辑轮速为:
四轮正解为:
平移和旋转叠加后,某一只轮可能超过允许速度。程序寻找轮速绝对值最大值 vmax_actual。若它超过配置上限 vmax_limit,则对所有轮使用同一比例缩放:
统一缩放可以限制轮速,同时保留各轮之间的比例,避免分别截断造成运动方向失真。
C620 按 DJI 电机协议周期返回反馈:
| 字节 | 内容 |
|---|---|
| 0~1 | 转子编码器值 ecd |
| 2~3 | 转子转速 speed_rpm,有符号 16 位 |
| 4~5 | 实际转矩电流,有符号 16 位 |
| 6 | 温度 |
| 7 | 保留 |
底盘使用标准帧 0x200 同时控制 ID 1~4:
| 字节 | 对应电机 |
|---|---|
| 0~1 | ID 1 / 0x201 |
| 2~3 | ID 2 / 0x202 |
| 4~5 | ID 3 / 0x203 |
| 6~7 | ID 4 / 0x204 |
每个控制值为大端序有符号 16 位电流指令。工程另外限制了最大控制输出,并在调试模式下进一步限流。
C620 返回的是 M3508 转子转速。轮缘线速度根据轮半径和减速比换算:
其中:
R:轮半径,默认0.076 m;i:减速比,默认19;- 参数必须与实际轮组一致,否则速度估计和 PID 标度都会错误。
每只有效车轮拥有独立 PID:
目标轮缘速度
↓
按减速比/轮径换算后的实际轮缘速度
↓
速度误差 → PID → C620 电流指令
默认 PID 仅作为安全起调值,不是对所有底盘都适用的最终参数。机器人质量、轮径、轮胎接触、供电电压、控制频率和机械阻力都会影响整定结果。
CBoard_Omni_Chassis/
├─ application/
│ ├─ chassis_config.h # 底盘类型、机械参数、方向、限速和 PID
│ ├─ omni_kinematics.c/.h # 三轮/四轮正解、逆解和轮速归一化
│ ├─ chassis_task.c/.h # 2 ms 底盘任务、反馈更新和速度闭环
│ ├─ chassis_behaviour.c/.h # 遥控器模式与速度指令
│ ├─ CAN_receive.c/.h # M3508 反馈解析和电流帧发送
│ ├─ remote_control.c/.h # DJI DBUS 接收与解析
│ ├─ detect_task.c/.h # 遥控器和电机离线检测
│ └─ INS_task.c/.h # C 板板载 IMU 姿态任务
├─ bsp/ # DJI C 板板级支持
├─ components/ # PID、AHRS、BMI088、IST8310 等组件
├─ Drivers/ # STM32F4 HAL 与 CMSIS
├─ Middlewares/ # FreeRTOS
├─ Inc/、Src/ # STM32CubeMX 生成的外设与系统代码
├─ MDK-ARM/ # Keil MDK 工程
├─ tests/ # 运动学参考数据
├─ chassis_task.ioc # STM32CubeMX 配置
└─ LICENSE # GPL-3.0-or-later 完整协议文本
主要修改底盘功能时,建议遵循以下分层:
- 机械尺寸、方向、限速:修改
chassis_config.h; - 底盘几何模型:修改
omni_kinematics.c; - 遥控映射和工作模式:修改
chassis_behaviour.c; - PID 和发送安全逻辑:检查
chassis_task.c; - CAN ID 或电机协议:修改
CAN_receive.c/.h。
- DJI RoboMaster Development Board Type C;
- DJI M3508 电机 3 台或 4 台;
- DJI C620 电调 3 台或 4 台;
- 3 个或 4 个全向轮及对应机械底盘;
- DJI 遥控器和 DBUS 接收机;
- 24 V 级电机动力电源、保险和可靠急停;
- ST-Link 下载器;
- CAN 双绞线和总线终端电阻。
- C 板
CAN1连接所有底盘 C620,CAN_H 对 CAN_H,CAN_L 对 CAN_L。 - CAN 必须采用总线结构,避免长支线;总线物理两端各放置一个 120 Ω 终端电阻。
- C 板、C620 信号地和系统电源地应可靠共地。
- C620 ID 依次设置为 1~3 或 1~4。
- DJI DBUS 接收机连接 C 板 DBUS 接口;MCU 侧使用 USART3 RX(PC11)。
- 电机动力回路必须配置保险、总开关或急停,不要把软件停机作为唯一保护。
Note
chassis_task.ioc 中 CAN1 使用 PD0/PD1,USART3 使用 PC10/PC11。这些是 C 型开发板 MCU 侧引脚信息,实际接线应以开发板丝印和接口定义为准。
所有常用底盘参数集中在 application/chassis_config.h。
// 三轮 120°
#define CHASSIS_GEOMETRY OMNI_CHASSIS_3
// 四轮 X 型
#define CHASSIS_GEOMETRY OMNI_CHASSIS_4_X只能选择一种结构。非法配置会在编译阶段触发 #error。
#define CHASSIS_CENTER_TO_WHEEL_M 0.220f
#define CHASSIS_WHEEL_RADIUS_M 0.076f
#define M3508_REDUCTION_RATIO 19.0fCHASSIS_CENTER_TO_WHEEL_M 应测量底盘旋转中心到轮接地点的距离,而不是车架外形尺寸。
#define CHASSIS_MOTOR_0_DIRECTION 1.0f
#define CHASSIS_MOTOR_1_DIRECTION -1.0f
#define CHASSIS_MOTOR_2_DIRECTION 1.0f
#define CHASSIS_MOTOR_3_DIRECTION -1.0f方向值只能使用 1.0f 或 -1.0f。它会同时作用于目标速度和反馈速度,保证 PID 的符号关系一致。
#define CHASSIS_COMMISSIONING_MODE 1U
#define CHASSIS_COMMISSION_CURRENT 2500首次上板保持 1U。完成架空方向检查和急停测试后,再改为 0U。即使关闭调试模式,输出仍受 CHASSIS_MAX_CAN_CURRENT 限制。
#define CHASSIS_MAX_VX_MPS 1.0f
#define CHASSIS_MAX_VY_MPS 1.0f
#define CHASSIS_MAX_WZ_RADPS 3.0f
#define CHASSIS_MAX_WHEEL_MPS 2.5f
#define CHASSIS_MAX_CAN_CURRENT 8000.0f
#define CHASSIS_SPEED_PID_KP 6000.0f
#define CHASSIS_SPEED_PID_KI 10.0f
#define CHASSIS_SPEED_PID_KD 0.0f建议从低速、低电流开始,每次只调整一类参数,并记录空载与落地负载响应。
- Keil MDK-ARM;
- STM32F4 Device Family Pack;
- ST-Link 驱动;
- 可选:STM32CubeMX,用于查看
.ioc,但不要在不了解代码生成影响时直接覆盖用户代码。
- 打开
MDK-ARM/chassis_task.uvprojx。 - 选择
chassis_tasktarget。 - 确认
application分组中包含omni_kinematics.c。 - Build 工程并消除所有 error;建议同时检查 warning。
- 连接 ST-Link 和 C 板。
- 保持电机动力断开,先下载并确认程序正常启动。
- 准备急停、架空底盘后再接通电机动力。
默认通道定义位于 application/chassis_task.h:
| 功能 | 通道 |
|---|---|
前后 vx |
CH1 / 数组通道 1 |
左右 vy |
CH0 / 数组通道 0 |
旋转 wz |
CH2 / 数组通道 2 |
| 底盘模式开关 | Switch 0 |
默认开关行为:
- 向下:目标速度归零,速度环主动抑制车轮转动;
- 中间:车体坐标系速度控制,推荐用于首次测试;
- 向上:底盘航向闭环模式,依赖 IMU 姿态结果。
如果遥控器离线,底盘直接发送四路零电流,不继续使用最后一次摇杆指令。
- 确认工程选择了正确的三轮/四轮结构;
- 检查轮半径、中心距和减速比;
- 检查 CAN_H/CAN_L、共地和两个终端电阻;
- 确认所有 C620 ID 唯一;
- 确认急停能够物理切断电机动力;
- 保持
CHASSIS_COMMISSIONING_MODE = 1U。
- 架空并固定底盘,确保所有车轮不会接触地面或人员。
- 遥控开关拨到下,接通控制电源和动力电源。
- 在调试器中检查每台电机的
ecd、speed_rpm、given_current和temperate是否更新。 - 开关拨到中,只给极小的前进指令。
- 按本文轮序观察方向,错误轮只修改对应的
CHASSIS_MOTOR_x_DIRECTION。 - 分别执行纯前进、纯左移和纯逆时针旋转。
- 检查正解得到的
vx、vy、wz与指令方向是否一致。 - 关闭遥控器,确认 CAN 电流指令立即归零。
- 逐一断开某台电机反馈,确认对应通道电流归零。
- 将速度和电流限制保持在较低值。
- 在宽阔区域测试前后、横移和旋转。
- 检查底盘是否出现持续振荡、明显偏航、某轮打滑或电机过热。
- 确认急停、遥控掉线停机和重新上电流程可靠。
- 完成所有检查后才逐步提高限制,并重新整定速度 PID。
- DBUS 离线:四路控制电流全部置零;
- 某台电机反馈离线:该通道电流独立置零;
- 三轮模式:第 4 路目标速度与控制电流强制置零;
- 轮速超限:全部车轮按相同比例缩放;
- PID 输出:受最大 CAN 电流约束;
- 调试模式:使用更低的二次电流上限;
- 上电后先等待底层任务和设备初始化,再进入控制循环。
需要注意:发送零电流不等于机械制动,也不能替代保险、急停、限位和可靠的电源设计。
通常是轮序或电机方向错误。先核对 C620 ID 与安装位置,再逐一调整 CHASSIS_MOTOR_x_DIRECTION。不要通过交换多处公式符号来临时修补。
立即切断动力。常见原因包括:
- 目标方向与反馈方向符号不一致;
- C620 ID 与逻辑轮序不一致;
- PID 参数过大;
- DBUS 通道中值或解析异常;
- 调试限流被提前关闭。
检查 CAN_H/CAN_L 是否接反、是否共地、终端电阻、C620 ID、CAN 波特率和电调供电。正常底盘反馈 ID 应为 0x201~0x204。
程序仍发送统一的 0x200 八字节帧,但第 4 路字段固定为零。这是 DJI 四电机组帧协议的正常行为。
检查轮半径、M3508 减速比以及 C620 返回转速是否为转子侧 RPM。轮子负载变形和打滑也会造成开环里程估计偏差。
向上模式使用底盘航向闭环,依赖 C 板板载 IMU 初始化、安装方向和姿态解算。首次底盘测试请使用开关中位的车体坐标速度模式。
已完成:
- Keil 工程 XML 结构检查;
- 新增运动学源码的工程分组检查;
- 三轮和四轮条件编译分支的 C 语法解析;
- 两种结构各 10,000 组随机“逆解→正解”往返测试;
- 最大参考数值误差为
1.332e-15; - DBUS、电机离线、三轮第 4 路和调试限流路径检查。
以上内容为当前已完成的离线验证记录。
当前离线环境未连接实物,也未安装 Keil/ARM 编译器,因此仓库不能宣称已经完成特定机器人整机验证。使用者仍需完成 Keil Build、架空测试和低速落地测试。
工程整合参考:
- DJI C 型开发板
17.chassis_task示例:STM32F4 板级初始化、FreeRTOS、DBUS、CAN、PID、设备检测和 IMU; - 三轮 120° 与四轮运动学思路;
- M3508 反馈和多电机 CAN 组帧思路。
本项目包含并修改了 RoboMaster 官方示例代码。上游项目采用 GNU General Public License v3 或更高版本(GPL-3.0-or-later),因此本项目按相同协议开源。完整协议见 LICENSE,上游许可证见 RoboMaster/Development-Board-C-Examples。分发本项目或其修改版本时,应同时提供相应源代码、保留版权与许可声明,并以 GPL-3.0-or-later 继续授权派生作品。
本项目不是 DJI 官方产品或官方维护仓库。DJI、RoboMaster、M3508、C620 等名称归各自权利人所有,如有侵权请联系删除。
- 增加串口上位机参数整定;
- 增加航向保持与世界坐标系控制;
- 使用 IMU 和轮速进行里程计融合;
- 增加功率限制、电机温度降额和堵转保护;
- 增加自动化 C 单元测试和 CI 编译;
- 支持 ROS/ROS 2 速度指令接口;
- 支持其他减速比和电机型号的统一驱动层。