Browse Source

docs: add team 7-Nano guides and environment setup

Copy project PX4 notes into docs/project and add a clone/build
workflow for shared development on this GitLab snapshot.
7-nano-minimal-vtol
蔡享 1 month ago
parent
commit
624f9b2981
  1. 383
      docs/project/CUAV_7-Nano_GPS2配置与检查.md
  2. 635
      docs/project/PX4_EKF2数据融合与尾座式VTOL切换逻辑.md
  3. 856
      docs/project/PX4_NuttX操作系统架构与运行机制.md
  4. 948
      docs/project/PX4_ULog日志分析实用指南.md
  5. 465
      docs/project/PX4_rcS启动流程与实机准备.md
  6. 405
      docs/project/PX4四电机编号与当前尾座式配置.md
  7. 402
      docs/project/PX4源码学习路线.md
  8. 21
      docs/project/README.md
  9. 216
      docs/project/环境搭建流程.md

383
docs/project/CUAV_7-Nano_GPS2配置与检查.md

@ -0,0 +1,383 @@
# CUAV 7-Nano GPS2 配置与检查
## 1. 当前设备和固件配置
- 飞控:CUAV 7-Nano V2
- PX4:`v1.17.0`
- 固件目标:`cuav_7-nano_minimal_vtol`
- 当前 GPS 物理连接口:`GPS2`
- GPS协议:UBX(从当前 `gps status` 输出判断)
当前固件中的串口映射为:
| 物理接口 | PX4设备节点 |
|---|---|
| GPS1 | `/dev/ttyS0` |
| GPS2 | `/dev/ttyS6` |
| TELEM1 | `/dev/ttyS5` |
| TELEM2 | `/dev/ttyS3` |
| TELEM3 | `/dev/ttyS1` |
该映射来自:
```text
boards/cuav/7-nano/minimal_vtol.px4board
```
其中定义:
```text
CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0"
CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS6"
```
---
## 2. 当前检测结果
在 NuttShell 中执行:
```sh
gps status
```
得到:
```text
INFO [gps] Main GPS
INFO [gps] protocol: UBX
INFO [gps] status: NOT OK, port: /dev/ttyS0, baudrate: 0
INFO [gps] sat info: disabled
INFO [gps] rate reading: 0 B/s
```
这段输出表示:
1. GPS驱动已经启动。
2. 驱动正在把 `/dev/ttyS0` 当作 Main GPS 端口。
3. `/dev/ttyS0` 对应物理 `GPS1` 接口。
4. 当前 GPS 实际插在物理 `GPS2` 接口,即 `/dev/ttyS6`
5. 驱动当前读取了错误的物理串口。
6. `rate reading: 0 B/s` 表示该串口没有收到任何 GPS 字节。
7. `status: NOT OK` 不是单纯的“室内没有卫星定位”,而是当前端口连串口数据都没有收到。
因此,当前首要问题是 GPS 端口配置与实际接线不一致。
---
## 3. GPS串口配置参数
当前固件中,GPS串口配置值含义为:
| 参数值 | 端口 |
|---:|---|
| `0` | Disabled,禁用 |
| `101` | TELEM1 |
| `102` | TELEM2 |
| `103` | TELEM3 |
| `201` | GPS1 |
| `202` | GPS2 |
相关参数:
- `GPS_1_CONFIG`:配置 Main GPS 所使用的串口。
- `GPS_2_CONFIG`:配置 Secondary GPS 所使用的串口。
这里的 `GPS_1_CONFIG``GPS_2_CONFIG` 表示“主 GPS 实例”和“次 GPS 实例”,并不强制要求主 GPS 一定插在物理 GPS1 口。
例如:只有一个 GPS,且它插在物理 GPS2 口时,可以让 Main GPS 使用 GPS2:
```text
GPS_1_CONFIG=202
GPS_2_CONFIG=0
```
---
## 4. 当前推荐配置
当前只有一个 GPS,并且插在 GPS2 物理接口,因此推荐将它配置成 Main GPS。
先查看现有参数:
```sh
param show GPS_1_CONFIG
param show GPS_2_CONFIG
```
然后设置:
```sh
param set GPS_1_CONFIG 202
param set GPS_2_CONFIG 0
param save
reboot
```
设置结果表示:
```text
Main GPS → GPS2物理口 → /dev/ttyS6
Secondary GPS → 禁用
```
`GPS_1_CONFIG``GPS_2_CONFIG` 都属于需要重启后生效的串口配置参数。
不要同时把两个 GPS 实例配置到同一个物理串口,否则会产生串口占用冲突。
---
## 5. 重启后的验证步骤
### 5.1 检查 GPS 驱动状态
```sh
gps status
```
首先确认端口已经变成:
```text
port: /dev/ttyS6
```
如果串口和模块正常,应看到:
```text
status: OK
rate reading: 非0 B/s
```
波特率也应被自动检测为一个实际值,而不是长期保持 `0`
### 5.2 检查原始 GPS 数据
```sh
listener sensor_gps -n 5
```
重点字段:
| 字段 | 含义 | 正常表现 |
|---|---|---|
| `timestamp` | 数据时间戳 | 每次输出持续增加 |
| `fix_type` | 定位类型 | 室外最终至少达到 `3` |
| `satellites_used` | 使用的卫星数量 | 室外逐渐增加并趋于稳定 |
| `latitude_deg` | 纬度 | 定位后为有效值 |
| `longitude_deg` | 经度 | 定位后为有效值 |
| `altitude_msl_m` | 海拔高度 | 定位后为有效值 |
| `eph` | 水平精度估计 | 定位后逐渐降低并稳定 |
| `epv` | 垂直精度估计 | 定位后逐渐降低并稳定 |
| `vel_m_s` | 地面速度 | 静止时接近0 |
常见 `fix_type`
| 数值 | 含义 |
|---:|---|
| `0` | 没有有效 GPS |
| `1` | 没有定位 |
| `2` | 2D定位 |
| `3` | 3D定位 |
| `4` | DGPS |
| `5` | RTK Float |
| `6` | RTK Fixed |
GPS在室内可能已经有非零串口数据,但长时间无法达到 `3D Fix`。这表示通信已经建立、卫星信号不足,和 `rate reading: 0 B/s` 是不同问题。
### 5.3 检查 EKF2 是否融合 GPS
```sh
ekf2 status
```
然后查看融合标志:
```sh
listener estimator_status_flags -n 1
```
重点关注类似字段:
```text
cs_gnss_pos: True
cs_gnss_vel: True
```
只有 `sensor_gps` 有数据,不代表 EKF 一定已经采用它。EKF还会检查定位类型、精度、数据质量和稳定时间。
### 5.4 检查最终位置输出
```sh
listener vehicle_global_position -n 3
listener vehicle_local_position -n 3
```
判断链路如下:
```text
GPS串口收到字节
gps驱动解析UBX数据
sensor_gps持续发布
EKF2检查质量并融合
vehicle_global_position / vehicle_local_position
```
---
## 6. 推荐的一次性检查命令
重启飞控后,按顺序执行:
```sh
param show GPS_1_CONFIG
param show GPS_2_CONFIG
gps status
listener sensor_gps -n 5
ekf2 status
listener estimator_status_flags -n 1
listener vehicle_global_position -n 3
listener vehicle_local_position -n 3
```
预期参数应为:
```text
GPS_1_CONFIG = 202
GPS_2_CONFIG = 0
```
---
## 7. 如果改为 GPS2 后仍然没有数据
如果重启后已经看到:
```text
port: /dev/ttyS6
```
但仍然是:
```text
status: NOT OK
rate reading: 0 B/s
```
说明参数端口已经正确,问题转向硬件、线序或设备类型。按以下顺序检查。
### 7.1 检查供电
- GPS模块指示灯是否亮。
- GPS2接口是否有正确供电电压。
- GPS模块需要的电压是否与飞控接口兼容。
- 插头是否完全插入、方向是否正确。
### 7.2 检查 UART 线序
UART连接需要交叉:
```text
GPS TX → 飞控 RX
GPS RX → 飞控 TX
GPS GND → 飞控 GND
GPS VCC → 正确电源
```
不同厂家即使使用相同外形插头,针脚顺序也不一定一致。不能仅凭插头能插入就认定线序兼容,必须核对 CUAV 7-Nano 与 GPS 模块各自的针脚定义。
### 7.3 确认 GPS 接口类型
确认模块输出的是哪一种接口:
- UART UBX
- UART NMEA
- DroneCAN/UAVCAN
如果模块是 DroneCAN GPS,就不应插在普通 UART GPS2 口并由 `gps` 串口驱动读取。DroneCAN设备应连接 CAN 接口,并检查:
```sh
uavcan status
```
### 7.4 检查串口占用
确认 GPS2 没有同时配置给:
- MAVLink
- 遥控接收机
- DShot遥测
- 其他串口驱动
- Secondary GPS的另一个实例
一个物理串口通常只能由一个驱动占用。
### 7.5 检查协议和波特率
通常保持 GPS协议自动检测即可。当前输出已经显示协议为 UBX,但如果始终没有任何接收字节,首先仍应检查供电、线序和端口,而不是反复修改协议参数。
---
## 8. 如果将来安装两个 GPS
如果将来同时在 GPS1 和 GPS2 各安装一个串口 GPS,可以配置:
```sh
param set GPS_1_CONFIG 201
param set GPS_2_CONFIG 202
param save
reboot
```
对应关系:
```text
Main GPS → GPS1 → /dev/ttyS0
Secondary GPS → GPS2 → /dev/ttyS6
```
两个 GPS 发布时,`sensor_gps` 会存在多个实例。可以使用:
```sh
listener sensor_gps -i 0 -n 3
listener sensor_gps -i 1 -n 3
```
具体 `listener` 参数以当前固件中的 `listener help` 输出为准。
---
## 9. 当前结论
当前状态不是“GPS有数据但没有卫星定位”,而是:
```text
GPS插在GPS2物理口
PX4仍在读取GPS1对应的/dev/ttyS0
读取速率为0 B/s
GPS状态NOT OK
```
当前应先应用:
```sh
param set GPS_1_CONFIG 202
param set GPS_2_CONFIG 0
param save
reboot
```
重启后,以 `gps status` 是否显示 `/dev/ttyS6` 和非零 `rate reading` 作为第一步验证。通信正常后,再到室外等待 `fix_type >= 3`,最后确认 EKF2 已经融合 GNSS 位置和速度。

635
docs/project/PX4_EKF2数据融合与尾座式VTOL切换逻辑.md

