PX4学习笔记

目录

  • 网址
  • PX4.io网页指导
  • Pixhawk、PX4、APM 、 ArduPilot关系
  • 硬件照片、示意图
  • 逻辑图 集
    • 多旋翼控制框架
    • 软件框架
  • 辅助工具、软件、使用方法
    • source insight新建工程、导入PX4源码
    • source insight 使用技巧
  • 说明(误区)
    • 裸机运行
    • 基于OS运行
      • 例子
    • 可执行程序、应用、源码(代码)、进程、线程、任务
    • 源码、固件的区分
  • 计算机组成原理
  • 何为驱动、处理器通过驱动访问某外设的过程
  • C++
    • 命名空间
    • PX4源码中C++的常用套路
  • 编译、汇编、链接
    • 预编译
    • 条件编译
  • Pixhawk的启动流程
  • PX4工程目录节后分析
    • 大概逻辑
  • 固件下载的过程、原理
  • 源码分析
  • mc_pos_control_main.cpp 分析
  • 编译环境搭建
    • Linux编译环境搭建
    • Windows编译环境搭建
  • 1 编译源码(编译固件)
    • 1.1 适用平台(编译时的board target)
    • 1.2 选择目标平台后执行编译命令
    • 1.3 Uploading Firmware (Flashing the board)
    • 1.4 编译命令解析
    • 1.5 更多内容
    • 1.6 编译过程中的常见问题
  • 官方例程的使用
  • PX4与Ardupilot的区别
  • 专业英语词汇、英文缩写(学习代码过程中遇到)
  • 未解之谜
  • 已解之谜
  • 1. Linux使用
    • 1.1 与Windows共享文件
    • 1.2 Ubuntu文件管理器中copy、pastepw、delete的进度显示
  • 1. PX4 系统架构概述
    • 1.1 顶层软件架构
  • 1. PX4应用开发
    • 1.1 hello sky
    • 1.2 UORB
      • 1.2.1 Topics
    • MVLink消息与UORB消息的关系
    • 1.3 PX4之UORB开发
  • 1.MAVLink
    • 1.1 概述
    • 1.2 Packets Format(包的结构)
    • 1.3 Packet 的封装过程
    • 1.4 Packet、messages、commands、enums的关系。
    • 1.5 其他知识点
    • 1.4 PX4中MAVLink的使用

网址

  • PX4原生固件及其地面站网址
    https://github.com/PX4
    http://px4.io/
    原生固件代码:C++,构架清晰,容易维护修改,多进程
    目前来讲功能方面和细节上不如APM固件

  • AutoPoilt 固件及其地面站网址
    http://ardupilot.org/
    https://github.com/ArduPilot/ardupilot
    https://github.com/ArduPilot/MissionPlanner
    APM固件代码:C++,稳定成熟,功能丰富,发起时间比较早
    系统构架不如原生固件那么清晰,相对来讲不容易维护和修改

  • PIXHAWK控制器硬件
    https://github.com/PX4/Hardware

PX4.io网页指导

  • 相关官网
    PX4学习笔记_第1张图片
  • 使用文档、开发文档
    在网页最低端位置
    PX4学习笔记_第2张图片
    PX4学习笔记_第3张图片

Pixhawk、PX4、APM 、 ArduPilot关系

经常有人将 Pixhawk、PX4、APM 还有 ArduPilot 弄混。这里首先还是简要 说明一下: Pixhawk 是飞控硬件平台,PX4 和 ArduPilot 都是开源的可以烧写到 Pixhawk 飞控中的自驾仪软件,PX4 称为原生固件,专为 Pixhawk 打造。APM(Ardupilot Mega)早期也是一款自驾仪硬件,到 APM3.0 版本,这款基于 Arduino Mega 的 自驾仪已经走到了它的终点。ArduPilot 早期是 APM 自驾仪的固件,Pixhawk 作 为 APM 的升级版,也兼容 ArduPilot 固件,APM 自驾仪卒了之后,ArduPilot 现 在全面支持 Pixhawk,现在大家亲切的称 ArduPilot 固件为 APM。

