ArduSub程序学习(11)--EKF实现逻辑③

13 篇文章 0 订阅
10 篇文章 0 订阅

目录

EKF的五大主要步骤

1.状态预测(State Prediction)

2.协方差预测(Covariance Prediction)

3.卡尔曼增益计算(Kalman Gain Calculation)

4.状态更新(State Update)

5.协方差更新(Covariance Update) 

补充说明:滤波器重置机制


下面开始寻找EKF五大公式

EKF的五大主要步骤

  1. 状态预测(State Prediction)
  2. 协方差预测(Covariance Prediction)
  3. 卡尔曼增益计算(Kalman Gain Calculation)
  4. 状态更新(State Update)
  5. 协方差更新(Covariance Update)
/********************************************************
*                 UPDATE FUNCTIONS                      *
********************************************************/
// Update Filter States - this should be called whenever new IMU data is available
//更新扩展卡尔曼滤波器 (EKF) 的核心方法
void NavEKF2_core::UpdateFilter(bool predict)
{
    // Set the flag to indicate to the filter that the front-end has given permission for a new state prediction cycle to be started

    //设置标志用来向ekf2滤波器,指示前端已允许启动新的状态预测周期。
    startPredictEnabled = predict;

    // don't run filter updates if states have not been initialised
    //如果未初始化状态完成,请不要运行过滤器更新
    if (!statesInitialised) {
        return;
    }

    // start the timer used for load measurement
    //启动用于负载测量的定时器
#if ENABLE_EKF_TIMING
    void *istate = hal.scheduler->disable_interrupts_save();
    static uint32_t timing_start_us;
    timing_start_us = dal.micros();
#endif

    fill_scratch_variables();

    // TODO - in-flight restart method

    //get starting time for update step获取更新步骤的开始时间
    imuSampleTime_ms = frontend->imuSampleTime_us / 1000;

    // Check arm status and perform required checks and mode changes
    //检查遥控器是否解锁电机和执行必要的检查和模式
    controlFilterModes();

    // read IMU data as delta angles and velocities
    //读取IMU数据作为角度和速度
    readIMUData();

    // Run the EKF equations to estimate at the fusion time horizon if new IMU data is available in the buffer

    //如果在缓冲区中存在新的IMU数据,在满足的融合时间内,运行EKF方程
    if (runUpdates) {
        // Predict states using IMU data from the delayed time horizon
        //预测方程:使用IMU的数据,从延迟尺度时间-
        //EKF第一个方程(状态预测方程)
        //负责根据IMU数据(如角速度和加速度)预测系统的下一个状态。这涉及到使用系统的运动学模型(例如,导航方程)来预测飞机或飞行器在下一个时间步的状态。
        UpdateStrapdownEquationsNED();

        // 预测协方差增长Predict the covariance growth
        //EKF第二个方程(协方差预测方程)
        //用于预测状态协方差矩阵的增长。它通过应用系统的状态转移矩阵和过程噪声协方差矩阵,计算预测后的协方差。这一步骤反映了在预测过程中由于过程噪声引入的不确定性增加。
        CovariancePrediction();

        // Run the IMU prediction step for the GSF yaw estimator algorithm
        // using IMU and optionally true airspeed data.
        // Must be run before SelectMagFusion() to provide an up to date yaw estimate
        runYawEstimatorPrediction();

        // 使用地磁更新滤波器状态Update states using  magnetometer data
        //后面都EFK第三四个方程,(更新状态)(卡尔曼增益的计算)
        //卡尔曼增益的计算通常在各个传感器融合函数内部完成,如 SelectMagFusion(), SelectVelPosFusion() 等。
        SelectMagFusion();

        // 使用GPS和气压计进行状态更新Update states using GPS and altimeter data
        SelectVelPosFusion();

        // Run the GPS velocity correction step for the GSF yaw estimator algorithm
        // and use the yaw estimate to reset the main EKF yaw if requested
        // Muat be run after SelectVelPosFusion() so that fresh GPS data is available
        runYawEstimatorCorrection();

        // 使用测距仪器更新滤波器状态Update states using range beacon data
        SelectRngBcnFusion();

        // 使用光流传感器进行更新数据Update states using optical flow data
        SelectFlowFusion();

        // 使用空速计数据进行更新数据Update states using airspeed data
        SelectTasFusion();

        // 更新应用侧滑约束假设的飞越飞行器状态Update states using sideslip constraint assumption for fly-forward vehicles
        SelectBetaFusion();

        // 更新滤波器的状态Update the filter status
        //EKF第5个方程,用于更新滤波器的状态信息,如健康状态、滤波器的稀疏程度等。这有助于监控滤波器的性能,并在必要时触发滤波器的重置。
        updateFilterStatus();
    }

    // 从融合数据到数据输出Wind output forward from the fusion to output time horizon
    //EKF第5个方程,负责计算最终的输出状态,并更新协方差矩阵。这包括应用卡尔曼增益对状态和协方差进行最终调整,以反映最新的测量数据。
    calcOutputStates();

    // stop the timer used for load measurement
#if ENABLE_EKF_TIMING
    static uint32_t total_us;
    static uint32_t timing_counter;
    total_us += dal.micros() - timing_start_us;
    if (timing_counter++ == 4000) {
        hal.console->printf("ekf2 avg %.2f us\n", total_us / float(timing_counter));
        total_us = 0;
        timing_counter = 0;
    }
    hal.scheduler->restore_interrupts(istate);
#endif

    /*
      this is a check to cope with a vehicle sitting idle on the
      ground and getting over-confident of the state. The symptoms
      would be "gyros still settling" when the user tries to arm. In
      that state the EKF can't recover, so we do a hard reset and let
      it try again.
     */
    if (filterStatus.value != 0) {
        last_filter_ok_ms = dal.millis();
    }
    if (filterStatus.value == 0 &&
        last_filter_ok_ms != 0 &&
        dal.millis() - last_filter_ok_ms > 5000 &&
        !dal.get_armed()) {
        // we've been unhealthy for 5 seconds after being healthy, reset the filter
        GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "EKF2 IMU%u forced reset",(unsigned)imu_index);
        last_filter_ok_ms = 0;
        statesInitialised = false;
        InitialiseFilterBootstrap();
    }
    
}
1.状态预测(State Prediction)
UpdateStrapdownEquationsNED();

