【FEJ】type_base 成员的数学推导

📐 一、type_base 成员的数学推导

1. _value:当前状态估计值

在贝叶斯滤波框架下,状态估计是后验概率的最大值:

x^k=arg⁡max⁡xp(xk∣z1:k,u1:k)\hat{\mathbf{x}}_k = \arg\max_{\mathbf{x}} p(\mathbf{x}_k | \mathbf{z}_{1:k}, \mathbf{u}_{1:k})x^k=argxmaxp(xkz1:k,u1:k)

其中:

  • x^k\hat{\mathbf{x}}_kx^k:时刻 k 的状态估计(对应 _value
  • z1:k\mathbf{z}_{1:k}z1:k:所有观测
  • u1:k\mathbf{u}_{1:k}u1:k:所有控制输入(IMU 测量)

在 EKF 中
x^k=E[xk∣z1:k]\hat{\mathbf{x}}_k = \mathbb{E}[\mathbf{x}_k | \mathbf{z}_{1:k}]x^k=E[xkz1:k]

维度_size 决定,对于不同类型:

  • Vec(3):x∈R3\mathbf{x} \in \mathbb{R}^3xR3
  • JPLQuat:q∈H\mathbf{q} \in \mathbb{H}qH(4维)
  • PoseJPL:[q,p]T∈R7[\mathbf{q}, \mathbf{p}]^T \in \mathbb{R}^7[q,p]TR7
  • IMU:[q,p,v,bg,ba]T∈R16[\mathbf{q}, \mathbf{p}, \mathbf{v}, \mathbf{b}_g, \mathbf{b}_a]^T \in \mathbb{R}^{16}[q,p,v,bg,ba]TR16

2. _fej:First Estimate Jacobian

问题背景:EKF 线性化导致的不一致性

在 EKF 中,非线性函数 f(x)f(\mathbf{x})f(x) 在点 xˉ\bar{\mathbf{x}}xˉ 处泰勒展开:

f(x)≈f(xˉ)+F∣xˉ(x−xˉ)f(\mathbf{x}) \approx f(\bar{\mathbf{x}}) + \mathbf{F}|_{\bar{\mathbf{x}}} (\mathbf{x} - \bar{\mathbf{x}})f(x)f(xˉ)+Fxˉ(xxˉ)

其中雅可比矩阵:
F=∂f∂x∣xˉ\mathbf{F} = \frac{\partial f}{\partial \mathbf{x}}\bigg|_{\bar{\mathbf{x}}}F=xfxˉ

不一致性问题:如果每次更新都在新的 x^k\hat{\mathbf{x}}_kx^k 处线性化,会导致:

零空间不一致:N(H1)≠N(H2)\text{零空间不一致:} \mathcal{N}(\mathbf{H}_1) \neq \mathcal{N}(\mathbf{H}_2)零空间不一致:N(H1)=N(H2)

FEJ 解决方案
FFEJ=∂f∂x∣x^0\boxed{\mathbf{F}_{\text{FEJ}} = \frac{\partial f}{\partial \mathbf{x}}\bigg|_{\hat{\mathbf{x}}_0}}FFEJ=xfx^0

固定在首次估计值 x^0\hat{\mathbf{x}}_0x^0 处计算雅可比,存储在 _fej 中。

数学证明(简化):

对于状态转移:
xk+1=f(xk,uk)\mathbf{x}_{k+1} = f(\mathbf{x}_k, \mathbf{u}_k)xk+1=f(xk,uk)

误差状态传播:
x~k+1=Φkx~k+wk\tilde{\mathbf{x}}_{k+1} = \mathbf{\Phi}_k \tilde{\mathbf{x}}_k + \mathbf{w}_kx~k+1=Φkx~k+wk

其中状态转移矩阵:
Φk=∂f∂x∣xˉk\mathbf{\Phi}_k = \frac{\partial f}{\partial \mathbf{x}}\bigg|_{\bar{\mathbf{x}}_k}Φk=xfxˉk

使用 FEJ
ΦkFEJ=∂f∂x∣x^fej\mathbf{\Phi}_k^{\text{FEJ}} = \frac{\partial f}{\partial \mathbf{x}}\bigg|_{\hat{\mathbf{x}}_{\text{fej}}}ΦkFEJ=xfx^fej

保证:
如果 x~0∈N(H)⇒x~k∈N(H),∀k\text{如果 } \tilde{\mathbf{x}}_0 \in \mathcal{N}(\mathbf{H}) \Rightarrow \tilde{\mathbf{x}}_k \in \mathcal{N}(\mathbf{H}), \forall k如果 x~0N(H)x~kN(H),k


3. _id:状态向量中的唯一标识

全局状态向量
xglobal=[xIMUxclone1⋮xcloneNxlandmark1⋮xlandmarkM]\mathbf{x}_{\text{global}} = \begin{bmatrix} \mathbf{x}_{\text{IMU}} \\ \mathbf{x}_{\text{clone}_1} \\ \vdots \\ \mathbf{x}_{\text{clone}_N} \\ \mathbf{x}_{\text{landmark}_1} \\ \vdots \\ \mathbf{x}_{\text{landmark}_M} \end{bmatrix}xglobal=xIMUxclone1xcloneNxlandmark1xlandmarkM

ID 映射
_id:Type→N\text{\_id} : \text{Type} \rightarrow \mathbb{N}_id:TypeN

使得:
xtype=xglobal[_id:_id+_size]\mathbf{x}_{\text{type}} = \mathbf{x}_{\text{global}}[\text{\_id} : \text{\_id} + \text{\_size}]xtype=xglobal[_id:_id+_size]

用途

  • 协方差矩阵索引:P[idi:idi+n,idj:idj+m]\mathbf{P}[\text{id}_i:\text{id}_i+n, \text{id}_j:\text{id}_j+m]P[idi:idi+n,idj:idj+m]
  • 卡尔曼增益计算:K=PHT(HPHT+R)−1\mathbf{K} = \mathbf{P}\mathbf{H}^T(\mathbf{H}\mathbf{P}\mathbf{H}^T + \mathbf{R})^{-1}K=PHT(HPHT+R)1

4. _size:状态维度

流形上的维度

类型流形嵌入维度切空间维度 (_size)
Vec(n)Rn\mathbb{R}^nRnnn
JPLQuatSO(3)SO(3)SO(3)43
PoseJPLSE(3)SE(3)SE(3)76
IMUSE(3)×R9SE(3) \times \mathbb{R}^9SE(3)×R91615

误差状态维度

对于四元数:
q←q⊗[12δθ1]\mathbf{q} \leftarrow \mathbf{q} \otimes \begin{bmatrix} \frac{1}{2}\delta\boldsymbol{\theta} \\ 1 \end{bmatrix}qq[21δθ1]

误差状态 δθ∈R3\delta\boldsymbol{\theta} \in \mathbb{R}^3δθR3,而不是 R4\mathbb{R}^4R4

协方差矩阵大小
P∈RN×N,N=∑i_sizei\mathbf{P} \in \mathbb{R}^{N \times N}, \quad N = \sum_i \text{\_size}_iPRN×N,N=i_sizei


📊 二、完整的运动学方程推导

1. IMU 运动学(连续时间)

状态定义:

xIMU=[GqIGpIGvIbgba]∈R16\mathbf{x}_{\text{IMU}} = \begin{bmatrix} ^G\mathbf{q}_I \\ ^G\mathbf{p}_I \\ ^G\mathbf{v}_I \\ \mathbf{b}_g \\ \mathbf{b}_a \end{bmatrix} \in \mathbb{R}^{16}xIMU=GqIGpIGvIbgbaR16

运动学微分方程:

(1) 姿态更新
q˙=12Ω(ω)q\dot{\mathbf{q}} = \frac{1}{2}\boldsymbol{\Omega}(\boldsymbol{\omega}) \mathbf{q}q˙=21Ω(ω)q

其中:
Ω(ω)=[−[ω]×ω−ωT0],ω=ωm−bg−ng\boldsymbol{\Omega}(\boldsymbol{\omega}) = \begin{bmatrix} -[\boldsymbol{\omega}]_\times & \boldsymbol{\omega} \\ -\boldsymbol{\omega}^T & 0 \end{bmatrix}, \quad \boldsymbol{\omega} = \boldsymbol{\omega}_m - \mathbf{b}_g - \mathbf{n}_gΩ(ω)=[[ω]×ωTω0],ω=ωmbgng

(2) 位置更新
Gp˙I=GvI^G\dot{\mathbf{p}}_I = {}^G\mathbf{v}_IGp˙I=GvI

(3) 速度更新
Gv˙I=GaI=GIR(am−ba−na)+Gg^G\dot{\mathbf{v}}_I = {}^G\mathbf{a}_I = {}^I_G\mathbf{R}(\mathbf{a}_m - \mathbf{b}_a - \mathbf{n}_a) + {}^G\mathbf{g}Gv˙I=GaI=GIR(ambana)+Gg

(4) 偏置更新(随机游走)
b˙g=nbg,b˙a=nba\dot{\mathbf{b}}_g = \mathbf{n}_{bg}, \quad \dot{\mathbf{b}}_a = \mathbf{n}_{ba}b˙g=nbg,b˙a=nba

完整形式:

q˙=12Ω(ωm−bg)qp˙=vv˙=R(am−ba)+gb˙g=nbgb˙a=nba\boxed{ \begin{aligned} \dot{\mathbf{q}} &= \frac{1}{2}\boldsymbol{\Omega}(\boldsymbol{\omega}_m - \mathbf{b}_g)\mathbf{q} \\ \dot{\mathbf{p}} &= \mathbf{v} \\ \dot{\mathbf{v}} &= \mathbf{R}(\mathbf{a}_m - \mathbf{b}_a) + \mathbf{g} \\ \dot{\mathbf{b}}_g &= \mathbf{n}_{bg} \\ \dot{\mathbf{b}}_a &= \mathbf{n}_{ba} \end{aligned} }q˙p˙v˙b˙gb˙a=21Ω(ωmbg)q=v=R(amba)+g=nbg=nba


2. 误差状态运动学

定义误差状态:
x~=[δθδpδvδbgδba]∈R15\tilde{\mathbf{x}} = \begin{bmatrix} \delta\boldsymbol{\theta} \\ \delta\mathbf{p} \\ \delta\mathbf{v} \\ \delta\mathbf{b}_g \\ \delta\mathbf{b}_a \end{bmatrix} \in \mathbb{R}^{15}x~=δθδpδvδbgδbaR15

误差状态微分方程:

x~˙=Fcx~+Gcn\boxed{ \dot{\tilde{\mathbf{x}}} = \mathbf{F}_c\tilde{\mathbf{x}} + \mathbf{G}_c\mathbf{n} }x~˙=Fcx~+Gcn

其中连续时间雅可比:

Fc=[−[ω]×00−I3000I300−R[a]×000−R0000000000]15×15\mathbf{F}_c = \begin{bmatrix} -[\boldsymbol{\omega}]_\times & \mathbf{0} & \mathbf{0} & -\mathbf{I}_3 & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{I}_3 & \mathbf{0} & \mathbf{0} \\ -\mathbf{R}[\mathbf{a}]_\times & \mathbf{0} & \mathbf{0} & \mathbf{0} & -\mathbf{R} \\ \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} \end{bmatrix}_{15\times15}Fc=[ω]×0R[a]×00000000I3000I3000000R0015×15