硬件照片、示意图

PX4学习笔记_第4张图片


PX4学习笔记_第5张图片
PX4学习笔记_第6张图片
PX4学习笔记_第7张图片
pixhack硬件介绍:https://docs.px4.io/master/en/flight_controller/pixhack_v3.html#pixhack-v3

逻辑图 集

多旋翼控制框架

PX4学习笔记_第8张图片

软件框架

PX4学习笔记_第9张图片

辅助工具、软件、使用方法

  • 查看源码的工具:
    Source Insight、 understand
    PX4学习笔记_第10张图片
  • Ubuntu虚拟机的开发环境和下载地址:
    链接:http://pan.baidu.com/s/1gfJzNKv 密码:o9rx

source insight新建工程、导入PX4源码

  • step1
    在这里插入图片描述
  • step2
    PX4学习笔记_第11张图片
  • step3
    PX4学习笔记_第12张图片
  • step4
    PX4学习笔记_第13张图片

source insight 使用技巧

11

说明(误区)

裸机运行

51单片机,只有一个main函数,main函数中有一个主循环while。
全部代码被编译成为一个可执行文件

基于OS运行

初始化硬件、初始化OS等代码被编译成一个可以行程序,上电后执行。
如:姿态估计代码、姿态控制算法代码分别被编译成两个独立的可执行程序。这些独立的可执行程序(如windows中的**.exe)由OS以进程的形式执行,OS为这些可执行程序创建进程时,可配置执行频率。

例子

负责姿态估计的代码被编译为可执行程序,每一个之可执行程序都有一个入口main函数。
如该可执行程序中有一个循环,则对应的进程按照频率执行,若没有循环,执行完这段可执行程序后(遇到return),对应的进程即结束。

可执行程序、应用、源码(代码)、进程、线程、任务

1

源码、固件的区分

源码:即代码,还未编译,可以是多个.c文件(或其他语言的源文件);或是一个工程文件project
固件(Firmware):已经编译,并把各个已经编译好的文件打包成一个整体,以供烧录进单片机中。
PX4源码最后编译成以下固件:
PX4学习笔记_第14张图片
Firmware/ROMFS/px4fmu_common/init.d 文件夹下的 rcS 启动脚本(startup script)。 这个脚本位于被编译到固件中的 ROM 文件系统中。这个脚本检测可用的硬件,加载硬件驱动,并且根据你的设置启动系统正常运行所需的有 app(任务软件 , 包括位置和姿态估计,控制遥测等)。所有属于自启动程序的脚本文件可以在 init.d 文件夹中找到。

计算机组成原理

1

何为驱动、处理器通过驱动访问某外设的过程

作用:只是初始化?(配置寄存器)
对应的进程:只执行一次?无while死循环?
LED驱动的入口函数:
PX4学习笔记_第15张图片

C++

命名空间

class AttitudeEstimatorQ;
namespace attitude_estimator_q
{
AttitudeEstimatorQ *instance;
}

class AttitudeEstimatorQ
{
public:

}

PX4源码中C++的常用套路

class AttitudeEstimatorQ;
namespace attitude_estimator_q
{
AttitudeEstimatorQ *instance;
}

class AttitudeEstimatorQ
{
public:

}

先声明有这个类,再定义一个类的对象的指针instance,将这个变量(对象指针)放在一个名为attitude_estimator_q的命名空间中。
PX4学习笔记_第16张图片
_***的变量,以下划线开头的变量或者函数表示类的室友成员。

编译、汇编、链接

预编译

条件编译

Pixhawk的启动流程

