44 * See LICENSE for the license information
55 * -------------------------------------------------------------------------- */
66
7- #include < gtsam/sfm/TrajectoryAlignerSim3.h>
8-
97#include < gtsam/inference/Symbol.h>
8+ #include < gtsam/nonlinear/GncOptimizer.h>
9+ #include < gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
10+ #include < gtsam/sfm/TrajectoryAlignerSim3.h>
1011#include < gtsam/slam/expressions.h>
1112
1213#include < stdexcept>
@@ -22,7 +23,7 @@ struct MeasurementPair {
2223};
2324
2425std::vector<MeasurementPair> overlappingMeasurementPairs (
25- const std::vector<UnaryMeasurement<Pose3>> &first,
26+ const std::vector<UnaryMeasurement<Pose3>> &first,
2627 const std::vector<UnaryMeasurement<Pose3>> &second) {
2728 std::unordered_map<Key, size_t > indexLookup;
2829 indexLookup.reserve (second.size ());
@@ -41,7 +42,8 @@ std::vector<MeasurementPair> overlappingMeasurementPairs(
4142 return pairs;
4243}
4344
44- Similarity3 estimateInitialSim3 (const std::vector<MeasurementPair> &overlapPairs) {
45+ Similarity3 estimateInitialSim3 (
46+ const std::vector<MeasurementPair> &overlapPairs) {
4547 if (overlapPairs.size () < 2 ) return Similarity3 ();
4648 Pose3Pairs pairs;
4749 pairs.reserve (overlapPairs.size ());
@@ -60,10 +62,15 @@ Similarity3 estimateInitialSim3(const std::vector<MeasurementPair> &overlapPairs
6062} // namespace
6163
6264namespace gtsam {
65+
6366TrajectoryAlignerSim3::TrajectoryAlignerSim3 (
64- const std::vector<UnaryMeasurement<Pose3>> &aTi,
67+ const std::vector<UnaryMeasurement<Pose3>> &aTi,
6568 const std::vector<std::vector<UnaryMeasurement<Pose3>>> &bTi_all,
66- const std::vector<Similarity3> &bSa_all) {
69+ const std::vector<Similarity3> &bSa_all, const bool use_gnc_optimizer,
70+ const std::vector<std::vector<std::pair<Point3, Point3>>>
71+ &overlapping_points,
72+ const double point3_factor_sigma)
73+ : use_gnc_optimizer_(use_gnc_optimizer) {
6774 const size_t childCount = bTi_all.size ();
6875 if (!bSa_all.empty () && bSa_all.size () != childCount) {
6976 throw std::invalid_argument (
@@ -89,7 +96,7 @@ TrajectoryAlignerSim3::TrajectoryAlignerSim3(
8996 const auto overlap = overlappingMeasurementPairs (aTi, bTi);
9097 initial_.insert (simKey, estimateInitialSim3 (overlap));
9198 }
92-
99+
93100 const Expression<Similarity3> bSa (simKey);
94101 for (const auto &meas : bTi) {
95102 Key cameraKey = meas.key ();
@@ -100,18 +107,42 @@ TrajectoryAlignerSim3::TrajectoryAlignerSim3(
100107 graph_.addExpressionFactor (expected, meas.measured (), meas.noiseModel ());
101108 }
102109 }
110+
111+ // Any point3-point3 constraints between overlapping points.
112+ if (!overlapping_points.empty ()) {
113+ if (overlapping_points.size () != childCount) {
114+ throw std::invalid_argument (
115+ " TrajectoryAlignerSim3: overlapping_points and bTi_all sizes differ" );
116+ }
117+ for (size_t childIdx = 0 ; childIdx < childCount; ++childIdx) {
118+ const auto &overlap = overlapping_points[childIdx];
119+ const Key simKey = Symbol (' S' , childIdx);
120+ const Expression<Similarity3> bSa (simKey);
121+ for (const auto &[p1, p2] : overlap) {
122+ const Point3_ p1_ (p1);
123+ const Point3_ b_p1_ (bSa, &Similarity3::transformFrom, p1_);
124+ graph_.addExpressionFactor (
125+ b_p1_, p2, noiseModel::Isotropic::Sigma (3 , point3_factor_sigma));
126+ }
127+ }
128+ }
103129}
104130
105131Values TrajectoryAlignerSim3::solve () const {
106- if (graph_.empty () || initial_.empty ()) {
107- return initial_;
132+ if (graph_.empty () || initial_.empty ()) return initial_;
133+
134+ if (use_gnc_optimizer_) {
135+ GncOptimizer<GncParams<LevenbergMarquardtParams>> optimizer (graph_,
136+ initial_);
137+ return optimizer.optimize ();
138+ } else {
139+ LevenbergMarquardtOptimizer optimizer (graph_, initial_);
140+ return optimizer.optimize ();
108141 }
109- LevenbergMarquardtOptimizer optimizer (graph_, initial_);
110- return optimizer.optimize ();
111142}
112143
113144Marginals TrajectoryAlignerSim3::marginalize (
114- const Values& solution, const Ordering::OrderingType ordering_type) const {
145+ const Values & solution, const Ordering::OrderingType ordering_type) const {
115146 Ordering ordering = Ordering::Create (ordering_type, graph_);
116147 return Marginals (graph_, solution, ordering);
117148}
0 commit comments