Gc=[−I300000000−R0000I30000I3]15×12\mathbf{G}_c = \begin{bmatrix} -\mathbf{I}_3 & \mathbf{0} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & -\mathbf{R} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{I}_3 & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{I}_3 \end{bmatrix}_{15\times12}Gc=I3000000R00000I300000I315×12

噪声向量:
n=[ngnanbgnba]∼N(0,Qc)\mathbf{n} = \begin{bmatrix} \mathbf{n}_g \\ \mathbf{n}_a \\ \mathbf{n}_{bg} \\ \mathbf{n}_{ba} \end{bmatrix} \sim \mathcal{N}(\mathbf{0}, \mathbf{Q}_c)n=ngnanbgnbaN(0,Qc)


3. 离散化(用于 EKF)

状态转移矩阵
Φk=exp⁡(FcΔt)≈I+FcΔt+12(FcΔt)2\mathbf{\Phi}_k = \exp(\mathbf{F}_c \Delta t) \approx \mathbf{I} + \mathbf{F}_c\Delta t + \frac{1}{2}(\mathbf{F}_c\Delta t)^2Φk=exp(FcΔt)I+FcΔt+21(FcΔt)2

离散噪声协方差
Qd=∫0ΔtΦ(τ)GcQcGcTΦT(τ)dτ\mathbf{Q}_d = \int_0^{\Delta t} \mathbf{\Phi}(\tau)\mathbf{G}_c\mathbf{Q}_c\mathbf{G}_c^T\mathbf{\Phi}^T(\tau)d\tauQd=0ΔtΦ(τ)GcQcGcTΦT(τ)dτ

