diff --git a/gtsam/slam/dataset.cpp b/gtsam/slam/dataset.cpp index dc25026d2..40a2573b3 100644 --- a/gtsam/slam/dataset.cpp +++ b/gtsam/slam/dataset.cpp @@ -195,6 +195,33 @@ static SharedNoiseModel readNoiseModel(ifstream& is, bool smart, } } +/* ************************************************************************* */ +boost::optional > parseVertex(istream& is, const string& tag) { + if ((tag == "VERTEX2") || (tag == "VERTEX_SE2") || (tag == "VERTEX")) { + Key id; + double x, y, yaw; + is >> id >> x >> y >> yaw; + return pair(id, Pose2(x, y, yaw)); + } else { + return boost::none; + } +} + +/* ************************************************************************* */ +boost::optional, Pose2> > parseEdge(istream& is, const string& tag) { + if ((tag == "EDGE2") || (tag == "EDGE") || (tag == "EDGE_SE2") + || (tag == "ODOMETRY")) { + + Key id1, id2; + double x, y, yaw; + is >> id1 >> id2 >> x >> y >> yaw; + return pair, Pose2>(pair(id1, id2), + Pose2(x, y, yaw)); + } else { + return boost::none; + } +} + /* ************************************************************************* */ GraphAndValues load2D(const string& filename, SharedNoiseModel model, Key maxID, bool addNoise, bool smart, NoiseFormat noiseFormat, @@ -214,16 +241,15 @@ GraphAndValues load2D(const string& filename, SharedNoiseModel model, Key maxID, if (!(is >> tag)) break; - if ((tag == "VERTEX2") || (tag == "VERTEX_SE2") || (tag == "VERTEX")) { - Key id; - double x, y, yaw; - is >> id >> x >> y >> yaw; + const auto indexed_pose = parseVertex(is, tag); + if (indexed_pose) { + Key id = indexed_pose->first; // optional filter if (maxID && id >= maxID) continue; - initial->insert(id, Pose2(x, y, yaw)); + initial->insert(id, indexed_pose->second); } is.ignore(LINESIZE, '\n'); } @@ -251,13 +277,10 @@ GraphAndValues load2D(const string& filename, SharedNoiseModel model, Key maxID, if (!(is >> tag)) break; - if ((tag == "EDGE2") || (tag == "EDGE") || (tag == "EDGE_SE2") - || (tag == "ODOMETRY")) { - - // Read transform - double x, y, yaw; - is >> id1 >> id2 >> x >> y >> yaw; - Pose2 l1Xl2(x, y, yaw); + auto between_pose = parseEdge(is, tag); + if (between_pose) { + std::tie(id1, id2) = between_pose->first; + Pose2& l1Xl2 = between_pose->second; // read noise model SharedNoiseModel modelInFile = readNoiseModel(is, smart, noiseFormat, diff --git a/gtsam/slam/dataset.h b/gtsam/slam/dataset.h index dc7804c2d..76dd398a0 100644 --- a/gtsam/slam/dataset.h +++ b/gtsam/slam/dataset.h @@ -33,6 +33,7 @@ #include #include // for pair #include +#include namespace gtsam { @@ -88,6 +89,22 @@ GTSAM_EXPORT GraphAndValues load2D( NoiseFormat noiseFormat = NoiseFormatAUTO, KernelFunctionType kernelFunctionType = KernelFunctionTypeNONE); +/** + * Parse TORO/G2O vertex "id x y yaw" + * @param is input stream + * @param tag string parsed from input stream, will only parse if vertex type + */ +boost::optional > parseVertex(std::istream& is, + const std::string& tag); + +/** + * Parse TORO/G2O edge "id1 id2 x y yaw" + * @param is input stream + * @param tag string parsed from input stream, will only parse if edge type + */ +boost::optional, Pose2> > parseEdge( + std::istream& is, const std::string& tag); + /** * Load TORO/G2O style graph files * @param filename diff --git a/gtsam/slam/tests/testDataset.cpp b/gtsam/slam/tests/testDataset.cpp index b3e208b91..39c2d3722 100644 --- a/gtsam/slam/tests/testDataset.cpp +++ b/gtsam/slam/tests/testDataset.cpp @@ -26,6 +26,9 @@ #include +#include +#include + using namespace gtsam::symbol_shorthand; using namespace std; using namespace gtsam; @@ -39,6 +42,37 @@ TEST(dataSet, findExampleDataFile) { EXPECT(assert_equal(expected_end, actual_end)); } +/* ************************************************************************* */ +TEST( dataSet, parseVertex) +{ + const string str = "VERTEX2 1 2.000000 3.000000 4.000000"; + istringstream is(str); + string tag; + EXPECT(is >> tag); + const auto actual = parseVertex(is, tag); + EXPECT(actual); + if (actual) { + EXPECT_LONGS_EQUAL(1, actual->first); + EXPECT(assert_equal(Pose2(2, 3, 4), actual->second)); + } +} + +/* ************************************************************************* */ +TEST( dataSet, parseEdge) +{ + const string str = "EDGE2 0 1 2.000000 3.000000 4.000000"; + istringstream is(str); + string tag; + EXPECT(is >> tag); + const auto actual = parseEdge(is, tag); + EXPECT(actual); + if (actual) { + pair expected(0, 1); + EXPECT(expected == actual->first); + EXPECT(assert_equal(Pose2(2, 3, 4), actual->second)); + } +} + /* ************************************************************************* */ TEST( dataSet, load2D) {