# PX4 结构概述

PX4 主要由两层组成,即 飞行算法池 是一个估计和飞行控制系统,而 中间件 是一个通用机器人层,可支持任何类型的自主机器人,提供内部/外部通信和硬件集成。

所有 PX4 机身 共享一个代码库(包括其他机器人系统,如船只、漫游车、潜水艇等)。完整的系统设计是 反应 (打开新窗口)这意味着

  • 所有功能都分为可交换和可重复使用的组件
  • 通信是通过异步信息传递完成的
  • 系统可应对不同的工作量

# 高级软件架构

下图提供了 PX4 构件的详细概览。图的上半部分包含中间件模块,下半部分显示飞行算法池的组件。

PX4 结构

源代码被分割成独立的模块/程序(如图 单空间 在图中)。通常一个构件对应一个模块。

TIP

在运行时,您可以使用 顶级 命令,每个模块都可以通过 <module_name> 开始/停止.虽然 顶级 命令是 NuttX shell 特有的,其他命令也可以在 SITL shell (pxh>) 中使用。有关这些模块的更多信息,请参阅 模块和命令参考.

箭头显示的是 最重要的 模块之间的连接。实际上,连接的数量比显示的要多得多,而且大多数模块都会访问某些数据(如参数)。

模块之间通过名为 "发布-订阅 "的信息总线进行通信。 uORB.使用 "发布-订阅 "方案意味着:

  • 系统是被动的--它是异步的,当有新数据时会立即更新
  • 所有操作和通信都完全并行化
  • 系统组件可以线程安全的方式从任何地方消耗数据

备注

这种架构允许快速、轻松地更换每一个模块,甚至在运行时也是如此。

# 飞行算法池

飞行算法池是自主无人机制导、导航和控制算法的集合。它包括用于固定翼、多旋翼和 VTOL 机身的控制器,以及姿态和位置估算器。

下图显示了飞行算法池的构件概览。它包含从传感器、遥控输入和自主飞行控制(导航仪)到电机或伺服控制(执行器)的整个流程。

PX4 高级飞行算法池

一个 估计者 获取一个或多个传感器输入,将它们组合起来,计算出载具状态(例如,根据 IMU 传感器数据计算出载具姿态)。

A 控制器 是一个将设定点和测量值或估计状态(过程变量)作为输入的组件。其目标是调整过程变量的值,使其与设定点相匹配。输出是最终达到设定点的修正值。例如,位置控制器将位置设定点作为输入,过程变量是当前估计的位置,输出则是姿态和推力设定点,使飞行器向理想位置移动。

A 混频器 该系统接收力指令(如向右转弯),并将其转换为单个电机指令,同时确保不超出某些限制。这种转换针对具体的载具类型,并取决于各种因素,例如相对于重心的电机布置或载具的转动惯量。

# 中间件

中间件 主要包括用于嵌入式传感器的设备驱动程序、与外部世界(配套计算机、GCS 等)的通信以及 uORB 发布-订阅信息总线。

此外,中间件还包括一个 模拟层 它允许 PX4 飞行代码在桌面操作系统上运行,并在模拟世界中控制计算机模型飞行器。

# 更新费率

由于模块需要等待信息更新,因此通常由驱动程序定义模块的更新速度。大多数 IMU 驱动程序以 1kHz 的频率对数据进行采样,然后以 250Hz 的频率进行整合和发布。系统的其他部分,如 导航仪由于不需要这么高的更新率,因此运行速度要慢得多。

信息更新率可以是 检查 通过运行 顶部.

# 运行环境

PX4 可在提供 POSIX-API 的各种操作系统(如 Linux、macOS、NuttX 或 QuRT)上运行。它还应具有某种形式的实时调度功能(如先进先出)。

模块间通信(使用 uORB)基于共享内存。整个 PX4 中间件在一个地址空间内运行,即所有模块共享内存。

备注

根据系统的设计,只需极少的努力,就可以在单独的地址空间中运行每个模块(需要更改的部分包括 uORB, 参数接口, 数据管理员敷衍).

模块有两种不同的执行方式:

  • 任务:模块在自己的任务中运行,有自己的堆栈和进程优先级。

  • 工作队列任务:模块在共享工作队列上运行,与队列上的其他模块共享相同的堆栈和工作队列线程优先级。

    • 所有任务都必须相互合作,不能相互干扰。
    • 多个 工作队列任务 可以在一个队列上运行,也可以有多个队列。
    • A 工作队列任务 是通过指定未来的一个固定时间,或通过 uORB 主题更新回调来安排的。

    在工作队列上运行模块的优点是占用内存少,可能导致任务切换次数减少。缺点是 工作队列任务 不允许在消息上休眠或轮询,也不允许执行阻塞 IO(如从文件中读取)。长时间运行的任务(进行大量计算)也应在单独的任务或至少是单独的工作队列中运行。

备注

工作队列中运行的任务不会显示在 顶级 (只能看到工作队列本身--如 wq:lp_default).使用方法 工作队列状态 来显示所有活动的工作队列项目。

# 背景任务

px4_task_spawn_cmd() 用于启动新任务(NuttX)或线程(POSIX - Linux/macOS),它们独立于调用(父)任务运行:

独立任务 = px4_task_spawn_cmd(
    "指挥官";,                    // 进程名称
    SCHED_DEFAULT,                  // 调度类型(RR 或 FIFO)
    默认优先级 + 40,    // 调度优先级
    3600,                           // 新任务或线程的堆栈大小
    指挥官主线程,          // 任务(或线程)主函数
    (烧焦 *  *)及样品;参数[0]        // 传递给新任务的虚指针
                                    // (此处为命令行参数)。
    );

# 操作系统特定信息

# NuttX

NuttX (打开新窗口) 是在飞行控制板上运行 PX4 的主要 RTOS。它开源(BSD 许可)、轻量级、高效且非常稳定。

模块作为任务执行:它们有自己的文件描述符列表,但共享一个地址空间。任务仍可启动一个或多个共享文件描述符列表的线程。

每个任务/线程都有一个固定大小的堆栈,并有一个定期任务来检查所有堆栈是否还有足够的可用空间(基于堆栈着色)。

# Linux/macOS

在 Linux 或 macOS 上,PX4 在单个进程中运行,模块在各自的线程中运行(与 NuttX 没有任务和线程之分)。