预测步骤
x^k+1−=f(x^k,uk)Pk+1−=ΦkPkΦkT+Qd\begin{aligned} \hat{\mathbf{x}}_{k+1}^- &= f(\hat{\mathbf{x}}_k, \mathbf{u}_k) \\ \mathbf{P}_{k+1}^- &= \mathbf{\Phi}_k\mathbf{P}_k\mathbf{\Phi}_k^T + \mathbf{Q}_d \end{aligned}x^k+1Pk+1=f(x^k,uk)=ΦkPkΦkT+Qd


📷 三、观测方程推导

1. 相机投影模型

路标点 Gpf{}^G\mathbf{p}_fGpf 在相机坐标系下:

Cipf=GCiR(Gpf−GpCi){}^{C_i}\mathbf{p}_f = {}^{C_i}_G\mathbf{R}({}^G\mathbf{p}_f - {}^G\mathbf{p}_{C_i})Cipf=GCiR(GpfGpCi)

针孔相机投影
[uv]=π(Cipf)=[fxXZ+cxfyYZ+cy]\begin{bmatrix} u \\ v \end{bmatrix} = \pi({}^{C_i}\mathbf{p}_f) = \begin{bmatrix} f_x \frac{X}{Z} + c_x \\ f_y \frac{Y}{Z} + c_y \end{bmatrix}[uv]=π(Cipf)=[fxZX+cxfyZY+cy]