NUTTX启动(也就是上面的固件代码,汇编语句就是跳转到这个位置来执行stm32_start.c):
代码位置:Firmware/build_px4fmu-v2_default/px4fmu-v2/Nuttx/nuttx/arch/arm/src/stm32/stm32_start.c
注意:build_px4fmu-v2_default文件夹要编译整个工程之后才会生成。

stm32_start.c中处理器执行的第一条指令(px4使用的是stm32,入口在stm32_start.c中)
stm32_clockconfig() #初始化时钟
rcc_reset() #复位rcc
stm32_stdclockconfig() #初始化标准时钟
rcc_enableperipherals()#使能外设时钟
stm32_fpuconfig() #配置fpu
stm32_lowsetup() #基本初始化串口,之后可以使用up_lowputc()
stm32_gpioinit() #初始化gpio,只是调用stm32_gpioremap()设置重映射
up_earlyserialinit() #初始化串口,之后可以使用up_putc()
stm32_boardinitialize()
stm32_spiinitialize() #初始化spi,只是调用stm32_configgpio()设置gpio
stm32_usbinitialize() #初始化usb,只是调用stm32_configgpio()设置gpio
up_ledinit(); #初始化led,只是调用stm32_configgpio()设置gpio

在stm32_start.c文件中我们会看到这么一句话:
/* Then start NuttX */
showprogress(’\r’);
showprogress(’\n’);
os_start(); #系统开始启动

以下是 os_start()内容:
dq_init() #初始化各种状态的任务列表(置为null)
g_pidhash[i]= #初始化唯一可以确定的元素–进程ID
g_pidhash[PIDHASH(0)]= #分配空闲任务的进程ID为0
g_idletcb= #初始化空闲任务的任务控制块
sem_initialize()-- #初始化信号量
dq_init() #将信号量队列置为null
sem_initholders() #初始化持有者结构以支持优先级继承
up_allocate_heap() #分配用户模式的堆(设置堆的起点和大小)
kumm_initialize() #初始化用户模式的堆
up_allocate_kheap() #分配内核模式的堆
kmm_initialize() #初始化内核模式的堆
task_initialize() #初始化任务数据结构
irq_initialize() #将所有中断向量都指向同一个异常中断处理程序
wd_initialize() #初始化看门狗数据结构
clock_initialize() #初始化rtc
timer_initialize() #配置POSIX定时器
sig_initialize() #初始化信号
mq_initialize() #初始化命名消息队列
pthread_initialize() #初始化线程特定的数据,空函数
fs_initialize()— #初始化文件系统
sem_init() #初始化节点信号量为1
files_initialize() #初始化文件数组,空函数
net_initialize()-- #初始化网络
uip_initialize() #初始化uIP层
net_initroute() #初始化路由表
netdev_seminit() #初始化网络设备信号量
arptimer_init() #初始化ARP定时器
up_initialize()— #处理器特定的初始化
up_calibratedelay() #校准定时器
up_addregion() #增加额外的内存段
up_irqinitialize() #设置中断优先级,关联硬件异常处理函数
up_pminitialize() #初始化电源管理
up_dmainitialize() #初始化DMA
up_timerinit() #初始化定时器中断
devnull_register() #注册/dev/null
devzero_register() #注册/dev/zero
up_serialinit() #注册串口控制台/dev/console和串口/dev/ttyS0
up_rnginitialize() #初始化并注册随机数生成器
up_netinitialize() #初始化网络,是arch/arm/src/chip/stm32_eth.c中的
up_usbinitialize() #初始化usb驱动
board_led_on() #打开中断使能led,但很快会被其它地方的led操作改变状态
lib_initialize() #初始化c库,空函数
group_allocate() #分配空闲组
group_setupidlefiles() #在空闲任务上创建stdout、stderr、stdin
group_initialize() #完全初始化空闲组
os_bringup()------ #创建初始任务
KEKERNEL_THREAD() #启动内核工作者线程
board_initialize() #最后一刻的板级初始化
TASK_CREATE() #启动默认应用程序
forup_idle() #空闲任务循环
for( ; ; ) #不应该到达这里(程序不该执行到此)

  • __start 负责STM32 芯片的底层初始化,包括时钟,FPU,GPIO 等单元的初始化;
  • os_start 负责OS 的底层初始化,包括各种队列和进程结构的初始化;
  • os_bringup 负责OS 基本进程的启动以及用户进程的启动,用户启动入口由;(CONFIG_USER_ENTRYPOINT)宏进行指定是执行nsh_main还是user_start。