@ -0,0 +1,635 @@
# PX4 EKF2 数据融合与尾座式 VTOL 切换逻辑
## 1. 当前源码与机型背景
本文针对当前工程中的配置进行说明:
- PX4 源码版本:`v1.17.0`
- PX4 源码目录:`simulation_ws/deps/PX4-Autopilot`
- 飞控:雷迅/CUAV 7-Nano V2
- 固件目标:`cuav_7-nano_minimal_vtol`
- 机型:Generic VTOL Tailsitter
- `SYS_AUTOSTART=13200`
- `VT_TYPE=0`,表示尾座式 VTOL
需要先区分两个概念:
- `EKF2` 负责数据融合,回答“飞机当前姿态、位置、速度和风速是多少”。
- `vtol_att_control` 负责 VTOL 状态管理,决定使用多旋翼还是固定翼控制逻辑。
它们会相互使用数据,但不是同一个模块。
---
## 2. EKF2 数据融合的总体过程
PX4 使用扩展卡尔曼滤波器 EKF2。数据融合并不是简单地把多个传感器的读数求平均,而是持续执行“预测、比较、修正”。
```text
陀螺仪、加速度计
状态预测 Predict
├── 磁力计
├── GNSS/GPS
├── 气压计
├── 空速计
├── 测距仪
├── 光流
└── 外部视觉
计算创新量和可信度
状态修正 Correct
姿态、位置、速度、风速、传感器偏置
```
核心源码:
- `src/modules/ekf2/EKF2.cpp`
- `src/modules/ekf2/EKF/ekf.cpp`
- `src/modules/ekf2/EKF/control.cpp`
- `src/modules/ekf2/EKF/estimator_interface.cpp`
---
## 3. IMU 如何进行状态预测
IMU主要包含:
- 陀螺仪:测量机体三个轴的角速度。
- 加速度计:测量机体三个轴的比力。
陀螺仪用于推算姿态变化:
```text
上一时刻姿态 + 角速度积分 = 当前预测姿态
```
加速度经过当前姿态转换到地理坐标系,并扣除重力后,用来推算速度和位置:
```text
加速度积分 → 速度
速度积分 → 位置
```
IMU频率高,可以提供连续、快速的状态预测。但陀螺仪和加速度计都存在噪声及零偏,因此只依靠 IMU 会逐渐漂移。
`Ekf::update()` 的核心调用顺序如下:
```cpp
predictCovariance(imu_sample_delayed);
predictState(imu_sample_delayed);
controlFusionModes(imu_sample_delayed);
```
含义是:
1. 预测状态的不确定度。
2. 使用 IMU 预测姿态、速度和位置等状态。
3. 使用其他传感器观测修正预测结果。
源码位置:`src/modules/ekf2/EKF/ekf.cpp:137`。
### 3.1 EKF初始化姿态
启动时,EKF会检查飞机是否基本静止,例如:
- 加速度模长是否接近重力加速度。
- 角速度是否低于规定范围。
满足条件后,EKF可以使用重力方向初始化横滚角和俯仰角。因此飞控启动和传感器初始化时应保持机体静止。
---
## 4. 各传感器在融合中的作用
| 传感器 | 主要作用 |
|---|---|
| 陀螺仪 | 预测姿态变化 |
| 加速度计 | 预测速度、位置,并约束横滚和俯仰 |
| 磁力计 | 修正航向角 `yaw` |
| GNSS/GPS | 修正水平位置、地速,也可辅助高度和航向 |
| 气压计 | 修正高度和垂直位置 |
| 空速计 | 提供相对空气速度,辅助估算风速和状态 |
| 测距仪 | 提供近地距离和近地高度信息 |
| 光流 | 在无 GNSS 环境中提供水平移动信息 |
| 外部视觉 | 提供室内位置、姿态或速度观测 |
融合调度位于 `src/modules/ekf2/EKF/control.cpp:46`,其中根据编译配置、参数、传感器健康状态和数据有效性决定是否调用:
```cpp
controlMagFusion();
controlGpsFusion();
controlAirDataFusion();
controlHeightFusion();
controlExternalVisionFusion();
```
“代码被编译进固件”和“运行时正在融合”是两回事。例如固件包含空速融合代码,不代表没有连接空速计时它仍会融合空速数据。
---
## 5. EKF 如何判断传感器数据是否可信
假设 EKF 根据 IMU 推算飞机速度是 `12 m/s`,GNSS报告速度是 `15 m/s`
```text
创新量 innovation = 测量值 - 预测值
= 15 - 12
= 3 m/s
```
EKF会结合以下信息判断这个差值是否合理:
- 传感器测量噪声。
- 当前状态协方差,即 EKF 对自己预测结果的不确定程度。
- 创新检验门限。
- 数据时间戳和新鲜程度。
- 传感器健康状态。
- 当前是否正在地面、空中、多旋翼或固定翼飞行。
根据判断结果,EKF可能:
- 正常融合观测。
- 只进行较小幅度修正。
- 临时拒绝异常观测。
- 停止使用故障传感器。
- 必要时重置位置、速度或航向等状态。
卡尔曼增益决定一次观测应当把预测结果修正多少。因此 GNSS 突然跳变时,估计位置通常不会不加判断地跟着跳变。
---
## 6. 不同传感器如何进行时间对齐
不同传感器存在不同延迟,例如 GNSS、气压计和空速计的数据到达时间通常不一致。PX4会把 IMU 数据放入环形缓冲区,在一个延迟的融合时刻处理观测:
```text
过去 当前
│-----------------------------│
↑ ↑
延迟融合时刻 实时输出时刻
```
处理过程为:
1. IMU数据持续进入缓冲区。
2. EKF读取缓冲区中较早的 IMU 样本。
3. 把具有延迟的 GNSS、气压计、空速等观测对齐到对应时刻。
4. 在延迟时刻执行预测和融合修正。
5. 输出预测器把修正后的状态继续预测到当前时刻。
这样既能正确处理传感器延迟,又能避免控制器直接使用明显滞后的姿态数据。
相关源码:`src/modules/ekf2/EKF/estimator_interface.cpp:78`。
---
## 7. EKF2 输出哪些数据
EKF2通过 uORB 发布的主要消息包括:
- `vehicle_attitude`:当前姿态四元数。
- `vehicle_local_position`:本地坐标位置、速度、高度。
- `vehicle_global_position`:经纬度和海拔。
- `vehicle_odometry`:完整位姿和速度。
- `wind`:估算风速。
- `estimator_status`:估计器状态。
- `estimator_status_flags`:融合状态标志。
- `estimator_innovations`:各观测创新量。
多旋翼控制器和固定翼控制器使用同一套 EKF 状态。切换到固定翼模式时不会停止或重新启动 EKF。尾座式机体转过约 90 度后,EKF只是用四元数继续表示新的机体姿态。
---
## 8. 当前尾座式机型的融合特殊项
`13200_generic_vtol_tailsitter` 设置了:
```sh
param set-default EKF2_FUSE_BETA 0
```
这表示尾座式机型默认关闭固定翼零侧滑约束融合,因为当前 PX4 源码明确标记该功能尚不支持 tailsitter。
空速计仍然可以有两个互相独立的用途:
1. EKF2使用空速观测辅助估算风速和状态。
2. `vtol_att_control` 使用有效空速判断能否完成前转换。
第二项用途不等于 EKF 空速融合。即使 EKF没有使用某项空速融合方式,VTOL 状态机仍可能读取 `airspeed_validated`
---
## 9. 尾座式 VTOL 的物理转换过程
尾座式转换不是“停止旋翼发动机,再启动固定翼发动机”。对常见尾座式来说:
- 悬停时机头朝上,电机推力向上。
- 前转换时整架飞机向前俯转并加速。
- 固定翼状态时机头朝前,同一组电机继续提供前向推力。
- 空速足够后,机翼产生主要升力。
- 后转换时整架飞机重新转回接近竖直姿态。
真正发生变化的是:
- 飞机姿态目标。
- 多旋翼和固定翼控制输出的使用方式。
- 推力在不同控制坐标中的映射。
- 电机差动推力和舵面的控制权。
---
## 10. 尾座式状态机
状态机位于 `src/modules/vtol_att_control/tailsitter.cpp:59`
```text
多旋翼 MC_MODE
│ 请求固定翼
前转换 TRANSITION_FRONT_P1
│ 姿态和空速等条件满足
固定翼 FW_MODE
│ 请求多旋翼
后转换 TRANSITION_BACK
│ 接近竖直姿态或达到时间限制
多旋翼 MC_MODE
```
`VT_TYPE=0` 表示使用 Tailsitter 实现。
VTOL切换请求可以来自遥控器开关、飞行任务、QGroundControl命令或失效保护逻辑。状态机不会因为检测到机体倾斜就自行随意切换模式,它需要相应的转换请求。
---
## 11. 前转换:多旋翼到固定翼
收到固定翼请求后,状态变化为:
```text
MC_MODE → TRANSITION_FRONT_P1
```
PX4会保存转换开始时间和初始姿态,并生成一个不断向前旋转的姿态目标。
目标旋转速率近似为:
```text
90° / VT_F_TRANS_DUR
```
参数默认值为:
```text
VT_F_TRANS_DUR = 5 s
```
这表示期望姿态目标大约用 5 秒从竖直方向转到水平飞行方向。它不是对飞机实际转换时间的绝对保证。实际姿态变化还受以下因素影响:
- 推重比。
- 机体惯量。
- 多旋翼姿态和角速度参数。
- 电机响应速度。
- 气流和外部扰动。
源码位置:`src/modules/vtol_att_control/tailsitter.cpp:212`。
### 11.1 转换期间由哪个控制器控制
前转换期间,尾座式主要由多旋翼姿态控制器完成整机姿态旋转:
```text
转换姿态目标
多旋翼姿态控制器
多旋翼角速度控制器
电机力矩和推力
```
原因是刚开始转换时空速较低,机翼和舵面的气动控制能力还很弱,不能立即完全依靠固定翼舵面。
在非 `FW_MODE` 状态下,电机推力和力矩主要来自:
```text
vehicle_torque_setpoint_virtual_mc
vehicle_thrust_setpoint_virtual_mc
```
相关源码:`src/modules/vtol_att_control/tailsitter.cpp:314`。
---
## 12. 前转换完成条件
当前尾座式实现首先要求实际俯仰角达到:
```text
pitch <= -60°
```
阈值位于 `src/modules/vtol_att_control/tailsitter.h:52`
### 12.1 有有效空速计
`airspeed_validated` 中存在有效的真实传感器空速,并且 `FW_USE_AIRSPD` 启用时,完成条件是:
```text
实际俯仰角 <= -60°
并且
校准空速 >= VT_ARSP_TRANS
```
默认参数:
```text
VT_ARSP_TRANS = 10 m/s
```
两个条件都满足后,状态机才会从 `TRANSITION_FRONT_P1` 进入 `FW_MODE`
### 12.2 没有有效空速计
如果 `vtol_att_control` 没有取得有效的传感器空速,尾座式专用判断主要依靠姿态:
```text
实际俯仰角 <= -60°
```
然后允许完成转换。这意味着系统无法直接确认机翼是否真的获得了足够空速,安全性更依赖推重比、转换时间、机体实际性能和试飞验证。
完成判断位于 `src/modules/vtol_att_control/tailsitter.cpp:337`
---
## 13. 固定翼模式下的控制
进入 `FW_MODE` 后,控制链路为:
```text
固定翼位置/模式控制器
航迹、滚转、俯仰和油门目标
固定翼姿态与角速度控制器
virtual_fw 力矩和推力
vtol_att_control 坐标映射
电机、差动推力和舵面
```
固定翼控制器发布:
```text
vehicle_torque_setpoint_virtual_fw
vehicle_thrust_setpoint_virtual_fw
```
尾座式代码把固定翼 X 轴的前向推力转换到尾座式电机对应的推力轴:
```cpp
_thrust_setpoint_0->xyz[2] =
-_vehicle_thrust_setpoint_virtual_fw->xyz[0];
```
源码位置:`src/modules/vtol_att_control/tailsitter.cpp:287`。
这不是电机停止或重新启动,而是控制输出来源和控制坐标发生变化。
如果启用了相关参数,固定翼控制器还可以通过电机差动推力产生滚转、俯仰或偏航力矩。
---
## 14. 舵面什么时候参与控制
当前 `13200_generic_vtol_tailsitter` 设置:
```text
VT_ELEV_MC_LOCK = 0
```
这表示多旋翼状态下不锁住升降副翼。对应逻辑是:
```cpp
if (!VT_ELEV_MC_LOCK || 当前不是MC模式) {
使用固定翼控制器产生的舵面力矩;
}
```
源码位置:`src/modules/vtol_att_control/tailsitter.cpp:328`。
因此当前配置下:
- 电机在 MC 和转换阶段主要采用多旋翼控制输出。
- 舵面仍可以接收固定翼控制器输出。
- 低速时舵面气动效果较弱。
- 随空速增加,舵面产生的实际控制力自然增大。
这里的逐渐接管主要来自气动控制能力随空速增大,而不是尾座式代码将 MC 和 FW 电机力矩简单地做线性平均。
---
## 15. 后转换:固定翼回到多旋翼
请求切回多旋翼后,状态变化为:
```text
FW_MODE → TRANSITION_BACK
```
PX4生成逐渐回到竖直方向的姿态目标。目标旋转速率近似为:
```text
90° / VT_B_TRANS_DUR
```
13200机型把参数默认值设置为:
```text
VT_B_TRANS_DUR = 5 s
```
后转换期间再次由多旋翼姿态控制器负责转动机体,并把固定翼推力平滑连接到多旋翼推力。
后转换完成条件是:
```text
pitch >= -15°
或者
后转换时间 > VT_B_TRANS_DUR
```
相关源码:`src/modules/vtol_att_control/tailsitter.cpp:92`。
---
## 16. 转换失败与 Quadchute
Quadchute 是 VTOL 在固定翼飞行或转换异常时,紧急退回多旋翼模式的保护机制。可能触发的原因包括:
- 固定翼飞行高度低于允许值。
- 出现非指令性的持续掉高。
- 前转换掉高超过限制。
- 固定翼俯仰角超过限制。
- 固定翼横滚角超过限制。
- 前转换超时。
- 有空速计,但空速增长过慢。
- 外部命令要求立即退回 MC。
例如,当有有效空速时,满足下面的情况可能判断为前转换失败:
```text
转换时间 > VT_F_TR_OL_TM
并且
空速 < VT_ARSP_BLEND
```
相关保护判断位于 `src/modules/vtol_att_control/vtol_type.cpp:327`
需要注意,Quadchute不是降落伞功能。它表示从固定翼控制状态快速退回多旋翼控制状态。
---
## 17. 完整的数据和控制链路
```text
IMU / GNSS / 气压计 / 磁力计 / 空速计
EKF2
姿态、位置、速度、风速
┌─────────┴─────────┐
▼ ▼
多旋翼控制器 固定翼控制器
│ │
virtual_mc 输出 virtual_fw 输出
└─────────┬─────────┘
vtol_att_control
状态判断、姿态转换、输出选择
control_allocator
电机和舵机
```
要点如下:
1. 多旋翼和固定翼控制器共用同一个 EKF2 状态估计。
2. 转换时 EKF2 不会重新初始化。
3. MC 和 FW 控制模块会生成各自的虚拟控制输出。
4. `vtol_att_control` 根据当前状态选择并映射这些输出。
5. 尾座式前后转换期间主要由多旋翼控制器控制整机姿态旋转。
6. 有有效空速时,前转换会同时检查姿态和空速。
7. 同一组电机通常始终工作,变化的是推力方向、控制来源和坐标映射。
8. `control_allocator` 最终把期望推力和力矩分配为各个电机、舵机的具体输出。
---
## 18. 实机调试时建议观察的消息
可以在 PX4 控制台中使用 `listener`
```sh
listener estimator_status
listener estimator_status_flags
listener estimator_innovations
listener vehicle_attitude
listener vehicle_local_position
listener airspeed_validated
listener vtol_vehicle_status
listener vehicle_torque_setpoint_virtual_mc
listener vehicle_torque_setpoint_virtual_fw
listener vehicle_thrust_setpoint_virtual_mc
listener vehicle_thrust_setpoint_virtual_fw
```
其中:
- `estimator_status`:检查 EKF 整体状态和故障信息。
- `estimator_status_flags`:确认 GNSS、磁力计、气压、空速等是否正在融合。
- `estimator_innovations`:检查传感器观测与 EKF 预测的差异。
- `airspeed_validated`:检查空速来源、校准空速和数据是否有效。
- `vtol_vehicle_status`:检查当前处于 MC、前转换、FW 还是后转换。
- `virtual_mc/fw` 消息:比较两套控制器分别产生了什么输出。
实飞问题应优先提供 `.ulg` 日志。分析转换问题时,至少关注:
- 实际姿态与姿态目标。
- 空速、地速和高度。
- VTOL 状态变化时间点。
- MC/FW 虚拟推力和力矩。
- 电机及舵机最终输出。
- EKF创新量和融合状态。
- Quadchute原因及相关事件消息。
---
## 19. 当前参数的参考值
以下是当前源码中的主要默认值或 13200 机型覆盖值:
| 参数 | 参考值 | 含义 |
|---|---:|---|
| `VT_TYPE` | `0` | 尾座式 VTOL |
| `VT_F_TRANS_DUR` | `5 s` | 前转换目标姿态旋转时长 |
| `VT_B_TRANS_DUR` | `5 s` | 后转换目标姿态旋转时长,13200覆盖值 |
| `VT_ARSP_BLEND` | `8 m/s` | 转换检查使用的空速参考值 |
| `VT_ARSP_TRANS` | `10 m/s` | 有效空速条件下完成前转换的空速 |
| `VT_TRANS_TIMEOUT` | `15 s` | 前转换总超时 |
| `VT_TRANS_MIN_TM` | `2 s` | 通用最短前转换时间参数 |
| `VT_F_TR_OL_TM` | `6 s` | 前转换开环时间/检查参考时间 |
| `VT_ELEV_MC_LOCK` | `0` | MC模式下不锁住尾座式舵面 |
| `EKF2_FUSE_BETA` | `0` | 尾座式关闭零侧滑约束融合 |
不要仅根据默认值直接进行实机转换。转换参数必须结合以下实际数据确定:
- 机体重量和重心。
- 推重比和电机响应。
- 翼载荷及失速速度。
- 空速计安装方向与校准结果。
- 多旋翼和固定翼两套控制参数。
- 执行器几何和控制分配。
---
## 20. 首次实机验证顺序
建议按以下顺序逐级验证,不要第一次试飞就直接测试完整自动转换:
1. 拆除螺旋桨,确认机型、传感器方向和飞控安装方向。
2. 检查每个电机编号、旋转方向以及失控保护。
3. 检查每个舵面的方向、限位和中立位置。
4. 分别确认 MC 与 FW 模式下的执行器响应方向。
5. 完成加速度计、陀螺仪、磁力计、遥控器和空速计校准。
6. 确认 EKF 状态正常,所有所需观测正在融合。
7. 先完成稳定的多旋翼悬停和位置控制测试。
8. 根据机体条件验证固定翼控制参数和执行器方向。
9. 在模拟器或受控环境中验证前后转换状态机。
10. 在足够高度、足够空间和具备人工接管条件时进行实机转换测试。
特别需要确认:`13200` 是通用双电机、双舵面尾座式模板。实际飞机的电机数量、舵面形式和执行器几何必须与控制分配配置一致。仅仅选择该机型并不意味着它天然适配所有尾座式结构。

856
docs/project/PX4_NuttX操作系统架构与运行机制.md

