/* ---------------------------------------------------------------------------- * 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 * -------------------------------------------------------------------------- */ /* * @brief Unit tests for serialization of library classes * @author Frank Dellaert * @author Alex Cunningham */ /* ************************************************************************* */ // Serialization testing code. /* ************************************************************************* */ #include #include #include // includes for standard serialization types #include #include #include #include #include #include #include #include #include #include // whether to print the serialized text to stdout const bool verbose = false; // Templated round-trip serialization template void roundtrip(const T& input, T& output) { // Serialize std::ostringstream out_archive_stream; { boost::archive::text_oarchive out_archive(out_archive_stream); out_archive << input; } // Convert to string std::string serialized = out_archive_stream.str(); if (verbose) std::cout << serialized << std::endl << std::endl; // De-serialize { std::istringstream in_archive_stream(serialized); boost::archive::text_iarchive in_archive(in_archive_stream); in_archive >> output; } } // This version requires equality operator template bool equality(const T& input = T()) { T output; roundtrip(input,output); return input==output; } // This version requires equals template bool equalsObj(const T& input = T()) { T output; roundtrip(input,output); return input.equals(output); } // De-referenced version for pointers template bool equalsDereferenced(const T& input) { T output; roundtrip(input,output); return input->equals(*output); } /* ************************************************************************* */ // Templated round-trip serialization using XML template void roundtripXML(const T& input, T& output) { // Serialize std::string serialized; { std::ostringstream out_archive_stream; boost::archive::xml_oarchive out_archive(out_archive_stream); out_archive << boost::serialization::make_nvp("data", input); // Convert to string serialized = out_archive_stream.str(); } if (verbose) std::cout << serialized << std::endl << std::endl; // De-serialize std::istringstream in_archive_stream(serialized); boost::archive::xml_iarchive in_archive(in_archive_stream); in_archive >> boost::serialization::make_nvp("data", output); } // This version requires equality operator template bool equalityXML(const T& input = T()) { T output; roundtripXML(input,output); return input==output; } // This version requires equals template bool equalsXML(const T& input = T()) { T output; roundtripXML(input,output); return input.equals(output); } // This version is for pointers template bool equalsDereferencedXML(const T& input = T()) { T output; roundtripXML(input,output); return input->equals(*output); } /* ************************************************************************* */ // Actual Tests /* ************************************************************************* */ #include #include #include #include #include #include #include //#include //#include //#include #include #include #include using namespace std; using namespace gtsam; using namespace planarSLAM; /* ************************************************************************* */ TEST (Serialization, text_geometry) { EXPECT(equalsObj(Point2(1.0, 2.0))); EXPECT(equalsObj(Pose2(1.0, 2.0, 0.3))); EXPECT(equalsObj(Rot2::fromDegrees(30.0))); Point3 pt3(1.0, 2.0, 3.0); Rot3 rt3 = Rot3::RzRyRx(1.0, 3.0, 2.0); EXPECT(equalsObj(pt3)); EXPECT(equalsObj(rt3)); EXPECT(equalsObj(Pose3(rt3, pt3))); } /* ************************************************************************* */ TEST (Serialization, xml_geometry) { EXPECT(equalsXML(Point2(1.0, 2.0))); EXPECT(equalsXML(Pose2(1.0, 2.0, 0.3))); EXPECT(equalsXML(Rot2::fromDegrees(30.0))); Point3 pt3(1.0, 2.0, 3.0); Rot3 rt3 = Rot3::RzRyRx(1.0, 3.0, 2.0); EXPECT(equalsXML(pt3)); EXPECT(equalsXML(rt3)); EXPECT(equalsXML(Pose3(rt3, pt3))); } /* ************************************************************************* */ TEST (Serialization, text_linear) { // NOT WORKING: // EXPECT(equalsObj()); // EXPECT(equalsObj()); } /* ************************************************************************* */ TEST (Serialization, xml_linear) { // NOT WORKING: // EXPECT(equalsXML()); // EXPECT(equalsXML()); } /* ************************************************************************* */ // example noise models noiseModel::Diagonal::shared_ptr diag3 = noiseModel::Diagonal::Sigmas(Vector_(3, 0.1, 0.2, 0.3)); noiseModel::Gaussian::shared_ptr gaussian3 = noiseModel::Gaussian::SqrtInformation(2.0 * eye(3,3)); noiseModel::Isotropic::shared_ptr iso3 = noiseModel::Isotropic::Sigma(3, 0.2); noiseModel::Constrained::shared_ptr constrained3 = noiseModel::Constrained::MixedSigmas(Vector_(3, 0.0, 0.0, 0.1)); noiseModel::Unit::shared_ptr unit3 = noiseModel::Unit::Create(3); /* ************************************************************************* */ TEST (Serialization, noiseModels) { // tests using pointers to the derived class EXPECT( equalsDereferenced(diag3)); EXPECT(equalsDereferencedXML(diag3)); EXPECT( equalsDereferenced(gaussian3)); EXPECT(equalsDereferencedXML(gaussian3)); EXPECT( equalsDereferenced(iso3)); EXPECT(equalsDereferencedXML(iso3)); EXPECT( equalsDereferenced(constrained3)); EXPECT(equalsDereferencedXML(constrained3)); EXPECT( equalsDereferenced(unit3)); EXPECT(equalsDereferencedXML(unit3)); } /* ************************************************************************* */ TEST (Serialization, SharedGaussian_noiseModels) { EXPECT(equalsDereferenced(diag3)); EXPECT(equalsDereferencedXML(diag3)); EXPECT(equalsDereferenced(iso3)); EXPECT(equalsDereferencedXML(iso3)); EXPECT(equalsDereferenced(gaussian3)); EXPECT(equalsDereferencedXML(gaussian3)); EXPECT(equalsDereferenced(unit3)); EXPECT(equalsDereferencedXML(unit3)); EXPECT(equalsDereferenced(constrained3)); EXPECT(equalsDereferencedXML(constrained3)); } /* ************************************************************************* */ TEST (Serialization, SharedDiagonal_noiseModels) { EXPECT(equalsDereferenced(diag3)); EXPECT(equalsDereferencedXML(diag3)); EXPECT(equalsDereferenced(iso3)); EXPECT(equalsDereferencedXML(iso3)); EXPECT(equalsDereferenced(unit3)); EXPECT(equalsDereferencedXML(unit3)); EXPECT(equalsDereferenced(constrained3)); EXPECT(equalsDereferencedXML(constrained3)); } /* ************************************************************************* */ /* Create GUIDs for factors */ BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::Prior, "gtsam::planarSLAM::Prior"); BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::Bearing, "gtsam::planarSLAM::Bearing"); BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::Range, "gtsam::planarSLAM::Range"); BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::BearingRange,"gtsam::planarSLAM::BearingRange"); BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::Odometry, "gtsam::planarSLAM::Odometry"); BOOST_CLASS_EXPORT_GUID(gtsam::planarSLAM::Constraint, "gtsam::planarSLAM::Constraint"); /* ************************************************************************* */ TEST (Serialization, planar_system) { Values values; values.insert(PointKey(3), Point2(1.0, 2.0)); values.insert(PoseKey(4), Pose2(1.0, 2.0, 0.3)); SharedGaussian model1 = noiseModel::Isotropic::Sigma(1, 0.3); SharedGaussian model2 = noiseModel::Isotropic::Sigma(2, 0.3); SharedGaussian model3 = noiseModel::Isotropic::Sigma(3, 0.3); Prior prior(PoseKey(3), Pose2(0.1,-0.3, 0.2), model1); Bearing bearing(PoseKey(3), PointKey(5), Rot2::fromDegrees(0.5), model1); Range range(PoseKey(2), PointKey(9), 7.0, model1); BearingRange bearingRange(PoseKey(2), PointKey(3), Rot2::fromDegrees(0.6), 2.0, model2); Odometry odometry(PoseKey(2), PoseKey(3), Pose2(1.0, 2.0, 0.3), model3); Constraint constraint(PoseKey(9), Pose2(2.0,-1.0, 0.2)); Graph graph; graph.add(prior); graph.add(bearing); graph.add(range); graph.add(bearingRange); graph.add(odometry); graph.add(constraint); // text EXPECT(equalsObj(PoseKey(2))); EXPECT(equalsObj(PointKey(3))); EXPECT(equalsObj(values)); EXPECT(equalsObj(prior)); EXPECT(equalsObj(bearing)); EXPECT(equalsObj(bearingRange)); EXPECT(equalsObj(range)); EXPECT(equalsObj(odometry)); EXPECT(equalsObj(constraint)); EXPECT(equalsObj(graph)); // xml EXPECT(equalsXML(PoseKey(2))); EXPECT(equalsXML(PointKey(3))); EXPECT(equalsXML(values)); EXPECT(equalsXML(prior)); EXPECT(equalsXML(bearing)); EXPECT(equalsXML(bearingRange)); EXPECT(equalsXML(range)); EXPECT(equalsXML(odometry)); EXPECT(equalsXML(constraint)); EXPECT(equalsXML(graph)); } /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr); } /* ************************************************************************* */