/** * @file testNonlinearISAM * @author Alex Cunningham */ #include #include #include #include #include #include #include #include #include #include #include using namespace gtsam; const double tol=1e-5; /* ************************************************************************* */ TEST(testNonlinearISAM, markov_chain ) { int reorder_interval = 2; NonlinearISAM isamChol(reorder_interval, EliminatePreferCholesky); // create an ISAM object NonlinearISAM isamQR(reorder_interval, EliminateQR); // create an ISAM object SharedDiagonal model = noiseModel::Diagonal::Sigmas((Vec(3) << 3.0, 3.0, 0.5)); Sampler sampler(model, 42u); // create initial graph Pose2 cur_pose; // start at origin NonlinearFactorGraph start_factors; start_factors += NonlinearEquality(0, cur_pose); Values init; Values expected; init.insert(0, cur_pose); expected.insert(0, cur_pose); isamChol.update(start_factors, init); isamQR.update(start_factors, init); // loop for a period of time to verify memory usage size_t nrPoses = 21; Pose2 z(1.0, 2.0, 0.1); for (size_t i=1; i<=nrPoses; ++i) { NonlinearFactorGraph new_factors; new_factors += BetweenFactor(i-1, i, z, model); Values new_init; cur_pose = cur_pose.compose(z); new_init.insert(i, cur_pose.retract(sampler.sample())); expected.insert(i, cur_pose); isamChol.update(new_factors, new_init); isamQR.update(new_factors, new_init); } // verify values - all but the last one should be very close Values actualChol = isamChol.estimate(); for (size_t i=0; i(i), actualChol.at(i), tol)); } Values actualQR = isamQR.estimate(); for (size_t i=0; i(i), actualQR.at(i), tol)); } } /* ************************************************************************* */ TEST(testNonlinearISAM, markov_chain_with_disconnects ) { int reorder_interval = 2; NonlinearISAM isamChol(reorder_interval, EliminatePreferCholesky); // create an ISAM object NonlinearISAM isamQR(reorder_interval, EliminateQR); // create an ISAM object SharedDiagonal model3 = noiseModel::Diagonal::Sigmas((Vec(3) << 3.0, 3.0, 0.5)); SharedDiagonal model2 = noiseModel::Diagonal::Sigmas((Vec(2) << 2.0, 2.0)); Sampler sampler(model3, 42u); // create initial graph Pose2 cur_pose; // start at origin NonlinearFactorGraph start_factors; start_factors += NonlinearEquality(0, cur_pose); Values init; Values expected; init.insert(0, cur_pose); expected.insert(0, cur_pose); isamChol.update(start_factors, init); isamQR.update(start_factors, init); size_t nrPoses = 21; // create a constrained constellation of landmarks Key lm1 = nrPoses+1, lm2 = nrPoses+2, lm3 = nrPoses+3; Point2 landmark1(3., 4.), landmark2(6., 4.), landmark3(6., 9.); expected.insert(lm1, landmark1); expected.insert(lm2, landmark2); expected.insert(lm3, landmark3); // loop for a period of time to verify memory usage Pose2 z(1.0, 2.0, 0.1); for (size_t i=1; i<=nrPoses; ++i) { NonlinearFactorGraph new_factors; new_factors += BetweenFactor(i-1, i, z, model3); Values new_init; cur_pose = cur_pose.compose(z); new_init.insert(i, cur_pose.retract(sampler.sample())); expected.insert(i, cur_pose); // Add a floating landmark constellation if (i == 7) { new_factors += PriorFactor(lm1, landmark1, model2); new_factors += PriorFactor(lm2, landmark2, model2); new_factors += PriorFactor(lm3, landmark3, model2); // Initialize to origin new_init.insert(lm1, Point2()); new_init.insert(lm2, Point2()); new_init.insert(lm3, Point2()); } isamChol.update(new_factors, new_init); isamQR.update(new_factors, new_init); } // verify values - all but the last one should be very close Values actualChol = isamChol.estimate(); for (size_t i=0; i(i), actualChol.at(i), tol)); Values actualQR = isamQR.estimate(); for (size_t i=0; i(i), actualQR.at(i), tol)); // Check landmarks EXPECT(assert_equal(expected.at(lm1), actualChol.at(lm1), tol)); EXPECT(assert_equal(expected.at(lm2), actualChol.at(lm2), tol)); EXPECT(assert_equal(expected.at(lm3), actualChol.at(lm3), tol)); EXPECT(assert_equal(expected.at(lm1), actualQR.at(lm1), tol)); EXPECT(assert_equal(expected.at(lm2), actualQR.at(lm2), tol)); EXPECT(assert_equal(expected.at(lm3), actualQR.at(lm3), tol)); } /* ************************************************************************* */ TEST(testNonlinearISAM, markov_chain_with_reconnect ) { int reorder_interval = 2; NonlinearISAM isamChol(reorder_interval, EliminatePreferCholesky); // create an ISAM object NonlinearISAM isamQR(reorder_interval, EliminateQR); // create an ISAM object SharedDiagonal model3 = noiseModel::Diagonal::Sigmas((Vec(3) << 3.0, 3.0, 0.5)); SharedDiagonal model2 = noiseModel::Diagonal::Sigmas((Vec(2) << 2.0, 2.0)); Sampler sampler(model3, 42u); // create initial graph Pose2 cur_pose; // start at origin NonlinearFactorGraph start_factors; start_factors += NonlinearEquality(0, cur_pose); Values init; Values expected; init.insert(0, cur_pose); expected.insert(0, cur_pose); isamChol.update(start_factors, init); isamQR.update(start_factors, init); size_t nrPoses = 21; // create a constrained constellation of landmarks Key lm1 = nrPoses+1, lm2 = nrPoses+2, lm3 = nrPoses+3; Point2 landmark1(3., 4.), landmark2(6., 4.), landmark3(6., 9.); expected.insert(lm1, landmark1); expected.insert(lm2, landmark2); expected.insert(lm3, landmark3); // loop for a period of time to verify memory usage Pose2 z(1.0, 2.0, 0.1); for (size_t i=1; i<=nrPoses; ++i) { NonlinearFactorGraph new_factors; new_factors += BetweenFactor(i-1, i, z, model3); Values new_init; cur_pose = cur_pose.compose(z); new_init.insert(i, cur_pose.retract(sampler.sample())); expected.insert(i, cur_pose); // Add a floating landmark constellation if (i == 7) { new_factors += PriorFactor(lm1, landmark1, model2); new_factors += PriorFactor(lm2, landmark2, model2); new_factors += PriorFactor(lm3, landmark3, model2); // Initialize to origin new_init.insert(lm1, Point2()); new_init.insert(lm2, Point2()); new_init.insert(lm3, Point2()); } // Reconnect with observation later if (i == 15) { new_factors += BearingRangeFactor( i, lm1, cur_pose.bearing(landmark1), cur_pose.range(landmark1), model2); } isamChol.update(new_factors, new_init); isamQR.update(new_factors, new_init); } // verify values - all but the last one should be very close Values actualChol = isamChol.estimate(); for (size_t i=0; i(i), actualChol.at(i), tol)); Values actualQR = isamQR.estimate(); for (size_t i=0; i(i), actualQR.at(i), tol)); // Check landmarks EXPECT(assert_equal(expected.at(lm1), actualChol.at(lm1), tol)); EXPECT(assert_equal(expected.at(lm2), actualChol.at(lm2), tol)); EXPECT(assert_equal(expected.at(lm3), actualChol.at(lm3), tol)); EXPECT(assert_equal(expected.at(lm1), actualQR.at(lm1), tol)); EXPECT(assert_equal(expected.at(lm2), actualQR.at(lm2), tol)); EXPECT(assert_equal(expected.at(lm3), actualQR.at(lm3), tol)); } /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr); } /* ************************************************************************* */