上一篇文章中介绍了 ArduPliot 传感器采集用到的集中基本协议
初学者可以先阅读上一篇文章 https://mp.csdn.net/console/editor/html/106586743
英文原文地址 https://ardupilot.org/dev/docs/code-overview-sensor-drivers.html
基本概念
处理器通过上一篇文章所属的各种协议与外设设备或者传感器通信,ArduPilot 传感器驱动中,设计到一个重要的概念:前端/后端分离,典型的示意图如下。
无人机设备(Vehicle code)代码只能调用库的前端(又称传感器驱动程序)。系统在启动时,前端会根据传感器的自动检测(即在已知的I2C地址上探测响应)或用户定义的_TYPE参数(例如RNGFND_TYPE、RNGFND_TYPE2)创建一个或多个后端。前端维护着指向每个后端的指针,这些指针通常保存在名为 _drivers [] 的数组中。
一般来所,用户可设置的参数始终保存在前端中。
传感器驱动程序如何运行呢
上图显示了 ardupilot 架构的放大视图 ,左上方的蓝色框说明了传感器驱动程序的后端如何在后台线程中运行,收集来自传感器的原始数据,将其转换为标准单位,然后保存在驱动程序内的缓冲区中。
设备代码的主线程定期运行,(例如直升机主线程400 Hz),主线程可以通过驱动程序的前端访问数据。例如,为了计算最新的姿态估计,AHRS / EKF 将从传感器驱动程序的前端获取最新的加速度计,陀螺仪和指南针信息。
该图片有些笼统,对于使用I2C或SPI的驱动程序,它们必须在后台线程中运行,使得传感器的高速通信不会影响主循环的性能,但对于使用串行(又称为UART)接口的驱动程序,在主线程中运行是安全的,因为底层的串行驱动程序本身会在后台收集数据并包含缓冲区。
设备代码和前端示例
以下示例显示了直升机飞行器代码如何从测距仪(又名声纳,激光雷达)中提取数据,直升机代码的调度程序以20Hz的频率调用车辆的 read_rangefinder()任务。下面是此方法的图片,可以在 sensors.cpp文件中看到,rangefinder.update()通过驱动程序的前端调用。
以下是测距仪驱动程序的前端更新方法。这使驱动程序有机会在主线程中进行任何可能需要的常规处理。每个后端的更新方法都依次调用。
UART /串行后端示例
接下来是使用串行协议的LightWare后端的更新方法。如用户Wiki所述,串行测距仪可以连接到任何飞行控制器的串行端口,但是用户必须通过设置 SERIALX_BAUD 和 SERIALX_PROTOCOL 参数来指定使用哪个串行端口以及使用哪种波特率。
在串行驱动程序的后端代码中,它首先通过 serial_manager class 查找用户要使用哪个UART,该类将查找上述参数设置。
每次调用驱动程序的后端 update()方法时,都会调用 get_reading 方法,该方法检查传感器是否收到了新字符,然后对收到的数据进行解码。
由于串行通信自身配备了缓冲区,因此传感器的所有数据处理(请参见get_reading方法)都在此处在主线程中运行。即就像在I2C和SPI驱动程序中看到的那样,没有“ register_periodic_callback”。
I2C后端示例
此示例显示了 Lightware I2C 驱动程序的后端。在这种情况下,前端会在初始化期间获取 I2C 总线并将其传递给后端。
SPI后端示例
此示例显示了MPU9250 IMU 的驱动后端运行方式,其中数据包括陀螺仪,加速度计和指南针。前端获取 SPI 总线,并在初始化期间将其传递到后端。
在初始化期间将调用 start()方法并配置传感器,使用信号量来确保不干扰同一总线上的其他 SPI 设备。
已注册_read_sample 方法,以便在1000hz处调用它。请注意,在_read_sample方法中无需使用/提供信号量,因为这是作为定期回调代码的一部分完成的。
_block_read显示了如何从传感器的寄存器中读取数据。
其他建议
编写传感器驱动程序时,切勿包含任何等待或睡眠代码,因为这会延迟与所使用总线相关的主线程或后台线程。
如果编写了新库,则必须将其添加到车辆目录中的 wscript 文件(即/ ardupilot / ArduCopter / wscript)中,以便将其链接到最终的二进制文件中。
知识总结
传感器驱动运行过程中,前后台运行的设计宗旨是保证I2C或SPI的驱动程序在后台线程中运行,使得传感器的高速通信不会影响主循环的性能,但对于使用串行(又称为UART)接口的驱动程序,在主线程中运行是安全的,因为底层的串行驱动程序本身会在后台收集数据并包含缓冲区,可以实现数据存储。
对于类似 I2C 或者 SPI 接口类型传感器而言,初始化时首先将配置参数传递到后端,并且通过 register_periodic_callback 回调函数定时调用数据采集与数据解码任务,从而完成后台数据采集。
上述总结基于本人理解,有误之处烦请各位指出,邮箱: liuruiruijob@126.com