其中 Cipf=[X,Y,Z]T{}^{C_i}\mathbf{p}_f = [X, Y, Z]^TCipf=[X,Y,Z]T


2. 观测方程

zk=h(xk)+vk\mathbf{z}_k = h(\mathbf{x}_k) + \mathbf{v}_kzk=h(xk)+vk

其中:

  • zk\mathbf{z}_kzk:图像特征点坐标 [u,v]T[u, v]^T[u,v]T
  • h(⋅)h(\cdot)h():投影函数
  • vk∼N(0,R)\mathbf{v}_k \sim \mathcal{N}(\mathbf{0}, \mathbf{R})vkN(0,R):观测噪声

完整形式
z=π(ICR⋅GIR(Gpf−GpI)−CpI)\boxed{ \mathbf{z} = \pi\left({}^{C}_I\mathbf{R} \cdot {}^I_G\mathbf{R}({}^G\mathbf{p}_f - {}^G\mathbf{p}_I) - {}^{C}\mathbf{p}_I\right) }z=π(ICRGIR(GpfGpI)CpI)


3. 观测雅可比矩阵

对状态求偏导:
H=∂h∂x∣x^\mathbf{H} = \frac{\partial h}{\partial \mathbf{x}}\bigg|_{\hat{\mathbf{x}}}H=xhx^

分解
H=∂π∂Cp⏟Jπ⋅∂Cp∂x⏟Jtrans\mathbf{H} = \underbrace{\frac{\partial \pi}{\partial {}^C\mathbf{p}}}_{\mathbf{J}_\pi} \cdot \underbrace{\frac{\partial {}^C\mathbf{p}}{\partial \mathbf{x}}}_{\mathbf{J}_{\text{trans}}}H=JπCpπJtransxCp

(1) 投影雅可比
Jπ=[fxZ0−fxXZ20fyZ−fyYZ2]2×3\mathbf{J}_\pi = \begin{bmatrix} \frac{f_x}{Z} & 0 & -\frac{f_x X}{Z^2} \\ 0 & \frac{f_y}{Z} & -\frac{f_y Y}{Z^2} \end{bmatrix}_{2\times3}Jπ=[Zfx00ZfyZ2fxXZ2fyY]2×3

