ROB-310 · Lesson 10 of 12 · 32 min
Information filters, smoothing and factor graphs
The filters so far estimate only the current state and forget the past: once a measurement has been folded into the belief, it is never revisited. This is efficient, but it throws away the chance to improve old estimates with new information, and it locks in linearization errors made with poor estimates. Modern robotics increasingly uses smoothing instead, estimating the whole trajectory, or a recent window of it, from all the measurements at once, by solving a sparse nonlinear least-squares problem represented as a factor graph. This lesson builds the bridge from filtering to smoothing: first the information form of the Gaussian, in which fusion is simple addition; then batch least-squares estimation; then factor graphs and the sliding-window and incremental methods that make smoothing run in real time. These ideas are the foundation of the graph-based SLAM covered in ROB-340 and of most current visual-inertial and lidar odometry systems.
The information form
A Gaussian can be written with its covariance Σ and mean μ, the moment form, or with the information matrix \( \boldsymbol{\Omega} = \boldsymbol{\Sigma}^{-1} \) and information vector \( \boldsymbol{\xi} = \boldsymbol{\Omega}\boldsymbol{\mu} \), the canonical or information form. The two describe the same distribution, but they make different operations easy. In the information form, the measurement update of a Kalman filter becomes addition:
Each measurement contributes its own information, independent of the others, and fusing many sensors means summing their contributions, the matrix version of the inverse-variance addition of lesson 5. A complete absence of knowledge is easy to represent too: Ω = 0, which in moment form would need an infinite covariance. The price is that prediction, simple in moment form, becomes awkward in information form, and recovering the mean requires solving \( \boldsymbol{\Omega}\boldsymbol{\mu} = \boldsymbol{\xi} \). The information filter is therefore used where measurement updates dominate, such as fusing many sensors at once or decentralized estimation across several robots, where each robot can simply send its information contribution to the others.
Worked problem
Fusing in information form
Three independent sensors measure a robot's x position as 4.1 m (σ = 0.2 m), 3.9 m (σ = 0.1 m) and 4.3 m (σ = 0.4 m). Fuse them in information form.
Show solution
- Information: \( 1/0.04 = 25 \), \( 1/0.01 = 100 \), \( 1/0.16 = 6.25 \); total Ω = 131.25.
- Information vector: \( 25(4.1) + 100(3.9) + 6.25(4.3) = 102.5 + 390 + 26.875 = 519.375 \).
- Mean: \( 519.375/131.25 = 3.957 \) m; σ = \( 1/\sqrt{131.25} = 0.087 \) m.
Answer: The fused estimate is 3.96 m with σ = 0.087 m, dominated by the most precise sensor. The order of fusion does not matter, and adding a fourth sensor later just adds its two numbers.
Sparsity and the structure of robot problems
The information matrix reveals the structure of an estimation problem. Its off-diagonal entry between two variables is zero if and only if they are conditionally independent given all the other variables; equivalently, nonzero entries appear only between variables directly linked by some measurement or motion constraint. For a robot trajectory, pose \( x_t \) is directly linked only to \( x_{t-1} \) and \( x_{t+1} \) by odometry, and to the landmarks it observed. The information matrix of a full trajectory is therefore sparse: banded along the diagonal, with extra entries only for observations. The covariance matrix, in contrast, is dense, because every pose is indirectly correlated with every other through the chain. Sparse matrices can be stored and factorized in time roughly proportional to the number of nonzero entries rather than to the cube of the dimension, which is what makes estimating thousands of poses at once feasible.
Worked problem
Counting nonzeros
A trajectory of 1,000 planar poses (3 variables each) is linked only by odometry between consecutive poses. Compare the number of entries in the full information matrix with the number that can be nonzero.
Show solution
- Dimension: 3,000; full matrix: \( 3{,}000^2 = 9 \times 10^6 \) entries.
- Nonzero blocks: 1,000 diagonal 3×3 blocks and 999 pairs of off-diagonal blocks, about \( 1{,}000 \times 9 + 2 \times 999 \times 9 = 26{,}982 \) entries.
- Fraction: \( 26{,}982/9 \times 10^6 \approx 0.3 \% \).
Answer: Only about 0.3 % of the entries can be nonzero. Exploiting this, a solver can handle the whole trajectory in milliseconds, where a dense 3,000 × 3,000 inversion would take about a thousand times more work and memory.
From filtering to smoothing
Filtering estimates \( p(x_t \mid z_{1:t}) \), the current state from all data so far. Smoothing estimates \( p(x_{0:t} \mid z_{1:t}) \), the whole trajectory, so that a measurement at time t can also improve the estimate of where the robot was at time t − 10. For a linear Gaussian system, the forward Kalman filter followed by a backward Rauch–Tung–Striebel pass gives the exact smoothed estimates; past states benefit from future measurements and their uncertainty shrinks. For nonlinear systems, smoothing has a further advantage: it can re-linearize past models around improved estimates, removing the linearization errors that a filter locks in forever.
The modern way to compute a smoothed estimate is as a maximum a posteriori (MAP) problem. With Gaussian noise, maximizing the posterior of the trajectory is equivalent to minimizing a sum of squared, covariance-weighted residuals, one for each motion constraint, measurement and prior:
Here \( \mathbf{r}_k \) is the difference between what model k predicts and what was measured, such as odometry predicting \( x_t - x_{t-1} \) and measuring \( u_t \). Gauss–Newton solves this by repeatedly linearizing the residuals with their Jacobian J and solving the normal equations \( (\mathbf{J}^{\mathsf{T}}\mathbf{W}\mathbf{J})\Delta\mathbf{X} = -\mathbf{J}^{\mathsf{T}}\mathbf{W}\mathbf{r} \), where W holds the inverse covariances. The matrix \( \mathbf{J}^{\mathsf{T}}\mathbf{W}\mathbf{J} \) is exactly the information matrix of the trajectory, sparse for the reasons above. Levenberg–Marquardt adds damping for robustness when the starting estimate is poor.
Worked problem
A three-pose chain solved by least squares
A robot on a line starts at \( x_0 \) with prior 0 m (σ = 0.1 m), moves with odometry \( u_1 = 1.0 \) and \( u_2 = 1.0 \) m (σ = 0.1 m each), and at pose 2 a beacon measures its position as 2.3 m (σ = 0.1 m). Find the MAP estimates.
Show solution
- With equal σ, minimize \( x_0^2 + (x_1 - x_0 - 1)^2 + (x_2 - x_1 - 1)^2 + (x_2 - 2.3)^2 \).
- The 0.3 m disagreement between dead reckoning (2.0) and the beacon (2.3) is shared equally among the four residuals in the chain, 0.075 m each.
- Hence \( x_0 = 0.075 \), \( x_1 = 1.15 \), \( x_2 = 2.225 \).
- Check: residuals are 0.075, 0.075, 0.075 and −0.075, all equal in size.
Answer: The smoothed trajectory is (0.075, 1.15, 2.225) m. The beacon at pose 2 shifted not only pose 2 but also poses 1 and 0, something a filter, which had already committed to its estimates of earlier poses, could not do.
Factor graphs
A factor graph draws the least-squares problem as a bipartite graph. Variable nodes represent unknowns: robot poses, landmark positions, sensor biases, calibration parameters. Factor nodes represent the terms of the cost: a prior factor attached to the first pose, odometry factors between consecutive poses, measurement factors between a pose and a landmark, a GNSS factor on a single pose, an IMU preintegration factor linking two poses and their velocities and biases. The graph makes the sparsity visible, it makes the problem modular (adding a new sensor means defining a new kind of factor), and it maps directly onto efficient solvers. Libraries such as GTSAM, Ceres Solver and g2o are built around this abstraction, and most state-of-the-art odometry and SLAM systems, including visual-inertial systems like VINS-Mono and lidar systems like LIO-SAM, are factor-graph smoothers.
import numpy as np
rng = np.random.default_rng(12)
T, so, sb = 50, 0.05, 0.3 # 50 steps, odometry noise, beacon noise
fix_times = range(10, T + 1, 10) # beacon every 10 steps
def trial():
true = np.cumsum(np.r_[0.0, np.full(T, 0.5)])
u = np.diff(true) + rng.normal(0, so, T) # noisy odometry
beac = {t: true[t] + rng.normal(0, sb) for t in fix_times}
mu, P, filt = 0.0, 0.01, [0.0] # forward Kalman filter (1-D)
for t in range(1, T + 1):
mu, P = mu + u[t - 1], P + so**2
if t in beac: K = P/(P + sb**2); mu, P = mu + K*(beac[t] - mu), (1 - K)*P
filt.append(mu)
rows, rhs, w = [np.eye(T + 1)[0]], [0.0], [1/0.1**2] # batch least squares: prior,
for t in range(1, T + 1): # odometry factors,
rows.append(np.eye(T + 1)[t] - np.eye(T + 1)[t - 1]); rhs.append(u[t - 1]); w.append(1/so**2)
for t, z in beac.items(): # and beacon factors
rows.append(np.eye(T + 1)[t]); rhs.append(z); w.append(1/sb**2)
J, r, W = np.array(rows), np.array(rhs), np.diag(w)
Om = J.T @ W @ J; smooth = np.linalg.solve(Om, J.T @ W @ r)
rmse = lambda est: np.sqrt(np.mean((np.array(est) - true)**2))
return rmse(filt), rmse(smooth), np.count_nonzero(Om)
res = np.array([trial() for _ in range(300)])
print(f"mean RMSE over 300 runs: filter {res[:, 0].mean():.3f} m, smoother {res[:, 1].mean():.3f} m")
print(f"smoother better in {np.mean(res[:, 1] < res[:, 0])*100:.0f} % of runs")
print(f"information matrix nonzeros: {int(res[0, 2])} of {(T + 1)**2}")mean RMSE over 300 runs: filter 0.179 m, smoother 0.144 m smoother better in 73 % of runs information matrix nonzeros: 151 of 2601
Averaged over 300 simulated runs, the smoother's error over the whole trajectory is about 20 % lower than the filter's (0.144 m against 0.179 m), because each beacon fix corrects the poses before it as well as after it, while the filter's estimates of past poses keep the drift they had at the time. In any single run the noise can favour either method, which is why estimators are compared over many runs, but the smoother wins in about three runs out of four. The information matrix has only about three nonzeros per row, a tridiagonal band, so even this naive dense solve could be replaced by a banded solver whose cost grows linearly with trajectory length.
Real-time smoothing
A full smoother re-solving the entire history at every step would eventually become too slow. Two techniques keep smoothing real-time. Fixed-lag or sliding-window smoothing keeps only the most recent N poses (often 10 to 50) as variables and marginalizes older ones out, summarizing their effect as a prior on the oldest remaining pose. Marginalization in information form is computed with the Schur complement; it preserves the information from old measurements but turns their linearization into a fixed approximation and creates fill-in, new nonzeros linking all the variables that were connected to the removed ones. Most visual-inertial odometry systems use this approach. Incremental smoothing, exemplified by iSAM2 in GTSAM, keeps the whole graph but updates the factorization of the information matrix incrementally as new factors arrive, re-linearizing only the variables whose estimates have changed significantly. It gives the accuracy of a full batch solution at a cost close to that of a filter for most steps, with occasional larger updates, for example when a loop closure in SLAM connects the current pose to one seen long ago.
Worked problem
Sliding window size
A visual-inertial system keeps a window of 10 keyframes. Each keyframe has 15 variables (pose 6, velocity 3, gyro and accelerometer biases 6), and 200 landmarks of 3 variables each are tracked in the window. What is the size of the system solved at each step, and why are landmarks often eliminated first?
Show solution
- Keyframe variables: 10 × 15 = 150.
- Landmark variables: 200 × 3 = 600.
- Total: 750 variables.
- Each landmark connects only to the keyframes that saw it, so eliminating landmarks first (the Schur complement trick) leaves a small 150-variable system.
Answer: 750 variables in total, but eliminating the 600 landmark variables first, which is cheap because each landmark block is independent, reduces the core solve to 150 variables. This is the same trick bundle adjustment uses in photogrammetry.
Common mistakes
MistakeInverting the information matrix to read off the estimate
InsteadSolve the sparse system \( \boldsymbol{\Omega}\boldsymbol{\mu} = \boldsymbol{\xi} \) instead of forming a dense inverse.
MistakeExpecting a filter to correct past states
InsteadUse a smoother if past estimates matter, for example for maps or offline analysis.
MistakeMarginalizing old variables without considering fill-in
InsteadChoose elimination orders and window sizes that keep the system sparse.
MistakeStarting Gauss–Newton far from the solution
InsteadInitialize from odometry or a filter, and use Levenberg–Marquardt damping or robust kernels.
MistakeTreating the covariance as sparse
InsteadThe information matrix is sparse; the covariance of a trajectory is generally dense.
Summary and key terms
- The information form stores \( \boldsymbol{\Omega} = \boldsymbol{\Sigma}^{-1} \) and \( \boldsymbol{\xi} = \boldsymbol{\Omega}\boldsymbol{\mu} \), making measurement fusion additive.
- Zeros in the information matrix indicate conditional independence, so robot trajectory problems are sparse.
- Smoothing estimates the whole trajectory and lets later measurements improve earlier states.
- With Gaussian noise, MAP smoothing is weighted nonlinear least squares, solved by Gauss–Newton or Levenberg–Marquardt.
- Factor graphs represent unknowns as variables and cost terms as factors, matching the problem's sparsity.
- Sliding-window smoothers marginalize old states with the Schur complement; incremental smoothers such as iSAM2 update factorizations.
- Factor-graph smoothing underlies modern visual-inertial odometry, lidar odometry and SLAM.
- Information matrix
- The inverse of the covariance matrix, Ω.
- Information vector
- The product of the information matrix and the mean, ξ.
- Information filter
- A Kalman filter written in information form.
- Smoothing
- Estimating past and present states using all available measurements.
- Maximum a posteriori estimate
- The state that maximizes the posterior probability.
- Factor graph
- A bipartite graph of variables and factors representing a probabilistic cost.
- Normal equations
- The linear system \( \mathbf{J}^{\mathsf{T}}\mathbf{W}\mathbf{J}\Delta = -\mathbf{J}^{\mathsf{T}}\mathbf{W}\mathbf{r} \) solved at each Gauss–Newton step.
- Marginalization
- Removing variables from an estimation problem while keeping their information as a prior.
- Schur complement
- The matrix operation used to eliminate variables from a linear system.
- Fill-in
- New nonzero entries created by eliminating variables.
Practice problems
Work each problem on paper first, then reveal the answer to check.
Fuse 2.0 (σ = 0.5) and 2.4 (σ = 0.5) in information form.
Show answer
Ω = 8, ξ = 17.6, mean 2.2, σ = 0.354.
What does Ω = 0 represent?
Show answer
No information: a completely unknown variable.
What does a zero off-diagonal in Ω mean?
Show answer
Conditional independence given all other variables.
In a pure odometry chain, what pattern does Ω have?
Show answer
Block tridiagonal.
Name the backward pass that gives linear smoothed estimates.
Show answer
The Rauch–Tung–Striebel smoother.
Odometry predicts 1.0 m and measures 0.9 m with σ = 0.1. Weighted squared residual?
Show answer
\( (0.1/0.1)^2 = 1 \).
What does Levenberg–Marquardt add to Gauss–Newton?
Show answer
Damping that makes steps robust far from the solution.
What creates fill-in?
Show answer
Eliminating variables connected to several others.
Name a factor-graph library.
Show answer
GTSAM, Ceres Solver or g2o.
Why eliminate landmarks first in visual-inertial smoothing?
Show answer
Each landmark block is independent, leaving a small keyframe system.
Lesson quiz · 5 questions
Score 60% or more to complete this lesson.
Create a free account to save your progress, take quizzes and earn a certificate.