PX4工程目录节后分析

PX4学习笔记_第17张图片

大概逻辑

Pixhawk 整体逻辑大致为:

  1. commander 和 navigator 产生期望位置
  2. position_estimator 估计当前位置
  3. 通过 pos_ctrl 产生期望姿态
  4. attitude_estimator 估计当前姿态
  5. 通过 att_ctrl 产生 PWM 数值
  6. 最后通过 mixer 和 motor_driver 控制电机

固件下载的过程、原理

77

源码分析

  1. Modules中的代码,运行在主处理器F4中;
  2. 二次开发,只需关注Modules和Drivers两个文件夹的源码即可;

PX4学习笔记_第18张图片
PX4学习笔记_第19张图片

PX4学习笔记_第20张图片
PX4学习笔记_第21张图片
函数调用结构示意:
PX4学习笔记_第22张图片
官方解析:
后台任务
px4_task_spawn_cmd() 用于启动与父任务独立运行的新任务(NuttX)或者新线程(POSIX - Linux/macOS):

independent_task = px4_task_spawn_cmd(
    "commander",                    // 进程名称
    SCHED_DEFAULT,                  // 调度类型(RR 或 FIFO)
    SCHED_PRIORITY_DEFAULT + 40,    // 调度优先级
    3600,                           // 新任务或线程的堆栈大小
    commander_thread_main,          // 任务(或线程的主函数)
    (char * const *)&argv[0]        // Void 指针传递到新任务
                                    // (这里是命令行参数)
    );

操作系统相关的信息
NuttX
NuttX 是在飞控板上运行 PX4 的首选 RTOS 。 它是一个开源软件(BSD 许可), 非常轻量化,运行高效且稳定。

各模块以任务(Task)模式运行:他们有各自的文件描述列表,但共用一个地址空间。 单个任务可以使用同一个文件描述列表启动单个或者多个线程。

每一个任务/线程都有一个固定大小的栈堆,并且有一个周期性的任务会定期检查所有栈堆都有足够的可用空间(基于 stack coloring)。

Linux/MacOS
在 Linux 或者 macOS 系统上, PX4 在一个单独的进程中运行,各个模块在各自线程中运行(在 NuttX 中任务和线程没有任何区别)。

mc_pos_control_main.cpp 分析

task_main函数中:

  • 先订阅UORB消息
    PX4学习笔记_第23张图片

编译环境搭建

Linux编译环境搭建

请参考PX4开发者手册

Windows编译环境搭建

  1. 安装 Windows Cygwin 工具链
    该工具链支持:
    编译/上传 PX4到Nuttx目标(Pixhawk系列飞控)
    JMAVSim/SITL 仿真会获得比其他Windows工具链更好的性能
    类型校验,轻便安装,完整的命令行支持和许多其他特性
    Cygwin 工具链 仅支持NuttX/Pixhawk 平台和 jMAVSim仿真平台
  2. Cygwin 工具链下载地址1
    Cygwin 工具链下载地址2(fast)
  3. 双击.msi文件安装
    PX4学习笔记_第24张图片
  4. 下载PX4源码
  • 在Windows Cygwin安装结束后勾选clone the PX4 repository, build and run simulation with jMAVSim。下载的PX4源码存放在安装目录的home文件夹下。
  • 在Windows Cygwin安装结束后不勾选clone the PX4 repository, build and run simulation with jMAVSim,进入Windows Cygwin的安装目录,双击运行run-console.bat,以启动Cygwin bash控制台,在控制台中运行克隆PX4 Firmware仓库命令(下载的PX4源码存放在安装目录的home文件夹下。):
 git clone --recursive -j8 https://github.com/PX4/Firmware.git
  • 自行到GitHub上下载PX4工程源码 ,并移动至Windows Cygwin安装目录下的home目录下。 PX4源码下载网址
  1. 说明
    Cygwin控制台的初始位置是安装目录下的home目录。
    PX4学习笔记_第25张图片
    下载好的源码:
    PX4学习笔记_第26张图片
    PX4学习笔记_第27张图片

