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.

Simple Rotation

This is the smallest possible GTSAM optimization: a single variable, a single factor. The variable is a 2D rotation (Rot2); the factor is a prior -- a measurement from a sensor, with a noise model describing how much we trust it.

The story: a sensor measured a rotation to be close to 30 degrees. We start from a wrong initial guess of 20 degrees, and ask GTSAM to find the best estimate.

Open In Colab

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

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

See LICENSE for the license information

1. Keys

GPSFactorExample and OdometryExample label variables with plain integer keys (1, 2, 3, ...). Here we instead use symbol_shorthand.X, which packs a character ('x') and an index into the same underlying Key type -- a more readable choice once a problem has several kinds of variables (poses, landmarks, calibration, ...) that would otherwise collide under a single integer counter.

2. Create the prior factor

In general, creating a factor requires:

  • a key or set of keys labeling the variables it acts on,

  • a measurement value, and

  • a measurement model with the correct dimensionality.

Here the “measurement” is the goal angle of 30 degrees, and the noise model says we trust it to within about 1 degree (Isotropic.Sigma since a Rot2 has a single degree of freedom).

theta: 0.523599

3. Build the graph

Before optimizing, every factor needs to be added to a graph container. In a practical problem many factors would be added; here there is exactly one.

NonlinearFactorGraph: size: 1

Factor 0: PriorFactor on x1
  prior mean: : 0.523599
isotropic dim=1 sigma=0.0174533


4. Initial estimate

Optimization needs a starting linearization point for every variable in the graph. We deliberately start 10 degrees away from the prior’s goal angle, so the optimizer has something to do.

Values with 1 values:
Value x1: (gtsam::Rot2)
: 0.349066


5. Optimize

As in GPSFactorExample and OdometryExample, we solve with LevenbergMarquardtOptimizer.

Values with 1 values:
Value x1: (gtsam::Rot2)
: 0.523599


With only one factor in the graph, there is nothing else to compromise against, so the optimizer converges exactly to the prior’s goal angle of 30 degrees -- unlike the GPS factor notebook, where two competing factors (a prior and a GPS measurement) pulled the result to a noise-weighted blend between them. A single-factor graph like this one just returns that factor’s own measurement.