diff --git a/gtsam/CMakeLists.txt b/gtsam/CMakeLists.txt index 56bce727b..054664940 100644 --- a/gtsam/CMakeLists.txt +++ b/gtsam/CMakeLists.txt @@ -114,6 +114,12 @@ if (GTSAM_BUILD_SHARED_LIBRARY) endif() endif(GTSAM_BUILD_SHARED_LIBRARY) +# Set dataset paths +set_property(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/slam/dataset.cpp" + APPEND PROPERTY COMPILE_DEFINITIONS + "SOURCE_TREE_DATASET_DIR=\"${CMAKE_SOURCE_DIR}/examples/Data\"" + "INSTALLED_DATASET_DIR=\"${GTSAM_TOOLBOX_INSTALL_PATH}/gtsam_examples/Data\"") + # Create the matlab toolbox for the gtsam library if (GTSAM_INSTALL_MATLAB_TOOLBOX) # Set up codegen diff --git a/gtsam/slam/dataset.cpp b/gtsam/slam/dataset.cpp index 643764f71..e9ec73a85 100644 --- a/gtsam/slam/dataset.cpp +++ b/gtsam/slam/dataset.cpp @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -27,11 +29,41 @@ #include using namespace std; +namespace fs = boost::filesystem; #define LINESIZE 81920 namespace gtsam { +/* ************************************************************************* */ +string findExampleDataFile(const string& name) { + // Search source tree and installed location + vector rootsToSearch; + rootsToSearch.push_back(SOURCE_TREE_DATASET_DIR); // Defined by CMake, see gtsam/gtsam/CMakeLists.txt + rootsToSearch.push_back(INSTALLED_DATASET_DIR); // Defined by CMake, see gtsam/gtsam/CMakeLists.txt + + // Search for filename as given, and with .graph and .txt extensions + vector namesToSearch; + namesToSearch.push_back(name); + namesToSearch.push_back(name + ".graph"); + namesToSearch.push_back(name + ".txt"); + + // Find first name that exists + BOOST_FOREACH(const fs::path& root, rootsToSearch) { + BOOST_FOREACH(const fs::path& name, namesToSearch) { + if(fs::is_regular_file(root / name)) + return (root / name).string(); + } + } + + // If we did not return already, then we did not find the file + throw std::invalid_argument( + "gtsam::findExampleDataFile could not find a matching file in\n" + SOURCE_TREE_DATASET_DIR " or\n" + INSTALLED_DATASET_DIR " named\n" + + name + ", " + name + ".graph, or " + name + ".txt"); +} + /* ************************************************************************* */ pair load2D( pair > dataset, diff --git a/gtsam/slam/dataset.h b/gtsam/slam/dataset.h index c881ce2bd..7c38e13c9 100644 --- a/gtsam/slam/dataset.h +++ b/gtsam/slam/dataset.h @@ -25,6 +25,19 @@ namespace gtsam { + /** + * Find the full path to an example dataset distributed with gtsam. The name + * may be specified with or without a file extension - if no extension is + * give, this function first looks for the .graph extension, then .txt. We + * first check the gtsam source tree for the file, followed by the installed + * example dataset location. Both the source tree and installed locations + * are obtained from CMake during compilation. + * @return The full path and filename to the requested dataset. + * @throw std::invalid_argument if no matching file could be found using the + * search process described above. + */ + std::string findExampleDataFile(const std::string& name); + /** * Load TORO 2D Graph * @param dataset/model pair as constructed by [dataset] diff --git a/gtsam/slam/tests/testDataset.cpp b/gtsam/slam/tests/testDataset.cpp new file mode 100644 index 000000000..9181178f1 --- /dev/null +++ b/gtsam/slam/tests/testDataset.cpp @@ -0,0 +1,34 @@ +/* ---------------------------------------------------------------------------- + + * 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 testDataset.cpp + * @brief Unit test for dataset.cpp + * @author Richard Roberts + */ + +#include + +#include + +#include +#include + +using namespace std; +using namespace gtsam; + +TEST(dataSet, findExampleDataFile) { + const string expected_end = "gtsam/examples/Data/example.graph"; + const string actual = findExampleDataFile("example"); + string actual_end = actual.substr(actual.size() - expected_end.size(), expected_end.size()); + boost::replace_all(actual_end, "\\", "/"); // Convert directory separators to forward-slash + EXPECT(assert_equal(expected_end, actual_end)); +}