(2) 对姿态的雅可比
∂Cp∂δθ=−GCR[Gpf−GpI]×\frac{\partial {}^C\mathbf{p}}{\partial \delta\boldsymbol{\theta}} = -{}^C_G\mathbf{R}[{}^G\mathbf{p}_f - {}^G\mathbf{p}_I]_\timesδθCp=GCR[GpfGpI]×

(3) 对位置的雅可比
∂Cp∂GpI=−GCR\frac{\partial {}^C\mathbf{p}}{\partial {}^G\mathbf{p}_I} = -{}^C_G\mathbf{R}GpICp=GCR

(4) 对路标的雅可比
∂Cp∂Gpf=GCR\frac{\partial {}^C\mathbf{p}}{\partial {}^G\mathbf{p}_f} = {}^C_G\mathbf{R}GpfCp=GCR

完整观测矩阵
H=Jπ[HθHp000Hf]\mathbf{H} = \mathbf{J}_\pi \begin{bmatrix} \mathbf{H}_\theta & \mathbf{H}_p & \mathbf{0} & \mathbf{0} & \mathbf{0} & \mathbf{H}_f \end{bmatrix}H=Jπ[HθHp000Hf]


🔧 四、FEJ 使用推导

1. 不一致性问题分析

可观测性理论

系统的零空间(不可观测子空间):
N(H)={x~:Hx~=0}\mathcal{N}(\mathbf{H}) = \{\tilde{\mathbf{x}} : \mathbf{H}\tilde{\mathbf{x}} = \mathbf{0}\}N(H)={x~:Hx~=0}

对于 VIO 系统,理论上不可观测量:

  • 全局位置(3 DOF)
  • 全局偏航角(1 DOF)

问题:标准 EKF 线性化会导致:
dim⁡(N(HEKF))<dim⁡(N(Htrue))\dim(\mathcal{N}(\mathbf{H}_{\text{EKF}})) < \dim(\mathcal{N}(\mathbf{H}_{\text{true}}))dim(N(HEKF))<dim(N(Htrue))

即错误地观测到本不可观测的量,导致过度自信


2. FEJ 数学证明

定理:如果使用 FEJ,则:
N(HFEJ)=N(Hlinearized)\mathcal{N}(\mathbf{H}_{\text{FEJ}}) = \mathcal{N}(\mathbf{H}_{\text{linearized}})N(HFEJ)=N(Hlinearized)

证明(简化版):

考虑全局平移 δpglobal\delta\mathbf{p}_{\text{global}}δpglobal

标准 EKF:
Hk=∂h∂x∣x^k\mathbf{H}_k = \frac{\partial h}{\partial \mathbf{x}}\bigg|_{\hat{\mathbf{x}}_k}Hk=xhx^k

在不同时刻,线性化点不同 → 零空间不一致

FEJ:
HkFEJ=∂h∂x∣x^0\mathbf{H}_k^{\text{FEJ}} = \frac{\partial h}{\partial \mathbf{x}}\bigg|_{\hat{\mathbf{x}}_0}HkFEJ=xhx^0

固定线性化点 → 保持零空间一致性


3. FEJ 使用时机

场景是否使用 FEJ原因
状态预测 Φ\mathbf{\Phi}Φ✅ 使用保持传播一致性
观测更新 H\mathbf{H}H✅ 使用保持可观测性
首次初始化❌ 不用_fej = _value
路标三角化✅ 使用固定锚点位姿
边缘化✅ 使用保持先验一致性

代码中的体现

// Propagation with FEJ
Eigen::Matrix<double,3,3> R_fej = imu_Rot_fej(imu);  // Use FEJ value
Phi = compute_Phi(R_fej, ...);  // Compute state transition

// Update with FEJ
Eigen::Matrix<double,3,1> p_fej = imu_pos_fej(imu);
H = compute_H(p_fej, ...);  // Compute measurement Jacobian

4. FEJ 更新策略

初始化

void imu_init(type_imu* imu) {
    // _fej = _value at initialization
    type_set_fej(imu->base, &initial_value);
}

更新策略

策略何时更新 _fej优缺点
Never Update永不更新✅ 完美一致性
❌ 大偏差时精度下降
Update on Init仅初始化时⚖️ 平衡方案(常用)
Periodic Update周期性更新⚖️ 适应大运动
⚠️ 需谨慎

