尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PX4 EKF2 源码解析(一):状态估计问题与 EKF2 的工程定位

PX4 EKF2 源码解析(一):状态估计问题与 EKF2 的工程定位 PX4 EKF2 源码解析一状态估计问题与 EKF2 的工程定位摘要飞行控制器不能直接把陀螺仪、加速度计、GNSS、磁力计和气压计读数作为控制状态。各传感器的采样频率、延迟、噪声模型和可观测量不同必须由状态估计器在统一的动力学模型中完成时间对齐、信息融合与故障隔离。本文从飞行器状态估计问题出发说明 PX4 EKF2 的输入、输出、设计目标以及它在飞控软件栈中的边界。关键词PX4、EKF2、状态估计、传感器融合、飞行控制1. 控制器真正需要的状态位置控制、姿态控制和导航逻辑需要的是同一时刻、同一坐标系下连续且统计意义明确的状态而不是相互独立的传感器读数。控制所需状态主要信息来源直接使用的主要问题姿态与角速度陀螺仪、加速度计、磁力计陀螺积分漂移加速度计包含机动加速度水平位置与速度GNSS、视觉、光流延迟大、更新率低、遮挡或跳变高度与垂直速度气压计、GNSS、测距仪、IMU气压漂移、地形变化、振动噪声IMU 偏差由多源观测间接估计偏差通常不可直接测量且可观性随运动变化风速空速、地速、侧滑或阻力模型只有特定机动和观测组合下才可观若只对单个传感器做低通滤波无法解决跨传感器约束。例如GNSS 速度不仅能修正速度还能通过状态相关性修正姿态和加速度计偏差。这正是联合状态估计的价值。2. 状态估计的基本矛盾惯性测量频率高、短时连续但误差随积分累积绝对观测长期有界但频率低且存在明显延迟。EKF2 的核心任务可以表示为高频、连续、会漂移的惯性递推 低频、延迟、长期有界的绝对或相对观测 │ ▼ 同一坐标系、同一时间基准下的状态与不确定度其数学基础是递归贝叶斯估计。滤波器保留状态估计 (\hat{x}) 和协方差 (P)前者描述当前最可能的状态后者描述估计误差及各状态误差之间的相关性。3. EKF2 在 PX4 软件栈中的位置传感器驱动uORB 传感器话题EKF2vehicle_attitudevehicle_local_positionvehicle_global_positionestimator_status / aid_source姿态与位置控制器导航与任务层EKF2 不负责传感器硬件采样也不直接产生电机控制量。其边界如下上游接收经过驱动层校准、积分或预处理的 uORB 数据内部管理延迟、执行惯性预测、观测融合、健康检测和输出预测下游发布姿态、局部位置、全局位置、风速、偏差和估计器状态。4. 为什么需要统一的多状态 EKF一个状态误差可能以另一种观测残差的形式出现。例如机体存在微小俯仰误差时重力会被错误投影到水平轴继而形成水平速度漂移。GNSS 水平速度创新因此能够间接约束姿态误差和加速度计偏差。联合估计通过协方差非对角项保存这种耦合PijE[(xi−x^i)(xj−x^j)] P_{ij}E\left[(x_i-\hat{x}_i)(x_j-\hat{x}_j)\right]Pij​E[(xi​−x^i​)(xj​−x^j​)]若将姿态、位置和偏差拆成互不相关的滤波器上述统计相关性需要由额外启发式逻辑补偿复杂运动条件下较难保持一致性。5. EKF2 的主要工程设计设计解决的问题对应实现延迟融合时域不同传感器具有不同延迟EstimatorInterface、RingBuffer高频输出预测延迟融合结果不能直接供控制器使用OutputPredictor统一 24 维状态保存姿态、运动、偏差、磁场和风的相关性stateSample、P融合状态机观测可能中断、恢复或质量下降controlFusionModes()创新一致性检验拒绝与预测显著不一致的观测estimator_aid_source*多实例选优利用多 IMU/磁力计形成估计冗余EKF2Selector符号代码生成降低高维雅可比手工推导风险EKF/python/ekf_derivation6. 源码入口PX4 v1.14.3 中顶层模块入口位于src/modules/ekf2/ ├── EKF2.cpp # uORB 接口、参数与发布 ├── EKF2.hpp ├── EKF2Selector.cpp # 多实例选择 ├── ekf2_params.c # 参数定义 └── EKF/ ├── estimator_interface.cpp ├── ekf.cpp # 主滤波循环和状态预测 ├── control.cpp # 融合总调度 ├── covariance.cpp # 协方差预测与维护 └── *_control.cpp / *_fusion.cpp阅读源码时应先区分接口层和算法层。EKF2.cpp中出现大量 uORB 更新与发布代码并不代表滤波方程在该文件中实现核心算法集中在EKF/目录。7. 版本边界本文专栏固定以 PX4 v1.14.3 为基线。后续版本可能调整话题名称、状态规模、参数命名和融合控制结构因此不能仅凭函数名相同认定实现完全一致。文章中的结论分为两类数学和架构结论通常可迁移到相邻版本文件、函数、参数结论以 v1.14.3 源码为准。8. 从“可测量量”到“可估计状态”传感器是否能够输出某个数值与该数值能否作为滤波状态的独立观测是两个概念。例如加速度计输出三轴比力但不能在飞行中直接给出三轴线加速度fbRbn(an−gn)bana f^bR_{bn}(a^n-g^n)b_an_afbRbn​(an−gn)ba​na​式中同时存在姿态、真实线加速度、重力、偏差和噪声。只有结合姿态传播、外部速度或位置观测才能把这些因素分离。EKF2 的 24 维状态选择体现了这一可观测关系陀螺/加速度计 ──► 姿态、速度、位置的高频传播 GNSS/EV/光流 ──► 约束速度与位置漂移 磁/GNSS yaw ──► 约束绕重力轴的自由度 气压/GNSS/range ─► 约束垂直通道 空速/侧滑/阻力 ─► 约束水平风速 上述观测形成的交叉协方差 ─► 间接估计 IMU 偏差因此EKF2 的状态不是对所有传感器读数的简单集合而是为导航过程选择的一组最小工程变量。没有对应观测条件时某些状态虽然仍在矩阵中传播却可能处于弱可观或不可观状态。9. 为什么状态估计必须显式描述不确定度假设 GNSS 报告水平速度精度为 0.2 m/s而当前惯性预测速度方差为 4 (m/s)²。此时滤波器应主要相信 GNSS若刚完成高质量 GNSS 融合预测速度方差只有 0.01 (m/s)²而新 GNSS 数据质量下降则更新权重应明显减小。这一权衡不是固定比例而由 (P)、(R) 和状态相关性实时计算KP−HT(HP−HTR)−1 KP^-H^T(HP^-H^TR)^{-1}KP−HT(HP−HTR)−1只输出状态而不输出方差将使上层无法区分“位置数值暂时平稳”和“位置具有可靠外部约束”。PX4 因而同时发布位置有效性、航位推算状态、状态方差、创新检验和重置事件。10. 源码中的职责证据从类关系可以验证 EKF2 的工程定位类/结构持有内容不负责的内容EKF2uORB 订阅、参数句柄、发布器、Ekf对象观测雅可比推导EstimatorInterface传感器缓冲、时间基准、输入转换PX4 uORB 发布Ekf_state、P、控制/故障标志、融合器直接驱动执行机构OutputPredictor当前输出状态和历史缓冲完整观测协方差更新EKF2Selector多实例健康评分和主实例单实例内部滤波方程Ekf::update()只在延迟 IMU 缓冲更新时执行并按“协方差预测—状态预测—融合调度—地形估计—输出校正”的固定次序运行。该调用序列表明 EKF2 不是一个单独公式而是包含时间管理和恢复逻辑的实时状态机。11. 设计取舍准确性、实时性与资源完整的最优非线性贝叶斯估计需要维护任意形状概率分布目标板无法承担。EKF2 采用高斯近似和一阶线性化在以下约束间折中约束EKF2 的处理非线性四元数和非线性观测局部雅可比线性化实时计算IMU 降采样、标量顺序融合、生成稀疏表达式传感器延迟固定长度历史缓冲与 delayed horizon控制低延迟独立 Output Predictor 前推到当前时刻传感器失效每个观测源独立状态机和创新门限内存确定性固定容量 RingBuffer避免运行时动态分配这些取舍解释了若干看似复杂的实现。例如同时维护延迟主状态和当前输出状态增加了代码量却避免了把 100 ms 级 GNSS 延迟直接引入控制回路。12. EKF2 输出有效性的正确使用下游不能只判断话题是否更新。一个持续发布的局部位置可能已经进入惯性航位推算数值仍连续但误差随时间增长。正确使用应联合检查xy_valid、z_valid、速度有效性等输出标志estimator_status_flags中的水平、垂直 aiding 与 dead-reckoning最近成功融合时间位置、速度方差或精度估计reset counter 和对应 reset delta。这也说明状态估计器的输出契约包含“状态值 置信度 模式 事件”缺少其中任何一项都会降低飞控系统的故障处置能力。13. 从单传感器故障看统一估计的必要性以磁力计受电机电流干扰为例故障传播并不限于 yaw磁场观测偏转 ▼ yaw 被错误修正 ▼ 机体系比力旋转到错误 NED 方向 ▼ 水平速度预测与 GNSS 不一致 ▼ GNSS velocity innovation 增大 ├─ 若错误归因 GNSS可能停止健康位置源 └─ 若识别 yaw failure使用 EKFGSF 重置航向这一链路说明故障检测必须利用多状态、多观测的一致性。只对磁力计做幅值阈值检查无法覆盖方向性干扰只对 GNSS 创新做拒绝也可能错误隔离健康传感器。EKF2 同时维护磁场检查、速度创新、航向可观性、EKFGSF 和融合超时从系统层判断更合理的故障解释。类似地加速度计 z 轴 clipping 会让气压、GNSS 高度和 EV 高度同时产生创新。若多个独立高度源同向异常公共的惯性预测比多个传感器同时故障更可能。统一 EKF 的状态相关性与多源 aid status 为这种因果分析提供了数据基础。从安全设计角度EKF2 的目标不是保证任何时刻都有“看似稳定”的位置而是明确当前信息来源、置信度和退化状态。当外部辅助全部中断时滤波器继续提供连续惯性解同时设置 dead-reckoning当状态超出局部线性化范围时通过 reset 重建一致性当存在冗余 IMU 时由 Selector 在完整解层面切换。这三种行为分别对应连续性、一致性和容错性。评价估计器还应区分精度、完整性、连续性和可用性。精度描述误差大小完整性描述能否及时报告不可接受误差连续性描述输出是否在任务阶段不中断可用性描述满足全部要求的时间比例。EKF2 的创新门限、fault flags、reset 事件和多实例选优主要服务完整性与连续性而不仅是降低平均位置误差。对实际系统的验收因此至少包含正常精度、传感器中断后的连续输出、错误观测的告警时间和恢复后的重新融合时间。只用一段正常飞行轨迹计算 RMSE无法覆盖 EKF2 最重要的容错职责。源码解读从模块入口确认 EKF2 的工程边界本篇的核心理论是“EKF2 负责状态估计而不是传感器驱动或控制”。该结论可以从三个源码入口直接验证。1.EKF2是接口调度对象文件src/modules/ekf2/EKF2.hppclassEKF2final:publicModuleParams,publicpx4::ScheduledWorkItem{public:EKF2(boolmulti_mode,constpx4::wq_config_tconfig,boolreplay_mode);private:voidRun()override;voidVerifyParams();voidPublishAttitude(consthrt_abstimetimestamp);voidPublishAidSourceStatus(consthrt_abstimetimestamp);// ...};逐项对应源码元素理论/架构含义ModuleParamsEKF2 噪声、延迟、门限和融合开关来自 PX4 参数系统ScheduledWorkItem状态估计运行在工作队列而不是独立无限循环线程Run()一帧数据的接口层总入口PublishAttitude()估计结果通过 uORB 发布给控制器PublishAidSourceStatus()创新、方差和融合结果同时作为诊断输出类中没有电机混控或驱动寄存器操作说明 EKF2 与执行机构和硬件采样保持边界。2.EstimatorInterface统一算法输入文件src/modules/ekf2/EKF/estimator_interface.hclassEstimatorInterface{public:voidsetIMUData(constimuSampleimu_sample);voidsetMagData(constmagSamplemag_sample);voidsetGpsData(constgpsMessagegps);voidsetBaroData(constbaroSamplebaro_sample);// flow、range、EV、airspeed 等按编译配置存在};接口使用imuSample、gpsMessage等算法内部类型而不是直接暴露vehicle_imu_s、sensor_gps_s。因此数据链实际是uORB message │ EKF2.cpp时间、单位、坐标和有效性转换 ▼ imuSample / gpsMessage / magSample ... │ EstimatorInterface延迟修正与缓冲 ▼ Ekf预测、融合与故障处理理论中的观测 (z_k) 在代码中并不是原始 uORB 结构而是转换并对齐后的 sample。3.Ekf::update()对应滤波主周期文件src/modules/ekf2/EKF/ekf.cppboolEkf::update(){if(!_filter_initialised){_filter_initialisedinitialiseFilter();if(!_filter_initialised){returnfalse;}}if(_imu_updated){_imu_updatedfalse;constimuSample imu_sample_delayed_imu_buffer.get_oldest();predictCovariance(imu_sample_delayed);predictState(imu_sample_delayed);controlFusionModes(imu_sample_delayed);_output_predictor.correctOutputStates(/* ... */);returntrue;}returnfalse;}这段代码可以直接映射到状态估计流程源码理论步骤initialiseFilter()建立状态均值和初始协方差_imu_buffer.get_oldest()选择 delayed horizon 的惯性输入predictCovariance()(P-FPFTQ)predictState()(x^-f(x,u))controlFusionModes()选择有效观测并执行更新correctOutputStates()将延迟状态修正传播到当前输出时域初学者阅读时应注意update()没有直接出现 GPS、磁力计或气压计名称因为具体传感器由controlFusionModes()分发。主函数保持稳定各观测源可以独立扩展。4. 如何沿源码验证一个输出以vehicle_local_position为例可采用以下检索顺序EKF2.cpp::PublishLocalPosition() │ 调用 _ekf 的状态/有效性查询 ▼ Ekf / EstimatorInterface getter │ 读取 OutputPredictor 当前状态或主滤波状态 ▼ vehicle_local_position_s 字段赋值 │ └─ reset delta、valid flag、dead-reckoning 状态一并发布这条链证明控制器消费的是经过 Output Predictor 前推并附带有效性信息的状态而不是_state.pos的裸数组。5. 初学者的最小阅读闭环第一次阅读无需遍历整个目录建议完成以下闭环在EKF2.hpp找到Ekf _ekf成员以及订阅/发布成员在EKF2::Run()找到_ekf.setIMUData()和_ekf.update()在EstimatorInterface::setIMUData()找到输出预测和降采样在Ekf::update()找到预测与融合总调度在EKF2.cpp找到姿态和位置发布用一条 ULog 对照estimator_status_flags和vehicle_local_position。完成该闭环后理论中的输入、状态、观测更新和输出都能落到具体函数后续再进入单传感器融合文件不会失去主线。14. 小结EKF2 的本质并非“对传感器数据做平滑”而是在动力学约束、观测模型、时间延迟和统计不确定度共同作用下构造可供飞控实时使用的一致状态。理解这一定位后后续的 24 维状态、延迟缓冲、创新检验和输出预测将形成一条统一技术主线。
返回列表