@ -0,0 +1,856 @@
# PX4 NuttX 操作系统架构与运行机制
## 1. 当前系统配置
本文针对当前工程和飞控配置编写:
- 飞控:CUAV 7-Nano V2
- MCU:STM32H753II,ARM Cortex-M7
- PX4版本:`v1.17.0`
- 固件目标:`cuav_7-nano_minimal_vtol`
- 操作系统:Apache NuttX RTOS
- 当前NuttX源码提交:`fb2fadf6f599c1406f052db013efd00a2518e72c`
- 地址空间模型:Flat Build
- 系统基础Tick:`1 ms`
- 初始化入口:`nsh_main`
准确地说:
```text
NuttX是底层实时操作系统
PX4是运行在NuttX上的飞控软件平台和应用程序集
```
PX4本身不是操作系统。PX4使用NuttX提供的任务调度、中断、文件系统、设备驱动、内存管理和同步机制,完成传感器采集、状态估计、飞行控制和通信。
---
## 2. 整体软件分层
```text
PX4飞行功能
EKF2、姿态控制、位置控制、VTOL、MAVLink、Logger
PX4基础框架
uORB、参数系统、Work Queue、设备抽象、事件系统
NuttX实时操作系统
任务调度、线程、文件系统、驱动模型、网络、内存管理
STM32H753硬件
CPU、Flash、RAM、UART、SPI、I2C、CAN、USB、SD卡、定时器
```
以当前GPS2为例:
```text
GPS模块输出UBX串口数据
STM32 UART硬件
NuttX串口驱动:/dev/ttyS6
PX4 gps驱动解析UBX协议
发布uORB主题sensor_gps
EKF2检查并融合GNSS数据
```
NuttX负责UART字节收发,但不理解GNSS定位。UBX解析、数据健康检查和EKF融合属于PX4功能。
---
## 3. NuttX是什么
NuttX是面向微控制器的实时操作系统(RTOS),特点包括:
- 基于优先级的抢占式实时调度。
- 支持任务、POSIX线程和信号。
- 支持信号量、互斥锁和消息队列。
- 提供接近POSIX的编程接口。
- 使用类似Unix的设备文件模型。
- 支持多种文件系统。
- 支持UART、SPI、I2C、CAN、USB、SDMMC和网络。
- 占用空间远小于Linux。
- 可以直接运行在STM32等微控制器上。
飞控需要可预测的实时响应。例如陀螺仪产生新数据后,角速度控制器不能因为SD卡正在写日志或MAVLink正在发送数据而长期得不到CPU。
NuttX通过优先级调度确保高优先级控制任务可以抢占低优先级后台任务。
---
## 4. 实时任务调度
NuttX的基本调度方式是:
```text
高优先级任务变为就绪
抢占当前低优先级任务
执行高优先级实时工作
高优先级任务阻塞或完成
低优先级任务继续执行
```
当前构建配置:
```text
CONFIG_USEC_PER_TICK=1000
CONFIG_RR_INTERVAL=0
CONFIG_PRIORITY_INHERITANCE=y
```
含义:
- 基础系统Tick是 `1000 us`,即 `1 ms`
- 当前没有启用同优先级任务的固定时间片轮转间隔。
- 启用了优先级继承。
### 4.1 为什么1 ms Tick不限制高频控制
PX4的高频控制并不只依赖NuttX的1 ms基础Tick,还会使用:
- 硬件高分辨率定时器(HRT)。
- IMU数据就绪中断。
- DMA完成中断。
- uORB订阅回调。
- PX4定时工作队列。
因此传感器和控制回路可以按照数据到达事件或更精确的时间基准运行。
### 4.2 优先级继承
优先级反转示例:
```text
低优先级任务持有互斥锁
高优先级控制任务需要该锁
中优先级任务持续抢占低优先级任务
高优先级任务长时间等待
```
启用优先级继承后,持锁的低优先级任务可以临时继承等待者的高优先级,尽快释放锁,减少高优先级任务的阻塞时间。
---
## 5. PX4模块如何运行
PX4模块主要有两种运行形式。
### 5.1 独立任务或线程
部分模块拥有独立任务、独立栈和调度上下文,适合:
- 需要阻塞等待设备的驱动。
- 独立通信循环。
- 较复杂的后台服务。
- 命令行或管理任务。
在NSH中可以查看任务:
```sh
ps
```
查看CPU和栈使用情况:
```sh
top
```
### 5.2 PX4 Work Queue
许多PX4模块不各自建立一个永久线程,而是作为WorkItem挂到共享工作队列。
```text
多个模块WorkItem
按时间或数据回调加入队列
工作队列线程按顺序执行到期任务
```
优点:
- 减少线程数量。
- 减少每个线程所需的独立栈内存。
- 将相关功能放到合适的优先级。
- 方便使用传感器或uORB事件驱动模块运行。
当前PX4定义的典型工作队列包括:
```text
wq:rate_ctrl 角速度控制相关高优先级队列
wq:nav_and_controllers 导航、姿态和位置控制队列
wq:hp_default 默认高优先级工作
wq:lp_default 低优先级后台工作
wq:INS0~INS3 IMU和惯性传感器工作
wq:SPI0~SPI6 SPI总线相关工作
wq:I2C0~I2C4 I2C总线相关工作
wq:ttyS0~ttyS9 串口相关工作
wq:uavcan DroneCAN/UAVCAN工作
```
当前部分模块对应关系:
| PX4模块 | 工作队列 |
|---|---|
| `mc_rate_control` | `wq:rate_ctrl` |
| `vtol_att_control` | `wq:rate_ctrl` |
| `control_allocator` | `wq:rate_ctrl` |
| `vehicle_angular_velocity` | `wq:rate_ctrl` |
| `mc_att_control` | `wq:nav_and_controllers` |
| `mc_pos_control` | `wq:nav_and_controllers` |
| `fw_att_control` | `wq:nav_and_controllers` |
| `fw_lateral_longitudinal_control` | `wq:nav_and_controllers` |
| `airspeed_selector` | `wq:nav_and_controllers` |
| `land_detector` | `wq:nav_and_controllers` |
| `load_mon` | `wq:lp_default` |
| `temperature_compensation` | `wq:lp_default` |
可以尝试查看当前工作队列状态:
```sh
work_queue status
```
具体可用命令以当前固件的 `help` 输出为准。
---
## 6. uORB模块通信
PX4模块之间主要使用uORB发布/订阅系统通信:
```text
发布者
│ publish
uORB主题
│ subscribe
一个或多个订阅者
```
例如:
```text
gps驱动
│ 发布sensor_gps
EKF2和GPS选择模块
│ 发布位置估计
位置控制器和导航模块
```
uORB是PX4自己实现的中间件,不等于NuttX内核的消息队列。
NuttX提供:
- 线程和任务调度。
- 信号量和互斥锁。
- 等待和唤醒机制。
- 设备驱动接口。
- 内存管理。
PX4在这些机制之上实现uORB,使模块之间不需要直接调用彼此。
例如EKF2不需要知道GPS驱动对象的地址,只需订阅 `sensor_gps`
控制台可以观察uORB数据:
```sh
listener sensor_gps -n 3
listener vehicle_attitude -n 3
listener vehicle_local_position -n 3
```
---
## 7. Flat地址空间模型
当前实际构建配置:
```text
CONFIG_BUILD_FLAT=y
CONFIG_BUILD_PROTECTED未启用
CONFIG_BUILD_KERNEL未启用
```
这表示:
```text
NuttX内核
设备驱动
PX4基础框架
所有PX4模块
共享同一个地址空间
```
### 7.1 优点
- 函数调用开销低。
- 数据交换快。
- 内存占用较小。
- 不需要复杂的系统调用和地址空间切换。
- 适合资源有限的实时微控制器。
### 7.2 缺点
- 模块之间没有Linux进程级的内存隔离。
- 一个模块发生非法指针访问可能破坏其他模块的数据。
- 单个严重错误可能引起整个飞控HardFault和重启。
- 不能像Linux一样单独隔离一个崩溃进程。
因此PX4中的“模块”通常是同一固件地址空间中的线程、任务或WorkItem,不是Linux中完全隔离的进程。
---
## 8. 内存结构
CUAV 7-Nano使用STM32H753,主要存储区域如下。
### 8.1 内部Flash
```text
0x08000000
┌──────────────────────────────┐
│ PX4 Bootloader │ 128 KiB
├──────────────────────────────┤ 0x08020000
│ PX4应用 │ 1920 KiB
│ NuttX + PX4 + ROMFS │
└──────────────────────────────┘
```
### 8.2 RAM
```text
ITCM RAM 64 KiB
DTCM1 RAM 64 KiB
DTCM2 RAM 64 KiB
AXI SRAM 512 KiB
SRAM1 128 KiB
SRAM2 128 KiB
SRAM3 32 KiB
SRAM4 64 KiB
Backup RAM 4 KiB
```
不同RAM区域有不同的访问延迟、总线和DMA能力。任务栈、堆、DMA缓冲区、关键数据以及备份数据不一定放在同一区域。
NuttX负责:
- 创建和回收任务栈。
- 管理堆内存。
- 管理文件描述符。
- 管理信号量和互斥锁。
- 处理中断和上下文切换。
常用观察命令:
```sh
free
top
ps
```
分析时重点关注:
- 空闲堆内存是否持续下降。
- 某个任务栈是否接近耗尽。
- CPU负载是否持续过高。
- 是否出现HardFault、断言或栈溢出。
---
## 9. 设备文件模型
NuttX使用类似Unix的设备文件访问硬件。例如当前板卡的串口映射:
```text
GPS1 → /dev/ttyS0
TELEM3 → /dev/ttyS1
TELEM2 → /dev/ttyS3
TELEM1 → /dev/ttyS5
GPS2 → /dev/ttyS6
USB → /dev/ttyACM0(运行阶段按配置创建)
```
应用程序通过 `open()`、`read()`、`write()`、`ioctl()` 等接口访问设备。
例如MAVLink模块打开:
```text
/dev/ttyS5
```
就可以通过TELEM1收发MAVLink字节。
同一个串口通常不能同时分配给多个模块,否则会出现端口占用冲突或数据协议混乱。
---
## 10. 文件系统
当前NuttX构建启用了:
```text
FAT
ROMFS/CROMFS
procfs
BINFS
MTD
```
### 10.1 ROMFS/CROMFS
PX4固件内部携带只读文件系统,包含:
```text
/etc/init.d/rcS
/etc/init.d/rc.vtol_defaults
/etc/init.d/airframes/13200_generic_vtol_tailsitter
```
这些文件在编译时被打包进PX4应用固件并写入MCU内部Flash,不在SD卡中。
### 10.2 FAT与SD卡
SD卡通常使用FAT文件系统,并挂载到:
```text
/fs/microsd
```
主要保存:
- `.ulg`飞行日志。
- HardFault记录。
- 用户自定义配置文件。
- 自定义日志主题。
- 任务和运行时数据。
常用命令:
```sh
ls /fs/microsd
df
mount
```
### 10.3 procfs
procfs提供运行中的系统和任务状态。`ps`、任务栈信息等工具可以利用procfs数据。
### 10.4 MTD
MTD表示Memory Technology Device,用于访问Flash、FRAM或其他非易失性存储设备及其分区。
PX4可以使用这些区域保存:
- 参数。
- 硬件信息。
- 校准和持久化数据。
- 网络配置等板级数据。
具体保存位置取决于板卡硬件和PX4板级配置。
---
## 11. NSH控制台
当前看到的:
```text
NuttShell (NSH)
nsh>
```
是NuttX Shell。其作用类似简化的Unix Shell。
NuttX/NSH提供的典型命令:
```sh
ls
cd
cat
cp
rm
mount
df
ps
kill
free
ifconfig
```
PX4又把自己的内置模块命令注册到NSH:
```sh
gps status
ekf2 status
mavlink status
logger status
commander status
listener sensor_gps
param show GPS_1_CONFIG
```
执行 `gps status` 时:
```text
NSH解析命令
查找名为gps的PX4内置程序入口
调用gps模块的命令处理函数
gps模块输出当前状态
```
因此NSH是操作系统提供的Shell环境,`gps`、`ekf2`、`mavlink`等则是PX4注册进去的程序。
---
## 12. 网络功能
当前NuttX配置启用了网络栈,包括:
- Ethernet驱动支持。
- IPv4。
- TCP。
- UDP。
- ICMP。
- ARP。
- DHCP客户端。
- DNS客户端。
- Telnet服务相关能力。
当前CUAV 7-Nano板级默认还配置了一个Ethernet MAVLink实例。
常用检查命令:
```sh
ifconfig
netstat
ping <IP地址>
```
具体命令是否存在取决于当前minimal固件是否编译对应系统命令。
网络栈由NuttX提供,MAVLink UDP、远程NSH或其他PX4网络服务建立在该网络栈之上。
---
## 13. 系统启动流程
当前初始化入口为:
```text
CONFIG_INIT_ENTRYPOINT="nsh_main"
```
完整启动过程可以简化为:
```text
飞控上电或复位
PX4 Bootloader运行
├─ 有升级请求:停留在Bootloader
└─ 应用有效:跳转到0x08020000
STM32与NuttX底层初始化
创建Idle任务和初始化任务
nsh_main
board_app_initialize()
px4_platform_init()
挂载ROMFS、初始化PX4平台
执行/etc/init.d/rcS
读取参数和选择机型脚本
启动驱动、uORB、EKF2、控制器、MAVLink、Logger
```
板级初始化入口:
```text
boards/cuav/7-nano/src/init.c
```
PX4平台初始化入口:
```text
platforms/nuttx/src/px4/common/px4_init.cpp
```
NuttX负责启动操作系统和NSH;`rcS`负责按照板卡、参数和机型组织PX4模块启动。
---
## 14. 中断、驱动与控制链路
以IMU驱动控制回路为例:
```text
IMU硬件产生数据就绪中断
STM32中断处理和DMA/SPI传输
PX4 IMU驱动取得传感器数据
发布sensor_gyro/sensor_accel
传感器处理和EKF2更新
姿态/角速度控制器运行
control_allocator计算执行器输出
PWM或DShot驱动更新电机
```
中断处理程序通常只完成必要的快速操作,然后唤醒线程或Work Queue继续处理,避免在中断上下文中执行耗时算法。
---
## 15. 故障检测和HardFault
当前板卡配置启用了:
```text
CONFIG_BOARD_CRASHDUMP=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_DEBUG_HARDFAULT_ALERT=y
CONFIG_DEBUG_MEMFAULT=y
CONFIG_BOARD_RESET_ON_ASSERT=2
```
系统可以检测或记录:
- 非法内存访问。
- 总线错误。
- UsageFault。
- 栈溢出。
- 断言失败。
- 看门狗复位。
- 部分任务调度和栈使用异常。
发生严重错误时,因为当前是Flat共享地址空间,系统通常无法只终止一个模块并保证其他模块继续安全飞行,可能记录Crash Dump后复位整个飞控。
可检查:
```sh
dmesg
hardfault_log check
```
以及SD卡根目录中的:
```text
fault_*.log
```
如果 `.ulg` 日志在空中突然终止,也应同时检查HardFault记录和供电问题。
---
## 16. NuttX与Linux的区别
| 项目 | 当前NuttX系统 | Linux系统 |
|---|---|---|
| 主要目标 | 微控制器实时控制 | 通用计算和多用户应用 |
| CPU平台 | STM32 Cortex-M7 | 通常Cortex-A、x86等带MMU的处理器 |
| 地址空间 | 当前为Flat共享地址空间 | 用户进程通常有虚拟地址隔离 |
| 调度重点 | 固定优先级和实时响应 | 公平性、吞吐量及多种调度策略 |
| 程序形式 | 大部分模块编入一个固件 | 独立可执行文件和动态库 |
| Shell | NSH | Bash、Zsh等 |
| 模块通信 | PX4主要使用uORB | Socket、Pipe、共享内存等 |
| 存储 | MCU Flash、FRAM和SD卡 | 磁盘或大容量Flash文件系统 |
| 故障隔离 | Flat模式下较弱 | 进程隔离较强 |
| 启动时间 | 很短 | 通常更长 |
| 内存占用 | 很小 | 通常较大 |
因此不能直接用Linux进程的理解套用PX4模块。例如 `ekf2 start` 启动的是固件内部编译好的PX4模块任务,而不是从磁盘加载一个独立ELF可执行文件。
---
## 17. 常用系统诊断命令
### 17.1 CPU、任务和内存
```sh
top
ps
free
work_queue status
```
### 17.2 启动和系统消息
```sh
dmesg
ver all
shutdown status
```
### 17.3 文件系统和SD卡
```sh
mount
df
ls /fs/microsd
logger status
sd_bench -r 100
```
### 17.4 设备和通信
```sh
gps status
mavlink status
uavcan status
ifconfig
```
### 17.5 PX4模块与uORB
```sh
commander status
ekf2 status
listener sensor_gps -n 3
listener vehicle_attitude -n 3
listener estimator_status_flags -n 1
```
某些命令可能在minimal固件中被裁剪,应以控制台执行 `help` 后显示的命令为准。
---
## 18. 阅读源码的建议顺序
如果要从操作系统角度学习当前PX4,可以按以下顺序阅读:
1. 板级NuttX配置:
```text
boards/cuav/7-nano/nuttx-config/nsh/defconfig
```
2. CUAV板级初始化:
```text
boards/cuav/7-nano/src/init.c
boards/cuav/7-nano/src/board_config.h
```
3. PX4的NuttX平台初始化:
```text
platforms/nuttx/src/px4/common/px4_init.cpp
```
4. PX4启动脚本:
```text
ROMFS/px4fmu_common/init.d/rcS
```
5. PX4任务和工作队列:
```text
platforms/common/px4_work_queue/
platforms/common/include/px4_platform_common/px4_work_queue/
```
6. uORB实现:
```text
platforms/common/uORB/
src/modules/uORB/
```
7. 一个具体驱动和一个控制模块:
```text
src/drivers/gps/
src/modules/mc_rate_control/
```
这样可以沿着“操作系统初始化、PX4平台初始化、模块启动、消息通信、实际功能模块”的路径建立完整理解。
---
## 19. 核心结论
```text
NuttX负责:
让代码按优先级、按时运行,并管理硬件、内存和文件系统
PX4负责:
采集传感器、估计飞机状态、计算控制量并管理飞行任务
uORB负责:
让PX4各模块通过发布/订阅方式交换数据
Work Queue负责:
让多个PX4模块高效共享实时线程和调度优先级
rcS负责:
根据板卡、参数和机型启动所需的PX4模块
```
当前CUAV 7-Nano采用NuttX Flat Build以换取较低开销和更高实时效率,但模块之间没有Linux进程级内存隔离。因此编写和修改PX4底层代码时,需要特别重视指针安全、栈使用、执行时间和线程同步。

