(5)传感器驱动程序

简介: (5)传感器驱动程序

前言

ArduPilot 支持来自许多不同制造商的各种传感器。这方面的一个明显的例子可以在测距仪( list of range finders)(又称声纳、激光雷达)的列表中看到。本页试图解释传感器驱动程序是如何编写和集成到飞行器代码中的。

1 支持的协议

支持 I2CSPIUART(aka Serial)和 CANBUS(特别是 UAVCAN/DRoneCAN)协议。如果你打算编写一个新的驱动程序,你可能需要参考传感器的数据手册,以确定它使用的协议。

1.1 I2C

  • 一个主机,可能有许多从设备;
  • 一种相对简单的协议,适用于短距离通信(即小于1米);
  • 总线以 100kHz 或 400kHz 的速度运行,但与其他协议相比,数据速率相对较低;
  • 只需要4个引脚(VCC,GND,SDA,SCL)。



cda2aa39b78146ba967d36b8d77474bd.png

8d2302fd9cf7405184d790da8111811b.png

1.2 SPI

  • 一个主机,一个从机;
  • 20Mhz+ 的速度意味着它非常快,特别是与 I2C 相比;
  • 只适用于短距离内工作(10厘米);
  • 需要至少5个引脚(VCC、GND、SCLK、主-出-从-入、主-入-从-出)+ 每个从机的一个从机选择引脚。



b9ff310a47d64f80a924ecd04f3f3b3b.png


4e7a57027e1b451a85242f5681542ab4.png

1.3 Serial / UART

  • 一个主机,一个从机;
  • 基于字符的协议,与 I2C 和 SPI 相比,适合长距离通信(如1米);
  • 速度相对较快,57Kbps ~ 1.5Mbps;(Bps (Bytes per second),即字节每秒,因为一字节对应八比特,所以1Bps = 8bps)
  • 至少需要4个引脚(VCC,GND,TX,RX),加上2个可选的引脚(清除发送,清除接收)。

1.4 带有UAVCAN的CAN总线

  • 多主机总线,任何节点都可以在需要时启动数据传输;
  • 基于数据包的协议,适用于非常长的距离;
  • 高速,通常为1Mb(然而,只有50%的总线比特率可以在没有重大冲突的情况下真正使用);
  • 至少需要3个引脚(GND,CAN HI,CAN LO)。可选择使用 VCC 为节点供电;
  • 点对点拓扑结构。不建议使用星形或树枝形拓扑结构;
  • 总线的每一端都需要终端。


c9ca9a8c9c9446fa90defd9f1176b9fb.png

2 前端/后端分离

传感器驱动程序架构中的一个重要概念是前端/后端分离。


1b6220af7f6742d396363734a5d2f823.png

飞行器代码只会调用库(又称传感器驱动程序)的前端。

在启动时,前端根据传感器的自动检测(即探测已知 I2C 地址上的响应)或使用用户定义的 _TYPE 参数(即 RNGFND_TYPE,RNGFND_TYPE2)创建一个或多个后端。前端维护指向每个后端的指针,这些指针通常保存在一个名为 _drivers[] 的数组中。

用户可设置的参数总是被保存在前端。

3 如何以及何时运行驱动程序代码

86f88e14e0154bf2850c884b722c14d2.png

上图显示了 ardupilot 架构的放大视图。左上角的蓝框说明了传感器驱动程序的后端是如何在后台线程中运行的。收集来自传感器的原始数据,转换为标准单位,然后保存在驱动程序的缓冲区内。

无人机代码的主线程定期运行(如 400hz 的旋翼),并通过驱动程序前端的方法访问可用的最新数据。例如,为了计算最新的姿态估计,AHRS/EKF 将从传感器驱动程序的前端获取最新的加速度计、陀螺仪和罗盘信息。

图片是一个小小的概括,对于使用 I2C 或 SPI 的驱动程序,它们必须在后台线程中运行,这样与传感器的高速通信就不会影响主循环的性能,但对于使用串行(又称 UART)接口的驱动程序,在主线程中运行是安全的,因为底层串行驱动程序本身在后台收集数据并包括一个缓冲区。

4 无人机代码和前端示例

下面的例子显示了 Copter 无人机代码如何从测距仪(又称声纳、激光雷达)驱动程序中获取数据。旋翼代码的调度程序(scheduler)以 20Hz 的频率调用无人机的 read_rangefinder() 方法。下面是这个方法的图片,可以在 sensors.cpp 文件中看到最新版本。rangefinder.update() 方法是对驱动程序前端的一个调用。


3c6d8be7354a45969f28a5a38e0dd070.png

下面是测距仪驱动程序的前端更新方法( update method)。这给了驱动程序一个机会在主线程中做任何它可能想要的一般处理。每个后端的更新方法被依次调用。