推荐方案(本代码采用):

// FEJ is set once at initialization or anchor change
if (is_new_landmark || anchor_changed) {
    landmark_set_fej(landmark, &current_estimate);
}
// Thereafter, _fej remains fixed for Jacobian computation

📈 五、完整 EKF 流程

预测步骤

x^k−=f(x^k−1+,uk)Pk−=ΦkFEJPk−1+(ΦkFEJ)T+Qk\begin{aligned} \hat{\mathbf{x}}_k^- &= f(\hat{\mathbf{x}}_{k-1}^+, \mathbf{u}_k) \\ \mathbf{P}_k^- &= \mathbf{\Phi}_k^{\text{FEJ}}\mathbf{P}_{k-1}^+(\mathbf{\Phi}_k^{\text{FEJ}})^T + \mathbf{Q}_k \end{aligned}x^kPk=f(x^k1+,uk)=ΦkFEJPk1+(ΦkFEJ)T+Qk

更新步骤

Sk=HkFEJPk−(HkFEJ)T+RkKk=Pk−(HkFEJ)TSk−1x~k=Kk(zk−h(x^k−))x^k+=x^k−⊞x~kPk+=(I−KkHkFEJ)Pk−\begin{aligned} \mathbf{S}_k &= \mathbf{H}_k^{\text{FEJ}}\mathbf{P}_k^-(\mathbf{H}_k^{\text{FEJ}})^T + \mathbf{R}_k \\ \mathbf{K}_k &= \mathbf{P}_k^-(\mathbf{H}_k^{\text{FEJ}})^T\mathbf{S}_k^{-1} \\ \tilde{\mathbf{x}}_k &= \mathbf{K}_k(\mathbf{z}_k - h(\hat{\mathbf{x}}_k^-)) \\ \hat{\mathbf{x}}_k^+ &= \hat{\mathbf{x}}_k^- \boxplus \tilde{\mathbf{x}}_k \\ \mathbf{P}_k^+ &= (\mathbf{I} - \mathbf{K}_k\mathbf{H}_k^{\text{FEJ}})\mathbf{P}_k^- \end{aligned}SkKkx~kx^k+Pk+=HkFEJPk(HkFEJ)T+Rk=Pk(HkFEJ)TSk1=Kk(zkh(x^k))=x^kx~k=(IKkHkFEJ)Pk

注意:所有雅可比 Φ\mathbf{\Phi}ΦH\mathbf{H}H 都在 _fej 值处计算,而状态更新使用 _value


🎯 总结

  1. _value:当前最优估计,持续更新
  2. _fej:固定的线性化点,保证一致性
  3. _id:全局状态向量索引
  4. _size:误差状态流形维度

关键洞察:FEJ 通过牺牲少量精度(固定线性化点)来换取系统的长期一致性,避免滤波器过度自信和发散。

基础结构体的物理含义和关系:

2. 📊 类型系统架构图

type_base (基类)
    │
    ├─→ type_vec (向量)
    │       │
    │       └─→ 被以下类型使用:
    │           ├─ type_pose_jpl._p (位置)
    │           ├─ type_imu._v (速度)
    │           ├─ type_imu._bg (陀螺仪偏置)
    │           ├─ type_imu._ba (加速度计偏置)
    │           └─ type_landmark._v (路标坐标)
    │
    ├─→ type_jpl_quat (四元数)
    │       │
    │       └─→ 被以下类型使用:
    │           └─ type_pose_jpl._q (姿态)
    │
    ├─→ type_pose_jpl (位姿 = 姿态 + 位置)
    │       │
    │       └─→ 被以下类型使用:
    │           └─ type_imu._pose (IMU位姿)
    │
    ├─→ type_imu (IMU状态)
    │
    └─→ type_landmark (路标点)

1️⃣ type_base - 基础类型

typedef struct type_base_s {
    Eigen::MatrixXd _fej;
    Eigen::MatrixXd _value;
    int _id;
    int _size;
} type_base;

物理含义:所有类型的基类,提供状态管理的通用框架

成员含义

  • _value: 当前状态估计值
  • _fej: First Estimate Jacobian,用于保持 EKF 一致性的固定雅可比值
  • _id: 在状态向量中的唯一标识符
  • _size: 状态维度大小

