Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Galilean IMU preintegration with a left-invariant error

This guide follows the construction in Left-Invariant Galilean IMU Preintegration in Inertial and Rotating Frames: a direct-product preintegration state, exact zero-order-held Galilean increments, standard left-invariant error, adjoint covariance transport, right-applied bias correction, and exact constant-rate rotating-frame prediction.

The method retains the exact held-input Galilean composition introduced by Delama et al., but replaces their augmented tangent-semidirect-product model with Gal(3)×R6\mathrm{Gal}(3)\times\mathbb R^6 and the physical accelerometer and gyroscope biases. The Wϕ(X)UW\phi(X)U endpoint relation and constant-rate rotating-frame structure follow Barrau--Bonnabel and Brossard et al.; the direct-product bias model, left-invariant covariance, and right-applied correction are the construction developed in the companion paper.

For background, see the Gal3 guide, the Gal3ImuEKF guide, the NavState guide, and the standard ImuFactor guide. The companion NEES comparison evaluates all four GTSAM preintegration backends under identical high-dynamic IMU samples.

Open In Colab

1. Conventions: left-invariant error means an update on the right

We fix the convention before introducing the dynamics. For a matrix Lie group GG with Lie algebra g\mathfrak g, GTSAM uses

OperationDefinitionConsequence
RetractionX⊕δ=XExp⁡(δ)X\oplus\delta = X\operatorname{Exp}(\delta)A tangent increment is applied on the right.
Local coordinatesLocal⁡(X,Y)=Log⁡(X−1Y)\operatorname{Local}(X,Y)=\operatorname{Log}(X^{-1}Y)The displacement is expressed in the local frame of XX.
Error about X^\hat XX=X^Exp⁡(ϵ)X=\hat X\operatorname{Exp}(\epsilon)ϵ=Local⁡(X^,X)\epsilon=\operatorname{Local}(\hat X,X).

The group error X^−1X\hat X^{-1}X is left-invariant: replacing both arguments by AXAX and AX^A\hat X leaves it unchanged. Thus, throughout this guide, left-invariant error and right perturbation describe the same convention.

Delama et al.'s related construction instead uses the navigation error ΥΥ^−1\Upsilon\hat\Upsilon^{-1}, which is right-invariant, together with a left-applied first-order correction. Here we use the direct-product state and the left-invariant error Υ^−1Υ\hat\Upsilon^{-1}\Upsilon, with right perturbations throughout.

2. Physical state

The preintegration state consists of the accumulated Galilean motion and the physical six-axis IMU bias:

M=Gal(3)×R6,ξk=(Υk,βk),βk=[ba,kbω,k].\mathcal M=\mathrm{Gal}(3)\times\mathbb R^6,\qquad \xi_k=(\Upsilon_k,\beta_k),\qquad \beta_k=\begin{bmatrix}b_{a,k}\\b_{\omega,k}\end{bmatrix}.

Here Υk=(ΔRk,Δvk,Δpk,Δtk)\Upsilon_k=(\Delta R_k,\Delta v_k,\Delta p_k,\Delta t_k) is the motion being preintegrated. The second component is exactly gtsam::imuBias::ConstantBias; its vector representation stores accelerometer bias before gyroscope bias. There are no additional bias coordinates. Bias perturbations and bias-Jacobian columns retain this ordering throughout.

3. The Galilean motion component

A Galilean element stores rotation, velocity, position, and elapsed time:

X=(R,v,p,t)⟷X=[Rvp01t001].X=(R,v,p,t) \quad\longleftrightarrow\quad \mathbf X= \begin{bmatrix} R & v & p\\ 0 & 1 & t\\ 0 & 0 & 1 \end{bmatrix}.

Matrix multiplication gives

(R1,v1,p1,t1)(R2,v2,p2,t2)=(R1R2,  v1+R1v2,  p1+R1p2+t2v1,  t1+t2).(R_1,v_1,p_1,t_1)(R_2,v_2,p_2,t_2) =\left(R_1R_2,\;v_1+R_1v_2,\;p_1+R_1p_2+t_2v_1,\;t_1+t_2\right).