源码大小638.2 Mb,1.11版本。

运行make 后悔多出一个build目录,运行 make distclean 会清除build目录以及编译过程中的所有中间文件。

1 编译源码(编译固件)

先进入Firemare目录,再执行make命令。
运行编译之前,先运行

make distclean

1.1 适用平台(编译时的board target)

PX4学习笔记_第28张图片

1.2 选择目标平台后执行编译命令

The following list shows the build commands for common boards:

  • Pixhawk 4: make px4_fmu-v5_default
  • Pixracer: make px4_fmu-v4_default
  • Pixhawk 3 Pro: make px4_fmu-v4pro_default
  • Pixhawk Mini: make px4_fmu-v3_default
  • Pixhawk 2: make px4_fmu-v3_default
  • mRo Pixhawk: make px4_fmu-v3_default(支持 2MB 闪存)
  • HKPilot32: make px4_fmu-v2_default
  • Pixfalcon: make px4_fmu-v2_default
  • Dropix: make px4_fmu-v2_default
  • MindPX/MindRacer: make airmind_mindpx-v2_default
  • mRo X-2.1: make mro_x21_default
  • Crazyflie 2.0: make bitcraze_crazyflie_default
  • Intel® Aero Ready to Fly Drone: make intel_aerofc-v1_default
  • Pixhawk 1: make px4_fmu-v2_default > Warning You must use a supported version of GCC to build this board (e.g. the same as used by CI/docker) or remove modules from the build. 使用不受支持的 GCC 构建可能会失败,因为 PX4 对飞控板有 1MB 的闪存限制。
    Pixhawk 1 的 2 MB 闪存版: make px4_fmu-v3_default
    PX4学习笔记_第29张图片
    Linux下编译成功:
    PX4学习笔记_第30张图片
    固件位置:Firmware/build/px4_fmu-v3_default/px4_fmu-v3_default.px4

1.3 Uploading Firmware (Flashing the board)

make px4_fmu-v4_default upload

A successful run will end with this output:

Erase  : [====================] 100.0%
Program: [====================] 100.0%
Verify : [====================] 100.0%
Rebooting.

[100%] Built target upload

1.4 编译命令解析

This section shows how make options are constructed and how to find the available choices.
make命令语法:
make [ VENDOR_MODEL_VARIANT ] [ VIEWER_MODEL_DEBUGGER_WORLD ]
例如:
make px4_fmu-v4_default
make px4_sitl jmavsim

  • VENDOR: The manufacturer of the board: px4, aerotenna, airmind, atlflight, auav, beaglebone, intel, nxp, etc. The vendor name for Pixhawk series boards is px4.
  • MODEL: The board model “model”: sitl, fmu-v2, fmu-v3, fmu-v4, fmu-v5, navio2, etc.
  • VARIANT: Indicates particular configurations: e.g. rtps, lpe, which contain components that are not present in the default configuration. Most commonly this is default, and may be omitted.

1.5 更多内容

如:

  • 编译命令解析
  • 其他硬件target的编译
  • 针对仿真平台的编译
    等问题,详细请参考网站PX4开发者手册

1.6 编译过程中的常见问题