2️⃣ type_vec - 向量类型

typedef struct type_vec_s {
    type_base* base;
} type_vec;

物理含义:通用 N 维向量,用于表示各种线性量

应用场景

  • 3D 位置 (x, y, z)
  • 3D 速度 (vx, vy, vz)
  • 3D 偏置 (bx, by, bz)
  • 路标点坐标

特点:维度可变,初始化时指定


3️⃣ type_jpl_quat - JPL 四元数

typedef struct type_jpl_quat_s {
    type_base* base;
    Eigen::Matrix<double, 3, 3> _R;
    Eigen::Matrix<double, 3, 3> _Rfej;
} type_jpl_quat;

物理含义:表示 3D 旋转的四元数(JPL 约定)

成员含义

  • base->_value: 4×1 四元数 [qx, qy, qz, qw]
  • _R: 当前旋转矩阵(由四元数转换得到)
  • _Rfej: FEJ 版本的旋转矩阵

JPL vs Hamilton

  • JPL:quat = [qx, qy, qz, qw],向量在前,标量在后
  • Hamilton:quat = [qw, qx, qy, qz],标量在前

维度:4 维(但旋转自由度为 3)


4️⃣ type_pose_jpl - JPL 位姿

typedef struct type_pose_jpl_s {
    type_base* base;
    type_jpl_quat* _q;
    type_vec* _p;
}  type_pose_jpl;

物理含义:SE(3) 群上的刚体位姿 = 姿态 + 位置

成员含义

  • _q: 姿态(旋转),4 维四元数
  • _p: 位置(平移),3 维向量

物理意义

变换:P_world = R * P_local + t
其中:
  R = 旋转矩阵(由 _q 计算)
  t = 位置向量 (_p)

总维度:7 维(4 + 3)


5️⃣ type_imu - IMU 状态

typedef struct type_imu_s {
    type_base* base;
    type_pose_jpl* _pose;
    type_vec* _v;
    type_vec* _bg;
    type_vec* _ba;
} type_imu;

物理含义:IMU 的完整运动状态 + 传感器偏置

组成成分:

成员物理量维度单位说明
_pose位姿7-IMU 在世界坐标系中的姿态和位置
_pose->_q姿态4-旋转四元数
_pose->_p位置3m3D 坐标
_v速度3m/s线速度
_bg陀螺仪偏置3rad/s角速度测量偏差
_ba加速度计偏置3m/s²线加速度测量偏差

总维度:16 维(但四元数约束后实际 15 自由度)

运动学关系:

IMU 传播方程(连续时间):
┌─────────────────────────────────────┐
│ dR/dt = R * [ω_m - bg]×            │  (姿态)
│ dp/dt = v                          │  (位置)
│ dv/dt = R*(a_m - ba) + g           │  (速度)
│ dbg/dt = ng  (白噪声)              │  (陀螺仪偏置)
│ dba/dt = na  (白噪声)              │  (加速度计偏置)
└─────────────────────────────────────┘

其中:
  ω_m = 陀螺仪测量值
  a_m = 加速度计测量值
  g = 重力加速度
  [·]× = 反对称矩阵

6️⃣ type_landmark - 路标点

typedef struct type_landmark_s {
  type_base* base;
  type_vec* _v;
  size_t _featid;
  int _unique_camera_id;

  int _anchor_cam_id;

  double _anchor_clone_timestamp;

  bool has_had_anchor_change;

  /// Boolean if this landmark should be marginalized out
  bool should_marg;

  int update_fail_count;

  Eigen::Vector3d uv_norm_zero;
  /// First estimate normalized uv coordinate bearing of this measurement (used for single depth representation)
  Eigen::Vector3d uv_norm_zero_fej;
  type_landmark_representation feat_representation;

} type_landmark;

物理含义:环境中的 3D 特征点(路标)

关键成员:

成员含义说明
_v路标坐标根据表示方式不同,可以是 3D 坐标或逆深度
_featid特征 ID唯一标识符
_anchor_cam_id锚点相机 ID第一次观测到该特征的相机
_anchor_clone_timestamp锚点时间戳首次观测时刻
feat_representation表示方式见下表
uv_norm_zero归一化图像坐标首次观测的方向向量

