Files
ASER/App/est/corridor_ekf.h

162 lines
5.7 KiB
C
Raw Normal View History

2026-03-31 23:30:33 +08:00
/**
* @file corridor_ekf.h
* @brief EKF
*
* x = [e_y, e_th, s]^T
* - e_y : (m)
* - e_th : (rad)
* - s : 沿 (m)
*
2026-04-04 23:24:36 +08:00
* ( B IMU ):
* - : 1DOF e_y ()
* z_ey = VL53 ()
* - IMU : 1DOF e_th
* z_eth_imu = imu_yaw_rad - imu_yaw_ref_rad
* - (z_eth_L/z_eth_R) :
* VL53 (±2cm ~13° )
2026-03-31 23:30:33 +08:00
*
*
* - χ²
2026-04-04 23:24:36 +08:00
* - VL53 ()
* - R (退)
2026-03-31 23:30:33 +08:00
* - ()
*/
#ifndef CORRIDOR_EKF_H
#define CORRIDOR_EKF_H
#include <stdint.h>
#include <stdbool.h>
/* 先引入消息定义 (含 EKF_STATE_DIM/EKF_OBS_DIM 宏) */
#include "preproc/corridor_msgs.h"
#ifdef __cplusplus
extern "C" {
#endif
/* =========================================================
* EKF
* ========================================================= */
typedef struct {
/* 过程噪声协方差 Q */
float q_ey; // e_y 过程噪声方差
float q_eth; // e_th 过程噪声方差
float q_s; // s 过程噪声方差
2026-04-05 10:15:40 +08:00
float q_ey_eth; // [改进] e_y 和 e_th 耦合噪声 (横向-航向动力学耦合)
2026-03-31 23:30:33 +08:00
/* 观测噪声协方差 R */
float r_ey; // 横向观测噪声方差 (侧墙)
float r_eth; // 航向观测噪声方差 (侧墙)
2026-04-04 23:24:36 +08:00
float r_eth_imu; // 航向观测噪声方差 (IMU yaw)IMU 准确度高时可设较小值
2026-03-31 23:30:33 +08:00
/* 初始协方差 */
float P0_diag[3]; // 初始 P 对角线
/* χ² 检验门限 */
float chi2_1dof; // 1 自由度门限 (默认 3.84)
float chi2_2dof; // 2 自由度门限 (默认 5.99)
/* 走廊几何参数 */
float sensor_base_length; // 同侧前后雷达间距 L_s
float corridor_width; // 走廊标准宽度
float y_offset; // 期望偏置
2026-04-04 23:24:36 +08:00
float side_sensor_inset; // [兼容] 侧向传感器统一内缩距离 (当 left/right 未单独设置时使用)
float left_sensor_inset; // [改进A] 左侧 VL53 内缩距离 (传感器面到车体左外边缘, 实测)
float right_sensor_inset; // [改进A] 右侧 VL53 内缩距离 (传感器面到车体右外边缘, 实测)
2026-03-31 23:30:33 +08:00
float robot_width; // 车体外轮廓宽度 (用于单侧退化时的精确定位)
} CorridorEKFConfig_t;
/* =========================================================
* EKF
* ========================================================= */
typedef struct {
float x[EKF_STATE_DIM]; // 状态向量
float P[EKF_STATE_DIM][EKF_STATE_DIM]; // 状态协方差
float K[EKF_STATE_DIM][EKF_OBS_DIM]; // 卡尔曼增益
float S[EKF_OBS_DIM][EKF_OBS_DIM]; // 新息协方差
float S_inv[EKF_OBS_DIM][EKF_OBS_DIM]; // S 的逆
} CorridorEKFState_t;
/* =========================================================
* API
* ========================================================= */
/**
* @brief EKF
* @param config
*/
void CorridorEKF_Init(const CorridorEKFConfig_t *config);
/**
* @brief EKF ()
* @param odom_vx 线 (m/s)
* @param imu_wz IMU (rad/s)
* @param dt (s)
*/
void CorridorEKF_Predict(float odom_vx, float imu_wz, float dt);
/**
* @brief EKF () -
* @param obs
* @param out_state ()
* @return
*/
int CorridorEKF_Update(const CorridorObs_t *obs, CorridorState_t *out_state);
/**
* @brief EKF IMU ( Update )
*
* IMU yaw e_th 1DOF EKF
* (/退) e_th
*
* @param imu_yaw_rad IMU yaw (rad)
* @param imu_yaw_ref_rad IMU yaw (rad)
* z_eth_imu = imu_yaw_rad - imu_yaw_ref_rad
* @param valid IMU
*/
void CorridorEKF_UpdateIMUYaw(float imu_yaw_rad, float imu_yaw_ref_rad, bool valid);
/**
* @brief
*/
void CorridorEKF_GetState(CorridorState_t *out);
/**
* @brief EKF
*/
void CorridorEKF_Reset(void);
2026-04-04 17:09:19 +08:00
/**
* @brief
*
* e_y s e_th
*
*/
void CorridorEKF_ResetHeading(void);
/**
* @brief 180°
*
*
* - e_th 0
* - e_y
*/
void CorridorEKF_RebaseAfterTurnaround(void);
2026-03-31 23:30:33 +08:00
/**
* @brief ()
*/
void CorridorEKF_SetProcessNoise(float q_ey, float q_eth, float q_s);
/**
* @brief ()
*/
void CorridorEKF_SetMeasurementNoise(float r_ey, float r_eth);
#ifdef __cplusplus
}
#endif
#endif /* CORRIDOR_EKF_H */