/* ---------------------------------------------------------------------------- * GTSAM Copyright 2010, Georgia Tech Research Corporation, * Atlanta, Georgia 30332-0415 * All Rights Reserved * Authors: Frank Dellaert, et al. (see THANKS for the full author list) * See LICENSE for the license information * -------------------------------------------------------------------------- */ /** * @file testIncrementalFixedLagSmoother.cpp * @brief Unit tests for the Incremental Fixed-Lag Smoother * @author Stephen Williams (swilliams8@gatech.edu) * @date May 23, 2012 */ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace gtsam; Key MakeKey(size_t index) { return Symbol('x', index); } /* ************************************************************************* */ bool check_smoother(const NonlinearFactorGraph& fullgraph, const Values& fullinit, const IncrementalFixedLagSmoother& smoother, const Key& key) { Ordering ordering = *fullgraph.orderingCOLAMD(fullinit); GaussianFactorGraph linearized = *fullgraph.linearize(fullinit, ordering); GaussianBayesNet gbn = *GaussianSequentialSolver(linearized).eliminate(); VectorValues delta = optimize(gbn); Values fullfinal = fullinit.retract(delta, ordering); Point2 expected = fullfinal.at(key); Point2 actual = smoother.calculateEstimate(key); return assert_equal(expected, actual); } /* ************************************************************************* */ TEST_UNSAFE( IncrementalFixedLagSmoother, Example ) { // Test the IncrementalFixedLagSmoother in a pure linear environment. Thus, full optimization and // the IncrementalFixedLagSmoother should be identical (even with the linearized approximations at // the end of the smoothing lag) SETDEBUG("IncrementalFixedLagSmoother update", true); // Set up parameters SharedDiagonal odometerNoise = noiseModel::Diagonal::Sigmas(Vector_(2, 0.1, 0.1)); SharedDiagonal loopNoise = noiseModel::Diagonal::Sigmas(Vector_(2, 0.1, 0.1)); // Create a Fixed-Lag Smoother typedef IncrementalFixedLagSmoother::KeyTimestampMap Timestamps; IncrementalFixedLagSmoother smoother(7.0, ISAM2Params()); // Create containers to keep the full graph Values fullinit; NonlinearFactorGraph fullgraph; // i keeps track of the time step size_t i = 0; // Add a prior at time 0 and update the HMF { Key key0 = MakeKey(0); NonlinearFactorGraph newFactors; Values newValues; Timestamps newTimestamps; newFactors.add(PriorFactor(key0, Point2(0.0, 0.0), odometerNoise)); newValues.insert(key0, Point2(0.01, 0.01)); newTimestamps[key0] = 0.0; fullgraph.push_back(newFactors); fullinit.insert(newValues); // Update the smoother smoother.update(newFactors, newValues, newTimestamps); // Check CHECK(check_smoother(fullgraph, fullinit, smoother, key0)); ++i; } // Add odometry from time 0 to time 5 while(i <= 5) { Key key1 = MakeKey(i-1); Key key2 = MakeKey(i); NonlinearFactorGraph newFactors; Values newValues; Timestamps newTimestamps; newFactors.add(BetweenFactor(key1, key2, Point2(1.0, 0.0), odometerNoise)); newValues.insert(key2, Point2(double(i)+0.1, -0.1)); newTimestamps[key2] = double(i); fullgraph.push_back(newFactors); fullinit.insert(newValues); // Update the smoother smoother.update(newFactors, newValues, newTimestamps); // Check CHECK(check_smoother(fullgraph, fullinit, smoother, key2)); ++i; } // Add odometry from time 5 to 6 to the HMF and a loop closure at time 5 to the TSM { // Add the odometry factor to the HMF Key key1 = MakeKey(i-1); Key key2 = MakeKey(i); NonlinearFactorGraph newFactors; Values newValues; Timestamps newTimestamps; newFactors.add(BetweenFactor(key1, key2, Point2(1.0, 0.0), odometerNoise)); newFactors.add(BetweenFactor(MakeKey(2), MakeKey(5), Point2(3.5, 0.0), loopNoise)); newValues.insert(key2, Point2(double(i)+0.1, -0.1)); newTimestamps[key2] = double(i); fullgraph.push_back(newFactors); fullinit.insert(newValues); // Update the smoother smoother.update(newFactors, newValues, newTimestamps); // Check CHECK(check_smoother(fullgraph, fullinit, smoother, key2)); ++i; } // Add odometry from time 6 to time 15 while(i <= 15) { Key key1 = MakeKey(i-1); Key key2 = MakeKey(i); NonlinearFactorGraph newFactors; Values newValues; Timestamps newTimestamps; newFactors.add(BetweenFactor(key1, key2, Point2(1.0, 0.0), odometerNoise)); newValues.insert(key2, Point2(double(i)+0.1, -0.1)); newTimestamps[key2] = double(i); fullgraph.push_back(newFactors); fullinit.insert(newValues); // Update the smoother smoother.update(newFactors, newValues, newTimestamps); // Check CHECK(check_smoother(fullgraph, fullinit, smoother, key2)); ++i; } } /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr);} /* ************************************************************************* */