The term t2v1t_2v_1 is the defining Galilean coupling: during the second interval, the velocity accumulated by the first interval advances position. The inverse is

(R,v,p,t)−1=(R⊤,−R⊤v,−R⊤(p−tv),−t).(R,v,p,t)^{-1}=\left(R^\top,-R^\top v,-R^\top(p-tv),-t\right).

Using GTSAM’s tangent ordering, an algebra element is

x=(ω,ν,ρ,α)∈R10,x∧=[ω∧νρ00α000].x=(\omega,\nu,\rho,\alpha)\in\mathbb R^{10}, \qquad x^\wedge= \begin{bmatrix} \omega^\wedge & \nu & \rho\\ 0 & 0 & \alpha\\ 0 & 0 & 0 \end{bmatrix}.

For an integrated IMU increment, ω\omega is an angle, ν\nu a velocity increment, ρ\rho a position increment, and α\alpha an elapsed time. Before multiplication by Δt\Delta t, the corresponding rate vector has units (rad/s,m/s2,m/s,1)({\rm rad/s}, {\rm m/s^2}, {\rm m/s}, 1).

Exponential, Jacobians, and adjoint

Let JL(ω)J_L(\omega) be the SO(3)SO(3) left Jacobian and Γ2(ω)\Gamma_2(\omega) its second integral. Then

Exp⁡(x)=(Exp⁡(ω),JL(ω)ν,JL(ω)ρ+αΓ2(ω)ν,α).\operatorname{Exp}(x)= \left( \operatorname{Exp}(\omega), J_L(\omega)\nu, J_L(\omega)\rho+\alpha\Gamma_2(\omega)\nu, \alpha \right).

The αΓ2(ω)ν\alpha\Gamma_2(\omega)\nu term produces the familiar 12aΔt2\tfrac12a\Delta t^2 when rotation is zero. For the complete 10D algebra, define the right Jacobian JR(x)J_R(x) by

Exp⁡(x+δx)=Exp⁡(x)Exp⁡(JR(x)δx)+O(∥δx∥2).\operatorname{Exp}(x+\delta x) =\operatorname{Exp}(x) \operatorname{Exp}(J_R(x)\delta x)+O(\|\delta x\|^2).

This is the Jacobian required when both the state perturbation and the increment are applied on the right. It is related to the complete Galilean left Jacobian by

JR(x)=Ad⁡Exp⁡(−x)JL(x).J_R(x)=\operatorname{Ad}_{\operatorname{Exp}(-x)}J_L(x).

For X=(R,v,p,t)X=(R,v,p,t), the adjoint in the ordering (ω,ν,ρ,α)(\omega,\nu,\rho,\alpha) is

Ad⁡X=[R000v∧RR00(p−tv)∧R−tRRv0001].\operatorname{Ad}_X= \begin{bmatrix} R & 0 & 0 & 0\\ v^\wedge R & R & 0 & 0\\ (p-tv)^\wedge R & -tR & R & v\\ 0 & 0 & 0 & 1 \end{bmatrix}.

We write ad⁡xy=[x,y]\operatorname{ad}_x y=[x,y] for the algebra adjoint and use the identities Ad⁡X−1=Ad⁡X−1\operatorname{Ad}_{X^{-1}}=\operatorname{Ad}_X^{-1} and ad⁡xy=−ad⁡yx\operatorname{ad}_x y=-\operatorname{ad}_y x.

4. Mean preintegration

The measured input is the physical six-axis IMU sample supplied to GTSAM’s integrateMeasurement(measuredAcc, measuredOmega, deltaT) interface:

uk=[akωk]∈L=R6.u_k=\begin{bmatrix}a_k\\\omega_k\end{bmatrix} \in\mathcal L=\mathbb R^6.

It follows the same accelerometer-then-gyroscope ordering as the bias. Holding this sample constant over an interval of duration hh, its bias-corrected Galilean body rate is