5bc5a30fb9d348a9893d733348498a76.png

5 UART / Serial后端示例

接下来是 LightWare 后端(LightWare back-end)使用串行协议的更新方法。如用户维基上(user wiki)所述,串行测距仪可以连接到飞行控制器的任何一个串行端口,但用户必须通过设置SERIALX_BAUD 和 SERIALX_PROTOCOL 参数来指定哪个串行端口,以及使用什么波特率。

92d0ec9b08d44dedae4f65d766eaf0e3.png

在串行驱动程序的后端代码(backend code)中,它首先通过 serial_manager 类找到用户要使用的 UART,该类将查找上述的参数设置。


30dccef1b372463fa94d0f811557f221.png

每次调用驱动程序的后端 update() 方法时,它都会调用 get_reading 方法,检查是否有新的字符从传感器到达,然后对其进行解码。

如上所述,由于串行协议实现了自己的缓冲,来自传感器的任何数据(见 get_reading 方法)的处理都在主线程中运行。也就是说,没有像你在 I2C 和 SPI 驱动中看到的 "register_periodic_callback"。


eb18082cc5724c899b6f4e726cfd4058.png


e1569ecc05a34c06b860bfc178e07dcb.png

6 I2C后端示例

这个例子显示了 Lightware I2C 驱动程序的后端。在这种情况下,前端获得 I2C 总线,并在初始化时将其传递给后端。


b260682778f747af97e97a470c4de397.png

然后后端的 init 方法注册其“timer”方法,以 20hz 的频率调用。在 timer 方法中(未显示),get_reading() 方法被调用,它从传感器中读取字节并将距离转换为厘米。

7 SPI后端示例

这个例子显示了 MPU9250 IMU 的后端,它包括一个陀螺仪、加速度计和罗盘。前端获得 SPI 总线,并在初始化时将其传递给后端。


30804d76819841dabeb81d8aa9736871.png

在初始化期间将调用 start() 方法并配置传感器。它使用信号量来确保不干扰同一总线上的其他 SPI 设备。

注册 _read_sample 方法,以便以 1000hz 调用它。请注意,在 _read_sample 方法中不需要获取/释放信号量,因为这是作为定期回调代码的一部分完成的。

_block_read 方法显示如何从传感器的寄存器中读取数据。


0238d0180ccf4ef6b8d9ae0bc4633dcd.png

8 附加建议

在编写传感器驱动程序时,千万不要包含任何等待或睡眠代码,因为这将延迟主线程或正在使用的与总线相关的后台线程。

如果编写了一个新的库,它必须被添加到飞行器目录下的 wscript 文件中(即/ardupilot/ArduCopter/wscript),以便将其链接到最终的二进制文件中。


相关文章
|
开发工具 Docker 容器
Docker设置国内镜像源
Docker设置国内镜像源
18487 1
|
XML 数据格式 Python
Labelimg标注自己的数据集,及如何划分训练集和验证集,应用于Yolov5
Labelimg标注自己的数据集,及如何划分训练集和验证集,应用于Yolov5
3318 0
|
计算机视觉
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
1241 0
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
|
3月前
|
传感器 数据采集 算法
基于STM32 上开发的BMS系统
基于STM32 上开发的BMS系统
264 14
|
Python
新手向 Python:VsCode环境下Manim配置
该文介绍了如何准备和配置开发环境以使用Manim,主要包括两个步骤:一是准备工作,需要下载并安装VsCode和Anaconda,其中Anaconda需添加到系统PATH环境变量,并通过清华镜像源配置;二是配置环境,VsCode中安装中文插件和Python扩展,激活并配置虚拟环境。最后,安装ffmpeg和manim,通过VsCode运行测试代码验证配置成功。
1245 1
|
10月前
|
机器学习/深度学习 存储 自然语言处理
方案测评|巧用文档智能和RAG构建大语言模型知识库
本文介绍了一款基于文档智能和大语言模型(LLM)的文档解析及问答应用,旨在提升企业文档管理和信息检索效率。系统通过文档解析、知识库构建和问答服务三大模块,实现了从文档上传到智能问答的全流程自动化。
|
运维 Java Serverless
深度解析四大主流软件架构模型:单体架构、分布式应用、微服务与Serverless的优缺点及场景应用
深度解析四大主流软件架构模型:单体架构、分布式应用、微服务与Serverless的优缺点及场景应用
1554 0
|
传感器 Linux 开发工具
(1)学习ArduPilot代码库
(1)学习ArduPilot代码库
393 0
|
存储 Cloud Native 关系型数据库
Linux安装配置Nacos
Linux安装配置Nacos
8510 0
|
传感器 定位技术
(4)(4.6.1) ArduPilot操作的简单概述
(4)(4.6.1) ArduPilot操作的简单概述
272 0