General Build Errors
Many build problems are caused by either mismatching submodules or an incompletely cleaned-up build environment. Updating the submodules and doing a distclean can fix these kinds of errors:

git submodule update --recursive
make distclean

更多请参考PX4开发者手册 / troubleshooting

官方例程的使用

33

PX4与Ardupilot的区别

44

专业英语词汇、英文缩写(学习代码过程中遇到)

  • task_main_trampoline 中的 trampoline :蹦床,跳床,弹床

  • px4_task_spawn_cmd 中的 spawn :引发;引起;导致;造成

未解之谜

  • 是否函数名字包含main、并且参数列表为(int argc, char *argv[])的函数都会被单独编译成为一个独立的可执行程序???
    如:
void AttitudeEstimatorQ::task_main_trampoline(int argc, char *argv[])
{
	attitude_estimator_q::instance->task_main();
}

已解之谜

00

1. Linux使用

1.1 与Windows共享文件

  • 虚拟机设计

PX4学习笔记_第31张图片

  • Ubuntu共享文件目录的位置
    位置: /mnt/hgfs/
    / 为根目录。
    PX4学习笔记_第32张图片
    PX4学习笔记_第33张图片

1.2 Ubuntu文件管理器中copy、pastepw、delete的进度显示

PX4学习笔记_第34张图片

1. PX4 系统架构概述

PX4 由两个主要部分组成:一是 飞行控制栈(flight stack) ,该部分主要包括状态估计和飞行控制系统;另一个是 中间件 ,该部分是一个通用的机器人应用层,可支持任意类型的自主机器人,主要负责机器人的内部/外部通讯和硬件整合。

所有的 PX4 支持的 无人机机型 (包括其他诸如无人船、无人车、无人水下航行器等平台)均共用同一个代码库。 整个系统采用了 响应式(reactive) 设计,这意味着:

  • 所有的功能都可以被分割成若干可替换、可重复使用的部件。
  • 通过异步消息传递进行通信。
  • 系统可以应对不同的工作负载。

1.1 顶层软件架构

下面的架构图对 PX4 的各个积木模块以及各模块之间的联系进行了一个详细的概述。 图的上半部分包括了中间件模块,而下半部分展示的则是飞行控制栈的组件。
PX4学习笔记_第35张图片

1. PX4应用开发

1.1 hello sky

hello sky

1.2 UORB

The uORB is an asynchronous publish() / subscribe() messaging API used for inter-thread/inter-process communication.
uORB是用于线程间/进程间通信的异步publish()/subscribe()消息传递API。
数据被封装成一个UORB消息,C++编程编程中,以结构体为消息载体,进行发布、订阅。
规则:一个发布者、多个订阅者。

  • 订阅

PX4学习笔记_第36张图片

  • 发布

PX4学习笔记_第37张图片

  • Topic的读写
    读: 获取该Topic对应的UORB消息。
    写:发布最新(更新)UORB消息。
    通过句柄的方式对Topic进行读写。
    句柄:在程序设计中,句柄是一种特殊的智能指针,当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄
    例如:
//读:
int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined)); 
struct sensor_combined_s raw; 
whiletrue{
int poll_ret = px4_poll(fds, 1, 1000);
orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);
}

//写:
struct vehicle_attitude_s att;
orb_advert_t att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);
whiletrue{
att = 传感器硬件接口函数(或驱动);
orb_publish(ORB_ID(vehicle_attitude), att_pub_fd, &att);
}

解析:
PX4学习笔记_第38张图片
总结:
读:
orb_subscribe( )
orb_copy( )
写:
orb_advertise( )
orb_publish( )

1.2.1 Topics

各应用之间的消息通道被称为 topics ;