q(uk,βk)=[ωk−bω,kak−ba,k031].q(u_k,\beta_k)=\begin{bmatrix} \omega_k-b_{\omega,k}\\ a_k-b_{a,k}\\ 0_3\\ 1 \end{bmatrix}.

The exact discrete dynamics for this held input are

Fh((Υk,βk),uk)=(ΥkExp⁡(q(uk,βk)h),  βk).F_h((\Upsilon_k,\beta_k),u_k)= \left(\Upsilon_k\operatorname{Exp}(q(u_k,\beta_k)h),\;\beta_k\right).

The bias is constant inside preintegration because the three-way IMU factor uses a separate factor for bias evolution. No bias-process input is part of L\mathcal L. For a measured sample u~k=(a~k,ω~k)\tilde u_k=(\tilde a_k,\tilde\omega_k) and linearization bias β^k\hat\beta_k, let

qk=q(u~k,β^k),xk=qkh,Vk=Exp⁡(xk).q_k=q(\tilde u_k,\hat\beta_k),\qquad x_k=q_kh,\qquad V_k=\operatorname{Exp}(x_k).

Starting with Υ^ii=I\hat\Upsilon_{ii}=I, the preintegrated mean is updated on the right:

Υ^i,k+1=Υ^ikVk.\boxed{\hat\Upsilon_{i,k+1}=\hat\Upsilon_{ik}V_k}.

The group law automatically performs all four component updates. In particular, old velocity advances position by h Δvikh\,\Delta v_{ik}, while the exponential contributes the rotation-aware acceleration integral. No separate Euler position update is needed.

Gal(3) is internal to preintegration; the optimized keyframe states remain Xi,Xj∈SE2(3)X_i,X_j\in\mathrm{SE}_2(3). NavState stores and retracts it as (R,p,v)(R,p,v), and we define

Wij=NavState⁡ ⁣(I,12gΔtij2,gΔtij),ϕΔt(R,p,v)=(R,p+vΔt,v),W_{ij}=\operatorname{NavState}\!\left(I,\tfrac12g\Delta t_{ij}^2,g\Delta t_{ij}\right),\qquad \phi_{\Delta t}(R,p,v)=(R,p+v\Delta t,v),

and project the corrected Υij\Upsilon_{ij} to the body-frame increment

Uij(βi)=NavState⁡(ΔRij,Δpij,Δvij).U_{ij}(\beta_i)=\operatorname{NavState}(\Delta R_{ij},\Delta p_{ij},\Delta v_{ij}).

The inertial endpoint prediction is exactly

Xj=Wij ϕΔtij(Xi) Uij(βi).\boxed{X_j=W_{ij}\,\phi_{\Delta t_{ij}}(X_i)\,U_{ij}(\beta_i)}.

This Wϕ(X)UW\phi(X)U separation is important: gravity acts in the navigation frame on the left, autonomous coasting advances the existing position, and bias-corrected IMU motion acts in the body/local frame on the right.

5. Direct-product state and propagation

The preintegration state is the direct-product Lie group G=Gal(3)×(R6,+)\mathcal G=\mathrm{Gal}(3)\times(\mathbb R^6,+). Its coordinates ξ=(Υ,β)\xi=(\Upsilon,\beta) contain the Galilean state and the six physical IMU biases. Multiplication and inversion are

(Υ1,β1)(Υ2,β2)=(Υ1Υ2,β1+β2),(Υ,β)−1=(Υ−1,−β).(\Upsilon_1,\beta_1)(\Upsilon_2,\beta_2) =(\Upsilon_1\Upsilon_2,\beta_1+\beta_2),\qquad (\Upsilon,\beta)^{-1}=(\Upsilon^{-1},-\beta).

For an input held constant during a sample of duration hh, propagate the Galilean component by its body-coordinate increment and hold the bias fixed:

ξ+=(ΥExp⁡(q(u,β)h),  β).\boxed{\xi^+=\left(\Upsilon\operatorname{Exp}(q(u,\beta)h),\;\beta\right).}

The bias-corrected nominal input is u∘=u~−β^u^\circ=\tilde u-\hat\beta, and we write q∘=q(u~,β^)q^\circ=q(\tilde u,\hat\beta). The derivative of qq with respect to the corrected physical input maps GTSAM’s (a,ω)(a,\omega) order into Gal3’s (ω,ν,ρ,α)(\omega,\nu,\rho,\alpha) coordinates:

E=∂q∂(u−β)=[0I3I300000]∈R10×6.E=\frac{\partial q}{\partial(u-\beta)} =\begin{bmatrix} 0&I_3\\ I_3&0\\ 0&0\\ 0&0 \end{bmatrix} \in\mathbb R^{10\times6}.

The fixed zero position-rate and unit clock-rate coordinates have zero derivative. This matrix supplies the six physical bias and noise columns used in the error linearization below.

Delama et al.'s related model augments the bias to the full Galilean algebra and uses a tangent-semidirect-product construction. Here the direct product closes the propagation and error calculation on the physical six-dimensional bias space.

6. Left-invariant error and discrete dynamics

The direct-product error is the estimated state inverse multiplied by the true state:

ek=ξ^k−1ξk=(Υ^k−1Υk,  βk−β^k).\boxed{\mathsf e_k=\hat\xi_k^{-1}\xi_k =\left(\hat\Upsilon_k^{-1}\Upsilon_k,\;\beta_k-\hat\beta_k\right).}

It is left-invariant because (Zξ^)−1(Zξ)=ξ^−1ξ(Z\hat\xi)^{-1}(Z\xi)=\hat\xi^{-1}\xi. Its local coordinates are

ϵk=(ek,δβk)∈R16,ek=Log⁡(Υ^k−1Υk),δβk=βk−β^k.\epsilon_k=(e_k,\delta\beta_k)\in\mathbb R^{16},\qquad e_k=\operatorname{Log}(\hat\Upsilon_k^{-1}\Upsilon_k),\qquad \delta\beta_k=\beta_k-\hat\beta_k.

The navigation component is GTSAM’s right-retracted local coordinate. Linearizing the physical propagation in these coordinates gives the transition and noise matrices below.

Exact discrete linearization

Adopt the six-dimensional measurement convention

u~k=uk+ηk,ηk=(ηa,k,ηω,k)∈R6.\tilde u_k=u_k+\eta_k,\qquad \eta_k=(\eta_{a,k},\eta_{\omega,k})\in\mathbb R^6.

The true bias is constant during this preintegration step. For one nominal increment define

x=q(u~,β^)h,V=Exp⁡(x),C=JR(x)hE∈R10×6.x=q(\tilde u,\hat\beta)h,\qquad V=\operatorname{Exp}(x),\qquad C=J_R(x)hE\in\mathbb R^{10\times6}.

The true corrected physical input is u~−β^−δβ−η\tilde u-\hat\beta-\delta\beta-\eta. By the definition of the complete Galilean right Jacobian, its increment satisfies

Vtrue=Exp⁡(q(u~−η,β^+δβ)h)≃VExp⁡(−C(δβ+η)).V_{\mathrm{true}} =\operatorname{Exp}\left(q(\tilde u-\eta,\hat\beta+\delta\beta)h\right) \simeq V\operatorname{Exp}(-C(\delta\beta+\eta)).

Write E=Υ^−1Υ=Exp⁡(e)\mathcal E=\hat\Upsilon^{-1}\Upsilon=\operatorname{Exp}(e). After one mean update,

E+=V−1EVtrue.\mathcal E^+=V^{-1}\mathcal E V_{\mathrm{true}}.

Transporting the old right perturbation through VV and retaining first-order terms gives

e+=Ad⁡V−1e−Cδβ−Cη,δβ+=δβ.e^+=\operatorname{Ad}_{V^{-1}}e-C\delta\beta-C\eta,\qquad \delta\beta^+=\delta\beta.

