笔记来源于:沈阳无距科技-工业级无人机的中国名片(编程外星人)
目录
一、飞控整体架构
一、数据存储(Storage)
二、外部通讯(External Connectivity)
三、驱动程序(Drivers)
四、飞行控制(Flight Control)
六、消息总线(Message Bus)
二、编译选项与模块功能说明
三、uORB原理与使用
四、系统级驱动程序开发
五、应用级驱动程序开发
六、多进程、多线程与工作队列原理
七、创建并运行多进程程序
八、创建并运行多线程程序
九、工作队列
十、遥控器协议S-BUS、PWM与PPM协议
十一、命令响应与状态切换
一、飞控整体架构
PX4的设计从大角度划分为五个部分:
数据存储分为3个部分:
飞控程序的外部通讯采用的是Mavlink协议,Mavlink是无人机外部通讯的一个轻量级通讯协议。
与外部通讯即是与计算机上的地面站程序来进行通讯。我们可以使用Mavlink官方提供的协议生成工具来定制我们自己需要的协议内容,并可以通过需要生成不同编程语言所使用的源文件,例如C/C++、Java、Python等。这样的好处是同样的一个通讯协议可以被飞控程序、PC计算机、手机APP程序和其它程序同时使用。这样就有效的避免了不同运行平台上,不同类型程序运行的差异,而采用相同的协议通讯。
驱动程序是飞控程序中采集传感器数据的源头,常用的传感器驱动程序有:
飞控程序中内部消息传递采用的是异步消息机制uORB。它的设计理念很有趣,它可以实现不同模块中的数据快速通讯,并且以异步通讯为基本原则,也就是说在通讯过程中发送者只负责发送数据,而并不关心数据由谁接收,也不关心接收者是否能将所有的数据都接收到;而对于接收者来说并不关心数据是由谁发送的,也不关心在接收过程中是否将所有数据都接收到。
先来看看整体目录结构,然后我们会针对主要的功能模块说一些说明(由于篇幅限制本节所列出的目录与文件都是源代码中一少部分,实际上很多目录与文件夹都被省略了):
我自己也试着把文件的目录生成出来,但是还是太多了,所以还是用了网站的这个目录来学习
uORB在数据发布与接收过程中并不保证发送者的所有数据都可以被接收者收到,而只保证接收者在想要接收时能收到最新的数据。而发送与接收的分离可以使飞程中各个模块相互独立,互不干扰。实际上一个uORB可以由多个发送者发布,也可以被多个接收者接收。也就是说他们之间是多对多的关系。
下面我们来看一个具体的例子:
1.在msg文件夹中创建一个叫做extctl_sp.msg的文件,表示我们创建了一个新的uORB,它的名字叫作extctl_sp,其内容如下:
这是作者在做“外部控制”模式下所用到的一个uORB,在本节中读者可以不用了解其中变量的具体含义,只知道我们需要在extctl_sp.msg中定义一些指定属性即可。不过需要注意其定义的语法与C/C++类似但有些不同,参考PX4中现有的msg文件内容即可。
2.在msg文件夹中的CMakeLists.txt中添加刚刚我们添加的extctl_sp.msg,表示对其做编译处理:
即程序在编译时会根据extctl_sp.msg生成extctl_sp.h和extctl_sp.cpp文件,也就是我们在程序中所用到的结构定义:
3.发布者发布uORB时需要做两步操作:
(1)公告/多重公告uORB;
(2)发布uORB。
我们来看下面的的发布者的例子:
4.接收者接收uORB时需要做三步操作:
(1)订阅uORB;
(2)判断uORB数据是否有更新。
(3)复制uORB数据内容到本地内存。
我们来看下面的的者接收的例子
这就是uORB的使用方法,注意,发布和订阅只需要执行一次即可,而发布、检查更新和接收可以执行多次。下面我们来看看uORB中比较关键的几个函数的定义:
关于这些函数的用法、参数及反回值不做过多的说明,这些函数的参数和反回值源代码中有详细的说明,还是比较容易理解和使用的。
这部分涉及c/c++,以及linux系统相关的知识,我现在还有很大的欠缺,先放着先......
连接在这里:无人机中级篇:第四讲:系统级驱动程序开发
这部分涉及c/c++,以及linux系统相关的知识,我现在还有很大的欠缺,先放着先......哈哈哈哈哈......
连接在这里:无人机中级篇:第五讲:应用级驱动程序开发
无人机中级篇:第七讲:创建并运行多进程程序
无人机中级篇:第八讲:创建并运行多线程程序
无人机中级篇:第九讲:工作队列
PPM编码是PWM的扩展协议,可以在一个管脚中传输多路PWM信号。PPM的频率通常是50Hz,周期长度20ms,每一个周期中可以存放最多10路PWM信号,每一路PWM的周期为2ms。
在PX4中负责状态切换的模块为commander,在src/modules/commander文件夹下有很多文件,他们分别负责不同的功能,例如:主状态和导航状态切换、传感器校准、命令响应等等。我们主要来了解commander.cpp中命令响应与状态切换的相关内容。
在int commander_main(int argc, char *argv[])函数中定义了所有可执行的命令选项,我们可以根据其useage来对这个功能做一些简单的了解:
usage: commander {start|stop|status|calibrate|check|arm|disarm|takeoff|land|transition|mode}
commander calibrate accel
commander calibrate gyro
commander calibrate mag
commander calibrate level
commander calibrate airspeed
行前检查:check选项可以针对飞控当前的状态来进行行前检查,并显示当前飞控的状态是否达到飞行的条件
锁定/解锁与起降命令:arm/disarm/takeoff/land/transition这5个选项可以让飞控通过commander命令来使飞控直接完成相应功能:
commander arm:飞控解锁
commander disarm:飞控锁定
commander takeoff:起飞
commander land:着陆
commander transition:模态切换(倾转旋翼使用)
主状态模式:mode选项中有13个选项,这13个选项就是飞控的13个飞行模式,如下:
manual:MAIN_STATE_MANUAL:手动模式
altctl:MAIN_STATE_ALTCTL:定高模式
posctl:MAIN_STATE_POSCTL:位置模式
auto:mission:MAIN_STATE_AUTO_MISSION:任务模式
auto:loiter:MAIN_STATE_AUTO_LOITER:悬停模式
auto:rtl:MAIN_STATE_AUTO_RTL:返航模式
acro:MAIN_STATE_ACRO:特级模式
offboard::MAIN_STATE_OFFBOARD:离线模式
stabilized:MAIN_STATE_STAB:增稳模式
rattitude:MAIN_STATE_RATTITUDE:姿态特级模式
auto:takeoff:MAIN_STATE_AUTO_TAKEOFF:自动起飞
auto:land:MAIN_STATE_AUTO_LAND:自动降落
flowtarget:MAIN_STATE_FLOW_TARGET:跟随模式
Commander::run()函数中定义了一个while循环结构,这个循环结构在commander启动后就一直在运行,直到commander停止后才结束。