MVLink消息与UORB消息的关系

  • UORB是进程之间的通信机制,遵循订阅、发布主题的原则,这个机制建立在NUttx操作系统之上,UORB消息(message)以C++的结构体作为数据载体,进行发布和订阅。进程(app)之间通信,通过UORB。
  • MALinnk是一种通信协议,该协议广泛应用于地面站(Ground Control Station,GCS)与无人载具(Unmanned vehicles)之间的通信。该协议中,数据的载体被称为消息包(MassagePacket)。消息包则通过串口(或者其他通信接口负责发送,底层实现)。
  • 在飞控中,一些关键的UORB消息通常会包打包成MAVLink的消息包,发送给地面站,如心跳包;飞控也会发送MAVLink消息包给飞控,然后MAVLink消息包被转换成UORB消息发布到对应的Topic中,以便控制飞控,如参数修改,航点写入等。负责打包和发送的进程为MALink_app。发送至地面站的MAVLink消息(包)如下图可在地面站中查看。

1.3 PX4之UORB开发

1.MAVLink

1.1 概述

  • UORB是进程之间的通信机制,遵循订阅、发布主题的原则,这个机制建立在NUttx操作系统之上,UORB消息(message)以C++的结构体作为载体,进行发布和订阅。进程(app)之间通信,通过UORB。
  • MALinnk是一种通信协议,该协议广泛应用于地面站(Ground Control Station,GCS)与无人载具(Unmanned vehicles)之间的通信。该协议中,数据的载体被称为消息包(MassagePacket)。消息包则通过串口(或者其他通信接口负责发送,底层实现)。
  • 在飞控中,一些关键的UORB消息通常会包打包成MAVLink的消息包,发送给地面站,如心跳包;飞控也会发送MAVLink消息包给飞控,然后MAVLink消息包被转换成UORB消息发布到对应的Topic中,以便控制飞控,如参数修改,航点写入等。负责打包和发送的进程为MALink_app。发送至地面站的MAVLink消息(包)如下图可在地面站中查看。

PX4学习笔记_第39张图片
消息包种类、通用的MAVLink消息(包)的定义和用途介绍可以查阅网站https://mavlink.io/en/messages/common.html#messages了解。

消息包结构封装的信息用于发送消息、接收消息、识别消息种类,而负载信息则用于描述消息所要传达的具体内容,可以理解为信封和信纸的关系

通过MavLink协议实现通信需要地面站软件和飞行控制软件的协作。地面站软件与飞行控制软件在发送、接收MavLink消息时需要依照预先设定的流程,本文以无人机与地面站连接时通信握手、参数列表请求、参数设定、状态消息包循环收发为例,在第四章介绍。

1.2 Packets Format(包的结构)

  • MavLink 1.0版本
    PX4学习笔记_第40张图片
    包中各字段的含义:

PX4学习笔记_第41张图片

  • MAVLink 2.0版本
     1234
    包中各字段的含义:
    PX4学习笔记_第42张图片
    C代码定义:
uint8_t magic;              ///< protocol magic marker
uint8_t len;                ///< Length of payload
uint8_t incompat_flags;     ///< flags that must be understood
uint8_t compat_flags;       ///< flags that can be ignored if not understood
uint8_t seq;                ///< Sequence of packet
uint8_t sysid;              ///< ID of message sender system/aircraft
uint8_t compid;             ///< ID of the message sender component
uint8_t msgid 0:7;          ///< first 8 bits of the ID of the message
uint8_t msgid 8:15;         ///< middle 8 bits of the ID of the message
uint8_t msgid 16:23;        ///< last 8 bits of the ID of the message
uint8_t payload[max 255];   ///< A maximum of 255 payload bytes
uint16_t checksum;          ///< X.25 CRC
uint8_t signature[13];      ///< Signature which allows ensuring that the link is tamper-proof (optional)
  • The minimum packet length is 12 bytes for acknowledgment packets without payload.
  • The maximum packet length is 280 bytes for a signed message that uses the whole payload.

1.3 Packet 的封装过程