路标表示方式 (feat_representation):

typedef enum {
    GLOBAL_3D,
    GLOBAL_FULL_INVERSE_DEPTH,
    ANCHORED_3D,
    ANCHORED_FULL_INVERSE_DEPTH,
    ANCHORED_MSCKF_INVERSE_DEPTH,
    ANCHORED_INVERSE_DEPTH_SINGLE,
    UNKNOWN
} type_landmark_representation;
表示方式维度参数化说明
GLOBAL_3D3[x, y, z]全局 3D 坐标
GLOBAL_FULL_INVERSE_DEPTH6[x, y, z, θ, φ, ρ]全局逆深度(5+1)
ANCHORED_3D3[dx, dy, dz]相对锚点的 3D 坐标
ANCHORED_FULL_INVERSE_DEPTH3[θ, φ, ρ]相对锚点的逆深度
ANCHORED_MSCKF_INVERSE_DEPTH1[ρ]MSCKF 风格单参数逆深度
ANCHORED_INVERSE_DEPTH_SINGLE1[ρ]简化的单参数逆深度

7️⃣ type_wrapper - 类型包装器

struct type_wrapper {
    type_base* base;
    void* specific_data;  // Points to specific type_imu, type_pose_jpl, etc.
    int type_id;          // Identifies specific type
    bool is_c_version;    // Identifies if it's C version
};

功能含义:统一接口包装器,用于多态处理

Type ID 枚举

enum TypeID {
    TYPE_BASE = 0,
    TYPE_VEC = 1,
    TYPE_JPL_QUAT = 2,
    TYPE_POSE_JPL = 3,
    TYPE_IMU = 4,
    TYPE_LANDMARK = 5
};

🔗 与 type_imu 的关系总结

type_imu (15 DOF)
    │
    ├─→ _pose (type_pose_jpl) - 7 维
    │       │
    │       ├─→ _q (type_jpl_quat) - 4 维
    │       │   └─→ base (type_base) - 存储四元数值
    │       │
    │       └─→ _p (type_vec) - 3 维
    │           └─→ base (type_base) - 存储位置
    │
    ├─→ _v (type_vec) - 3 维
    │   └─→ base (type_base) - 存储速度
    │
    ├─→ _bg (type_vec) - 3 维
    │   └─→ base (type_base) - 存储陀螺仪偏置
    │
    └─→ _ba (type_vec) - 3 维
        └─→ base (type_base) - 存储加速度计偏置

📐 物理关系与数学模型

VIO/SLAM 系统中的协作关系:

┌─────────────────────────────────────────────────────┐
│                    SLAM 状态向量                     │
├─────────────────────────────────────────────────────┤
│                                                     │
│  [IMU 状态]   [路标状态]   [相机克隆状态]            │
│  type_imu     type_landmark  type_pose_jpl[]       │
│     │              │               │                │
│     │              │               │                │
│     ▼              ▼               ▼                │
│  ┌─────┐      ┌────────┐      ┌──────┐             │
│  │R,p,v│◄────►│ 3D点   │◄────►│相机位姿│             │
│  │bg,ba│      │        │      │      │             │
│  └─────┘      └────────┘      └──────┘             │
│                                                     │
│  通过 EKF/ESKF 融合:                               │
│  - IMU 预测(高频)                                  │
│  - 视觉更新(低频)                                  │
│  - 路标三角化                                        │
└─────────────────────────────────────────────────────┘

测量模型:

  1. IMU 测量

    ω_m = ω_true + bg + nω
    a_m = R^T(a_true - g) + ba + na
    
  2. 视觉测量(重投影):

    z = h(x_imu, x_landmark)
      = π(R^T * (p_landmark - p_imu))
    
    其中 π 是相机投影函数
    

🎯 设计要点

  1. 分层设计:基于 type_base 的继承体系(用 C 结构体模拟)
  2. FEJ 支持:每个状态都有 FEJ 版本,保证 EKF 一致性
  3. 模块化:各类型独立,便于扩展
  4. 纯 C 风格:使用结构体指针和函数指针模拟面向对象

这个类型系统完整实现了 VIO/SLAM 所需的所有状态表示,支持高效的状态估计和优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大江东去浪淘尽千古风流人物

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值