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.

GPS Factor Example

A GPSFactor ties a 3D position measurement -- for example, a reading from a GPS receiver -- to a Pose3 variable in a factor graph. Because GPS only observes position, a single GPSFactor constrains the translation part of a pose but says nothing about orientation.

This notebook builds the smallest possible example of that idea: one pose, one prior, one GPS measurement. We optimize with Levenberg-Marquardt and see the pose’s position pulled toward the GPS reading while its orientation is left to the prior.

Open In Colab

GTSAM Copyright 2010-2026, Georgia Tech Research Corporation, Atlanta, Georgia 30332-0415 All Rights Reserved

Authors: Mandy Xie, Frank Dellaert, et al. (see THANKS for the full author list)

See LICENSE for the license information

1. Set up the problem

lat0, lon0, h0 play the role of a single GPS reading -- the ENU origin where the plane was in hold next to the runway. We use two noise models:

  • GPS_NOISE is 3-dimensional, since a GPS measurement only observes x, y, z position.

  • PRIOR_NOISE is 6-dimensional, since the prior constrains the full Pose3 (position and orientation).

2. Build the factor graph

The PriorFactorPose3 anchors pose key 1 at the identity pose -- deliberately different from the GPS reading, so the optimizer has real work to do. The GPSFactor then adds the position-only measurement on the same key.

NonlinearFactorGraph: size: 2

Factor 0: PriorFactor on 1
  prior mean:  R: [
	1, 0, 0;
	0, 1, 0;
	0, 0, 1
]
t: 0 0 0
isotropic dim=6 sigma=0.25

Factor 1:  GPSFactor on 1
  GPS measurement:    33.87
-84.3063
     274
isotropic dim=3 sigma=0.1


3. Initial estimate

For illustrative purposes, the initial estimate is deliberately set to the identity pose -- far from the GPS reading -- so we can watch the optimizer correct it.

Values with 1 values:
Value 1: (gtsam::Pose3)
R: [
	1, 0, 0;
	0, 1, 0;
	0, 0, 1
]
t: 0 0 0


4. Optimize

We solve with LevenbergMarquardtOptimizer, the general-purpose nonlinear least-squares solver used throughout GTSAM.

Values with 1 values:
Value 1: (gtsam::Pose3)
R: [
	1, 0, 0;
	0, 1, 0;
	0, 0, 1
]
t:  29.1983 -72.6778  236.207


Notice that the optimized translation lands close to, but not exactly at, the GPS reading (lat0, lon0, h0). It’s a noise-weighted compromise between the two factors: the prior pulls it toward (0, 0, 0) with sigma=0.25, while the GPS factor pulls it toward the measurement with a tighter sigma=0.1, so the tighter (more confident) factor dominates. The rotation, meanwhile, stays exactly at the prior’s identity value -- a single GPSFactor has no way to observe orientation from one position measurement. That information has to come from somewhere else (multiple GPS readings over time, an IMU, a compass, etc.).