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.

InitializePose3

Open In Colab

The InitializePose3 structure provides static methods for computing an initial estimate for 3D poses (Pose3) in a factor graph, particularly useful for Structure from Motion (SfM) or SLAM problems. The core idea is to first estimate the orientations (Rot3) independently and then use these estimates to initialize a linear system for the translations.

Key static methods:

  • buildPose3graph(graph): Extracts the subgraph containing only Pose3 BetweenFactor and PriorFactor constraints from a larger NonlinearFactorGraph.

  • computeOrientationsChordal(pose3Graph): Estimates rotations using chordal relaxation on the rotation constraints.

  • computeOrientationsGradient(pose3Graph, initialGuess): Estimates rotations using gradient descent on the manifold.

  • initializeOrientations(graph): Convenience function combining buildPose3graph and computeOrientationsChordal.

  • computePoses(initialRot, poseGraph): Computes translations given estimated rotations by solving a linear system (performing one Gauss-Newton iteration on poses).

  • initialize(graph): Performs the full initialization pipeline (extract graph, estimate rotations via chordal, compute translations).

  • initialize(graph, givenGuess, useGradient): Full pipeline allowing specification of an initial guess and choosing between chordal or gradient descent for rotations.

Example Initialization Pipeline

We’ll create a simple 3D pose graph and use the InitializePose3.initialize method to get an initial estimate.

Original Factor Graph:
size: 4

Factor 0: PriorFactor on x0
  prior mean:  R: [
	0.995004, -0.0998334, 0;
	0.0998334, 0.995004, 0;
	0, 0, 1
]
t: 0.1   0   0
  noise model: diagonal sigmas [0.01; 0.01; 0.01; 0.05; 0.05; 0.05];

Factor 1: BetweenFactor(x0,x1)
  measured:  R: [
	0.877582562, -0.479425539, 0;
	0.479425539, 0.877582562, 0;
	0, 0, 1
]
t:   1 0.1   0
  noise model: diagonal sigmas [0.05; 0.05; 0.05; 0.2; 0.2; 0.2];

Factor 2: BetweenFactor(x1,x2)
  measured:  R: [
	0.921060994, -0.389418342, 0;
	0.389418342, 0.921060994, 0;
	0, 0, 1
]
t:  0.9 -0.1    0
  noise model: diagonal sigmas [0.05; 0.05; 0.05; 0.2; 0.2; 0.2];

Factor 3: BetweenFactor(x2,x0)
  measured:  R: [
	0.621609968, 0.78332691, 0;
	-0.78332691, 0.621609968, 0;
	0, 0, 1
]
t: -1.8 0.05    0
  noise model: diagonal sigmas [0.1; 0.1; 0.1; 0.4; 0.4; 0.4];


Initial Estimate (using InitializePose3.initialize):

Values with 3 values:
Value x0: (class gtsam::Pose3)
R: [
	0.995004165, -0.0998334166, 0;
	0.0998334166, 0.995004165, 0;
	0, 0, 1
]
t:             0.1 -7.63278329e-15               0

Value x1: (class gtsam::Pose3)
R: [
	0.825335615, -0.564642473, 0;
	0.564642473, 0.825335615, 0;
	0, 0, 1
]
t: 0.956742586 0.343109526           0

Value x2: (class gtsam::Pose3)
R: [
	0.540302306, -0.841470985, 0;
	0.841470985, 0.540302306, 0;
	0, 0, 1
]
t:  1.62773065 0.912529884           0

Notes

  • The quality of the initial estimate depends heavily on the quality and connectivity of the pose graph factors.

  • Chordal relaxation (computeOrientationsChordal) is generally faster and often sufficient.

  • Gradient descent (computeOrientationsGradient) might provide slightly more accurate orientations but is slower and requires a good initial guess.

  • The final computePoses step performs only a single Gauss-Newton iteration, assuming the rotations are fixed. The resulting estimate is meant as an initialization for a full nonlinear optimization (e.g., using GaussNewtonOptimizer or LevenbergMarquardtOptimizer).