Therefore, with ϵ=(e,δβ)∈R16\epsilon=(e,\delta\beta)\in\mathbb R^{16},

ϵ+=ALIϵ+BLIη,\boxed{\epsilon^+=A_{\mathrm{LI}}\epsilon+B_{\mathrm{LI}}\eta},

where

ALI=[Ad⁡V−1−C06×10I6]∈R16×16,BLI=[−C06×6]∈R16×6.\boxed{ A_{\mathrm{LI}}= \begin{bmatrix} \operatorname{Ad}_{V^{-1}}&-C\\ 0_{6\times10}&I_6 \end{bmatrix} \in\mathbb R^{16\times16},\qquad B_{\mathrm{LI}}= \begin{bmatrix} -C\\ 0_{6\times6} \end{bmatrix} \in\mathbb R^{16\times6}.}

The upper-left block is not generally the identity: Ad⁡V−1\operatorname{Ad}_{V^{-1}} transports a body/local error through the next increment. The upper-right block maps the physical GTSAM-ordered bias error directly into Gal3 coordinates through CC; no virtual bias columns are introduced.

For an input held constant during the sample, the corresponding continuous-time error matrix is

Ac=[−ad⁡q∘−E00],Exp⁡(Ach)=ALI.A_c=\begin{bmatrix}-\operatorname{ad}_{q^\circ}&-E\\0&0\end{bmatrix}, \qquad \operatorname{Exp}(A_c h)=A_{\mathrm{LI}}.

The −ad⁡q∘-\operatorname{ad}_{q^\circ} block describes transport of the body-coordinate error; the −E-E block describes the effect of bias error on the corrected input.

Covariance propagation

Let Σk∈R16×16\Sigma_k\in\mathbb R^{16\times16} be the covariance of (e,δβ)(e,\delta\beta). In GTSAM order, the continuous-time IMU noise density is

Qu=diag⁡(Qa,Qω)∈R6×6,Qd=1hQu,Q_u=\operatorname{diag}(Q_a,Q_\omega)\in\mathbb R^{6\times6}, \qquad Q_d=\frac{1}{h}Q_u,

where QdQ_d is the covariance of the sampled rate noise. The first-order augmented propagation is

Σk+1=ALIΣkALI⊤+BLIQdBLI⊤.\boxed{ \Sigma_{k+1}=A_{\mathrm{LI}}\Sigma_kA_{\mathrm{LI}}^\top +B_{\mathrm{LI}}Q_dB_{\mathrm{LI}}^\top}.

Only physical accelerometer and gyroscope noise enters this model. If a caller already supplies per-sample rather than continuous-time covariances, the 1/h1/h conversion must not be applied a second time.

The three-way IMU factor does not itself constrain temporal bias evolution. It uses the navigation uncertainty conditioned on the bias linearization value, while a separate bias between-factor supplies the chosen random-walk model. Therefore initialize δβ=0\delta\beta=0 and propagate the conditional 10×1010\times10 navigation covariance directly:

Σe,k+1=Ad⁡Vk−1Σe,kAd⁡Vk−1⊤+CkQuhCk⊤.\boxed{ \Sigma_{e,k+1}=\operatorname{Ad}_{V_k^{-1}}\Sigma_{e,k}\operatorname{Ad}_{V_k^{-1}}^\top +C_k\frac{Q_u}{h}C_k^\top}.

The deterministic 10×610\times6 bias sensitivity derived next accounts for changing the optimizer’s bias away from its linearization value; it is not part of this conditional covariance. A combined-bias factor could extend the input with a physical six-dimensional bias random walk and retain the full augmented covariance, without introducing virtual coordinates.

The augmented covariance above belongs to the standard left-invariant error of the direct-product group used in GTSAM. It must not be identified directly with Delama et al.'s semidirect-product covariance, whose navigation and bias components use different frames and coordinates. For the conditioned navigation covariance consumed by the ordinary factor, the descriptions agree after the corresponding frame conversion.

