Skip to content

Commit 14a7e06

Browse files
authored
Merge pull request #1808 from borglab/python-localization-example
2 parents 46765ec + c57d5a0 commit 14a7e06

File tree

6 files changed

+91
-5
lines changed

6 files changed

+91
-5
lines changed

gtsam_unstable/gtsam_unstable.i

+15
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,21 @@ class AHRS {
671671
//void print(string s) const;
672672
};
673673

674+
#include <gtsam_unstable/slam/PartialPriorFactor.h>
675+
template <T = {gtsam::Pose2, gtsam::Pose3}>
676+
virtual class PartialPriorFactor : gtsam::NoiseModelFactor {
677+
PartialPriorFactor(gtsam::Key key, size_t idx, double prior,
678+
const gtsam::noiseModel::Base* model);
679+
PartialPriorFactor(gtsam::Key key, const std::vector<size_t>& indices,
680+
const gtsam::Vector& prior,
681+
const gtsam::noiseModel::Base* model);
682+
683+
// enabling serialization functionality
684+
void serialize() const;
685+
686+
const gtsam::Vector& prior();
687+
};
688+
674689
// Tectonic SAM Factors
675690

676691
#include <gtsam_unstable/slam/TSAMFactors.h>

gtsam_unstable/slam/PartialPriorFactor.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ namespace gtsam {
5050
Vector prior_; ///< Measurement on tangent space parameters, in compressed form.
5151
std::vector<size_t> indices_; ///< Indices of the measured tangent space parameters.
5252

53-
/** default constructor - only use for serialization */
54-
PartialPriorFactor() {}
55-
5653
/**
5754
* constructor with just minimum requirements for a factor - allows more
5855
* computation in the constructor. This should only be used by subclasses
@@ -65,7 +62,8 @@ namespace gtsam {
6562
// Provide access to the Matrix& version of evaluateError:
6663
using Base::evaluateError;
6764

68-
~PartialPriorFactor() override {}
65+
/** default constructor - only use for serialization */
66+
PartialPriorFactor() {}
6967

7068
/** Single Element Constructor: Prior on a single parameter at index 'idx' in the tangent vector.*/
7169
PartialPriorFactor(Key key, size_t idx, double prior, const SharedNoiseModel& model) :
@@ -85,6 +83,8 @@ namespace gtsam {
8583
assert(model->dim() == (size_t)prior.size());
8684
}
8785

86+
~PartialPriorFactor() override {}
87+
8888
/// @return a deep copy of this factor
8989
gtsam::NonlinearFactor::shared_ptr clone() const override {
9090
return std::static_pointer_cast<gtsam::NonlinearFactor>(

python/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ if(GTSAM_UNSTABLE_BUILD_PYTHON)
189189
gtsam::BinaryMeasurementsPoint3
190190
gtsam::BinaryMeasurementsUnit3
191191
gtsam::BinaryMeasurementsRot3
192+
gtsam::SimWall2DVector
193+
gtsam::SimPolygon2DVector
192194
gtsam::CameraSetCal3_S2
193195
gtsam::CameraSetCal3Bundler
194196
gtsam::CameraSetCal3Unified

python/gtsam/examples/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
| InverseKinematicsExampleExpressions.cpp | |
1818
| ISAM2Example_SmartFactor | |
1919
| ISAM2_SmartFactorStereo_IMU | |
20-
| LocalizationExample | impossible? |
20+
| LocalizationExample | :heavy_check_mark: |
2121
| METISOrderingExample | |
2222
| OdometryExample | :heavy_check_mark: |
2323
| PlanarSLAMExample | :heavy_check_mark: |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
A simple 2D pose slam example with "GPS" measurements
3+
- The robot moves forward 2 meter each iteration
4+
- The robot initially faces along the X axis (horizontal, to the right in 2D)
5+
- We have full odometry between pose
6+
- We have "GPS-like" measurements implemented with a custom factor
7+
"""
8+
import numpy as np
9+
10+
import gtsam
11+
from gtsam import BetweenFactorPose2, Pose2, noiseModel
12+
from gtsam_unstable import PartialPriorFactorPose2
13+
14+
15+
def main():
16+
# 1. Create a factor graph container and add factors to it.
17+
graph = gtsam.NonlinearFactorGraph()
18+
19+
# 2a. Add odometry factors
20+
# For simplicity, we will use the same noise model for each odometry factor
21+
odometryNoise = noiseModel.Diagonal.Sigmas(np.asarray([0.2, 0.2, 0.1]))
22+
23+
# Create odometry (Between) factors between consecutive poses
24+
graph.push_back(
25+
BetweenFactorPose2(1, 2, Pose2(2.0, 0.0, 0.0), odometryNoise))
26+
graph.push_back(
27+
BetweenFactorPose2(2, 3, Pose2(2.0, 0.0, 0.0), odometryNoise))
28+
29+
# 2b. Add "GPS-like" measurements
30+
# We will use PartialPrior factor for this.
31+
unaryNoise = noiseModel.Diagonal.Sigmas(np.array([0.1,
32+
0.1])) # 10cm std on x,y
33+
34+
graph.push_back(
35+
PartialPriorFactorPose2(1, [0, 1], np.asarray([0.0, 0.0]), unaryNoise))
36+
graph.push_back(
37+
PartialPriorFactorPose2(2, [0, 1], np.asarray([2.0, 0.0]), unaryNoise))
38+
graph.push_back(
39+
PartialPriorFactorPose2(3, [0, 1], np.asarray([4.0, 0.0]), unaryNoise))
40+
graph.print("\nFactor Graph:\n")
41+
42+
# 3. Create the data structure to hold the initialEstimate estimate to the solution
43+
# For illustrative purposes, these have been deliberately set to incorrect values
44+
initialEstimate = gtsam.Values()
45+
initialEstimate.insert(1, Pose2(0.5, 0.0, 0.2))
46+
initialEstimate.insert(2, Pose2(2.3, 0.1, -0.2))
47+
initialEstimate.insert(3, Pose2(4.1, 0.1, 0.1))
48+
initialEstimate.print("\nInitial Estimate:\n")
49+
50+
# 4. Optimize using Levenberg-Marquardt optimization. The optimizer
51+
# accepts an optional set of configuration parameters, controlling
52+
# things like convergence criteria, the type of linear system solver
53+
# to use, and the amount of information displayed during optimization.
54+
# Here we will use the default set of parameters. See the
55+
# documentation for the full set of parameters.
56+
optimizer = gtsam.LevenbergMarquardtOptimizer(graph, initialEstimate)
57+
result = optimizer.optimize()
58+
result.print("Final Result:\n")
59+
60+
# 5. Calculate and print marginal covariances for all variables
61+
marginals = gtsam.Marginals(graph, result)
62+
print("x1 covariance:\n", marginals.marginalCovariance(1))
63+
print("x2 covariance:\n", marginals.marginalCovariance(2))
64+
print("x3 covariance:\n", marginals.marginalCovariance(3))
65+
66+
67+
if __name__ == "__main__":
68+
main()

python/gtsam_unstable/gtsam_unstable.tpl

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <pybind11/eigen.h>
1111
#include <pybind11/stl_bind.h>
12+
#include <pybind11/stl.h>
1213
#include <pybind11/pybind11.h>
1314
#include <pybind11/functional.h>
1415
#include <pybind11/iostream.h>

0 commit comments

Comments
 (0)