948
docs/project/PX4_ULog日志分析实用指南.md

@ -0,0 +1,948 @@
# PX4 ULog 日志分析实用指南
## 1. 这份文档解决什么问题
本文针对当前工程环境编写:
- PX4:`v1.17.0`
- 飞控:CUAV 7-Nano V2
- 机型:Generic VTOL Tailsitter
- `SYS_AUTOSTART=13200`
- 固件目标:`cuav_7-nano_minimal_vtol`
- 本机已经安装:`pyulog 1.2.3`
本文说明:
1. `.ulg` 文件是什么。
2. 如何从飞控中取得日志。
3. 有哪些现成的日志分析工具。
4. 如何系统地分析一次飞行故障。
5. 如何重点分析 EKF2、振动、控制器和尾座式 VTOL 转换。
6. 把日志交给他人分析时还需要提供什么信息。
---
## 2. `.ulg` 文件是什么
`.ulg` 是 PX4 的 ULog 二进制日志文件。它不是普通文本日志,而是按时间记录大量 uORB 主题数据,例如:
- 飞行模式和解锁状态。
- 飞机姿态、位置、速度和高度。
- 姿态、角速度、位置和速度目标值。
- IMU、GNSS、磁力计、气压计和空速计数据。
- EKF2融合状态、创新量和故障标志。
- 遥控器输入。
- 电机和舵机输出。
- 电池电压、电流和剩余电量。
- VTOL状态和前后转换过程。
- PX4事件、警告和错误消息。
- 飞行时使用的参数值以及固件版本信息。
它的核心价值是:把同一时刻的“输入、状态估计、控制目标、控制输出和故障事件”放在一条时间线上进行比较。
```text
传感器输入
EKF状态估计
控制目标与实际响应
电机/舵机输出
飞机运动结果和故障事件
```
仅看 QGroundControl 当时显示的一句错误,通常只能知道“系统发现了什么”;ULog 才能进一步判断“错误发生前后各数据如何变化”。
---
## 3. 日志如何产生
PX4默认通常在解锁时开始记录,在上锁后停止记录。每次完整的解锁飞行一般都会生成一个新的 `.ulg` 文件。
在 MAVLink 控制台中可以检查记录器:
```sh
logger status
```
查看完整命令帮助:
```sh
logger help
```
手动开始和停止记录:
```sh
logger on
logger off
```
### 3.1 建议的基本参数
首次调试建议保持:
```text
SDLOG_BACKEND:启用 SD 卡日志
SDLOG_MODE=0:解锁时开始、上锁时停止
SDLOG_PROFILE=1:默认通用分析主题
```
`SDLOG_PROFILE` 是位掩码,不是单选编号。当前 v1.17 的常见位如下:
| 位 | 数值 | 用途 |
|---:|---:|---|
| 0 | 1 | 默认通用分析主题 |
| 1 | 2 | EKF2完整回放主题 |
| 2 | 4 | 温度校准 |
| 3 | 8 | 系统辨识 |
| 4 | 16 | 高速机动、控制器和执行器高频记录 |
| 5 | 32 | 自定义调试主题 |
| 6 | 64 | 多传感器对比 |
| 7 | 128 | 视觉与避障 |
| 8 | 256 | 陀螺仪原始 FIFO 高频数据 |
| 9 | 512 | 加速度计原始 FIFO 高频数据 |
| 10 | 1024 | MAVLink tunnel 消息 |
| 11 | 2048 | 高频传感器主题 |
多个配置需要把数值相加。例如:
```text
默认主题 + 高频控制主题 = 1 + 16 = 17
```
不要为了“记录得更全”直接设置为 `4095`。高频原始 IMU 会显著增加写入带宽和文件大小,SD卡写入不及时反而会造成日志丢帧。
### 3.2 针对当前尾座式的建议
- 日常飞行和第一次排查:`SDLOG_PROFILE=1`。
- 角速度跟踪、PID或快速转换细节:短时间测试可用 `SDLOG_PROFILE=17`
- EKF深度回放不是普通故障排查的必需项,不要一开始就启用全部高频配置。
- 改变 `SDLOG_PROFILE` 后需要重启飞控。
### 3.3 确认日志没有严重丢帧
日志质量也要检查。可以用:
```sh
ulog_info flight.ulg
```
输出中会显示:
```text
Dropouts: count, total duration, max, mean
```
少量很短的 dropout 未必影响分析,但故障发生的关键时间段存在长时间丢帧,会使因果链不完整。
如果日志经常丢帧,可检查:
- SD卡质量和格式。
- 是否启用了过多高频记录主题。
- 日志文件是否过大。
- SD卡写入是否出现长时间阻塞。
飞控控制台可以测试 SD 卡:
```sh
sd_bench -r 100
```
---
## 4. 如何从飞控下载 `.ulg`
### 4.1 使用 QGroundControl
最方便的方式是:
1. 连接飞控。
2. 打开 QGroundControl 的 Analyze/分析页面。
3. 进入 Log Download/日志下载。
4. 刷新日志列表。
5. 根据日期、时间和大小选择对应日志。
6. 下载为 `.ulg` 文件。
下载时建议记录:
- 飞行日期和大致时间。
- 哪一次解锁对应哪个文件。
- 故障大约发生在起飞后多少秒。
### 4.2 直接读取 SD 卡
也可以断电后取出 SD 卡,在日志目录中复制 `.ulg` 文件。操作前应正常上锁并断电,避免日志尚未写完或文件系统损坏。
### 4.3 日志突然在空中结束
如果 `.ulg` 在空中突然中止,应同时检查 SD 卡根目录是否存在类似文件:
```text
fault_YYYY_MM_DD_HH_MM_SS.log
```
日志突然结束的常见原因包括:
- 飞控掉电或供电瞬断。
- PX4/NuttX发生硬故障。
- SD卡被移除或写入失败。
仅凭 `.ulg` 结束无法区分掉电和系统硬故障,`fault_*.log`、飞行视频和供电记录都很重要。
---
## 5. 有哪些现成的分析工具
| 工具 | 类型 | 适合用途 | 注意事项 |
|---|---|---|---|
| PX4 Flight Review | 在线网页 | 第一次快速全面检查 | 日志会上传到公网服务,敏感数据需谨慎 |
| PlotJuggler | 本地 GUI | 自由选择全部 uORB 字段、同步多图分析 | 需要安装,初次使用要建立布局 |
| pyulog | 本地命令行/Python | 查看主题、参数、事件、转CSV和自动化分析 | 需要理解主题字段 |
| PX4 EKF分析脚本 | 本地 Python | 自动生成 EKF健康结果、CSV和PDF | 只针对 EKF,不等于整机故障诊断 |
| FlightPlot | 本地 GUI | 常规曲线查看 | 功能和维护状态需按实际版本确认 |
建议采用这样的组合:
```text
Flight Review快速总览
找出异常发生的准确时间
PlotJuggler检查相关原始主题
pyulog或Python做精确提取和批量分析
```
如果日志包含敏感航迹、经纬度、设备编号或任务信息,不应上传公共 Flight Review;可以只使用本地工具,或者自建私有 Flight Review。
---
## 6. 工具一:PX4 Flight Review
地址:<https://logs.px4.io/>
使用方式:
1. 打开网页。
2. 上传 `.ulg`
3. 等待生成报告。
4. 查看报告中的事件、模式、姿态、振动、GPS、EKF和执行器曲线。
5. 保存分析页面链接,方便多人查看同一份报告。
### 6.1 Flight Review适合检查什么
- 固件、机型和关键参数。
- 解锁、起飞、模式切换、转换和上锁时间。
- PX4产生的 warning、error 和 failsafe 事件。
- 姿态或角速度目标跟踪。
- 位置和高度目标跟踪。
- IMU振动、剪切和FFT。
- GNSS质量和位置跳变。
- EKF创新量及估计器异常。
- 电池电压、电流和压降。
- 电机或舵机输出饱和。
- VTOL模式背景:MC、FW和转换阶段。
Flight Review 中常见背景颜色会表示飞行模式;VTOL还会标记多旋翼、固定翼和转换区段。因此先确定故障发生在哪个模式,再看对应控制器。
### 6.2 Flight Review的局限
- 它展示的是预设图表,不会把日志中的所有字段全部显示出来。
- 自动告警是线索,不一定是根因。
- 某个曲线异常可能是前一个问题的结果。
- 日志上传到公共服务会涉及数据隐私。
例如“EKF高度创新异常”可能由气压计气流干扰、强振动、GNSS高度跳变或实际快速下沉引起,不能只看这一条自动结论。
---
## 7. 工具二:PlotJuggler
PlotJuggler 是适合深入分析 ULog 的桌面工具。它能列出日志中实际存在的全部 uORB 主题和字段,并将多个曲线放在同步时间轴上。
基本使用方式:
1. 安装并启动 PlotJuggler。
2. 打开 `.ulg` 文件。
3. 在左侧搜索主题或字段。
4. 将字段拖到绘图区。
5. 横向缩放到故障时间段。
6. 分割多个面板,对比输入、目标、状态和输出。
7. 保存 Layout,下次分析同类日志直接复用。
### 7.1 建议建立的四层布局
```text
第一层:模式、状态和事件
第二层:目标值与实际状态
第三层:传感器和 EKF 创新量
第四层:电机、舵机、电池和执行器饱和
```
PlotJuggler还可以:
- 用四元数计算 roll、pitch 和 yaw。
- 做字段间加减、缩放和滤波。
- 用 X/Y 字段显示二维航迹。
- 保存尾座式专用分析模板。
### 7.2 为什么需要多图同步
假设飞机转换时突然掉高,单看高度只能知道“发生了掉高”。同步查看以下数据才能判断原因:
```text
VTOL状态
俯仰目标与实际俯仰
空速和地速
高度与垂直速度
推力目标
最终电机输出
电池电压
EKF垂直创新量
```
如果俯仰没有跟上目标且电机已经饱和,重点检查推重比、控制参数和重心;如果姿态正常但空速增长不足,重点检查推力、阻力和空速计;如果物理状态正常而估计高度突然跳变,则重点检查 EKF 和高度传感器。
---
## 8. 工具三:pyulog
当前电脑已经安装:
```text
pyulog 1.2.3
ulog_info:/home/jiagu/.local/bin/ulog_info
ulog2csv:/home/jiagu/.local/bin/ulog2csv
```
如果终端能找到用户级命令,可直接运行;如果提示找不到命令,可以使用完整路径,或把 `$HOME/.local/bin` 加入用户的 `PATH`
### 8.1 查看日志概况和主题
```sh
ulog_info flight.ulg
```
详细显示:
```sh
ulog_info -v flight.ulg
```
重点检查:
- 日志开始时间和持续时间。
- 是否存在 dropout。
- 硬件和固件版本。
- 日志包含哪些 uORB 主题。
- 每个主题的数据点数量。
如果想分析某个问题,却发现关键主题没有记录,事后无法从该日志恢复这些数据,只能调整日志配置后重新测试。
### 8.2 把指定主题导出为 CSV
不要默认把全部主题导出成几百个 CSV。应按问题选择主题:
```sh
mkdir -p csv_out
ulog2csv -m vehicle_status,vtol_vehicle_status,vehicle_attitude,vehicle_local_position,airspeed_validated -o csv_out flight.ulg
```
仅导出特定时间段:
```sh
ulog2csv -ts 30 -te 55 -m vehicle_attitude,vehicle_attitude_setpoint,airspeed_validated -o csv_out flight.ulg
```
`-ts``-te` 使用日志开始后的秒数,适合只提取故障附近的窗口。
查看帮助:
```sh
ulog_info -h
ulog2csv -h
```
### 8.3 Python读取示例
```python
from pyulog import ULog
ulog = ULog("flight.ulg")
print("Start timestamp:", ulog.start_timestamp)
print("Last timestamp:", ulog.last_timestamp)
for dataset in ulog.data_list:
print(dataset.name, dataset.multi_id, len(dataset.data["timestamp"]))
vtol = ulog.get_dataset("vtol_vehicle_status").data
print(vtol.keys())
```
使用前先通过 `ulog_info``data.keys()` 确认字段名。不同 PX4 版本的主题和字段可能变化,不应把其他版本脚本中的字段名直接套用。
---
## 9. 工具四:PX4自带 EKF2 分析脚本
当前源码仓库包含:
```text
Tools/ecl_ekf/process_logdata_ekf.py
Tools/ecl_ekf/analyse_logdata_ekf.py
Tools/ecl_ekf/batch_process_logdata_ekf.py
```
在 PX4 源码目录中执行:
```sh
cd /home/jiagu/seeker_debug_tool1/simulation_ws/deps/PX4-Autopilot
python3 Tools/ecl_ekf/process_logdata_ekf.py /完整路径/flight.ulg
```
脚本正常完成后会生成类似文件:
```text
flight.ulg-0.mdat.csv
flight.ulg-0.pdf
```
- `.mdat.csv`:EKF各项指标和 Pass/Warning/Fail 结果。
- `.pdf`:EKF关键曲线报告。
- `-0`:第0个 EKF 实例;启用多 EKF 时可能有多个实例。
只运行检测、不生成图:
```sh
python3 Tools/ecl_ekf/process_logdata_ekf.py /完整路径/flight.ulg --no-plots
```
该脚本至少需要日志中包含:
- `estimator_states`
- `estimator_status`
- `estimator_status_flags`
- `estimator_innovations`
- 能够判断起飞和着陆的数据
如果日志没有检测到有效飞行段,或者缺少必要主题,脚本会报告前置条件不满足。
### 9.1 自动 EKF 报告的正确用法
自动报告适合:
- 快速检查 GNSS、磁力计、高度、速度和空速创新。
- 批量比较多次试飞。
- 找出异常时间段和异常指标。
它不负责:
- 判断舵面安装反向。
- 判断电机编号映射错误。
- 分析全部 VTOL 转换逻辑。
- 代替对飞行视频、机体结构和供电系统的检查。
因此 EKF报告为 Pass,不代表整架飞机所有系统都正常;报告为 Fail,也要继续判断是什么外部因素导致 EKF观测异常。
---
## 10. 通用日志分析方法
分析日志不要一上来查看所有曲线。建议固定采用以下流程。
### 第一步:明确问题和时间点
先用一句话描述现象,例如:
```text
解锁后起飞正常,前转换约3秒后飞机快速掉高并自动退回MC。
```
同时记录:
- 故障发生在起飞后多少秒。
- 当时飞行模式。
- 遥控器执行了什么动作。
- 飞机实际表现。
- QGC显示了什么消息。
### 第二步:检查日志是否完整
检查:
- 日志是否覆盖故障前后。
- 是否在空中突然结束。
- dropout 是否严重。
- 关键主题是否存在。
- 固件版本和参数是否与预期一致。
### 第三步:建立事件时间线
优先查找:
- 解锁。
- 起飞。
- 模式变化。
- VTOL转换请求和状态变化。
- PX4 warning/error/failsafe事件。
- Quadchute。
- 上锁、坠机或日志中断。
### 第四步:比较目标与实际状态
控制问题最重要的判断原则:
```text
目标是否合理?
实际状态是否跟上目标?
控制输出是否还有余量?
```
典型比较包括:
- 期望姿态 vs 实际姿态。
- 期望角速度 vs 实际角速度。
- 期望高度 vs 实际高度。
- 期望速度 vs 实际速度。
- 期望推力/力矩 vs 最终执行器输出。
### 第五步:判断是估计问题还是物理响应问题
```text
传感器变化合理,但EKF输出异常 → 重点查融合和参数
传感器本身跳变 → 重点查传感器、安装、供电和干扰
EKF状态正常,实际未跟目标 → 重点查控制器、执行器、重心和动力
控制目标本身异常 → 重点查模式、任务、设定值和上游逻辑
```
### 第六步:寻找最早异常,不要只看最后告警
坠机前往往会连续出现很多错误。最后出现的“姿态失控”“EKF异常”可能只是结果。应向前回溯,找出第一条偏离正常状态的数据。
### 第七步:用其他证据交叉验证
日志不能直接看到:
- 螺旋桨是否断裂或脱落。
- 舵面连杆是否松脱。
- 机架是否开裂。
- 外部风况和碰撞过程。
- 电源接头是否瞬间接触不良。
因此最好同时保留:
- 飞行视频。
- QGC画面或截图。
- 机体照片和损伤情况。
- 参数文件。
- 电机、螺旋桨、舵面和电源配置。
---
## 11. EKF2问题重点看什么
推荐主题:
```text
estimator_status
estimator_status_flags
estimator_innovations
estimator_states
vehicle_attitude
vehicle_local_position
vehicle_global_position
sensor_gps / vehicle_gps_position(以日志实际主题为准)
sensor_mag
vehicle_air_data
airspeed_validated
```
### 11.1 检查融合状态
`estimator_status_flags` 用于确认在异常时刻:
- GNSS位置是否正在融合。
- GNSS速度是否正在融合。
- 磁力计或其他航向源是否正在融合。
- 气压、GNSS、测距或视觉高度源是否启用。
- 空速是否参与相关融合。
- 是否进入惯性推算或失去位置辅助。
### 11.2 检查创新量和检验比
创新量是观测与预测的差:
```text
innovation = measurement - prediction
```
需要关注:
- 异常是否短暂还是持续。
- 哪一类观测首先出现异常。
- 是否和模式切换、油门增加、振动或供电变化同时发生。
- 检验比是否越过拒绝门限。
不能只凭创新量大就认定 EKF算法错误。强振动、气压口受螺旋桨气流影响、磁场干扰、GNSS遮挡和空速管安装错误都可能造成创新异常。
### 11.3 尾座式姿态变化的特殊性
尾座式前转换会产生约90度的姿态变化和明显加速,以下现象需要一起观察:
- 实际俯仰是否平滑跟随转换目标。
- 加速度变化是否与推力和姿态变化相符。
- 气压高度是否受气流干扰。
- GNSS垂直速度与气压高度是否一致。
- 空速增长是否合理。
- 转换过程中是否发生磁力计或GNSS融合切换。
---
## 12. 振动问题重点看什么
推荐主题和图表:
- 原始或滤波后的加速度计数据。
- `sensor_accel`
- `sensor_gyro`
- `vehicle_angular_velocity`
- 加速度功率谱。
- Actuator Controls FFT。
- IMU clipping/剪切计数。
常见特征:
- 悬停时加速度曲线很粗、三个轴互相覆盖。
- 某个固定频率出现强峰值。
- 提高油门后振动突然明显增加。
- IMU clipping持续增长。
- 振动出现后紧接着发生EKF创新异常。
振动可能来自:
- 螺旋桨不平衡或损伤。
- 电机轴弯曲、轴承问题。
- 电机或机臂松动。
- 飞控减振安装不当。
- 机架、起落架或线束共振。
- 高频控制参数不合适。
日志能证明振动存在并确定频率和发生时间,但不一定能单独指出是哪一个物理零件,需要结合实机检查。
---
## 13. 控制器和执行器问题重点看什么
推荐主题:
```text
vehicle_attitude
vehicle_attitude_setpoint
vehicle_angular_velocity
vehicle_rates_setpoint
vehicle_torque_setpoint
vehicle_thrust_setpoint
actuator_motors
actuator_servos
actuator_outputs
battery_status
```
不同版本和驱动配置记录的最终执行器主题可能不同,应以 `ulog_info` 实际输出为准。
### 13.1 目标跟踪差
如果目标变化正常,但实际姿态或角速度跟不上:
- 检查输出是否饱和。
- 检查电机和舵面方向。
- 检查控制参数是否过低或过高。
- 检查重心、惯量和执行器能力。
- 检查电池压降和推重比。
### 13.2 输出长期饱和
某些电机或舵机长期达到上下限,通常表示控制器没有足够余量。可能原因包括:
- 飞机过重或推力不足。
- 重心偏移。
- 舵面行程不足。
- 电机、螺旋桨或舵机异常。
- 错误的执行器几何或控制分配。
- 过于激进的目标和控制参数。
短时间满油门并不必然是故障,必须结合飞行阶段和目标判断。
---
## 14. 当前尾座式 VTOL 转换如何分析
推荐至少记录和查看:
```text
vehicle_status
vtol_vehicle_status
vehicle_attitude
vehicle_attitude_setpoint
vehicle_angular_velocity
vehicle_rates_setpoint
vehicle_local_position
airspeed_validated
vehicle_torque_setpoint_virtual_mc
vehicle_torque_setpoint_virtual_fw
vehicle_thrust_setpoint_virtual_mc
vehicle_thrust_setpoint_virtual_fw
vehicle_torque_setpoint
vehicle_thrust_setpoint
actuator_motors / actuator_servos / actuator_outputs
battery_status
estimator_status
estimator_status_flags
estimator_innovations
```
默认日志中大部分主题已经存在;部分虚拟控制输出是 optional,必须先用 `ulog_info` 确认实际日志是否记录。
### 14.1 建立转换时间线
按顺序标记:
```text
收到固定翼转换请求
进入 TRANSITION_TO_FW
俯仰目标开始向固定翼方向变化
实际俯仰跟随、飞机加速、空速上升
├── 条件满足 → 进入 FW
└── 条件失败/保护触发 → Quadchute回MC
```
### 14.2 前转换逐项检查
1. `vtol_vehicle_status` 是否确实进入前转换。
2. 姿态目标是否平滑向前俯转。
3. 实际俯仰是否跟随目标,有没有明显滞后或振荡。
4. 多旋翼虚拟力矩和推力是否正常输出。
5. 电机最终输出是否饱和或明显不对称。
6. 电池电压是否在加速时大幅下降。
7. 空速是否连续、合理地增长。
8. 地速和空速是否符合当时风况。
9. 高度和垂直速度是否发生不可接受的下降。
10. 是否进入固定翼状态,或者出现 Quadchute 事件。
### 14.3 常见异常模式
| 日志现象 | 优先怀疑方向 |
|---|---|
| 姿态目标正常,实际俯仰跟不上,电机已饱和 | 推重比、重心、控制参数、电机能力 |
| 姿态跟踪正常,但空速增长很慢 | 推力不足、阻力过大、逆风、空速计或安装问题 |
| 空速突然跳变,而地速和姿态无对应变化 | 空速计、皮托管、气路或校准问题 |
| 转换时高度估计跳变,GNSS垂直运动不支持该变化 | 气压气流干扰或EKF高度源问题 |
| 电机输出正常,但某一轴姿态突然失控 | 电机/舵面机械问题、控制分配、振动或传感器异常 |
| 转换达到固定翼后立即退回MC | 查看Quadchute原因、空速、角度、掉高和超时条件 |
| 日志在高功率阶段突然结束 | 供电、飞控重启、硬故障或SD卡问题 |
### 14.4 后转换逐项检查
1. 状态是否从 FW 进入 `TRANSITION_TO_MC`
2. 姿态目标是否回到接近竖直悬停方向。
3. 实际俯仰是否平滑跟随。
4. 固定翼推力向多旋翼推力的连接是否连续。
5. 空速下降过程中舵面控制能力是否减弱。
6. 多旋翼电机力矩是否及时恢复。
7. 是否出现掉高、振荡或输出饱和。
8. 是否最终进入 MC 状态。
---
## 15. 电池和供电问题重点看什么
推荐主题:
```text
battery_status
system_power
vehicle_status
actuator_motors
cpuload
```
检查:
- 大油门时电压是否严重下跌。
- 电流是否达到电池、线材或电源模块极限。
- 电压下降是否和姿态失控、重启或日志终止同时发生。
- 剩余电量估计是否突然变化。
- 是否出现电池相关 failsafe。
ULog可能在彻底掉电前来不及记录最后一个瞬间,因此“日志内没有看到电压为0”不能排除供电瞬断。
---
## 16. QGC消息和事件如何分析
ULog会记录 PX4事件、warning 和 error。Flight Review会根据日志中的事件元数据将其翻译成人类可读内容。
分析事件时应记录:
- 事件准确时间。
- 事件严重级别。
- 事件发生前5至10秒的传感器和控制数据。
- 事件之后系统采取了什么动作。
例如 QGC显示“Transition timeout”,真正需要查的是超时前:
- 是否收到转换请求。
- 姿态是否达到要求。
- 空速是否增长。
- 电机是否饱和。
- 是否掉高。
- 空速是否有效。
事件说明 PX4在哪个保护条件上作出了判断,但根因可能更早发生。
---
## 17. 把日志交给我分析时需要提供什么
可以直接提供原始 `.ulg` 文件。不要先只转成截图或只给 CSV,因为原始文件包含更完整的主题、参数、事件和时间关系。
同时建议提供以下信息:
```text
1. 问题发生在哪一次飞行。
2. 大约发生在起飞后多少秒。
3. 当时飞行模式,以及是否正在前/后转换。
4. 遥控器或QGC当时发出了什么命令。
5. 肉眼看到的飞机动作。
6. QGC显示的原始报错文字或截图。
7. 是否有同步视频。
8. 是否改过参数、固件或执行器分配。
9. 电机、舵面、GPS、空速计和电池配置。
10. 是否发生碰撞、断桨、掉电或飞控重启。
```
一个有效的问题描述示例:
```text
文件:2026-08-12-15-30-20.ulg
现象:起飞后约42秒请求前转换,约47秒快速掉高并自动回MC。
操作:遥控器VTOL开关从MC切到FW,没有其他摇杆动作。
QGC消息:Transition timeout,随后提示Quadchute。
机体:双电机双舵面尾座式,空速计已连接CAN并校准。
改动:VT_F_TRANS_DUR从5秒改为4秒,其余转换参数未改。
附件:机载视频和QGC截图。
```
有了这些上下文,可以先定位时间段,再对照状态机、空速、姿态、EKF和执行器输出,分析效率会高很多。
---
## 18. 哪些结论不能仅凭 ULog 得出
ULog非常重要,但不是完整的“黑匣子真相”。以下情况通常需要其他证据:
- 某个螺旋桨是否在空中脱落。
- 某个舵机连杆是否滑脱。
- 实际风速、阵风和外部碰撞。
- 线缆或接插件是否发生微秒级瞬断。
- 相机、图传或独立设备内部故障。
- 飞控断电后未能写入日志的最后瞬间。
合理的结论应区分:
- 日志直接证明的事实。
- 多项数据共同支持的高概率原因。
- 当前证据无法排除的可能性。
---
## 19. 推荐的日常工作流
每次重要试飞建议保留一个独立目录:
```text
flight_2026-08-12_01/
├── flight.ulg
├── params.params
├── qgc_message.png
├── flight_video.mp4
├── airframe_notes.md
└── analysis.md
```
建议分析步骤:
1. 保存原始 `.ulg`,不要修改。
2. 用 `ulog_info` 检查完整性、版本、主题和 dropout。
3. 用 Flight Review 做快速全局检查;敏感日志使用本地工具。
4. 建立异常事件时间线。
5. 用 PlotJuggler同步比较目标、实际、估计和输出。
6. EKF问题运行 PX4自带 EKF脚本。
7. 必要时用 `ulog2csv` 只导出相关主题和时间窗口。
8. 把结论、证据和下一次只改变的一个变量写入 `analysis.md`
9. 下一次试飞后对比两份日志,而不是凭主观感觉判断改善。
---
## 20. 快速命令清单
```sh
# 查看日志主题、时长、固件信息和丢帧
ulog_info flight.ulg
# 查看详细信息
ulog_info -v flight.ulg
# 导出尾座式转换常用主题
mkdir -p csv_out
ulog2csv \
-m vehicle_status,vtol_vehicle_status,vehicle_attitude,vehicle_attitude_setpoint,vehicle_local_position,airspeed_validated,battery_status \
-o csv_out \
flight.ulg
# 只导出日志开始后30至55秒
ulog2csv \
-ts 30 -te 55 \
-m vtol_vehicle_status,vehicle_attitude,vehicle_attitude_setpoint,airspeed_validated \
-o csv_out \
flight.ulg
# PX4 EKF专项分析
cd /home/jiagu/seeker_debug_tool1/simulation_ws/deps/PX4-Autopilot
python3 Tools/ecl_ekf/process_logdata_ekf.py /完整路径/flight.ulg
# 仅生成EKF检查结果,不生成PDF图表
python3 Tools/ecl_ekf/process_logdata_ekf.py /完整路径/flight.ulg --no-plots
```
---
## 21. 最终建议
对于当前尾座式项目,最实用的工具组合是:
1. `ulog_info`:确认日志是否可用和包含什么。
2. Flight Review:快速发现事件、振动、控制跟踪、EKF和执行器异常。
3. PlotJuggler:围绕转换时间点做多主题同步分析。
4. PX4 EKF脚本:对估计器进行专项健康检查。
5. 原始 `.ulg` + 视频 + 现象描述:进行最终根因判断。
不要直接根据一张曲线修改大量参数。先找出最早异常,建立因果关系,每次只验证一个主要假设,并保留修改前后的日志用于对比。

