4. 飞行数据解析
无人机日志回放调试的核心,在于从海量、异构的日志数据中准确提取出能够反映飞行状态的关键信息。IMU(惯性测量单元)、GPS、姿态、速度、位置这五类数据构成了飞行控制闭环的“感知层”基础。解析这些数据,不仅是回放的第一步,更是后续进行模型输出对比和控制动作分析的前提。本节将系统讲解这些数据的物理含义、日志中的存储格式、提取方法以及常见的解析陷阱。
上图展示了从原始传感器数据到状态估计输出的完整解析链路。在实际工程中,我们通常不会直接读取二进制日志,而是借助飞控厂商提供的解析工具(如PX4的ulog解析库、ArduPilot的bin文件解析器)或开源工具(如pyulog、Mission Planner)将日志转换为结构化数据。下面我们逐一深入解析各类数据的提取细节。
4.1 IMU数据提取:加速度计与陀螺仪的原始信号
IMU数据是飞行控制最底层的输入,直接反映了机体受到的比力和角速度。在PX4的ULog文件中,IMU数据通常存储在sensor_combined或vehicle_imu主题中;ArduPilot的bin文件则通过IMU消息记录。提取时需关注以下核心参数:
- 加速度计(Accelerometer):输出三轴比力(Specific Force),单位为m/s²。注意它包含重力分量,静止时读数为[0, 0, -9.8](NED系)或[0, 0, 9.8](ENU系)。
- 陀螺仪(Gyroscope):输出三轴角速度,单位为rad/s。用于姿态变化率的计算。
- 采样时间戳:每个IMU样本都带有硬件时间戳,用于与其他传感器同步。
提取IMU数据时,一个常见误区是直接使用未经处理的原始值。实际上,飞控内部已经进行了温度补偿、零偏校正和尺度因子校准。因此,日志中记录的通常是校准后的物理量。但在某些调试场景下(如分析振动问题),可能需要查看原始计数值(如sensor_mag原始值),此时应选择未经过滤波的原始数据流。
vehicle_imu主题包含经过滤波和融合后的IMU数据,而sensor_combined是传感器原始数据。进行控制回路分析时,应使用vehicle_imu;进行振动分析或传感器故障诊断时,应使用sensor_combined。
4.2 GPS数据提取:位置与速度的基准
GPS数据提供了无人机在全局坐标系下的位置和速度信息,是长航时飞行和导航的核心数据源。在日志中,GPS数据通常包含以下关键字段:
| 字段名 | 物理含义 | 单位 | 典型值/范围 |
|---|---|---|---|
| lat / lon | 纬度 / 经度 | 度(°) | [-90, 90] / [-180, 180] |
| alt | 海拔高度(椭球高) | 米(m) | 通常为WGS84椭球高 |
| vel_n / vel_e / vel_d | 北向/东向/地向速度 | m/s | NED坐标系下的速度分量 |
| fix_type | 定位类型 | 枚举 | 0=无, 2=2D, 3=3D, 4=RTK浮点, 5=RTK固定 |
| sats | 可见卫星数 | 颗 | 通常≥10为良好 |
提取GPS数据时,需要特别注意坐标系转换。日志中存储的经纬度是WGS84地理坐标系,而飞控内部导航解算使用的是本地NED(北东地)坐标系。因此,在回放分析时,如果要将GPS位置与飞控估计位置对比,必须先将GPS经纬度转换为与飞控相同的本地坐标系原点下的位置。常用的转换方法包括:
- 固定原点法:以起飞点或日志中第一个有效GPS点为原点,使用等距圆柱投影或UTM投影将经纬度转换为平面坐标。
- 使用飞控内部转换:直接读取日志中
vehicle_local_position主题的lat/lon字段,该字段已经是飞控内部转换后的本地坐标。
4.3 姿态数据提取:四元数与欧拉角的转换
姿态数据是飞控状态估计的核心输出,通常以四元数(Quaternion)形式存储,因为四元数避免了欧拉角的万向锁问题,且计算效率高。在PX4中,姿态数据位于vehicle_attitude主题,ArduPilot中则通过ATT消息记录。
提取姿态数据时,需要掌握以下关键点:
- 四元数格式:通常为
[w, x, y, z],其中w为标量部分。使用前应检查是否已归一化(模长≈1)。 - 欧拉角转换:若需要直观的横滚(Roll)、俯仰(Pitch)、偏航(Yaw)角,需将四元数转换为欧拉角。转换公式因旋转顺序(如ZYX)和坐标系(NED/ENU)而异。
- 姿态参考系:确认姿态是相对于NED系还是机体坐标系。通常飞控输出的是机体坐标系相对于NED系的旋转。
# Python示例:四元数转欧拉角(ZYX旋转顺序,NED系)
import numpy as np
def quat_to_euler(q):
w, x, y, z = q
# 横滚角
roll = np.arctan2(2*(w*x + y*z), 1 - 2*(x*x + y*y))
# 俯仰角
pitch = np.arcsin(2*(w*y - z*x))
# 偏航角
yaw = np.arctan2(2*(w*z + x*y), 1 - 2*(y*y + z*z))
return np.degrees([roll, pitch, yaw])
在回放调试中,姿态数据通常用于验证飞控的响应是否与预期一致。例如,当遥控器输入横滚指令时,日志中的横滚角应平滑跟随,且无超调或振荡。
4.4 速度与位置数据提取:融合估计的最终输出
速度和位置数据是飞控导航解算的最终结果,通常由扩展卡尔曼滤波器(EKF)融合IMU、GPS、气压计、磁力计等传感器数据得到。在PX4中,这些数据位于vehicle_local_position主题,包含:
- 位置:
x, y, z(NED系,单位米),原点通常为起飞点。 - 速度:
vx, vy, vz(NED系,单位m/s)。 - 位置/速度协方差:用于评估估计质量。
提取这些数据时,需要特别关注dist_bottom(超声波或激光测距)与z(气压计高度)的区别。在低空飞行时,飞控可能优先使用测距传感器,导致高度数据跳变。此外,速度数据在GPS信号丢失时会退化为纯IMU积分,产生漂移,此时应结合estimator_status中的滤波器状态进行判断。
vehicle_local_position的x/y数据,发现漂移方向与GPS速度残差方向一致。进一步检查estimator_status中的GPS健康标志,发现GPS定位精度(EPH)在漂移期间从0.8m恶化到2.5m。最终确认是GPS天线受到螺旋桨振动干扰,导致位置估计漂移。
4.5 数据同步与时间戳对齐
多源数据的时间戳对齐是飞行数据解析中最容易出错、也最关键的环节。不同传感器具有不同的采样频率和延迟:IMU通常为200-1000Hz,GPS为5-20Hz,气压计为50-100Hz。在日志中,每个数据包都带有硬件时间戳(微秒级),但传感器之间的时间基准可能不同。
常用的时间对齐方法包括:
- 硬件同步:飞控通过PPS(脉冲秒信号)或传感器中断实现硬件同步,日志中会记录同步后的时间戳。
- 软件插值:以IMU时间戳为基准,对GPS等低频数据进行线性插值或最近邻匹配。
- 时间偏移补偿:通过互相关分析估计传感器之间的固定延迟,并进行补偿。
在PX4的ULog中,所有主题的时间戳已经过同步处理,可以直接使用。但在ArduPilot的bin文件中,不同消息的时间戳可能存在微小的偏移,建议使用timeUS字段进行对齐。
4.6 案例拆解:一次GPS丢星后的数据解析与问题定位
下面通过一个完整案例,展示如何综合运用上述解析方法定位飞行异常。
背景与约束:某无人机在城区执行巡检任务,飞行高度80m,速度12m/s。飞行至第3分钟时,飞控突然切换为姿态模式(自稳),位置保持失效。事后需要从日志中分析原因。
关键输入数据:
- PX4 ULog文件,时长5分12秒,包含
sensor_combined、vehicle_gps_position、vehicle_attitude、vehicle_local_position、estimator_status等主题。 - 飞行日志中第180秒附近出现模式切换标志。
分析判断过程:
- 提取GPS数据:从
vehicle_gps_position中提取fix_type和sats,发现第178秒时fix_type从3(3D定位)降为0(无定位),sats从14颗骤降至3颗。 - 检查估计器状态:查看
estimator_status中的gps_check_fail标志,确认GPS质量检查失败,EKF将GPS权重降为0。 - 对比位置数据:提取
vehicle_local_position的x/y,发现第178秒后位置输出不再更新,但速度数据仍由IMU积分提供,导致位置漂移。 - 检查控制模式切换逻辑:确认飞控因位置估计不可靠,自动降级为姿态模式。
实际操作步骤:
# 使用pyulog提取关键数据
from pyulog import ULog
ulog = ULog("flight.ulg")
# 提取GPS fix类型
gps_data = ulog.get_dataset("vehicle_gps_position")
fix_types = gps_data.data["fix_type"]
# 提取估计器状态
est_data = ulog.get_dataset("estimator_status")
gps_fail = est_data.data["gps_check_fail_flags"]
结果对比与复盘:通过数据解析,确认故障原因为GPS天线被机身遮挡导致卫星信号丢失。后续改进措施包括调整天线安装位置、增加GPS冗余(双天线)以及优化EKF的GPS故障检测阈值。此次排障中,准确提取并同步GPS与估计器数据是定位问题的关键。
4.7 常见误区与总结复盘
在飞行数据解析实践中,以下误区值得特别注意:
| 误区 | 后果 | 正确做法 |
|---|---|---|
| 忽略坐标系差异 | 位置/速度对比出现系统性偏差 | 统一使用NED系或明确标注坐标系 |
| 混淆高度基准 | 高度对比误差达数十米 | 区分椭球高、正高、气压高度 |
| 未检查时间戳同步 | 数据错位导致误判 | 使用飞控同步后的时间戳或进行插值 |
| 直接使用原始IMU值 | 包含噪声和零偏,影响分析 | 使用校准后的物理量 |
| 忽略数据质量标志 | 将无效数据当作有效数据 | 检查fix_type、sats、协方差等质量指标 |
总结而言,飞行数据解析的核心在于“三个对齐”:时间对齐(确保数据在同一时间基准下)、坐标系对齐(统一到NED或机体坐标系)、单位对齐(统一使用SI单位)。掌握这三点,就能从日志中准确提取出IMU、GPS、姿态、速度、位置等关键数据,为后续的模型输出对比和控制动作分析奠定坚实基础。
load_flight_data(ulog_file)函数,一次性返回所有关键数据集的DataFrame格式,可大幅提升回放调试效率。