ArduPilot之开源代码Sensor Drivers设计
- 1. 源由
- 2. Sensor Drivers设计
- 2.1 front-end / back-end分层
- 2.2 设计思想分析
- 3 实例理解
- 3.1 驱动初始化
- 3.2 业务应用代码
- 3.3 frond-end代码
- 3.3 back-end代码
- 3.3.1 UART
- 3.3.2 I2C
- 3.3.3 SPI
- 4. 参考资料
1. 源由
飞控代码除了最为基础的姿态控制以外,还要处理很多传感器或者控制单元,比如:雷达/光流计,GPS,起落架,云台等。
这些机载设备是如何整合到飞控应用中就是本章讨论的重点Sensor Drivers设计。
2. Sensor Drivers设计
2.1 front-end / back-end分层
Sensor Drivers设计的重要概念:front-end / back-end分层
- front-end:面向应用
- back-end:设备实例
注:ArduPilot的参数配置,主要应用在front-end层;而就setup系统初始化逻辑是一次性的。因此关于Sensor Driver参数调整,需要重启飞控才能起到真正的效果。
2.2 设计思想分析
基于上述Sensor Driver架构,back-end层在后台通过硬件总线与硬件传感器通信,不管更新缓存数据(并做好更新数据时间戳记录);应用通过front-end接口获取缓存的最新传感器数据;
该分层结构设计主要为了解决多传感器/多硬件总线/低速通信等待/异常容错与高频飞控应用之间的异步和效率问题。
换个角度,通过分层结构设计可以解决:
- 设备轮询耗时等待
- 合理分配轮询/中断,高效利用CPU
- 优化低速传感数据与应用的匹配度(应用频度/任务优先级等)
- 飞控业务解耦硬件驱动API(驱动主要在back-end完成)
3 实例理解
rangefinder传感器种类还是比较多的,目前代码支持大约有30种,市面上应该有更多的硬件,我们围绕这个驱动,作为一个例子。
3.1 驱动初始化
根据前面ArduPilot之开源代码Library&Sketches设计了解到AP_HAL_MAIN_CALLBACKS(&copter)
会将初始化部分关联,调用到AP_Vehicle::setup
,接下去的驱动初始化流程如下:
AP_Vehicle::setup
└──> init_ardupilot
└──> Copter::init_rangefinder
└──> rangefinder.init
└──> detect_instance // _add_backend
如果有多个传感器,配置正确的情况,将会有多个instance或者说多个back-end。
3.2 业务应用代码
通过rangefinder.update
进行业务数据更新。
3.3 frond-end代码
frond-end不关心具体back-end实现是通过哪条总线进来,怎么进来。只负责更新最终获取的缓存中的数据。
3.3 back-end代码
rangefinder传感器实际上是通过UART/I2C/SPI总线中的一种进行通信,这些就需要back-end处理。
3.3.1 UART
根据Param设置SERIALX_BAUD/SERIALX_PROTOCOL获取串口总线。
数据更新记录时间戳,以防脏数据。
鉴于串行总线有内部buffer,所以无需注册回调,直接串口字节流解析处理逻辑。
3.3.2 I2C
通过宏定义或者参数配置I2C地址,注册timer回调函数与设备进行通信。
3.3.3 SPI
自动检测SPI总线,枚举设备,添加到back-end,注册timer回调函数,从而进行SPi通信。
4. 参考资料
【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码框架
【3】ArduPilot飞控之ubuntu22.04-SITL安装
【4】ArduPilot飞控之ubuntu22.04-Gazebo模拟
【5】ArduPilot飞控之Mission Planner模拟
【6】ArduPilot飞控AOCODARC-H7DUAL固件编译
【7】ArduPilot之开源代码Library&Sketches设计