465
docs/project/PX4_rcS启动流程与实机准备.md

@ -0,0 +1,465 @@
# PX4 rcS 启动流程与实机准备
本文结合当前使用的 CUAV 7-Nano、PX4 v1.17.0 和尾座式 VTOL,说明 `rcS` 启动脚本的作用,并区分“飞控硬件已经适配”和“整机已经具备试飞条件”。
## 1. 先明确一个结论
CUAV 7-Nano 的板级设计和 PX4 板级代码已经绑定了飞控自身的基础硬件,包括:
- MCU 引脚和时钟
- SPI、I2C、CAN 和串口总线
- 板载 IMU、磁罗盘和气压计
- GPS、遥测、CAN、USB 等接口
- PWM、DShot 和安全按钮驱动
- 电池电压、电流采样接口
- 蜂鸣器和状态灯
因此,不需要从零编写飞控板卡驱动。但是,这只表示“飞控板能够运行 PX4 并访问这些接口”,不表示任意飞机装上电机、电池和 GPS 后就可以直接飞行。
实机是否具备飞行条件,还取决于:
- 机型是否正确
- 飞控安装方向是否正确
- 电机数量、位置和推力方向是否正确
- 电机编号和旋转方向是否正确
- 舵面类型、方向和行程是否正确
- 控制分配是否与真实机构一致
- 重心和结构强度是否符合设计
- 电源模块、电池和电调参数是否正确
- 传感器、遥控器和空速计是否正确校准
- failsafe 和返航行为是否经过验证
- 多旋翼、固定翼和 VTOL 过渡参数是否适合实际飞机
对于尾座式 VTOL,尤其不能跳过电机、舵面和过渡验证。
## 2. rcS 是什么
主启动脚本位于:
```text
simulation_ws/deps/PX4-Autopilot/ROMFS/px4fmu_common/init.d/rcS
```
`rcS` 是 PX4 在 NuttX 启动后执行的总启动脚本。它本身不执行姿态控制或导航计算,而是按顺序完成系统初始化,并启动各个 PX4 模块。
整体流程:
```text
飞控上电
-> 打印版本与硬件信息
-> 挂载 SD 卡
-> 加载参数
-> 加载板级默认配置
-> 根据 SYS_AUTOSTART 加载机型
-> 启动板载和外部传感器
-> 启动 EKF2
-> 启动遥控、Commander 和执行器输出
-> 启动对应机型的控制器
-> 启动串口、USB、MAVLink 和导航
-> 启动日志和 DroneCAN
-> 通知系统启动完成
```
## 3. 初始化启动变量
脚本首先设置路径和状态变量,例如:
```sh
set R /
set VEHICLE_TYPE none
set STORAGE_AVAILABLE no
set STARTUP_TUNE 1
```
其中:
- `R` 是 ROMFS 根路径
- `VEHICLE_TYPE` 保存最终加载的飞行器类别
- `STORAGE_AVAILABLE` 表示存储设备是否可用
- `STARTUP_TUNE` 决定启动提示音
脚本使用:
```sh
set +e
```
这表示单个命令失败时不会立即终止整个启动流程。因此,某个备用传感器探测失败后,PX4 仍可能继续启动。
## 4. 打印固件和硬件信息
启动时执行:
```sh
ver all
```
它会输出:
- PX4 版本
- Git commit
- 硬件架构
- NuttX 版本
- 编译时间和工具链
当前固件应报告:
```text
PX4 version: v1.17.0
HW arch: CUAV_7_NANO
```
## 5. 挂载和检查 SD 卡
`rcS` 尝试把 SD 卡挂载到:
```text
/fs/microsd
```
SD 卡主要用于:
- ULog 飞行日志
- 参数备份
- HardFault 崩溃日志
- 自定义启动脚本
- 外部 airframe 脚本
如果 SD 卡中存在 `.format` 文件,启动脚本会请求格式化 SD 卡。不要随意创建该文件。
## 6. 加载和恢复参数
脚本选择参数文件并执行:
```sh
param select $PARAM_FILE
param import
```
如果主参数文件损坏,它会尝试从以下文件恢复:
```text
/fs/microsd/parameters_backup.bson
```
这意味着刷写新固件后,旧参数有可能从内部存储或 SD 卡备份中恢复。更换固件版本或机型时,应检查参数是否仍然适用。
## 7. 加载 CUAV 7-Nano 板级默认值
`rcS` 会执行:
```text
boards/cuav/7-nano/init/rc.board_defaults
```
当前板级默认配置主要完成:
- 设置以太网 MAVLink 默认参数
- 设置电池电压和电流换算默认值
- 设置 USB MAVLink 模式
- 启动安全按钮
板级脚本多数使用:
```sh
param set-default
```
它只设置参数默认值,不会覆盖已经保存的用户值。`param set` 才会直接修改当前参数。
## 8. 根据 SYS_AUTOSTART 加载机型
`rcS` 调用自动生成的:
```text
/etc/init.d/rc.autostart
```
该脚本根据 `SYS_AUTOSTART` 查找机型文件。
当前通用尾座式 VTOL 应使用:
```text
SYS_AUTOSTART=13200
```
对应文件:
```text
ROMFS/px4fmu_common/init.d/airframes/13200_generic_vtol_tailsitter
```
它先调用 `rc.vtol_defaults`,将:
```sh
VEHICLE_TYPE=vtol
```
然后设置通用尾座式默认参数,例如:
```text
CA_AIRFRAME=4
CA_ROTOR_COUNT=2
CA_SV_CS_COUNT=2
VT_TYPE=0
VT_B_TRANS_DUR=5
```
这套通用机型默认是两电机、两舵面。如果真实飞机不是这种结构,必须重新配置控制分配。
`SYS_AUTOSTART=1002` 是 HIL Standard VTOL QuadPlane,只用于硬件在环仿真,不适用于实机。
如果找不到机型,`rcS` 会把 `SYS_AUTOSTART` 重置为 `0`,并报告:
```text
No airframe file found
No autostart ID found
```
## 9. 启动 7-Nano 板载传感器
`rcS` 执行:
```text
boards/cuav/7-nano/init/rc.board_sensors
```
该脚本尝试启动:
- IIM42652 IMU
- BMI088 IMU
- IIM42653 备用 IMU
- IST8310 或 IIS2MDC 磁罗盘
- BMP581 气压计
- ICP201xx 气压计
- GPS1/I2C1 接口上的外部磁罗盘
- 板载 ADC 或 ADS1115
部分设备采用“先尝试型号 A,失败后尝试型号 B”的兼容逻辑。因此,启动日志中单个 `no device on bus` 不一定意味着飞控损坏,需要结合后续是否成功启动备用设备判断。
随后通用传感器脚本还会启动:
```text
battery_status
sensors
```
## 10. 启动状态估计器
默认使用:
```sh
ekf2 start
```
EKF2 融合:
- 加速度计和陀螺仪
- GPS/GNSS
- 磁罗盘
- 气压计
- 空速计
- 可选的测距、光流和外部视觉数据
并输出姿态、位置和速度估计,供控制器使用。
## 11. 启动遥控、Commander 和输出驱动
遥控相关模块:
```sh
rc_update start
manual_control start
rc_input start
```
随后启动:
```sh
commander start
dshot start
pwm_out start
```
作用分别是:
- `commander`:解锁、飞行状态、健康检查、模式切换和 failsafe
- `dshot`:DShot 电调输出
- `pwm_out`:PWM 电机和舵机输出
驱动存在只代表飞控能够输出信号,不代表输出通道和真实执行器已经正确对应。
## 12. 启动 VTOL 控制链
机型脚本将 `VEHICLE_TYPE` 设为 `vtol` 后,`rc.vehicle_setup` 会执行:
```text
rc.vtol_apps
```
它同时启动多旋翼、固定翼和 VTOL 模块:
```text
control_allocator
airspeed_selector
vtol_att_control
mc_rate_control
mc_att_control
mc_pos_control
flight_mode_manager
mc_hover_thrust_estimator
fw_rate_control
fw_att_control
fw_mode_manager
fw_lat_lon_control
land_detector
```
其中:
- `mc_*` 负责垂直起降和悬停
- `fw_*` 负责固定翼前飞
- `vtol_att_control` 管理飞行形态和过渡
- `control_allocator` 将期望力和力矩分配给电机与舵面
- `airspeed_selector` 管理空速来源和有效性
## 13. 启动通信、导航、日志和 CAN
后续启动内容包括:
- 串口设备和 GPS
- USB CDC/ACM
- MAVLink
- `navigator` 航点、任务和返航导航
- `logger` ULog 日志记录
- `uavcan` DroneCAN 设备
最后执行:
```sh
mavlink boot_complete
```
通知 QGroundControl 系统已完成启动。
## 14. 当前尾座式 VTOL 的完整启动链
```text
rcS
-> rc.filepaths
-> 参数导入和备份恢复
-> rc.board_arch_defaults
-> rc.board_defaults
-> rc.autostart
-> 13200_generic_vtol_tailsitter
-> rc.vtol_defaults
-> rc.board_sensors
-> rc.sensors
-> EKF2
-> rc_update / manual_control
-> Commander
-> DShot / PWM
-> rc.vehicle_setup
-> rc.vtol_apps
-> rc.serial / MAVLink
-> Navigator
-> Logger
-> DroneCAN
-> mavlink boot_complete
```
## 15. 从组装到首飞的正确流程
即使使用成熟飞控和现成整机设计,也建议按以下阶段验证。
### 阶段一:资料确认
- 确认飞控、载板和飞机结构的准确型号及版本
- 获取厂家接线图、参数文件和固件要求
- 确认机型 ID 和控制分配配置
- 确认电机、舵机、GPS、空速计和电源模块型号
### 阶段二:无桨上电
- 拆下所有螺旋桨
- 检查电源电压、电流量程和供电能力
- 确认 QGC 正确识别 PX4 v1.17.0 和 CUAV 7-Nano
- 确认 `SYS_AUTOSTART=13200` 或厂家指定机型
- 检查启动日志是否存在关键错误
### 阶段三:校准
- 加速度计校准
- 陀螺仪检查
- 磁罗盘校准
- 水平校准
- 遥控器校准
- 电源模块校准
- 空速计校准
### 阶段四:传感器方向检查
- 手动滚转飞机,确认 QGC 姿态同向变化
- 手动俯仰飞机,确认 QGC 姿态同向变化
- 转动机头,确认航向变化正确
- 检查 GPS 定位、卫星数和高度
- 检查静止时空速接近零
### 阶段五:无桨执行器检查
- 确认每个输出通道连接正确
- 确认每个电机编号正确
- 确认电机旋转方向正确
- 确认每个舵面方向正确
- 确认舵面中立位和最大行程合理
- 确认多旋翼和固定翼模式下的执行器行为
- 确认安全按钮、急停和失控保护
### 阶段六:动力与结构检查
- 检查螺旋桨型号和安装方向
- 检查电机、电调和电池电流余量
- 检查机架紧固、结构强度和振动
- 检查重心位置
- 检查尾座式起降支撑和地面稳定性
### 阶段七:分阶段飞行验证
```text
低功率动力测试
-> 受控短时悬停
-> 多旋翼模式稳定性验证
-> 高度和位置模式验证
-> 固定翼参数地面复核
-> 足够高度下的前向过渡
-> 固定翼飞行验证
-> 反向过渡和垂直降落验证
```
第一次悬停成功不代表可以立即测试 VTOL 过渡。过渡涉及两套控制器、空速、舵面和姿态状态机,风险明显更高。
## 16. 首飞前最低检查清单
- [ ] 固件目标与 CUAV 7-Nano 匹配
- [ ] PX4 版本和 Git hash 正确
- [ ] 实机 airframe 正确,未选择 HIL 机型
- [ ] 飞控安装方向正确
- [ ] 所有必要传感器已校准
- [ ] GPS 和磁罗盘方向正确
- [ ] 空速计数据正常且管路未接反
- [ ] 电池电压和电流读数合理
- [ ] 遥控器通道和模式开关正确
- [ ] RC 丢失和数传丢失 failsafe 已验证
- [ ] 电机编号、旋向和推力方向正确
- [ ] 舵面通道、方向、中立位和行程正确
- [ ] 控制分配与真实机构一致
- [ ] 急停、上锁和安全按钮有效
- [ ] ULog 能正常写入 SD 卡
- [ ] 无桨执行器测试全部通过
- [ ] 首飞场地、隔离距离和接管方案已确定
只有这些项目通过后,才能进入低风险的首次悬停测试。

