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.

Custom Factor Sensor Fusion

This notebook introduces gtsam.CustomFactor with a simple 1D tracking problem. We estimate a car’s position at five time steps and add three kinds of measurements one by one:

  • GPS factors on individual states

  • odometry factors between consecutive states

  • relative measurements to known landmarks

The goal is not realism. The goal is to show, as clearly as possible, how a Python callback becomes a factor in a GTSAM graph.

Open In Colab

1. Simulate a Simple 1D Trajectory

To keep the example focused on CustomFactor, each state is just a 1D vector containing the car’s position.

Ground-truth positions: [ 0. 10. 20. 30. 40.]
Keys: ['x0', 'x1', 'x2', 'x3', 'x4']

2. Create Noisy Measurements

We use three sensor types. GPS measures absolute position, odometry measures motion between consecutive states, and the landmark sensor measures the car’s position relative to a known landmark.

GPS measurements: [ 0.91415124  6.88004768 22.25135359 32.82169415 34.14689443]
Odometry measurements: [ 9.86978205 10.01278404  9.96837574  9.99831988]
Landmark-relative measurements: {0: np.float64(-5.85304392757358), 3: np.float64(2.8793979748628287)}

3. Define Custom Residual Callbacks

A Python CustomFactor callback always has the same shape:

callback(this, values, jacobians) -> residual

When GTSAM asks for Jacobians, we write them into the jacobians list.

4. Build and Solve Graphs

To make the comparison easy to read, we use a small helper that builds a factor graph with different sensor combinations.

5. Compare Three Sensor Suites

GPS only                     [ 0.91415124  6.88004768 22.25135359 32.82169415 34.14689443]   graph error = 0.000
GPS + odometry               [-0.48523821  9.38298896 19.39699917 29.36342957 39.3559616 ]   graph error = 3.083
GPS + odometry + landmarks   [-0.04999492  9.82674634 19.84976371 29.82570434 39.8177233 ]   graph error = 4.030

6. Visualize the Improvement

<Figure size 800x400 with 1 Axes>

Takeaways

  • CustomFactor lets you describe a factor by writing just a residual callback.

  • The callback can capture measurements and any other constants it needs.

  • Once the callback is wrapped in a factor, the rest of the workflow is standard GTSAM: build a graph, initialize variables, and optimize.