UpdateStrapdownEquationsNED() 函数负责根据IMU数据(如角速度和加速度)预测系统的下一个状态。这涉及到使用系统的运动学模型(例如,导航方程)来预测飞机或飞行器在下一个时间步的状态

2.协方差预测(Covariance Prediction)
CovariancePrediction();

CovariancePrediction() 函数用于预测状态协方差矩阵的增长。它通过应用系统的状态转移矩阵和过程噪声协方差矩阵,计算预测后的协方差。这一步骤反映了在预测过程中由于过程噪声引入的不确定性增加。

3.卡尔曼增益计算(Kalman Gain Calculation)

对应函数:

  • 卡尔曼增益的计算通常在各个传感器融合函数内部完成,如 SelectMagFusion(), SelectVelPosFusion() 等。这些函数在融合传感器数据时,会计算相应的卡尔曼增益。

解释:

  • 在EKF中,卡尔曼增益用于权衡预测状态与测量数据的信任度。每个传感器的数据融合步骤会根据当前协方差和测量噪声计算出相应的卡尔曼增益,以更新状态估计。
4.状态更新(State Update)
SelectMagFusion();
SelectVelPosFusion();
SelectRngBcnFusion();
SelectFlowFusion();
SelectTasFusion();
SelectBetaFusion();
runYawEstimatorCorrection();

 

  • 这些函数负责使用不同传感器(如磁力计、GPS、测距仪、光流传感器、空速计等)的测量数据来更新滤波器的状态估计。
  • 每个 Select*Fusion() 函数对应于特定传感器的数据融合,通过将测量数据与预测状态结合,修正状态估计。
  • runYawEstimatorCorrection() 函数特别用于利用GPS速度数据来校正偏航角的估计。
