3. DroneCAN协议入门
DroneCAN 是无人机与飞控设备之间广泛使用的一种轻量级现场总线协议。它并不是凭空出现的新协议,而是从 UAVCAN v0 演化而来的工程化分支。理解 DroneCAN 的起源、设计哲学、与 UAVCAN 的关系,以及它的节点模型和通信模式,是后续进行飞控设备开发、固件配置和故障排查的基础。
一、协议起源:从 UAVCAN v0 到 DroneCAN
UAVCAN 最初由 Pavel Kirienko 等人提出,目标是面向航空航天与机器人领域,提供一种基于 CAN 总线的、去中心化的、可自描述的通信协议。UAVCAN v0 在 PX4、ArduPilot 等开源飞控生态中被大量采用,用于电调、GPS、磁力计、电源模块、空速计等设备。
随着 UAVCAN 协议进入 v1 标准化阶段,其规范、工具链和许可证模式发生了变化。部分无人机厂商和开源社区希望继续保持 v0 的轻量、开放和易用特性,于是将 UAVCAN v0 的代码与规范分支独立出来,形成了 DroneCAN。因此,DroneCAN 可以理解为“面向无人机场景、延续 UAVCAN v0 设计理念、由社区共同维护”的协议实现。
关键结论:DroneCAN 与 UAVCAN v0 在报文格式、DSDL 描述、CAN 帧结构上高度兼容;但与 UAVCAN v1 不是简单升级关系,二者在寻址、传输层和工具链上存在明显差异。
二、设计哲学:去中心化、自描述、可互操作
DroneCAN 的设计哲学可以概括为以下四点:
- 去中心化:没有主站轮询,所有节点平等竞争总线,节点可动态加入或退出。
- 自描述:每个数据类型通过 DSDL 文件定义,包含字段名、类型、单位和默认值,设备可被自动识别。
- 面向消息:通信以“主题”和“服务”为核心,而不是寄存器地址,降低耦合。
- 资源受限友好:基于 CAN 2.0B,单帧最多 8 字节,适合 MCU 和实时系统。
这些哲学直接决定了 DroneCAN 的节点模型和通信模式:节点不需要预先分配固定地址,而是通过动态节点 ID 分配机制获得唯一 ID;数据通过发布/订阅传播,配置通过服务请求/响应完成。
三、与 UAVCAN 的关系:兼容、分支与差异
很多初学者会把 DroneCAN 和 UAVCAN 混为一谈。实际上,DroneCAN 是 UAVCAN v0 的延续,而 UAVCAN v1 是另一条演进路线。下表给出核心对比:
| 对比项 | DroneCAN | UAVCAN v1 |
|---|---|---|
| 协议基础 | UAVCAN v0 分支 | 重新设计的 v1 规范 |
| 寻址方式 | 动态节点 ID,1~127 | 固定节点 ID + 主题端口 |
| 数据类型 | DSDL 0.1 | DSDL 1.0 |
| 传输层 | CAN 2.0B,8 字节帧 | CAN FD / 以太网 |
| 典型生态 | PX4、ArduPilot、AP_Periph | 新一代 UAVCAN 工具链 |
在飞控设备开发中,如果目标是兼容现有 PX4/ArduPilot 生态,通常选择 DroneCAN;如果面向未来 CAN FD 和更大带宽场景,则需要评估 UAVCAN v1。
四、节点模型:逻辑节点、物理节点与动态 ID
DroneCAN 网络中的每个设备称为一个节点。节点可以是一个独立的 MCU 设备,也可以是飞控内部的一个逻辑功能单元。每个节点必须具有:
- 节点 ID:1~127,0 保留,255 为广播。
- 节点名称:如
gnss、esc、power,用于人类识别。 - 节点状态:OK、WARNING、ERROR、CRITICAL、OFFLINE。
- 健康信息:电压、温度、错误计数等。
节点启动后,会通过动态节点 ID 分配协议申请一个空闲 ID。飞控或分配器负责维护 ID 表,避免冲突。节点还会周期性发送 NodeStatus 心跳,让其他节点感知其在线状态。
五、通信模式:发布/订阅与服务请求/响应
DroneCAN 的通信模式分为两类,理解它们的差异对开发至关重要。
1. 发布/订阅(Pub/Sub):发送方将数据发布到某个主题,所有订阅该主题的节点都会收到。它是一对多、无连接、无确认的,适合周期性的状态广播,例如 GNSS 位置、电池电压、姿态估计。发布频率由发送方决定,接收方通过超时判断数据是否过期。
2. 服务请求/响应(RPC):客户端向服务端发送请求,服务端返回响应。它是一对一、有确认的,适合参数读写、固件升级、节点信息查询。请求和响应都带有传输 ID,支持多帧传输和超时重试。
# 典型 DroneCAN 主题与服务示例
uavcan.protocol.NodeStatus # 心跳,所有节点周期发布
uavcan.equipment.gnss.Fix # GNSS 定位信息,GNSS 节点发布
uavcan.equipment.power.BatteryInfo # 电池电压/电流,电源节点发布
uavcan.equipment.esc.RawCommand # 电调原始命令,飞控发布
uavcan.protocol.GetNodeInfo # 服务:查询节点信息
uavcan.protocol.param.GetSet # 服务:读写参数
uavcan.protocol.RestartNode # 服务:重启节点
六、案例场景:GNSS 节点接入飞控
假设我们开发一个 DroneCAN GNSS 节点,接入 PX4 飞控。典型流程如下:
- 节点上电,发送
NodeStatus心跳,申请动态节点 ID。 - 飞控通过
GetNodeInfo获取节点名称、软件版本和硬件版本。 - GNSS 节点周期发布
uavcan.equipment.gnss.Fix,包含经纬度、高度、速度、卫星数。 - 飞控订阅该主题,将数据送入 EKF 融合。
- 地面站通过
param.GetSet读取或修改 GNSS 节点参数,如波特率、动态模型。
调试建议:使用 dronecan_gui_tool 或 uavcan_gui_tool 可以直观查看总线上的节点、主题和服务。先确认心跳和节点 ID,再检查主题发布频率,最后验证服务响应。
七、常见误区与复盘
- 误区一:把 DroneCAN 当成 UAVCAN v1。二者数据格式和工具链不同,混用会导致节点无法识别。
- 误区二:忽略节点 ID 冲突。动态分配失败时,两个节点可能使用同一 ID,导致总线异常。应检查分配器日志。
- 误区三:认为发布/订阅有确认。Pub/Sub 不保证送达,接收方必须做超时和有效性判断。
- 误区四:服务调用不设超时。RPC 必须设置合理超时和重试,否则会阻塞任务。
复盘要点:DroneCAN 的稳定性依赖“心跳 + 超时 + 动态 ID”三件套。开发新节点时,优先保证 NodeStatus 心跳稳定,再实现主题发布和服务响应,最后再优化带宽和频率。