405
docs/project/PX4四电机编号与当前尾座式配置.md

@ -0,0 +1,405 @@
# PX4 四电机编号与当前尾座式配置
## 1. 电机编号不是简单的接口编号
PX4中的 `Motor 1`、`Motor 2` 等是控制分配器使用的逻辑电机编号,不天然等于飞控外壳上的 `MAIN OUT 1`、`MAIN OUT 2`。
完整关系是:
```text
机体几何参数
逻辑电机 Motor 1、Motor 2……
输出功能参数映射
飞控物理 PWM/DShot 输出口
电调和实际电机
```
因此需要分别确认:
1. 逻辑电机在机体上的位置和旋向是否正确。
2. 每个逻辑电机映射到了哪个物理输出口。
3. 对应输出口实际连接的是哪一个电调和电机。
---
## 2. PX4机体坐标系
PX4使用机体坐标系描述电机位置:
```text
X轴:机头前方为正
Y轴:机体右方为正
Z轴:机体下方为正
```
从飞机上方看:
```text
+X 机头方向
机体左侧 │ 机体右侧
-Y │ +Y
```
参数含义:
| 参数 | 含义 |
|---|---|
| `CA_ROTORn_PX` | 第n个旋翼相对重心在X轴的位置 |
| `CA_ROTORn_PY` | 第n个旋翼相对重心在Y轴的位置 |
| `CA_ROTORn_PZ` | 第n个旋翼相对重心在Z轴的位置 |
| `CA_ROTORn_AX` | 推力轴在X轴的方向分量 |
| `CA_ROTORn_AY` | 推力轴在Y轴的方向分量 |
| `CA_ROTORn_AZ` | 推力轴在Z轴的方向分量 |
| `CA_ROTORn_KM` | 旋翼反扭矩系数和旋向 |
对于尾座式飞机,这些位置仍然按照正常固定翼前飞时的机体坐标定义:
- 机头方向始终是 `+X`
- 右机翼方向始终是 `+Y`
- 不能按照飞机竖直停放时看到的“上、下、左、右”直接填写电机坐标。
---
## 3. 常见四旋翼X架构的电机编号
对于常见四旋翼 X 架构,从飞机上方观察,机头朝前:
```text
机头 +X
Motor 3 Motor 1
前左 CW 前右 CCW
\ /
\ /
\ /
机体
/ \
/ \
/ \
Motor 2 Motor 4
后左 CCW 后右 CW
```
对应关系:
| PX4逻辑电机 | 位置 | 从上方观察的旋向 |
|---|---|---|
| Motor 1 | 前右 | CCW,逆时针 |
| Motor 2 | 后左 | CCW,逆时针 |
| Motor 3 | 前左 | CW,顺时针 |
| Motor 4 | 后右 | CW,顺时针 |
这是PX4常见四旋翼X几何的逻辑定义。实际机体仍应以当前控制分配参数和QGroundControl的执行器页面为准。
---
## 4. QGC编号与内部参数编号
QGroundControl和用户界面从 `Motor 1` 开始编号;PX4内部旋翼几何参数从 `ROTOR0` 开始编号:
| QGC/用户看到的编号 | PX4内部参数前缀 |
|---|---|
| Motor 1 | `CA_ROTOR0_*` |
| Motor 2 | `CA_ROTOR1_*` |
| Motor 3 | `CA_ROTOR2_*` |
| Motor 4 | `CA_ROTOR3_*` |
这是一个容易混淆的地方。例如 `CA_ROTOR0_PX` 描述的是 Motor 1,而不是“Motor 0”。
---
## 5. 四旋翼X架构的位置参数示例
标准化位置可以写成:
```text
CA_ROTOR0_PX = 1 Motor 1:前
CA_ROTOR0_PY = 1 右
CA_ROTOR1_PX = -1 Motor 2:后
CA_ROTOR1_PY = -1 左
CA_ROTOR2_PX = 1 Motor 3:前
CA_ROTOR2_PY = -1 左
CA_ROTOR3_PX = -1 Motor 4:后
CA_ROTOR3_PY = 1 右
```
也可以填写实际距离,例如电机相对重心的位置是 `0.2 m`
```text
Motor 1:PX= 0.2,PY= 0.2
Motor 2:PX=-0.2,PY=-0.2
Motor 3:PX= 0.2,PY=-0.2
Motor 4:PX=-0.2,PY= 0.2
```
填写实际尺寸有助于准确描述非对称机体。无论使用归一化位置还是实际尺寸,都必须保持各电机之间正确的位置比例和符号。
---
## 6. 电机旋向参数
旋翼旋向由 `CA_ROTORn_KM` 表示:
```text
KM > 0:CCW,逆时针
KM < 0CW顺时针
```
PX4当前参数说明明确规定:
- 正值用于 CCW 旋翼。
- 负值用于 CW 旋翼。
常见四旋翼X示例:
```text
CA_ROTOR0_KM = 0.05 Motor 1:CCW
CA_ROTOR1_KM = 0.05 Motor 2:CCW
CA_ROTOR2_KM = -0.05 Motor 3:CW
CA_ROTOR3_KM = -0.05 Motor 4:CW
```
旋向的观察方向必须统一。本文四旋翼示意图中的 CW/CCW 按从飞机上方观察螺旋桨定义。
配置中的旋向必须和实际电机旋转方向一致,否则控制分配器对偏航反扭矩的计算会出错。
---
## 7. 逻辑电机如何映射到物理输出口
逻辑 Motor 1 不一定连接 `MAIN OUT 1`。物理输出功能由对应输出参数决定。
例如一种直接映射是:
```text
PWM_MAIN_FUNC1 = Motor 1
PWM_MAIN_FUNC2 = Motor 2
PWM_MAIN_FUNC3 = Motor 3
PWM_MAIN_FUNC4 = Motor 4
```
但也可以配置成:
```text
MAIN OUT 1 → Motor 3
MAIN OUT 2 → Servo 1
MAIN OUT 3 → Motor 1
```
只要输出功能和实际接线一致,逻辑电机不要求必须按物理口顺序排列。
应在QGroundControl中检查:
```text
Actuators → Actuator Outputs
```
确认每个输出通道的 Function/功能是:
- Motor 1
- Motor 2
- Motor 3
- Motor 4
- 或相应舵机功能
如果使用其他输出驱动,参数名可能不是 `PWM_MAIN_FUNCn`,但原则相同:物理通道必须分配到正确的逻辑执行器功能。
---
## 8. 安全验证电机编号
测试前必须:
1. 拆下所有螺旋桨。
2. 固定机体。
3. 确认电池和电调连接安全。
4. 确保周围无人接触电机。
然后在QGroundControl执行器测试中逐个测试:
```text
测试 Motor 1 → 只有实际前右电机转动
测试 Motor 2 → 只有实际后左电机转动
测试 Motor 3 → 只有实际前左电机转动
测试 Motor 4 → 只有实际后右电机转动
```
接着分别确认旋向:
```text
Motor 1 → CCW
Motor 2 → CCW
Motor 3 → CW
Motor 4 → CW
```
如果编号错误,优先修改输出功能映射或实际接线,使逻辑电机与几何定义一致。
如果编号正确但旋向错误,通常可以:
- 通过支持的电调配置工具改变电机方向。
- 对普通无刷电机交换任意两根相线。
不能只在软件中把 `KM` 正负号改成实际旋向,却不检查螺旋桨类型和整机期望旋向。几何、实际旋向以及安装的 CW/CCW 螺旋桨必须三者一致。
---
## 9. 当前13200尾座式配置的重要限制
当前使用的机型是:
```text
13200_generic_vtol_tailsitter
```
它的默认控制分配配置为:
```sh
param set-default CA_AIRFRAME 4
param set-default CA_ROTOR_COUNT 2
param set-default CA_ROTOR0_KM -0.05
param set-default CA_ROTOR0_PY -0.2
param set-default CA_ROTOR1_KM 0.05
param set-default CA_ROTOR1_PY 0.2
param set-default CA_SV_CS_COUNT 2
```
这表示当前模板预期:
- 两个电机。
- 两个舵面。
- 电机分别位于机体左右两侧。
具体关系:
| 逻辑执行器 | 位置/配置 |
|---|---|
| Motor 1 / Rotor 0 | `PY=-0.2`,机体左侧,`KM=-0.05`,CW |
| Motor 2 / Rotor 1 | `PY=+0.2`,机体右侧,`KM=+0.05`,CCW |
| Servo 1 | 一个尾座式控制面 |
| Servo 2 | 另一个尾座式控制面 |
相关源码:
```text
ROMFS/px4fmu_common/init.d/airframes/13200_generic_vtol_tailsitter
```
因此当前 `13200` 并不是四电机尾座式模板。
---
## 10. 如果实机是四电机尾座式
如果实际飞机有四个电机,只把四个电调插到四个输出口是不够的。当前控制分配器仍然只知道两个旋翼,因此必须建立与真实机体一致的四电机几何。
至少需要检查和修改:
```text
CA_ROTOR_COUNT = 4
CA_ROTOR0_PX/PY/PZ
CA_ROTOR1_PX/PY/PZ
CA_ROTOR2_PX/PY/PZ
CA_ROTOR3_PX/PY/PZ
CA_ROTOR0_AX/AY/AZ
CA_ROTOR1_AX/AY/AZ
CA_ROTOR2_AX/AY/AZ
CA_ROTOR3_AX/AY/AZ
CA_ROTOR0_KM
CA_ROTOR1_KM
CA_ROTOR2_KM
CA_ROTOR3_KM
```
还需要确认:
- 四个电机是否全部用于悬停和固定翼推进。
- 电机在固定翼姿态下相对重心的位置。
- 每个电机推力轴方向。
- 四个电机的实际旋向。
- 固定翼状态是否使用差动推力。
- 舵面数量和舵面力矩方向。
- PWM或DShot输出功能映射。
- 尾座式前后转换过程中的执行器使用方式。
不能直接照搬普通四旋翼X编号图,除非四电机尾座式的真实几何确实与该图相同。尾座式可能采用左右翼上下排列、非对称位置或不同推力轴,需要按真实结构建模。
---
## 11. 在控制台查看当前参数
查看当前旋翼数量:
```sh
param show CA_ROTOR_COUNT
```
查看前四个旋翼位置和旋向:
```sh
param show CA_ROTOR0_PX
param show CA_ROTOR0_PY
param show CA_ROTOR0_PZ
param show CA_ROTOR0_KM
param show CA_ROTOR1_PX
param show CA_ROTOR1_PY
param show CA_ROTOR1_PZ
param show CA_ROTOR1_KM
param show CA_ROTOR2_PX
param show CA_ROTOR2_PY
param show CA_ROTOR2_PZ
param show CA_ROTOR2_KM
param show CA_ROTOR3_PX
param show CA_ROTOR3_PY
param show CA_ROTOR3_PZ
param show CA_ROTOR3_KM
```
查看全部旋翼参数:
```sh
param show CA_ROTOR*
```
查看输出功能时,可以在QGroundControl执行器页面检查,也可根据实际输出驱动查询对应的 `FUNC` 参数。
---
## 12. 当前结论
对于普通四旋翼X,PX4常见逻辑编号是:
```text
Motor 1:前右,CCW
Motor 2:后左,CCW
Motor 3:前左,CW
Motor 4:后右,CW
```
但是当前项目的关键事实是:
```text
当前机型:13200 Generic VTOL Tailsitter
当前旋翼数量:CA_ROTOR_COUNT=2
当前模板:双电机、双舵面尾座式
```
如果实际飞机是四电机尾座式,在上桨、解锁或飞行前,必须根据真实电机位置、推力轴和旋向完成四电机控制分配,并通过拆桨执行器测试逐一验证逻辑编号和物理输出。

