飞控与外界无线数据通信

遥控器用于用户手动操纵指令传达。除此之外,四旋翼无人机还需要与地面站或其他四旋翼有数据交互,用于状态监控,集群协同等

硬件与协议

无人机与外界通信主流方案包括三种:WiFi,蓝牙,2.4G无线数传。其中WiFi与蓝牙也是传输信号也在2.4G频段,一般硬件设备都内置有WiFi,蓝牙功能,2.4G收发端都需要额外配置模块

飞控与外界无线数据通信的图1

也有部分数传模块可以工作在433MHz915MHz频段,相同功率,频率低衍射性能好,传输距离远;频率高则带宽大一点,传输速度快

通常开发这三类硬件需要一个2.4G射频芯片,在上层开发协议栈。这三类方案一些常见产品指标对比如下,其中蓝牙5.04.0在带宽和传输距离上有提升,数传模块产品性能区间较大,可以结合价格和场景需要选用

市面上这三种都是模块产品如ESP8366 WiFi模块,3DR 915MHz无线数传模块,对外屏蔽协议栈细节。与飞控走串口协议,在PX4中只需要读写串口解析应用层MAVLink协议即可

MAVLink协议

MAVLink定义了轻量级无人机之间传输数据格式,支持多种语言和多种平台,支持至多255种机型,并且高度可靠与安全。2009年发布MAVLink v12017年发布版本MAVLink v2. MAVLink系列无论是数据帧格式还是交互过程,都和socket十分相似,我们下面一起来看一下

1 MAVLink实现

1.1 协议

MAVLink v2相比于v1,头部标记由8字节升级到14字节,扩展性进一步提高。我们重点关注MAVLink v2,下面为MAVLink v2序列化后的数据帧格式 

飞控与外界无线数据通信的图2

飞控与外界无线数据通信的图3

收发端首先四次握手进行版本协商,然后即建立连接

系统与组件的认证ID标识了发送端可以广播给网络中的全部系统或组件,也可以发给指定系统或组件

接收端等待数据帧开始标志位,然后读取包长度的字节序列,并且做一些校验工作,再放入缓存做拼接,最后提供给上层应用

有两个很重要的API用于程序中数据结构和二进制消息相互转化,对MAVLink协议感兴趣的朋友可以阅读它的实现来了解协议设计细节

反序列化mavlink_parse_char

https://github.com/mavlink/c_library_v2/blob/master/mavlink_helpers.h#L988

序列化mavlink_msg_to_send_buffer

https://github.com/mavlink/c_library_v2/blob/master/mavlink_helpers.h#L445

1.2 消息类型

MAVLink消息定义在XML文件中,形式上可以参考下面的内容

https://github.com/mavlink/mavlink/blob/18955a04c7c7467e00ea42b704addb4a9c12b53a/message_definitions/v1.0/common.xml

MAVLink内置消息可以分为两类,主协议通用消息和子协议,如果内置消息仍然不能满足用户需要,MAVLink也支持用户自定义消息

a.主协议通用消息

通用消息设计已经足够满足大多数应用场景需求

https://mavlink.io/en/messages/common.html

包括飞机机型,飞行模式,飞机传感器数据,飞行状态的细节等

b.子协议

子协议通常用于特定场景,比较Domain-Specific。比如心跳协议用于确认组件状态,计算丢包率;参数协议用于交换组件参数等

有个比较有意思的是解锁认证协议

https://mavlink.io/en/services/arm_authorization.html

意思是说需要第三方认证如空管部门或一些私人认证机构,才允许解锁飞行

c.自定义消息

XML完成自定义消息后,可以用官方提供的codegen工具生成对应语言的消息定义源码。对C语言官方提供了一份已经生成好的消息定义头文件,并且针对嵌入式系统高度优化。

PX4作为发送端中用到的common消息可以参考

https://github.com/PX4/PX4-Autopilot/tree/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/streams

其中主要是定义了send接口,用于uORB订阅话题后序列化为二进制并发送到串口

对其他语言的支持可以参考官方开发者手册

https://mavlink.io/en/

1.3 测试

官方提供了一份测试用例,实现了串口和UDP简单收发接口

https://github.com/mavlink/c_uart_interface_example

另外也有一份比较完善的基于C++17的软件开发包,支持包括同步、异步回调更多好用的上层封装

https://github.com/mavlink/MAVSDK/tree/main

我们留到后面实践篇再做详细测评

2 MAVLinkPX4中的使用

对于MAVLink消息上层接口需求,总体可以归为同步、异步两类。既需要同步消息统一处理关心的数据,又需要异步接口来支持随时打印调试信息

2.1通过MAVLink发布异步调试信息

比较常见的是mavlink_log_info

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/lib/systemlib/mavlink_log.h#L82

不过这类接口将会逐渐被Events机制替代,events::send()接口封装调试信息,实际上是通过uORB发布事件

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/platforms/common/events.cpp#L48

下面订阅进队列,再统一发布MAVLink消息,这样方便和同步消息统一管理

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2545  

2.2 通过MAVLink例行发布接收关心的数据

此时飞控设备既是发送端,又是接收端,相应任务由两个task执行

1)发送端

MAVLink模块发送任务中,完成外设配置,需要输出消息订阅发送以及接收消息的反序列化和发布

在主循环中,统一对关注的消息进行订阅和发布:

结合带宽调整发送速率

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2320

udp或串口外设进行配置

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2332

兼容旧MAVLink版本,直接调MAVLink序列化接口发布云台消息

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2463

检查通过shell传进来的消息,通过MAVLink发送

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2486

MAVLinkShell实现来看,主要是对于父子关系的两个任务,子任务会继承得到文件描述符,并通过stdio管道通信,从shell读入消息并且发送,很显然,可用于调试

通过uORB订阅消息,并逐个通过MAVLink发送

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_main.cpp#L2503

2)接收端

接收端启动

https://github.com/PX4/PX4-Autopilot/blob/2f448e9d9f3996698dffc5d24e90b405bc55c045/src/modules/mavlink/mavlink_receiver.cpp#LL3276C4-L3276C24

流程上和发送端刚好相反,不过消息反序列化后,都是直接实现的处理函数,也包括一些子协议的处理,如FTP协议、Mission子协议等,然后通过uORB发布

这就是飞机与外部数据交互的软硬件层面原理以及PX4实现。

源自:SantyNotebook

默认 最新
当前暂无评论,小编等你评论哦!
点赞 评论 收藏
关注