PX4学习笔记_第43张图片

  • 包的示例
    本文开始提到MavLink使用消息库的形式定义传输规则,用户可以在在源码中查阅消息库的内容,此处使用Java语言下的消息库作为实例,以便更清晰地展示包结构(MavLink源码自带了多语言的生成器,可从源码中的xml文件转换为对应C,C++,Java等语言的MavLink协议包)。以下表格中,SEQ为计算得出,数值不固定,故用X代替,SYS,COMP两项为笔者使用的Mission Planner地面站设定的系统ID和组件ID,MSG项0代表HEARTBEAT消息的ID,PAYLOAD内存储详细信息,下一章节再介绍,最后的CKA CKB为封包后计算得出,以Y代替。
    在这里插入图片描述
    msg_request_data_stream:数据流请求包,地面站使用该消息包向飞行控制软件提交数据流申请,飞行控制软件收到该消息后将按照设定的参数周期性返回消息包。
    在这里插入图片描述
    例子:
    在这里插入图片描述

1.4 Packet、messages、commands、enums的关系。

两个或多个MAVLink系统之间通信的方式:相互收发 Packet 。
Packet可以分为两类:

  • messages
  • commands
    组成:
    Messages are encoded using message elements.
    Commands are defined as entries in the MAV_CMD enum, and encoded into real messages that are sent using the Mission Protocol or Command Protocol.
    选择:
    如果出现以下情况,请考虑发送message:
  • 所发送的information不适合comand(即,它不适合7个可用的数字字段)。
  • 该消息是另一个协议的一部分。
  • 消息必须广播或流式传输(即不需要ACK)

如果满足以下条件,请考虑发送command:

  • 该消息应作为任务的一部分执行。
  • 您希望在任务外部使用现有的任务命令。根据自动驾驶仪的不同,您可能可以在两种模式下使用相同的代码来处理消息。
  • 您正在使用MAVLink 1,并且没有新消息的免费ID(MAVLink 1具有比消息ID更大的MAVLink命令免费ID池)。
  • 重要的是,不要错过您的命令消息,因此需要ACK / NACK。使用现有协议确认可能比为确认定义另一个消息更快/更容易。

否则,可以自由使用任何一种方法。

Use commands for actions in missions or if you need acknowledgment or retry logic from a request. Otherwise use messages.

关系:
messages:
PX4学习笔记_第44张图片
command:
PX4学习笔记_第45张图片

1.5 其他知识点

区分 information nessages data message-data command enum 的含义即联系。
message type

message set 消息集
message 消息
消息在XML文件中定义
大多数地面控制站和自动驾驶仪实现的参考消息集在common.xml中定义
PX4学习笔记_第46张图片
MAVLink方言(Dialects)是XML文件,用于定义协议和特定于供应商的消息,枚举和命令。
枚举用于定义命名的值,这些值可以用作消息中的选项-例如,定义错误,状态或模式。还有一个特殊的枚举MAV_CMD,用于定义MAVLink命令。
MAVLink XML文件的大致结构:



<mavlink>

    <include>common.xmlinclude>
    <include>other_dialect.xmlinclude>

    
    

    <dialect>8dialect>

    <enums>
        
    enums>

    <messages>
        
    messages>

mavlink>

MAVLink的enums、 messages,、commands 和 other elements在XML文件中定义,然后使用代码生成器转换为支持的编程语言的库。

1.4 PX4中MAVLink的使用

本教程假定你在 msg/ca_trajectory.msg 文件中定义了一个名为 ca_trajectory 的 自定义 uORB 消息,以及在 mavlink/include/mavlink/v2.0/custom_messages/mavlink_msg_ca_trajectory.h 文件中定义了一个名为 ca_trajectory的 自定义 MAVLink 消息。

此章节旨在说明:如何使用一条自定义uORB消息,并将其作为一条MAVLink消息发送出去。

你可能感兴趣的:(PX4,无人机,旋翼机,Ardupilot)