402
docs/project/PX4源码学习路线.md

@ -0,0 +1,402 @@
# PX4 源码学习路线
本文面向第一次接触飞控和 PX4 的开发者,结合当前项目使用的 CUAV 7-Nano、PX4 v1.17.0 和尾座式 VTOL,给出一条从基本概念到源码调试的学习路线。
当前 PX4 源码目录:
```text
/home/jiagu/seeker_debug_tool1/simulation_ws/deps/PX4-Autopilot
```
## 1. 学习原则
PX4 包含硬件驱动、状态估计、飞行模式、控制器、通信和安全机制。第一次学习时,不建议直接从 EKF2、寄存器驱动或控制算法细节开始。
建议先沿着下面这条主线建立整体认识:
```text
传感器
-> 状态估计
-> 飞行模式与设定值
-> 姿态/位置控制器
-> 控制分配
-> 电机和舵机
```
阅读代码时始终回答三个问题:
1. 这个模块订阅了哪些 uORB 消息?
2. 它根据什么状态或参数进行计算?
3. 它发布了哪些消息,交给哪个下游模块?
实机学习和测试时必须拆下螺旋桨。
## 2. 先掌握 QGroundControl 和飞控基本概念
在深入源码前,先通过 QGroundControl 熟悉:
- 机型和 `SYS_AUTOSTART`
- 参数保存、恢复和重启生效
- 传感器及遥控器校准
- 解锁前检查
- 手动、定高、定点和任务模式
- 多旋翼、固定翼及 VTOL 状态
- failsafe(失效保护)
- 执行器、电机和舵机功能映射
- MAVLink 与地面站通信
当前尾座式 VTOL 的通用实机机型 ID 是:
```text
SYS_AUTOSTART=13200
```
不要选择 `1002`。它是 HIL Standard VTOL QuadPlane,只用于硬件在环仿真。
## 3. 阅读 PX4 启动流程
首先阅读主启动脚本:
```text
ROMFS/px4fmu_common/init.d/rcS
```
重点了解下面的启动顺序:
```text
加载参数
-> 读取 SYS_AUTOSTART
-> 加载机型脚本
-> 启动板载传感器
-> 启动状态估计器
-> 启动控制器
-> 启动 MAVLink 和日志
```
当前尾座式 VTOL 的机型脚本:
```text
ROMFS/px4fmu_common/init.d/airframes/13200_generic_vtol_tailsitter
```
阅读时重点关注:
- `CA_AIRFRAME`:控制分配机型类型
- `CA_ROTOR_COUNT`:电机数量
- `CA_SV_CS_COUNT`:舵面数量
- `MAV_TYPE`:MAVLink 飞行器类型
- `VT_TYPE`:VTOL 类型
- `VT_B_TRANS_DUR`:回到多旋翼模式的过渡时间
通用 `13200` 默认是两电机、两舵面配置。如果实际飞机是四电机、三舵机或四舵面,需要按真实结构重新配置控制分配,不能直接照搬默认值。
## 4. 理解 uORB 消息总线
uORB 是 PX4 内部模块间的消息总线。模块通常通过发布和订阅消息交换数据,而不是直接互相调用。
典型数据流:
```text
传感器驱动
-> sensor_* 消息
-> EKF2
-> vehicle_attitude / vehicle_local_position
-> 飞行模式和控制器
-> vehicle_torque_setpoint / vehicle_thrust_setpoint
-> control_allocator
-> actuator_motors / actuator_servos
```
消息定义目录:
```text
msg/
```
建议优先了解这些消息:
```text
sensor_combined
vehicle_attitude
vehicle_local_position
vehicle_global_position
vehicle_status
vehicle_control_mode
vehicle_attitude_setpoint
vehicle_rates_setpoint
vehicle_torque_setpoint
vehicle_thrust_setpoint
actuator_motors
actuator_servos
```
可以在 PX4 Shell 中观察消息:
```sh
listener vehicle_attitude
listener vehicle_status
listener actuator_motors
uorb top
```
## 5. 学习 Commander 和飞行模式
### 5.1 Commander
目录:
```text
src/modules/commander
```
Commander 主要负责:
- 解锁和上锁
- 飞行器状态管理
- 健康与解锁前检查
- 飞行模式切换
- failsafe 决策
- 电池、遥控和导航状态处理
遇到“无法解锁”“模式切换失败”或“进入 failsafe”时,优先沿 Commander 和健康检查代码排查。
### 5.2 Flight Mode Manager
目录:
```text
src/modules/flight_mode_manager
```
它根据当前飞行模式生成位置、速度或轨迹设定值。建议先区分:
- 飞行模式负责决定“飞机应该去哪里、以什么状态运动”
- 姿态和位置控制器负责决定“怎样产生对应的力和力矩”
## 6. 沿多旋翼控制链阅读
多旋翼控制链:
```text
mc_pos_control
-> mc_att_control
-> mc_rate_control
-> control_allocator
```
对应目录:
```text
src/modules/mc_pos_control
src/modules/mc_att_control
src/modules/mc_rate_control
src/modules/control_allocator
```
各模块作用:
- `mc_pos_control`:位置和速度控制,输出姿态与推力设定值
- `mc_att_control`:姿态控制,输出角速度设定值
- `mc_rate_control`:角速度控制,输出机体力矩和推力
- `control_allocator`:将期望力和力矩分配给各电机与舵面
尾座式 VTOL 在起飞、悬停和垂直降落阶段主要使用这条控制链。
## 7. 沿固定翼控制链阅读
对应目录:
```text
src/modules/fw_mode_manager
src/modules/fw_lateral_longitudinal_control
src/modules/fw_att_control
src/modules/fw_rate_control
```
各模块主要作用:
- `fw_mode_manager`:固定翼飞行模式与设定值管理
- `fw_lateral_longitudinal_control`:横向和纵向制导/控制
- `fw_att_control`:固定翼姿态控制
- `fw_rate_control`:固定翼角速度控制
尾座式 VTOL 完成前向过渡后,主要使用固定翼控制链。
## 8. 重点学习 VTOL 状态与过渡
目录:
```text
src/modules/vtol_att_control
```
对尾座式飞机,这是最需要重点阅读的模块。建议关注:
- 当前处于多旋翼、前向过渡、固定翼还是反向过渡状态
- 多旋翼和固定翼控制输出如何混合
- 过渡完成条件
- 过渡超时和失败处理
- 空速是否参与过渡判断
- `VT_*` 参数如何影响状态机
先理解状态机,再调整过渡参数。不要在不清楚状态转换条件时直接修改控制输出。
## 9. 学习控制分配与执行器
目录:
```text
src/modules/control_allocator
```
控制器输出的是期望力和力矩,控制分配器将其转换成具体电机和舵机命令。
需要结合实际飞机确认:
- 电机数量和物理位置
- 每个电机的推力方向
- 电机旋转方向和反扭矩符号
- 舵面类型、方向和力矩作用
- 输出通道对应关系
- 多旋翼和固定翼模式下哪些执行器参与控制
控制分配错误可能导致飞机一解锁就翻转。执行器检查必须无桨进行。
## 10. 最后学习 EKF2
目录:
```text
src/modules/ekf2
```
EKF2 融合以下数据并估计姿态、位置、速度和传感器偏差:
- IMU(加速度计和陀螺仪)
- GPS/GNSS
- 磁罗盘
- 气压计
- 空速计
- 光流或视觉里程计(如果使用)
- 测距传感器(如果使用)
初学阶段先理解 EKF2 的输入、输出和健康状态,不需要立刻深入协方差矩阵及融合数学。
可先观察:
```sh
listener estimator_status
listener estimator_status_flags
listener vehicle_attitude
listener vehicle_local_position
```
## 11. 学习 CUAV 7-Nano 板级代码
板级目录:
```text
boards/cuav/7-nano
```
主要内容包括:
- `default.px4board`:默认启用的驱动和模块
- `minimal_vtol.px4board`:当前项目的精简 VTOL 配置
- `init/rc.board_sensors`:板载传感器启动
- `src/board_config.h`:GPIO、总线和板级定义
- `src/spi.cpp`:SPI 设备和片选配置
- `src/i2c.cpp`:I2C 总线配置
- `src/can.c`:CAN 板级初始化
- `nuttx-config`:NuttX 系统配置
建议在理解上层数据流之后再深入板级驱动,否则容易陷入引脚、总线和寄存器细节。
## 12. MAVLink、DroneCAN 和 ROS 2 的区别
### MAVLink
主要用于 PX4 与 QGroundControl、数传和伴随计算机通信。当前实机需要保留 MAVLink。
### DroneCAN/UAVCAN
用于连接 CAN GPS、CAN 空速计、CAN 电调等设备。当前固件保留了 DroneCAN 支持。
### Micro XRCE-DDS
用于 PX4 与 ROS 2 交换 uORB/`px4_msgs` 数据。如果实机不使用 ROS 2,可以在精简固件中关闭。
## 13. 推荐的第一个源码练习
第一个练习建议新增一个只读模块:
```text
订阅 vehicle_attitude
-> 每隔一段时间输出滚转、俯仰和偏航
-> 不发布控制指令
```
这个练习可以学习:
- PX4 模块基本结构
- CMake/Kconfig 配置
- 编译和刷写
- uORB 订阅
- PX4 Shell 命令
- 日志和调试
它不会直接改变控制器或执行器输出,风险明显低于一开始修改姿态控制、VTOL 状态机或 EKF2。
## 14. 推荐学习阶段
### 第一阶段:会使用和观察
- 完成机型选择和传感器校准
- 会使用 `param show`、`listener`、`uorb top`、`top` 和 `ver all`
- 能看懂启动日志中的模块启动顺序
- 理解 QGC、MAVLink 和 uORB 的职责
### 第二阶段:看懂控制数据流
- 跟踪姿态、位置和执行器消息
- 理解多旋翼、固定翼和 VTOL 控制链
- 理解控制分配参数与实际执行器的关系
- 能从日志判断当前 VTOL 状态
### 第三阶段:进行低风险修改
- 新增只读模块
- 新增参数
- 增加日志和状态检查
- 在 SITL 中验证修改
### 第四阶段:修改飞行行为
- 调整控制器或过渡逻辑
- 修改控制分配
- 增加新的传感器或通信接口
- 完成 SITL、台架和实机分阶段验证
## 15. 安全边界
以下修改不适合作为第一次练习:
- 删除解锁前检查或 failsafe
- 绕过传感器校准
- 直接修改 EKF2 融合逻辑
- 未验证就修改电机混控和旋向
- 在有桨状态进行执行器测试
- 将 SITL 参数整套导入实机
- 未完成悬停验证就尝试 VTOL 过渡
推荐验证顺序:
```text
SITL
-> 无桨上电检查
-> 无桨执行器测试
-> 固定台架测试
-> 低风险悬停
-> 固定翼与过渡测试
```

