3. DroneCAN设备模型

DroneCAN 不是简单的“总线+报文”协议,它在上层定义了一套完整的设备模型。理解这套模型,是后续做固件升级、参数读写、节点监控和故障定位的基础。一个 DroneCAN 节点在网络上并不是“匿名设备”,它拥有节点 ID、名称、健康状态、参数集合、固件版本以及可被动态分配的身份信息。总线上的飞控或管理端通过这些信息完成设备发现、参数同步和即插即用。

一、节点属性:设备在总线上的“身份证”

每个 DroneCAN 节点都维护一组核心属性,这些属性通过标准消息对外发布。最关键的包括:

  • 节点 ID(Node ID):1~127 的整数,是总线通信的寻址基础。0 通常保留给管理端或飞控,255 用于匿名节点。
  • 节点名称(Node Name):如 org.ardupilot.esc、com.hex.flow,用于人类识别设备类型。
  • 健康状态(Health):OK、WARNING、ERROR、CRITICAL,反映设备运行状况。
  • 模式(Mode):OPERATIONAL、INITIALIZATION、MAINTENANCE、SOFTWARE_UPDATE 等,固件升级时节点会进入 SOFTWARE_UPDATE 模式。
  • 固件版本(Software Version):主版本、次版本、补丁号及可选 VCS 提交号。
  • 硬件版本(Hardware Version):用于区分同一设备的不同硬件批次。
  • 唯一 ID(Unique ID):128 位全局唯一标识,通常来自 MCU 的 UID 或芯片序列号,是动态分配和即插即用的关键依据。

这些属性通过 uavcan.protocol.NodeStatus、uavcan.protocol.GetNodeInfo 等标准服务获取。管理端周期性接收 NodeStatus,从而知道节点是否在线、是否健康、是否处于可升级状态。

二、参数服务器:设备配置的统一入口

DroneCAN 参数服务器是节点内部的一个标准化参数存储与访问接口。每个节点可以暴露若干参数,例如 ESC 的 ESC_PWM_MIN、ESC_PWM_MAX、ESC_CURRENT_LIMIT,或 GPS 的 GPS_BAUD、GPS_TYPE。参数具有名称、类型、默认值、最小/最大值和当前值。

参数访问通过 uavcan.protocol.param.GetSet 服务完成。管理端可以读取单个参数、批量读取、写入参数,甚至保存到非易失存储。参数服务器让不同厂商的设备拥有一致的配置方式,飞控无需为每种设备写专用驱动。

参数服务器的核心价值:把“设备配置”抽象成统一协议。无论设备是 ESC、GPS、电源模块还是舵机控制器,管理端都用同一套 GetSet 接口读写参数,极大降低了集成成本。

三、动态节点分配与即插即用机制

DroneCAN 支持动态节点 ID 分配。新设备上电时,如果尚未配置固定 ID,会先以匿名节点身份出现,使用 255 作为临时节点 ID,并通过 uavcan.protocol.dynamic_node_id.Allocation 消息请求分配。管理端(通常是飞控)根据设备的唯一 ID、节点名称和当前 ID 占用情况,分配一个空闲的 1~127 节点 ID。

分配完成后,节点会保存该 ID,后续上电直接使用。即插即用机制正是建立在这一流程之上:设备插入总线后,管理端自动发现、自动分配 ID、自动读取节点信息和参数,无需人工配置。对于固件升级场景,这意味着新设备接入后可以立即被识别并进入升级流程。

动态分配依赖唯一 ID。如果两个设备烧录了相同的唯一 ID,会导致分配冲突,表现为节点反复掉线或 ID 冲突告警。生产时应确保每台设备唯一 ID 不同。

四、设备发现流程:从上线到可管理

设备发现是 DroneCAN 管理端与节点建立完整认知的过程。典型流程如下:

  1. 节点上电,发送 NodeStatus,管理端感知到新节点 ID 出现。
  2. 若节点为匿名状态,管理端响应动态分配请求,分配正式节点 ID。
  3. 管理端发送 GetNodeInfo,获取节点名称、固件版本、硬件版本、唯一 ID。
  4. 管理端读取参数列表,同步参数服务器内容。
  5. 管理端根据节点名称和版本判断是否需要固件升级。
  6. 若需要升级,管理端请求节点进入 SOFTWARE_UPDATE 模式,开始固件传输。

下面这张图展示了 DroneCAN 设备模型的核心组成与发现流程关系:

DroneCAN 设备模型与设备发现流程 管理端 / 飞控 Node ID 通常为 0 负责发现、分配、升级 DroneCAN 节点 ESC / GPS / 电源模块 Node ID 1~127 节点属性 • Node ID / 名称 • 健康状态 / 模式 • 固件 / 硬件版本 • 128 位唯一 ID 参数服务器 • GetSet 读写 • 名称 / 类型 / 范围 • 默认值 / 当前值 • 非易失保存 动态节点分配 • 匿名节点 255 • Allocation 请求 • 唯一 ID 去重 • 分配 1~127 设备发现与即插即用流程 1. 上电广播 NodeStatus 2. 动态分配 Allocation 3. 获取信息 GetNodeInfo 4. 同步参数 GetSet 5. 判断升级 SOFTWARE_UPDATE 即插即用 = 自动发现 + 自动分配 ID + 自动同步参数 + 自动判断升级

五、案例与场景:ESC 节点接入与升级

假设一台四轴飞行器使用 DroneCAN ESC。上电后,ESC 以匿名节点身份发送 Allocation 请求,飞控分配 Node ID 10。飞控通过 GetNodeInfo 得知该 ESC 名称为 org.ardupilot.esc,固件版本 1.2.0,唯一 ID 为 0x3A7F...C21D。飞控读取参数,发现 ESC_PWM_MIN=1000、ESC_PWM_MAX=2000。随后飞控检查固件版本,发现最新版本为 1.3.0,于是请求 ESC 进入 SOFTWARE_UPDATE 模式,开始固件传输。升级完成后,ESC 重启,重新走发现流程,飞控确认版本已更新。

# 典型发现日志(示意)
[dronecan] Node 10 online: org.ardupilot.esc
[dronecan] Unique ID: 3A7F...C21D
[dronecan] FW: 1.2.0  HW: 2.1
[dronecan] Param ESC_PWM_MIN = 1000
[dronecan] Param ESC_PWM_MAX = 2000
[dronecan] Upgrade available: 1.3.0
[dronecan] Node 10 entering SOFTWARE_UPDATE
[dronecan] Transfer 100% OK
[dronecan] Node 10 reboot, FW now 1.3.0

六、常见误区与复盘

误区 现象 正确做法
认为节点 ID 可以随意固定 多个设备使用相同 ID,总线冲突 优先使用动态分配,固定 ID 需确保全网唯一
忽略唯一 ID 的唯一性 动态分配失败或节点反复掉线 生产时写入不同唯一 ID,避免克隆固件
参数服务器不保存 重启后参数恢复默认 写入后执行保存操作,确认非易失存储生效
升级前未检查模式 节点拒绝升级或传输中断 先确认节点进入 SOFTWARE_UPDATE 模式
发现流程只看 NodeStatus 无法获取版本和参数 必须结合 GetNodeInfo 和 GetSet 完成完整发现
在固件升级工程中,设备发现不是“可选项”,而是升级流程的前置条件。只有完整获取节点属性、参数和版本信息,才能判断是否需要升级、升级哪个固件、升级后如何验证。跳过发现流程直接传输固件,极易导致设备变砖或版本错乱。