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.

Known landmark localization in ℝ³

This example demonstrates 3D localization of a single point state xx from four known landmarks using KnownLandmarkSquaredRangeFactor3.

A single unknown point x∈R3x \in \mathbb{R}^3 is observed through range measurements to several fixed, known landmarks LiL_i. A conventional range residual has the form

ei(x)=∥x−Li∥−di,e_i(x) = \|x - L_i\| - d_i,

where did_i is the measured range to landmark LiL_i. Because the Euclidean norm contains a square root, this residual is not polynomial in the state.

KnownLandmarkSquaredRangeFactor2 and KnownLandmarkSquaredRangeFactor3 instead use the squared-range residual

ei(x)=∥x−Li∥2−di2,e_i(x) = \|x - L_i\|^2 - d_i^2,

which is quadratic in xx. This polynomial form is suitable for lifted QCQP formulations and subsequent semidefinite relaxations. If the semidefinite relaxation is tight, meaning that the lifted solution has the required rank, the relaxed problem recovers a globally optimal solution to the original QCQP.

In this notebook, the factor is used with GTSAM’s standard nonlinear optimizer; QCQP/certifiable conversion is not included.

Several geometrically distinct landmarks are required to uniquely determine the point. This example uses four known landmarks and noisy range measurements to estimate the 3D position.

See the KnownLandmarkSquaredRangeFactor API notebook for more details on the factor.

Open In Colab

Create a 3D synthetic localization problem

We choose one true 3D point and four fixed landmarks. The landmarks are spread through space so that the resulting range measurements provide independent geometric constraints.

Gaussian noise is added to each raw range measurement for realism.

True point: [1. 2. 3.]
Raw range standard deviation: 0.100 m

L0: [0. 0. 0.] True range = 3.742 m,  Measured range = 3.772 m
L1: [5. 0. 0.] True range = 5.385 m,  Measured range = 5.281 m
L2: [0. 6. 0.] True range = 5.099 m,  Measured range = 5.174 m
L3: [1. 0. 8.] True range = 5.385 m,  Measured range = 5.479 m

Propagate range uncertainty into squared-range units

The sensor uncertainty above is expressed in range units, while KnownLandmarkSquaredRangeFactor3 uses the squared-range residual

ei(x)=∥x−Li∥2−di2.e_i(x) = \|x - L_i\|^2 - d_i^2.

For y=d2y = d^2, first-order uncertainty propagation gives

σy≈∣∂d2∂d∣σd=2d σd.\sigma_y \approx \left|\frac{\partial d^2}{\partial d}\right|\sigma_d = 2d\,\sigma_d.

Therefore, the standard deviation used by each factor is approximately

σd2≈2d σd.\sigma_{d^2} \approx 2d\,\sigma_d.

Even when each range measurement has the same σd\sigma_d, their respective squared-range uncertainties differ between landmarks.

Build the factor graph

Each range measurement contributes one factor to the same unknown point state.

Choose an initial estimate

The nonlinear optimizer needs an initial value for the point state. The initial position is deliberately offset from the true position.

Optimize

We solve the nonlinear least-squares problem with Levenberg-Marquardt.

True point:  [1. 2. 3.]
Initial point:  [1.2 1.7 3.2]
Estimated point:  [1.14882058 1.99174407 2.96859758]
Final graph error:  0.41722601045710256
Localization error:  0.15232149470799192

Visualize the result

The interactive 3D plot below shows the known landmarks, true position, initial estimate, and optimized estimate. Rotate or zoom the plot to inspect the geometry from different viewpoints.

Loading...

Takeaways

  • KnownLandmarkSquaredRangeFactor3 estimates a 3D Euclidean point, not a pose.

  • Each factor relates the point to one fixed known landmark.

  • Pass the non-negative range measurement dd to the constructor; the factor stores d2d^2 internally.

  • The residual is scalar, so each factor uses a one-dimensional noise model.

  • Raw range uncertainty should be propagated into squared-range units before use in the factor noise model.

  • Known landmarks are fixed factor data and are not inserted into Values.