5.协方差更新(Covariance Update) 
calcOutputStates();
updateFilterStatus();
  • calcOutputStates() 函数负责计算最终的输出状态,并更新协方差矩阵。这包括应用卡尔曼增益对状态和协方差进行最终调整,以反映最新的测量数据。
  • updateFilterStatus() 函数用于更新滤波器的状态信息,如健康状态、滤波器的稀疏程度等。这有助于监控滤波器的性能,并在必要时触发滤波器的重置。
补充说明:滤波器重置机制
if (filterStatus.value != 0) {
    last_filter_ok_ms = dal.millis();
}
if (filterStatus.value == 0 &&
    last_filter_ok_ms != 0 &&
    dal.millis() - last_filter_ok_ms > 5000 &&
    !dal.get_armed()) {
    // 强制重置滤波器并重新初始化
    GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "EKF2 IMU%u forced reset",(unsigned)imu_index);
    last_filter_ok_ms = 0;
    statesInitialised = false;
    InitialiseFilterBootstrap();
}

该部分代码监控滤波器的健康状态 (filterStatus)。如果滤波器在一段时间内(例如,5000毫秒)处于不健康状态,并且飞行器未解锁 (!dal.get_armed()),则会强制重置滤波器并重新初始化。这确保了滤波器在异常情况下能够恢复,从而维持系统的稳定性和可靠性。 

EKF步骤对应函数作用
状态预测UpdateStrapdownEquationsNED()根据IMU数据预测下一个状态
协方差预测CovariancePrediction()预测协方差矩阵的增长,反映过程噪声引入的不确定性
卡尔曼增益计算SelectMagFusion(), SelectVelPosFusion(), 等各个传感器融合函数内部计算并应用卡尔曼增益,以权衡预测状态与测量数据的信任度
状态更新SelectMagFusion(), SelectVelPosFusion(), SelectRngBcnFusion(), SelectFlowFusion(), SelectTasFusion(), SelectBetaFusion(), runYawEstimatorCorrection()使用不同传感器的数据更新状态估计
协方差更新calcOutputStates(), updateFilterStatus()计算最终输出状态并更新协方差矩阵,监控和更新滤波器的健康状态

 未完待续~~

下面逐个分析各个函数

EKF-SLAM(Extended Kalman Filter SLAM)是一种基于扩展卡尔曼滤波器的SLAM算法,可以实现同时定位和建图。以下是使用C++实现EKF-SLAM的基本步骤: 1. 定义状态向量和观测向量 在EKF-SLAM中,状态向量包括机器人的位姿和地图中的特征点位置。观测向量包括机器人的传感器测量值和地图中已知的特征点位置。 2. 初始化协方差矩阵和状态向量 协方差矩阵表示状态变量不确定性的度量,初始时应设置为较大的值,以便在后续更新过程中逐渐收敛。状态向量的初始值可以从机器人的传感器数据中估计出来。 3. 实现运动模型 运动模型用于估计机器人的位姿随时间的变化。常见的运动模型包括里程计模型和惯性导航模型。 4. 实现观测模型 观测模型用于预测机器人观测到的特征点位置。常见的观测模型包括单个特征点的距离或角度测量值,以及多个特征点的距离或角度测量值。 5. 实现EKF算法 EKF算法用于更新状态向量和协方差矩阵。在每个时间步骤中,先使用运动模型预测下一个状态向量和协方差矩阵,然后使用观测模型将当前状态向量和协方差矩阵更新为最新的估计值。 6. 更新地图 当机器人观测到新的特征点时,应该将这些点添加到地图中。可以使用一些技术来确定新观测到的特征点是否已经在地图中存在,例如最近邻搜索或图像配准。 7. 重复执行步骤3-6,直到SLAM问题收敛。 以上是使用C++实现EKF-SLAM的基本步骤,但实现过程中需要深入了解卡尔曼滤波器理论和SLAM算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仗剑走代码

“您的支持是我创作的动力”

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值