7. Bias correction must also act on the right

Preintegration is performed once at a linearization bias β^=(b^a,b^ω)\hat\beta=(\hat b_a,\hat b_\omega) in GTSAM order. When optimization proposes β^+δβ\hat\beta+\delta\beta, recomputing every IMU sample would be wasteful. Define Jk∈R10×6J_k\in\mathbb R^{10\times6} directly by

Υk(β^+δβ)≃Υ^k(β^)Exp⁡(Jkδβ).\Upsilon_k(\hat\beta+\delta\beta) \simeq\hat\Upsilon_k(\hat\beta) \operatorname{Exp}(J_k\delta\beta).

This correction is on the right, matching the retraction convention. For Vk=Exp⁡(xk)V_k=\operatorname{Exp}(x_k) and Ck=JR(xk)hE∈R10×6C_k=J_R(x_k)hE\in\mathbb R^{10\times6}, transport of the old correction through the new increment gives

Jk+1=Ad⁡Vk−1Jk−Ck,Ji=0.\boxed{J_{k+1}=\operatorname{Ad}_{V_k^{-1}}J_k-C_k}, \qquad J_i=0.

The minus sign follows from differentiating u~−β\tilde u-\beta. The same recursion is obtained by accumulating the upper-right block of ALIA_{\mathrm{LI}}: the direct-product transition exposes the physical bias-to-navigation sensitivity directly. Apply it as

Υk(β)≃Υ^kExp⁡(Jk(β−β^)).\Upsilon_k(\beta)\simeq \hat\Upsilon_k \operatorname{Exp} \left(J_k(\beta-\hat\beta)\right).

The six columns of JkJ_k are ordered (ba,bω)(b_a,b_\omega), exactly like ConstantBias::vector(). There is no intermediate 10×1010\times10 virtual-bias Jacobian and no final column permutation. For the standard Galilean PIM, bias evolution remains the responsibility of a separate factor.

8. From the Galilean uncertainty to a GTSAM factor

The factor consumes a nine-dimensional NavState residual rather than the ten-dimensional Gal3 local error. In their respective tangent orderings,

e=(δθ,δv,δp,δt)∈R10,n=(δθ,δp,δv)∈R9.e=(\delta\theta,\delta v,\delta p,\delta t)\in\mathbb R^{10},\qquad n=(\delta\theta,\delta p,\delta v)\in\mathbb R^9.

Define the required selection and permutation when constructing the factor:

n=PNe,PN=[I300000I300I300]∈R9×10.n=P_Ne,\qquad P_N= \begin{bmatrix} I_3&0&0&0\\ 0&0&I_3&0\\ 0&I_3&0&0 \end{bmatrix} \in\mathbb R^{9\times10}.

The final column removes elapsed time, which is known exactly from the measurement timestamps. This projection applies to local errors, covariances, and Jacobians. The mean Galilean element is converted separately to NavState as (R,p,v)(R,p,v).

Let Σe∈R10×10\Sigma_e\in\mathbb R^{10\times10} be the conditional Galilean covariance propagated above. The factor’s NavState residual covariance is

ΣN=PNΣePN⊤∈R9×9.\Sigma_N=P_N\Sigma_eP_N^\top\in\mathbb R^{9\times9}.

Likewise, the first-order bias sensitivity of the local navigation error is

JN=PNJk∈R9×6.J_N=P_NJ_k\in\mathbb R^{9\times6}.

For the mean, first apply the Galilean bias correction and then construct

ΔXij=NavState⁡(ΔRij,Δpij,Δvij).\Delta X_{ij}= \operatorname{NavState} (\Delta R_{ij},\Delta p_{ij},\Delta v_{ij}).

The known gravity and elapsed-time terms combine this delta with XiX_i to form predictedState_j. The residual used by the existing GTSAM preintegration machinery is