21
docs/project/README.md

@ -0,0 +1,21 @@
# 项目文档
本目录是当前飞控项目自己的说明,基于 CUAV 7-Nano、PX4 v1.17.0 和尾座式 VTOL。
`docs/en`、`docs/zh` 仍是官方手册,不要和这里的文件混用。
## 先看这个
- [环境搭建流程](环境搭建流程.md):新同事从零拉代码、装工具链、编译烧录、日常提交。
## 机型和飞控
- [PX4 源码学习路线](PX4源码学习路线.md)
- [PX4 rcS 启动流程与实机准备](PX4_rcS启动流程与实机准备.md)
- [CUAV 7-Nano GPS2 配置与检查](CUAV_7-Nano_GPS2配置与检查.md)
- [PX4 四电机编号与当前尾座式配置](PX4四电机编号与当前尾座式配置.md)
## 系统与估计
- [PX4 NuttX 操作系统架构与运行机制](PX4_NuttX操作系统架构与运行机制.md)
- [PX4 EKF2 数据融合与尾座式 VTOL 切换逻辑](PX4_EKF2数据融合与尾座式VTOL切换逻辑.md)
- [PX4 ULog 日志分析实用指南](PX4_ULog日志分析实用指南.md)

216
docs/project/环境搭建流程.md

@ -0,0 +1,216 @@
# 环境搭建流程
本文说明如何从公司 GitLab 拉起当前飞控固件仓库,并达到可以一起改代码、编译、烧录的状态。
当前仓库是 **PX4 v1.17.0 的日常开发快照**,不是官方完整历史。目标飞控是 **CUAV 7-Nano**,默认固件目标是 `cuav_7-nano_minimal_vtol`。该目标已关闭以太网和飞控上的 ROS 2 / DDS。USB 和 TELEM 数传不受影响。
官方英文/中文手册仍在 `docs/en`、`docs/zh`。项目自己的说明在 `docs/project`
## 1. 机器要求
| 项 | 要求 |
|---|---|
| 系统 | Ubuntu 22.04 或 24.04,x86_64 |
| 磁盘 | 建议预留 20 GB 以上 |
| 权限 | 能 `sudo` 装软件包 |
| 网络 | 能访问 `gitlab.jiagutech.com`(SSH 端口 **22722**) |
不要对 GitLab 走代理。公司 GitLab 在国内,走代理会连错或超时。
## 2. 配置 SSH
本机生成密钥(已有 `~/.ssh/id_ed25519` 可跳过):
```sh
ssh-keygen -t ed25519 -C "你的名字"
cat ~/.ssh/id_ed25519.pub
```
把公钥加到 Gitea:**Settings → SSH / GPG Keys**。
写入 `~/.ssh/config`
```text
Host gitlab.jiagutech.com
HostName gitlab.jiagutech.com
User git
Port 22722
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
```
```sh
chmod 600 ~/.ssh/config
```
测试:
```sh
ssh -T git@gitlab.jiagutech.com
```
成功时会看到类似:
```text
Hi there, <用户名>! You've successfully authenticated ... but Gitea does not provide shell access.
```
`does not provide shell access` 是正常的,表示密钥已经认到。
## 3. 克隆仓库
```sh
mkdir -p ~/work
cd ~/work
git clone -b 7-nano-minimal-vtol \
ssh://git@gitlab.jiagutech.com:22722/caixiang/PX4-Autopilot.git
cd PX4-Autopilot
git log --oneline -5
```
当前日常分支是 `7-nano-minimal-vtol`。NuttX、MAVLink 等源码已经打进这个仓库,**不需要**再执行 `git submodule update`
不要用 `http://` 地址做第一次完整推送。HTTP 会被 Nginx 的上传大小限制拦住(413)。日常拉代码、推小改动用 SSH。
## 4. 安装编译工具链
在仓库根目录执行官方脚本,装 NuttX / ARM 交叉编译器:
```sh
cd ~/work/PX4-Autopilot
bash Tools/setup/ubuntu.sh --no-sim-tools
```
`--no-sim-tools` 表示不装 Gazebo 等仿真依赖。如果也要在本机跑 SITL,去掉这个参数。
装完重新打开终端,或:
```sh
source ~/.profile
arm-none-eabi-gcc --version
```
应能看到 `arm-none-eabi-gcc`
## 5. 编译和烧录
USB 连接 CUAV 7-Nano 后:
```sh
cd ~/work/PX4-Autopilot
make cuav_7-nano_minimal_vtol
make cuav_7-nano_minimal_vtol upload
```
固件产物:
```text
build/cuav_7-nano_minimal_vtol/cuav_7-nano_minimal_vtol.px4
```
也可以在 QGroundControl 里选这个 `.px4` 文件刷写。
编译成功后用 QGC 连上飞控,**Analyze → MAVLink Console** 检查:
```sh
ver all
free
```
硬件架构应是 `CUAV_7_NANO`
不要编 `cuav_7-nano_default`,除非你明确需要以太网和飞控 ROS 2。日常统一用 `minimal_vtol`
## 6. 本仓库相对官方的差异
| 项 | 本仓库 |
|---|---|
| 基础版本 | PX4 v1.17.0 |
| 日常分支 | `7-nano-minimal-vtol` |
| 以太网 / NuttX 网络栈 | 关闭 |
| 飞控 `UXRCE_DDS_CLIENT` | 关闭 |
| `netman` | 未编入 |
| 空速计 | I2C MS4525DO,需设 `SENS_EN_MS4525DO=1` |
| 历史 | 只有日常快照和之后的提交,没有官方全部 Git 历史 |
板级改动主要在:
```text
boards/cuav/7-nano/minimal_vtol.px4board
boards/cuav/7-nano/nuttx-config/minimal_vtol/defconfig
boards/cuav/7-nano/init/rc.board_defaults
boards/cuav/7-nano/init/rc.board_sensors
```
## 7. 日常开发约定
```sh
git switch 7-nano-minimal-vtol
git pull --ff-only
# 改代码、编译确认
make cuav_7-nano_minimal_vtol
git add <具体文件>
git status
git commit -m "简要说明改了什么"
git push
```
约定:
1. 不要把 `build/`、工具链压缩包、`.vscode/` 提交上去。
2. 不要把官方 `docs/en`、`docs/zh` 的大范围格式化混进项目文档提交。
3. 提交说明写清机型或模块,例如 `7-nano: enable MS4525 airspeed`
4. 需要官方某次提交做对照时,到 [PX4 官方仓库](https://github.com/PX4/PX4-Autopilot) 查看 `v1.17.0`,不要在本仓库里重拉全部历史。
## 8. 实机常用检查
空速计(I2C,地址 `0x28`,总线 1):
```sh
i2cdetect -b 1
param show SENS_EN_MS4525DO
ms4525do status
listener differential_pressure
```
若驱动未启动:
```sh
param set SENS_EN_MS4525DO 1
param set SYS_HAS_NUM_ASPD 1
param set ASPD_PRIMARY 1
param set UAVCAN_ENABLE 0
param save
reboot
```
GPS 插在物理 GPS2 时,见 [CUAV 7-Nano GPS2 配置与检查](CUAV_7-Nano_GPS2配置与检查.md)。
## 9. 常见问题
**SSH 超时或一直无响应**
确认 `~/.ssh/config` 里端口是 `22722`,不要用默认 22。不要给 `gitlab.jiagutech.com` 配 HTTP/SOCKS 代理。
**HTTPS 推送报 413**
这是 Nginx 上传大小限制。请用 SSH 推送,不要用 `http://` 传整仓。
**`git push` 终端不弹出用户名密码**
SSH 不需要密码。如果误用了 HTTPS,先检查是否被 VS Code 的 `GIT_ASKPASS``GIT_TERMINAL_PROMPT=0` 拦掉。日常请用 SSH。
**编译找不到 `arm-none-eabi-gcc`**
重新执行 `bash Tools/setup/ubuntu.sh --no-sim-tools`,并新开一个终端。
**QGC 连上但没有以太网 MAVLink**
这是预期行为。`minimal_vtol` 固件不包含网络栈,地面站走 USB 或数传。
**想重新打开以太网或飞控 ROS 2**
需要改 `boards/cuav/7-nano/minimal_vtol.px4board`,并恢复带网络的 NuttX `defconfig`。改之前先和当前维护者确认。
## 10. 建议阅读顺序
1. 本文
2. [PX4 源码学习路线](PX4源码学习路线.md)
3. [PX4 rcS 启动流程与实机准备](PX4_rcS启动流程与实机准备.md)
4. 按任务再看 GPS、电机编号、NuttX、EKF2 或 ULog 文档
Loading…
Cancel
Save