本文为《无人机飞控固件开发教程》系列视频的辅助资料,已经在“网易云课堂”上线,视频链接:https://study.163.com/course/introduction/1209568864.htm?share=1&shareId=1448054983
无人机调试,飞控硬件定制、固件修改,日志分析,请QQ联系:3500985284
本文以APM飞控的GPS驱动为例,深入讲解APM飞控驱动程序的结构和运行原理。
一、APM库的结构
APM飞控的驱动的程序都在ardupilot/libraries文件夹下面,此文件夹下有多个子文件夹,其中每个文件夹对应一种驱动程序,下面列出了几种常见驱动:
- AC_AttitudeControl:姿态控制
- AC_Fence:地理围栏
- AC_PrecLand:精准降落
- AC_WPNav:航点导航
- AP_Airspeed:空速计
- AP_Baro:气压高度计
- AP_Camera:相机控制
- AP_Compass:磁罗盘
- AP_GPS:GPS模块
- AP_HAL:硬件抽象,对应底层的SPI接口、串口、CAN接口、IIC接口等
- AP_HAL_PX4:PX4硬件硬件抽象
- AP_Mission:自动任务
- AP_Motors:电机控制,多旋翼的混控也在这里面
- AP_OpticalFlow:光流模块
- AP_Parachute:降落伞控制
- AP_RangeFinder:定高设备驱动,如超声波、激光测距仪、毫米波雷达等
二、GPS库的调用关系
小知识点:其实,我们飞控的“GPS模块”,更专业的叫法应该叫“GNSS模块”。GPS(Global Positioning System)中文全称是“全球定位系统”,专指美国的GPS系统,因为是美国最先做的全球定位系统,因此这个名字就被赋予了美国的那套卫星定位系统。而后来俄罗斯出了“格洛纳斯(GLONASS)”、我国出了“北斗(Compass)”、欧洲出了“伽利略卫星导航系统”,从而,这些平行并且竞争关系的系统统称为“GNSS(Global Navigation Satellite System)”,中文全称是“全球导航卫星系统”。现在我们大部分接收机都支持双系统、三系统、甚至四系统联合定位,因此叫“GPS”就不合适了。当然,习惯的力量是强大的,我们继续叫它“GPS模块”是没有问题的,心里知道怎么回事即可。
以AP_GPS文件夹为例,此文件夹下面的AP_GPS.cpp和AP_GPS.h两个文件定义了GPS类驱动程序统一的对外接口,这样对于顶层代码来讲,不管飞控连接的是哪种协议的GPS模块、不管接了几个GPS模块,都通过统一的接口定时提取位置和速度信息。GPS_Backend.cpp和GPS_Backend.h两个文件定义的GPS类驱动程序统一的内部接口,各种类型的GPS模块的驱动都是在此基础上“派生”出来的,只是具体实现不同而已。这种“Backend”架构,利于实现飞控上同时连接多个不同类型的GPS,非常方便。
AP_GPS文件夹中支持的GPS外设如下:
- AP_GPS_ERB:基于ERB协议的GNSS设备;
- AP_GPS_GSOF:Trimble(天宝)公司的GNSS设备;
- AP_MAV:基于Mavlink通信协议的GNSS设备;
- AP_MTK:联发科GNSS设备;
- AP_MTK19:联发科基于其V1.6~V1.9版本通信协议的GNSS设备;
- AP_NMEA:基于NMEA协议的GNSS设备;
- AP_NOVA:基于诺瓦泰协议的GNSS设备,注意,常用的多个品牌的RTK设备(诺瓦泰、司南导航、和芯星通等等)均采用这个协议;
- AP_SBF: Septentrio 品牌的GNSS设备;
- AP_SBP: Swift Navigation 品牌的GNSS设备;
- AP_SBP2: Swift Navigation 品牌的GNSS设备(估计是升级版本的协议);
- AP_SIRF:SIRF公司的GNSS设备;
- AP_GPS_UAVCAN:基于UAVCAN协议的GNSS协议,数据走的不是串口,而是CAN总线;
- AP_GPS_UBLOX:ublox公司的GNSS通信协议,我们常用的ublox-M8N就是用的这个协议,这个协议在ublox官方文档中被命名为“UBX”协议。

GPS驱动在初始化的时候,会根据飞控参数设置,动态地添加不同类型的GPS驱动,生成一个个的实例(instance),组成一个实例数组,然后会定时依次调用各个实例下的解析处理函数,实现多个不同类型的GPS的同时工作(也可以是多个相同类型的GPS同时工作),其结构图如下:

三、我们来惊叹一下GPS库中神奇的解帧方法
packed union!我当年上大学的时候,C语言课程上,一直没有搞明白union有什么用,直到我看了APM中GPS的解帧方法,我才明白union是多么有用!
教学视频中,我们将以AP_NOVA为例,详细讲一下这个神奇的解帧方法的具体实现过程。

大家可以看到,在AP_NOVA中,帧头( nova_header )、帧数据( msgbuffer )处使用了union,但是CRC计算那里还是用了移位这种常规方法。大家应该看到了,对于这种“变帧长”的帧,使用union优势非常明显,但是其crc部分只有4个字节,并且格式是统一的,这时如果再使用union这种方法定义一堆东西,反而有点麻烦,因此官方驱动直接用了移位的方法。
case nova_msg_parser::CRC1:
nova_msg.crc = (uint32_t) (temp << 0);
nova_msg.nova_state = nova_msg_parser::CRC2;
break;
case nova_msg_parser::CRC2:
nova_msg.crc += (uint32_t) (temp << 8);
nova_msg.nova_state = nova_msg_parser::CRC3;
break;
case nova_msg_parser::CRC3:
nova_msg.crc += (uint32_t) (temp << 16);
nova_msg.nova_state = nova_msg_parser::CRC4;
break;
case nova_msg_parser::CRC4:
nova_msg.crc += (uint32_t) (temp << 24);
nova_msg.nova_state = nova_msg_parser::PREAMBLE1;
四、顺便讲讲RTK的基本原理
教学视频中,此处将讲述RTK的基本原理以及飞控在软硬件上是如何集成RTK功能的。
1、RTK基本原理

2、无人机系统集成RTK软硬件架构

无人机调试,飞控硬件定制、固件修改,日志分析,请QQ联系:3500985284