rij=Local⁡NavState(Xj,predictedState⁡j)=Xj.logmap(predictedState⁡j).r_{ij}=\operatorname{Local}_{\mathrm{NavState}} (X_j,\operatorname{predictedState}_j) =X_j.\texttt{logmap}(\operatorname{predictedState}_j).

In the C++ interface this is NavState::logmap; the argument order is intentional because GTSAM’s IMU residual asks how the measured state retracts to the prediction. This factor residual is independent of the optimization chart selected by GTSAM_NAVSTATE_EXPMAP.

Conceptually this is a three-variable relation (Xi,Xj,βi)(X_i,X_j,\beta_i). The GalileanImuFactor alias uses ImuFactorT, so each NavState is exposed as separate pose and velocity keys and the concrete graph factor has five keys. In both views there is one bias variable for the entire interval. Bias evolution remains a separate factor, exactly as for the standard ImuFactor.

When bias evolution and state--bias correlation should be modeled inside the IMU factor, use PreintegratedCombinedMeasurementsG with GalileanCombinedImuFactor. The Combined PIM retains the same Galilean mean while propagating a public 15×1515\times15 covariance over (R,p,v,ba,bω)(R,p,v,b_a,b_\omega). The Gal(3) clock coordinate is deterministic and is projected out exactly. The resulting six-way factor adds the six bias-random-walk residuals to the nine navigation residuals.

9. Exact prediction in a rotating navigation frame

Let ωn\omega_n be the constant angular velocity of the navigation frame, expressed in navigation-frame coordinates, and let Ω=[ωn]×\Omega=[\omega_n]_\times. In the (R,v,p)(R,v,p) display order, the continuous dynamics are

R˙=−ΩR+R[ω]×,v˙=g+Ra−2Ωv−Ω2p,p˙=v.\dot R=-\Omega R+R[\omega]_\times,\qquad \dot v=g+Ra-2\Omega v-\Omega^2p,\qquad \dot p=v.

GTSAM stores the same state as NavState(R,p,v). Define the mutually inverse transported-velocity maps in that order by

LΩ(R,p,v)=(R,p,vˉ),vˉ=v+Ωp,PΩ(R,p,vˉ)=(R,p,v),v=vˉ−Ωp.\mathcal L_\Omega(R,p,v)=(R,p,\bar v),\quad \bar v=v+\Omega p,\qquad \mathcal P_\Omega(R,p,\bar v)=(R,p,v),\quad v=\bar v-\Omega p.

For θij=−ωnΔtij\theta_{ij}=-\omega_n\Delta t_{ij}, form the exact SO(3)SO(3) kernels

Aij=Exp⁡(θij),Gijv=JL(θij),Gijp=JL(θij)−Γ2(θij),A_{ij}=\operatorname{Exp}(\theta_{ij}),\qquad G^v_{ij}=J_L(\theta_{ij}),\qquad G^p_{ij}=J_L(\theta_{ij})-\Gamma_2(\theta_{ij}),

and the rotating-frame world increment, now written directly in NavState order,

WijΩ=NavState⁡(Aij,GijpgΔtij2,GijvgΔtij).W^\Omega_{ij}=\operatorname{NavState}\left( A_{ij},G^p_{ij}g\Delta t_{ij}^2,G^v_{ij}g\Delta t_{ij} \right).

The complete endpoint prediction preserves the same left-linear backbone:

Xj=PΩ ⁣(WijΩ ϕΔtij(LΩ(Xi)) Uij(βi)).\boxed{X_j=\mathcal P_\Omega\!\left( W^\Omega_{ij}\,\phi_{\Delta t_{ij}}(\mathcal L_\Omega(X_i))\,U_{ij}(\beta_i) \right)}.

Writing Uij=(ΔR,Δp,Δv)U_{ij}=(\Delta R,\Delta p,\Delta v) and WijΩ=(A,pW,vW)W^\Omega_{ij}=(A,p_W,v_W) in GTSAM order makes the implementation explicit:

Rj=ARiΔR,pj=pW+A(pi+vˉiΔt+RiΔp),R_j=AR_i\Delta R,\qquad p_j=p_W+A(p_i+\bar v_i\Delta t+R_i\Delta p),
vˉj=vW+A(vˉi+RiΔv),vj=vˉj−Ωpj.\bar v_j=v_W+A(\bar v_i+R_i\Delta v),\qquad v_j=\bar v_j-\Omega p_j.

This is the companion paper’s extension of Brossard et al.'s transported-velocity construction to the Galilean body-frame increment. It gives an exact constant-rate rotating-frame transition: Coriolis and centrifugal terms arise from the lift, group composition, and projection rather than an appended acceleration correction. The body-frame increment UijU_{ij}, its covariance, and its bias correction are unchanged; only endpoint prediction and its Jacobians depend on ωn\omega_n. In Python, enable this path with params.setOmegaCoriolis(omega_n). Omitting it (or setting exactly zero) selects the inertial prediction.

10. Intended use

A user-facing workflow mirrors the existing IMU factors:

  1. Construct preintegration parameters and a PreintegratedImuMeasurementsG at the current bias estimate. When the navigation frame rotates, call setOmegaCoriolis with its constant angular velocity in navigation-frame coordinates.

  2. Integrate each accelerometer/gyroscope sample. The public API and all six-dimensional quantities use GTSAM order (a,ω)(a,\omega); the lift places them in Gal3 order internally. Each call advances the Galilean mean on the right and propagates its conditional covariance.

  3. Construct a GalileanImuFactor between the two pose/velocity pairs and the interval’s bias key. During optimization, use the right-applied first-order bias correction rather than reintegrating immediately.

  4. Add a separate factor between consecutive bias keys when bias random-walk evolution is part of the model. Alternatively, construct PreintegratedCombinedMeasurementsG and a GalileanCombinedImuFactor to model the second bias key, its random walk, and state--bias correlation inside one factor.

In schematic C++ form:

PreintegratedImuMeasurementsG pim(params, biasHat);
for (const ImuSample& sample : samples) {
  pim.integrateMeasurement(sample.acceleration, sample.angularRate,
                           sample.deltaT);
}
graph.emplace_shared<GalileanImuFactor>(
    X(i), V(i), X(j), V(j), B(i), pim);

The Combined alternative has the corresponding form:

PreintegratedCombinedMeasurementsG combinedPim(combinedParams, biasHat);
// Integrate the same samples as above.
graph.emplace_shared<GalileanCombinedImuFactor>(
    X(i), V(i), X(j), V(j), B(i), B(j), combinedPim);

The API is deliberately familiar; the essential differences are internal geometric choices. The executable Python example below follows the same sequence. It predicts a consistent endpoint only to demonstrate factor construction; in a real graph, XjX_j is an optimizer variable rather than the prediction itself.

Integrated 0.030 s
NavState residual covariance shape: (9, 9)
Factor error at the predicted endpoint: [-5.69983774e-21 -4.35407115e-19  0.00000000e+00  0.00000000e+00
  0.00000000e+00  0.00000000e+00  0.00000000e+00  0.00000000e+00
  0.00000000e+00]

References

  • Left-Invariant Galilean IMU Preintegration in Inertial and Rotating Frames (companion paper): the direct-product model implemented and derived here.

  • M. Brossard, A. Barrau, P. Chauchat, and S. Bonnabel, Associating Uncertainty to Extended Poses for On Lie Group IMU Preintegration With Rotating Earth, IEEE Transactions on Robotics, 2022.

  • G. Delama, A. Fornasier, R. Mahony, and S. Weiss, Equivariant IMU Preintegration with Biases: a Galilean Group Approach, IEEE Robotics and Automation Letters, 2025.

  • gtsam::Gal3: group operations, exponential and logarithmic maps, and adjoints.

  • Gal3ImuEKF: Galilean state propagation in an invariant EKF.

  • NavState: GTSAM’s navigation manifold and local-coordinate convention.

  • ImuFactor: standard preintegration and factor-graph usage.