diff --git a/.github/workflows/ci_windows.yml b/.github/workflows/ci_windows.yml
index 43ca7126872ff..9e5dc46b21bf7 100644
--- a/.github/workflows/ci_windows.yml
+++ b/.github/workflows/ci_windows.yml
@@ -21,7 +21,7 @@ jobs:
env:
BUILD_TYPE: ${{ matrix.build_type }}
VCPKG_ROOT: "C:/dartsim/vcpkg"
- VCPKG_BUILD_TAG: v0.2.0-70f192e
+ VCPKG_BUILD_TAG: v6.13-c973b49-1
steps:
- name: Checkout
uses: actions/checkout@v2
diff --git a/Brewfile b/Brewfile
index 6211ab3807e7a..68ff9e0013232 100644
--- a/Brewfile
+++ b/Brewfile
@@ -3,10 +3,10 @@ brew 'cmake'
brew 'pkg-config'
brew 'assimp'
-brew 'boost'
brew 'bullet'
brew 'eigen'
brew 'fcl'
+brew 'fmt'
brew 'flann'
brew 'ipopt'
brew 'libccd'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ae03efb9e329..5e5ae2da226df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
### [DART 6.13.0 (TBD)](https://github.com/dartsim/dart/milestone/69?closed=1)
+* Dependency
+
+ * Added required dependencies: fmt
+ * Added optional dependencies: spdlog
+ * Removed required dependencies: Boost
+
* Build
* Dropped supporting FCL < 0.5: [#1647](https://github.com/dartsim/dart/pull/1647)
@@ -12,7 +18,7 @@
* Added spdlog support as underlying logging framework: [#1633](https://github.com/dartsim/dart/pull/1633)
* Added custom memory allocators: [#1636](https://github.com/dartsim/dart/pull/1636), [#1637](https://github.com/dartsim/dart/pull/1637), [#1639](https://github.com/dartsim/dart/pull/1639), [#1645](https://github.com/dartsim/dart/pull/1645), [#1646](https://github.com/dartsim/dart/pull/1646)
* Added Stopwatch class to replace Timer: [#1638](https://github.com/dartsim/dart/pull/1638)
- * Removed use of boos::filesystem and boost::optional: [#1648](https://github.com/dartsim/dart/pull/1648)
+ * Removed Boost dependency: [#1648](https://github.com/dartsim/dart/pull/1648), [#1651](https://github.com/dartsim/dart/pull/1651)
* Dynamics
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a7e2968f967d4..28ca5f2f8b4b7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,7 +68,7 @@ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3"
set(DART_VERSION "${DART_MAJOR_VERSION}.${DART_MINOR_VERSION}.${DART_PATCH_VERSION}")
set(DART_PKG_DESC "Dynamic Animation and Robotics Toolkit.")
-set(DART_PKG_EXTERNAL_DEPS "eigen, ccd, fcl, assimp, boost")
+set(DART_PKG_EXTERNAL_DEPS "eigen, ccd, fcl, assimp")
#===============================================================================
# Build options
diff --git a/Dockerfile b/Dockerfile
index c751e7c6e9068..aeb5ef9ab10da 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,7 +20,7 @@ RUN apt-get update \
libassimp-dev \
libccd-dev \
libfcl-dev \
- libboost-all-dev \
+ libfmt-dev \
libnlopt-cxx-dev \
coinor-libipopt-dev \
libbullet-dev \
@@ -34,6 +34,7 @@ RUN apt-get update \
libxmu-dev \
freeglut3-dev \
libopenscenegraph-dev \
+ libspdlog-dev \
&& rm -rf /var/lib/apt/lists/*
# Install dartpy dependencies
diff --git a/cmake/DARTFindBoost.cmake b/cmake/DARTFindBoost.cmake
deleted file mode 100644
index 0c1663cf6dbc0..0000000000000
--- a/cmake/DARTFindBoost.cmake
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (c) 2011-2022, The DART development contributors
-# All rights reserved.
-#
-# The list of contributors can be found at:
-# https://github.com/dartsim/dart/blob/master/LICENSE
-#
-# This file is provided under the "BSD-style" License
-
-set(DART_MIN_BOOST_VERSION 1.65.1 CACHE INTERNAL "Boost min version requirement" FORCE)
-if(MSVC)
- add_definitions(-DBOOST_ALL_NO_LIB)
-endif()
-add_definitions(-DBOOST_TEST_DYN_LINK)
-set(Boost_USE_MULTITHREADED ON)
-set(Boost_USE_STATIC_RUNTIME OFF)
-set(BOOST_REQUIRED_COMPONENTS system filesystem)
-if(DART_VERBOSE)
- find_package(Boost ${DART_MIN_BOOST_VERSION} REQUIRED COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
-else()
- find_package(Boost ${DART_MIN_BOOST_VERSION} QUIET REQUIRED COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
-endif()
-
-if(NOT TARGET Boost::system)
- add_library(Boost::system INTERFACE IMPORTED)
- set_target_properties(Boost::system PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
- INTERFACE_LINK_LIBRARIES "${Boost_SYSTEM_LIBRARY}"
- )
-endif()
-if(NOT TARGET Boost::filesystem)
- add_library(Boost::filesystem INTERFACE IMPORTED)
- set_target_properties(Boost::filesystem PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
- INTERFACE_LINK_LIBRARIES "${Boost_FILESYSTEM_LIBRARY}"
- )
-endif()
diff --git a/cmake/DARTFindDependencies.cmake b/cmake/DARTFindDependencies.cmake
index b4ef4fce15456..3cdb6ea8df61e 100644
--- a/cmake/DARTFindDependencies.cmake
+++ b/cmake/DARTFindDependencies.cmake
@@ -9,6 +9,10 @@ if(DART_VERBOSE)
message(STATUS "[ Required dependencies for DART core ]")
endif()
+# fmt
+dart_find_package(fmt)
+dart_check_required_package(fmt "libfmt")
+
# Eigen
dart_find_package(Eigen3)
dart_check_required_package(EIGEN3 "eigen3")
@@ -85,9 +89,6 @@ if(ASSIMP_FOUND)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()
-# Boost
-dart_find_package(Boost)
-
# octomap
dart_find_package(octomap)
if(MSVC)
diff --git a/cmake/DARTFindfmt.cmake b/cmake/DARTFindfmt.cmake
new file mode 100644
index 0000000000000..2eee80f666e24
--- /dev/null
+++ b/cmake/DARTFindfmt.cmake
@@ -0,0 +1,9 @@
+# Copyright (c) 2011-2022, The DART development contributors
+# All rights reserved.
+#
+# The list of contributors can be found at:
+# https://github.com/dartsim/dart/blob/master/LICENSE
+#
+# This file is provided under the "BSD-style" License
+
+find_package(fmt)
diff --git a/dart/CMakeLists.txt b/dart/CMakeLists.txt
index 8c7ecda232a76..e97af485f9c88 100644
--- a/dart/CMakeLists.txt
+++ b/dart/CMakeLists.txt
@@ -39,8 +39,8 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${DART_BINARY_DIR}/lib")
# Targets - {dependency targets}, source directories, [external dependency libs]
#===============================================================================
# dart - common, math, integration, lcpsolver, optimizer, dynamics, collision,
-# collision/dart, collision/fcl, constraint, simulation, [eigen3, libccd,
-# fcl, assimp, boost]
+# collision/dart, collision/fcl, constraint, simulation, [assimp, eigen3,
+# fcl, fmt, libccd]
# dart-optimizer-ipopt - {dart}, optimizer/ipopt, [ipopt]
# dart-optimizer-nlopt - {dart}, optimizer/nlopt, [nlopt]
# dart-collision-bullet - {dart}, collision/bullet, [bullet]
@@ -131,10 +131,8 @@ target_link_libraries(dart
Eigen3::Eigen
ccd
fcl
+ fmt::fmt
assimp
- Boost::boost
- Boost::system
- Boost::filesystem
)
# spdlog settings
@@ -207,7 +205,7 @@ endif()
add_component_targets(${PROJECT_NAME} dart dart)
add_component_dependencies(${PROJECT_NAME} dart external-odelcpsolver)
add_component_dependency_packages(${PROJECT_NAME} dart
- Eigen3 ccd fcl assimp Boost
+ assimp Eigen3 ccd fcl fmt
)
if(TARGET octomap)
add_component_dependency_packages(${PROJECT_NAME} dart octomap)
diff --git a/dart/common/String.cpp b/dart/common/String.cpp
new file mode 100644
index 0000000000000..a60a42eb198c1
--- /dev/null
+++ b/dart/common/String.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011-2022, The DART development contributors
+ * All rights reserved.
+ *
+ * The list of contributors can be found at:
+ * https://github.com/dartsim/dart/blob/master/LICENSE
+ *
+ * This file is provided under the following "BSD-style" License:
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "dart/common/String.hpp"
+
+#include
+
+namespace dart::common {
+
+//==============================================================================
+std::string toUpper(std::string str)
+{
+ toUpperInPlace(str);
+ return str;
+}
+
+//==============================================================================
+void toUpperInPlace(std::string& str)
+{
+ std::transform(str.begin(), str.end(), str.begin(), ::toupper);
+}
+
+//==============================================================================
+std::string toLower(std::string str)
+{
+ toLowerInPlace(str);
+ return str;
+}
+
+//==============================================================================
+void toLowerInPlace(std::string& str)
+{
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+}
+
+//==============================================================================
+std::string trim(const std::string& str, const std::string& whitespaces)
+{
+ return trimRight(trimLeft(str, whitespaces), whitespaces);
+}
+
+//==============================================================================
+std::string trimLeft(const std::string& str, const std::string& whitespaces)
+{
+ size_t startpos = str.find_first_not_of(whitespaces);
+ return (startpos == std::string::npos) ? "" : str.substr(startpos);
+}
+
+//==============================================================================
+std::string trimRight(const std::string& str, const std::string& whitespaces)
+{
+ size_t endpos = str.find_last_not_of(whitespaces);
+ return (endpos == std::string::npos) ? "" : str.substr(0, endpos + 1);
+}
+
+//==============================================================================
+std::vector split(
+ const std::string& str, const std::string& delimiters)
+{
+ std::vector tokens;
+ std::size_t start = str.find_first_not_of(delimiters), end = 0;
+
+ while ((end = str.find_first_of(delimiters, start)) != std::string::npos)
+ {
+ tokens.push_back(str.substr(start, end - start));
+ start = str.find_first_not_of(delimiters, end);
+ }
+
+ if (start != std::string::npos)
+ {
+ tokens.push_back(str.substr(start));
+ }
+
+ return tokens;
+}
+
+} // namespace dart::common
diff --git a/dart/common/String.hpp b/dart/common/String.hpp
new file mode 100644
index 0000000000000..53540698bae0f
--- /dev/null
+++ b/dart/common/String.hpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011-2022, The DART development contributors
+ * All rights reserved.
+ *
+ * The list of contributors can be found at:
+ * https://github.com/dartsim/dart/blob/master/LICENSE
+ *
+ * This file is provided under the following "BSD-style" License:
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DART_COMMON_STRING_HPP_
+#define DART_COMMON_STRING_HPP_
+
+#include
+#include
+
+namespace dart::common {
+
+/// Converts string to upper cases
+std::string toUpper(std::string str);
+
+/// Converts string to upper cases in place
+void toUpperInPlace(std::string& str);
+
+/// Converts string to lower cases
+std::string toLower(std::string str);
+
+/// Converts string to lower cases in place
+void toLowerInPlace(std::string& str);
+
+/// Trims both sides of string
+std::string trim(
+ const std::string& str, const std::string& whitespaces = " \n\r\t");
+
+/// Trims left side of string
+std::string trimLeft(
+ const std::string& str, const std::string& whitespaces = " \n\r\t");
+
+/// Trims right side of string
+std::string trimRight(
+ const std::string& str, const std::string& whitespaces = " \n\r\t");
+
+/// Splits string given delimiters
+std::vector split(
+ const std::string& str, const std::string& delimiters = " \n\r\t");
+
+} // namespace dart::common
+
+#endif // DART_COMMON_STRING_HPP_
diff --git a/dart/utils/CMakeLists.txt b/dart/utils/CMakeLists.txt
index 1f9342dae0f03..be0162f8cefb2 100644
--- a/dart/utils/CMakeLists.txt
+++ b/dart/utils/CMakeLists.txt
@@ -2,33 +2,11 @@
dart_find_package(tinyxml2)
dart_check_optional_package(TINYXML2 "dart-utils" "tinyxml2" "1.0.1")
-# Test whether boost algorithm and lexical_cast headers are available.
-include(CheckCXXSourceCompiles)
-set(CMAKE_REQUIRED_FLAGS "-w")
-set(CMAKE_REQUIRED_INCLUDES "${Boost_INCLUDE_DIRS}")
-check_cxx_source_compiles(
- "
- #include
- #include
- int main()
- {
- return 0;
- }
- "
- HAS_BOOST_ALGORITHM_LEXICAL_CAST
-)
-if(HAS_BOOST_ALGORITHM_LEXICAL_CAST)
- if(DART_VERBOSE)
- message(STATUS "Looking for Boost algorithm and lexical_cast headers - found")
- endif()
-else()
- message(WARNING "Looking for Boost algorithm and lexical_cast headers - NOT found, to use dart-utils, please install missing boost headers")
- return()
-endif()
-
# Search all header and source files
file(GLOB hdrs "*.hpp")
file(GLOB srcs "*.cpp")
+file(GLOB detail_hdrs "detail/*.hpp")
+file(GLOB detail_srcs "detail/*.cpp")
function(dart_add_utils_headers)
dart_property_add(DART_UTILS_HEADERS ${ARGN})
@@ -50,7 +28,7 @@ set(target_name ${PROJECT_NAME}-utils)
set(component_name utils)
# Add target
-dart_add_library(${target_name} ${hdrs} ${srcs} ${dart_utils_headers} ${dart_utils_sources})
+dart_add_library(${target_name} ${hdrs} ${srcs} ${detail_hdrs} ${detail_srcs} ${dart_utils_headers} ${dart_utils_sources})
target_link_libraries(${target_name} PUBLIC dart tinyxml2::tinyxml2)
# Component
@@ -82,8 +60,13 @@ install(
DESTINATION include/dart/utils
COMPONENT headers
)
+install(
+ FILES ${detail_hdrs}
+ DESTINATION include/dart/utils/detail
+ COMPONENT headers
+)
# Add subdirectories (components)
add_subdirectory(urdf)
-dart_format_add(${hdrs} ${srcs} ${dart_utils_headers} ${dart_utils_sources})
+dart_format_add(${hdrs} ${srcs} ${detail_hdrs} ${detail_srcs} ${dart_utils_headers} ${dart_utils_sources})
diff --git a/dart/utils/XmlHelpers.cpp b/dart/utils/XmlHelpers.cpp
index 14c257d4727ab..42d2805adce1d 100644
--- a/dart/utils/XmlHelpers.cpp
+++ b/dart/utils/XmlHelpers.cpp
@@ -35,8 +35,7 @@
#include
#include
-#include
-#include
+#include
#include "dart/common/Console.hpp"
#include "dart/common/LocalResourceRetriever.hpp"
@@ -48,90 +47,45 @@ namespace utils {
//==============================================================================
std::string toString(bool v)
{
- return boost::lexical_cast(v);
+ return fmt::format("{}", v);
}
//==============================================================================
std::string toString(int v)
{
- return boost::lexical_cast(v);
+ return std::to_string(v);
}
//==============================================================================
std::string toString(unsigned int v)
{
- return boost::lexical_cast(v);
+ return std::to_string(v);
}
//==============================================================================
std::string toString(float v)
{
- return boost::lexical_cast(v);
+ return std::to_string(v);
}
//==============================================================================
std::string toString(double v)
{
- return boost::lexical_cast(v);
+ return std::to_string(v);
}
//==============================================================================
std::string toString(char v)
{
- return boost::lexical_cast(v);
-}
-
-//==============================================================================
-std::string toString(const Eigen::Vector2d& v)
-{
- return boost::lexical_cast(v.transpose());
-}
-
-//==============================================================================
-std::string toString(const Eigen::Vector3d& v)
-{
- return boost::lexical_cast(v.transpose());
-}
-
-//==============================================================================
-std::string toString(const Eigen::Vector3i& v)
-{
- return boost::lexical_cast(v.transpose());
-}
-
-//==============================================================================
-std::string toString(const Eigen::Vector6d& v)
-{
- return boost::lexical_cast(v.transpose());
-}
-
-//==============================================================================
-std::string toString(const Eigen::VectorXd& v)
-{
- return boost::lexical_cast(v.transpose());
-}
-
-//==============================================================================
-std::string toString(const Eigen::Isometry3d& v)
-{
- std::ostringstream ostr;
- ostr.precision(6);
-
- Eigen::Vector3d xyz = math::matrixToEulerXYZ(v.linear());
-
- ostr << v.translation()(0) << " " << v.translation()(1) << " "
- << v.translation()(2) << " ";
- ostr << xyz[0] << " " << xyz[1] << " " << xyz[2];
-
- return ostr.str();
+ return fmt::format("{}", v);
}
//==============================================================================
bool toBool(const std::string& str)
{
- if (boost::to_upper_copy(str) == "TRUE" || str == "1")
+ if (common::toUpper(str) == "TRUE" || str == "1")
return true;
- else if (boost::to_upper_copy(str) == "FALSE" || str == "0")
+ else if (common::toUpper(str) == "FALSE" || str == "0")
return false;
else
{
@@ -144,30 +98,42 @@ bool toBool(const std::string& str)
//==============================================================================
int toInt(const std::string& str)
{
- return boost::lexical_cast(str);
+ return std::stoi(str);
}
//==============================================================================
unsigned int toUInt(const std::string& str)
{
- return boost::lexical_cast(str);
+ return static_cast(std::stoul(str));
}
//==============================================================================
float toFloat(const std::string& str)
{
- return boost::lexical_cast(str);
+ return std::stof(str);
}
//==============================================================================
double toDouble(const std::string& str)
{
- return boost::lexical_cast(str);
+ return std::stod(str);
}
+
//==============================================================================
char toChar(const std::string& str)
{
- return boost::lexical_cast(str);
+ if (str.empty())
+ {
+ DART_ERROR("");
+ return 0;
+ }
+
+ if (str.size() != 1)
+ {
+ DART_ERROR("");
+ }
+
+ return str[0];
}
//==============================================================================
@@ -175,10 +141,7 @@ Eigen::Vector2d toVector2d(const std::string& str)
{
Eigen::Vector2d ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 2);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -187,9 +150,9 @@ Eigen::Vector2d toVector2d(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::Vector2d[" << i
@@ -206,10 +169,7 @@ Eigen::Vector2i toVector2i(const std::string& str)
{
Eigen::Vector2i ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 2);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -218,9 +178,9 @@ Eigen::Vector2i toVector2i(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::Vector2i[" << i
@@ -237,10 +197,7 @@ Eigen::Vector3d toVector3d(const std::string& str)
{
Eigen::Vector3d ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 3);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -249,9 +206,9 @@ Eigen::Vector3d toVector3d(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::Vector3d[" << i
@@ -268,10 +225,7 @@ Eigen::Vector3i toVector3i(const std::string& str)
{
Eigen::Vector3i ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 3);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -280,9 +234,9 @@ Eigen::Vector3i toVector3i(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid int for Eigen::Vector3i[" << i
@@ -299,10 +253,7 @@ Eigen::Vector4d toVector4d(const std::string& str)
{
Eigen::Vector4d ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 4);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -311,9 +262,9 @@ Eigen::Vector4d toVector4d(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::Vector4d[" << i
@@ -330,10 +281,7 @@ Eigen::Vector6d toVector6d(const std::string& str)
{
Eigen::Vector6d ret;
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 6);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -342,9 +290,9 @@ Eigen::Vector6d toVector6d(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::Vector6d[" << i
@@ -359,10 +307,7 @@ Eigen::Vector6d toVector6d(const std::string& str)
//==============================================================================
Eigen::VectorXd toVectorXd(const std::string& str)
{
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() > 0);
Eigen::VectorXd ret(pieces.size());
@@ -373,9 +318,9 @@ Eigen::VectorXd toVectorXd(const std::string& str)
{
try
{
- ret(i) = boost::lexical_cast(pieces[i].c_str());
+ ret[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for Eigen::VectorXd[" << i
@@ -392,10 +337,7 @@ Eigen::Isometry3d toIsometry3d(const std::string& str)
{
Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
Eigen::Vector6d elements = Eigen::Vector6d::Zero();
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 6);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -404,9 +346,9 @@ Eigen::Isometry3d toIsometry3d(const std::string& str)
{
try
{
- elements(i) = boost::lexical_cast(pieces[i].c_str());
+ elements[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for SE3[" << i
@@ -425,10 +367,7 @@ Eigen::Isometry3d toIsometry3dWithExtrinsicRotation(const std::string& str)
{
Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
Eigen::Vector6d elements = Eigen::Vector6d::Zero();
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
+ const std::vector pieces = common::split(common::trim(str));
assert(pieces.size() == 6);
for (std::size_t i = 0; i < pieces.size(); ++i)
@@ -437,9 +376,9 @@ Eigen::Isometry3d toIsometry3dWithExtrinsicRotation(const std::string& str)
{
try
{
- elements(i) = boost::lexical_cast(pieces[i].c_str());
+ elements[i] = toDouble(pieces[i]);
}
- catch (boost::bad_lexical_cast& e)
+ catch (std::exception& e)
{
std::cerr << "value [" << pieces[i]
<< "] is not a valid double for SE3[" << i
@@ -477,9 +416,9 @@ bool getValueBool(
std::string str = parentElement->FirstChildElement(name.c_str())->GetText();
- if (boost::to_upper_copy(str) == "TRUE" || str == "1")
+ if (common::toUpper(str) == "TRUE" || str == "1")
return true;
- else if (boost::to_upper_copy(str) == "FALSE" || str == "0")
+ else if (common::toUpper(str) == "FALSE" || str == "0")
return false;
else
{
diff --git a/dart/utils/XmlHelpers.hpp b/dart/utils/XmlHelpers.hpp
index 1b191c948c6ea..1d3684582f7a1 100644
--- a/dart/utils/XmlHelpers.hpp
+++ b/dart/utils/XmlHelpers.hpp
@@ -36,13 +36,14 @@
#include
#include
-#include
-#include
+#include
#include
#include "dart/common/Console.hpp"
#include "dart/common/Deprecated.hpp"
+#include "dart/common/Logging.hpp"
#include "dart/common/ResourceRetriever.hpp"
+#include "dart/math/Geometry.hpp"
#include "dart/math/MathTypes.hpp"
namespace dart {
@@ -54,12 +55,12 @@ std::string toString(unsigned int v);
std::string toString(float v);
std::string toString(double v);
std::string toString(char v);
-std::string toString(const Eigen::Vector2d& v);
-std::string toString(const Eigen::Vector3d& v);
-std::string toString(const Eigen::Vector3i& v);
-std::string toString(const Eigen::Vector6d& v);
-std::string toString(const Eigen::VectorXd& v);
-std::string toString(const Eigen::Isometry3d& v);
+template
+std::string toString(const Eigen::Matrix& v);
+template
+std::string toString(
+ const Eigen::Transform& v,
+ const std::string& rotationType = "intrinsic");
bool toBool(const std::string& str);
int toInt(const std::string& str);
@@ -75,46 +76,8 @@ Eigen::Vector4d toVector4d(const std::string& str);
Eigen::Vector6d toVector6d(const std::string& str);
Eigen::VectorXd toVectorXd(const std::string& str);
template
-Eigen::Matrix toVectorNd(const std::string& str)
-{
- Eigen::Matrix ret = Eigen::Matrix::Zero();
-
- std::vector pieces;
- std::string trimedStr = boost::trim_copy(str);
- boost::split(
- pieces, trimedStr, boost::is_any_of(" "), boost::token_compress_on);
- std::size_t sizeToRead = std::min(N, pieces.size());
- if (pieces.size() < N)
- {
- dterr << "Failed to read a vector because the dimension '" << pieces.size()
- << "' is less than the expectation '" << N << "'.\n";
- }
- else if (pieces.size() > N)
- {
- dterr << "Failed to read a vector because the dimension '" << pieces.size()
- << "' is greater than the expectation '" << N << "'.\n";
- }
-
- for (std::size_t i = 0; i < sizeToRead; ++i)
- {
- if (pieces[i] != "")
- {
- try
- {
- ret(i) = boost::lexical_cast(pieces[i].c_str());
- }
- catch (boost::bad_lexical_cast& e)
- {
- dterr << "value [" << pieces[i]
- << "] is not a valid double for Eigen::Vector" << N << "d[" << i
- << "]: " << e.what() << "\n";
- }
- }
- }
-
- return ret;
-}
-// TODO: The definition of _str is not clear for transform (see: #250)
+Eigen::Matrix toVectorNd(const std::string& str);
+// TODO: The definition of str is not clear for transform (see: #250)
Eigen::Isometry3d toIsometry3d(const std::string& str);
Eigen::Isometry3d toIsometry3dWithExtrinsicRotation(const std::string& str);
@@ -206,11 +169,7 @@ Eigen::VectorXd getAttributeVectorXd(
const tinyxml2::XMLElement* element, const std::string& attributeName);
template
Eigen::Matrix getAttributeVectorNd(
- const tinyxml2::XMLElement* element, const std::string& attributeName)
-{
- const std::string val = getAttributeString(element, attributeName);
- return toVectorNd(val);
-}
+ const tinyxml2::XMLElement* element, const std::string& attributeName);
/// TemplatedElementEnumerator is a convenience class to help visiting all the
/// child elements of given parent element. This class is templated to cover
@@ -225,85 +184,34 @@ class TemplatedElementEnumerator
public:
/// Constructor that takes parent element and
TemplatedElementEnumerator(
- ElementPtr parentElement, const std::string& childElementName)
- : mParentElement(parentElement),
- mChildElementName(childElementName),
- mCurrentElement(nullptr)
- {
- }
+ ElementPtr parentElement, const std::string& childElementName);
/// Destructor
- ~TemplatedElementEnumerator() {}
+ ~TemplatedElementEnumerator();
/// Set the current element to the next sibling element or to the first child
/// element of given parent element if it exists; returns success
- bool next()
- {
- if (!mParentElement)
- return false;
-
- if (mCurrentElement)
- {
- mCurrentElement
- = mCurrentElement->NextSiblingElement(mChildElementName.c_str());
- }
- else
- {
- mCurrentElement
- = mParentElement->FirstChildElement(mChildElementName.c_str());
- }
-
- if (!valid())
- mParentElement = nullptr;
-
- return valid();
- }
+ bool next();
/// Get the current element
- ElementPtr get() const
- {
- return mCurrentElement;
- }
+ ElementPtr get() const;
/// Dereference operator
- ElementPtr operator->() const
- {
- return mCurrentElement;
- }
+ ElementPtr operator->() const;
/// Dereference operator
- ElementRef operator*() const
- {
- return *mCurrentElement;
- }
+ ElementRef operator*() const;
/// Equality operator
- bool operator==(const TemplatedElementEnumerator& rhs) const
- {
- // If they point at the same node, then the names must match
- return (this->mParentElement == rhs.mParentElement)
- && (this->mCurrentElement == rhs.mCurrentElement)
- && (this->mCurrentElement != nullptr
- || (this->mChildElementName == rhs.mChildElementName));
- }
+ bool operator==(const TemplatedElementEnumerator& rhs) const;
/// Assignment operator
TemplatedElementEnumerator& operator=(
- const TemplatedElementEnumerator& rhs)
- {
- this->mParentElement = rhs.mParentElement;
- this->mChildElementName = rhs.mChildElementName;
- this->mCurrentElement = rhs.mCurrentElement;
-
- return *this;
- }
+ const TemplatedElementEnumerator& rhs);
private:
/// Returns true if the current element is valid (not a nullptr)
- bool valid() const
- {
- return mCurrentElement != nullptr;
- }
+ bool valid() const;
private:
/// Parent element
@@ -329,4 +237,6 @@ bool copyChildNodes(
} // namespace utils
} // namespace dart
+#include "dart/utils/detail/XmlHelpers-impl.hpp"
+
#endif // #ifndef DART_UTILS_XMLHELPERS_HPP_
diff --git a/dart/utils/detail/XmlHelpers-impl.hpp b/dart/utils/detail/XmlHelpers-impl.hpp
new file mode 100644
index 0000000000000..6fdfc6038c8ce
--- /dev/null
+++ b/dart/utils/detail/XmlHelpers-impl.hpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2011-2022, The DART development contributors
+ * All rights reserved.
+ *
+ * The list of contributors can be found at:
+ * https://github.com/dartsim/dart/blob/master/LICENSE
+ *
+ * This file is provided under the following "BSD-style" License:
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DART_UTILS_DETAIL_XMLHELPERS_IMPL_HPP_
+#define DART_UTILS_DETAIL_XMLHELPERS_IMPL_HPP_
+
+#include "dart/common/String.hpp"
+#include "dart/utils/XmlHelpers.hpp"
+
+namespace dart::utils {
+
+//==============================================================================
+template
+std::string toString(const Eigen::Matrix& v)
+{
+ std::stringstream ss;
+ ss << v.transpose();
+ return ss.str();
+}
+
+//==============================================================================
+template
+std::string toString(
+ const Eigen::Transform& v,
+ const std::string& rotationType)
+{
+ Eigen::Matrix angles;
+ if (rotationType == "intrinsic")
+ {
+ angles = math::matrixToEulerXYZ(v.rotation());
+ }
+ else if (rotationType == "extrinsic")
+ {
+ angles = math::matrixToEulerZYX(v.rotation()).reverse();
+ }
+ else
+ {
+ DART_ERROR(
+ "Unsupported rotation type [{}]. Assuming intrinsic.", rotationType);
+ angles = math::matrixToEulerXYZ(v.rotation());
+ }
+
+ std::stringstream ss;
+ ss.precision(6);
+ ss << v.translation().transpose() << " ";
+ ss << angles;
+
+ return ss.str();
+}
+
+//==============================================================================
+template
+Eigen::Matrix toVectorNd(const std::string& str)
+{
+ const std::vector pieces = common::split(common::trim(str));
+ const std::size_t sizeToRead = std::min(N, pieces.size());
+ if (pieces.size() < N)
+ {
+ dterr << "Failed to read a vector because the dimension '" << pieces.size()
+ << "' is less than the expectation '" << N << "'.\n";
+ }
+ else if (pieces.size() > N)
+ {
+ dterr << "Failed to read a vector because the dimension '" << pieces.size()
+ << "' is greater than the expectation '" << N << "'.\n";
+ }
+
+ Eigen::Matrix ret = Eigen::Matrix::Zero();
+
+ for (std::size_t i = 0; i < sizeToRead; ++i)
+ {
+ if (pieces[i] != "")
+ {
+ try
+ {
+ ret[i] = toDouble(pieces[i]);
+ }
+ catch (std::exception& e)
+ {
+ dterr << "value [" << pieces[i]
+ << "] is not a valid double for Eigen::Vector" << N << "d[" << i
+ << "]: " << e.what() << "\n";
+ }
+ }
+ }
+
+ return ret;
+}
+
+//==============================================================================
+template
+Eigen::Matrix getAttributeVectorNd(
+ const tinyxml2::XMLElement* element, const std::string& attributeName)
+{
+ const std::string val = getAttributeString(element, attributeName);
+ return toVectorNd(val);
+}
+
+//==============================================================================
+template
+TemplatedElementEnumerator::TemplatedElementEnumerator(
+ ElementPtr parentElement, const std::string& childElementName)
+ : mParentElement(parentElement),
+ mChildElementName(childElementName),
+ mCurrentElement(nullptr)
+{
+ // Do nothing
+}
+
+//==============================================================================
+template
+TemplatedElementEnumerator::~TemplatedElementEnumerator()
+{
+ // Do nothing
+}
+
+//==============================================================================
+template
+bool TemplatedElementEnumerator::next()
+{
+ if (!mParentElement)
+ return false;
+
+ if (mCurrentElement)
+ {
+ mCurrentElement
+ = mCurrentElement->NextSiblingElement(mChildElementName.c_str());
+ }
+ else
+ {
+ mCurrentElement
+ = mParentElement->FirstChildElement(mChildElementName.c_str());
+ }
+
+ if (!valid())
+ mParentElement = nullptr;
+
+ return valid();
+}
+
+//==============================================================================
+template
+typename TemplatedElementEnumerator::ElementPtr
+TemplatedElementEnumerator::get() const
+{
+ return mCurrentElement;
+}
+
+//==============================================================================
+template
+typename TemplatedElementEnumerator::ElementPtr
+ TemplatedElementEnumerator::operator->() const
+{
+ return mCurrentElement;
+}
+
+//==============================================================================
+template
+typename TemplatedElementEnumerator::ElementRef
+ TemplatedElementEnumerator::operator*() const
+{
+ return *mCurrentElement;
+}
+
+//==============================================================================
+template
+bool TemplatedElementEnumerator::operator==(
+ const TemplatedElementEnumerator& rhs) const
+{
+ // If they point at the same node, then the names must match
+ return (this->mParentElement == rhs.mParentElement)
+ && (this->mCurrentElement == rhs.mCurrentElement)
+ && (this->mCurrentElement != nullptr
+ || (this->mChildElementName == rhs.mChildElementName));
+}
+
+//==============================================================================
+template
+TemplatedElementEnumerator&
+TemplatedElementEnumerator::operator=(
+ const TemplatedElementEnumerator& rhs)
+{
+ this->mParentElement = rhs.mParentElement;
+ this->mChildElementName = rhs.mChildElementName;
+ this->mCurrentElement = rhs.mCurrentElement;
+
+ return *this;
+}
+
+//==============================================================================
+template
+bool TemplatedElementEnumerator::valid() const
+{
+ return mCurrentElement != nullptr;
+}
+
+} // namespace dart::utils
+
+#endif // #ifndef DART_UTILS_DETAIL_XMLHELPERS_IMPL_HPP_
diff --git a/dart/utils/mjcf/MjcfParser.cpp b/dart/utils/mjcf/MjcfParser.cpp
index 09abf80eb7e25..3a74945315243 100644
--- a/dart/utils/mjcf/MjcfParser.cpp
+++ b/dart/utils/mjcf/MjcfParser.cpp
@@ -539,7 +539,7 @@ bool createShapeNodes(
// Create ShapeNode with the shape created above
dynamics::ShapeNode* shapeNode
= bodyNode->createShapeNodeWith(
- shape, site.getName());
+ shape, "site:" + site.getName());
// RGBA
dynamics::VisualAspect* visualAspect = shapeNode->getVisualAspect();
diff --git a/dart/utils/mjcf/detail/Body.cpp b/dart/utils/mjcf/detail/Body.cpp
index 6d15f66bf1eaa..710f7aceb13af 100644
--- a/dart/utils/mjcf/detail/Body.cpp
+++ b/dart/utils/mjcf/detail/Body.cpp
@@ -157,7 +157,7 @@ Errors Body::preprocess(const Compiler& compiler)
for (Geom& geom : mGeoms)
{
- const Errors geomErrors = geom.preprocess(compiler);
+ const Errors geomErrors = geom.preprocess(compiler, true);
errors.insert(errors.end(), geomErrors.begin(), geomErrors.end());
}
diff --git a/dart/utils/mjcf/detail/Geom.cpp b/dart/utils/mjcf/detail/Geom.cpp
index da8991f565624..ba15e85d06733 100644
--- a/dart/utils/mjcf/detail/Geom.cpp
+++ b/dart/utils/mjcf/detail/Geom.cpp
@@ -110,7 +110,7 @@ static bool canUseFromTo(
}
//==============================================================================
-Errors Geom::preprocess(const Compiler& compiler)
+Errors Geom::preprocess(const Compiler& compiler, bool autoName)
{
Errors errors;
@@ -118,6 +118,11 @@ Errors Geom::preprocess(const Compiler& compiler)
{
mName = *mAttributes.mName;
}
+ else if (autoName)
+ {
+ static unsigned int index = 0;
+ mName = "geom (" + std::to_string(index++) + ")";
+ }
mType = mAttributes.mType;
mConType = mAttributes.mConType;
diff --git a/dart/utils/mjcf/detail/Geom.hpp b/dart/utils/mjcf/detail/Geom.hpp
index 2464940235160..169428da151af 100644
--- a/dart/utils/mjcf/detail/Geom.hpp
+++ b/dart/utils/mjcf/detail/Geom.hpp
@@ -117,7 +117,7 @@ class Geom final
const GeomAttributes& defaultAttributes);
/// Updates attributes and elements that doesn't require any other elements.
- Errors preprocess(const Compiler& compiler);
+ Errors preprocess(const Compiler& compiler, bool autoName = false);
/// Updates attributes and elements that require the preprocessed child
/// elements of this .
diff --git a/dart/utils/urdf/BackwardCompatibility.hpp.in b/dart/utils/urdf/BackwardCompatibility.hpp.in
index 815a2fada8604..83b2918af1882 100644
--- a/dart/utils/urdf/BackwardCompatibility.hpp.in
+++ b/dart/utils/urdf/BackwardCompatibility.hpp.in
@@ -47,25 +47,4 @@
(URDFDOM_HEADERS_MINOR_VERSION > y || (URDFDOM_HEADERS_MINOR_VERSION >= y && \
URDFDOM_HEADERS_PATCH_VERSION >= z))))
-#if URDFDOM_HEADERS_VERSION_AT_LEAST(1,0,0)
-#include
-#else
-#include "boost/shared_ptr.hpp"
-#include "boost/weak_ptr.hpp"
-#endif
-
-namespace dart {
-namespace utils {
-
-#if URDFDOM_HEADERS_VERSION_AT_LEAST(1,0,0)
-template using urdf_shared_ptr = std::shared_ptr;
-template using urdf_weak_ptr = std::weak_ptr;
-#else
-template using urdf_shared_ptr = boost::shared_ptr;
-template using urdf_weak_ptr = boost::weak_ptr;
-#endif
-
-} // namespace utils
-} // namespace dart
-
#endif // DART_UTILS_URDF_BACKWARDCOMPATIBILITY_HPP_
diff --git a/dart/utils/urdf/DartLoader.cpp b/dart/utils/urdf/DartLoader.cpp
index 6a04b48641ff5..2a171e18db871 100644
--- a/dart/utils/urdf/DartLoader.cpp
+++ b/dart/utils/urdf/DartLoader.cpp
@@ -60,8 +60,9 @@
namespace dart {
namespace utils {
-using ModelInterfacePtr = urdf_shared_ptr;
+using ModelInterfacePtr = std::shared_ptr;
+//==============================================================================
DartLoader::Options::Options(
common::ResourceRetrieverPtr resourceRetriever,
RootJointType defaultRootJointType,
diff --git a/dart/utils/urdf/urdf_world_parser.hpp b/dart/utils/urdf/urdf_world_parser.hpp
index c088e271101d5..41acde5ddc09b 100644
--- a/dart/utils/urdf/urdf_world_parser.hpp
+++ b/dart/utils/urdf/urdf_world_parser.hpp
@@ -62,7 +62,7 @@ class Entity
/// Copy over a standard urdfEntity
Entity(const urdf::Entity& urdfEntity);
- urdf_shared_ptr model;
+ std::shared_ptr model;
urdf::Pose origin;
urdf::Twist twist;
diff --git a/package.xml b/package.xml
index 0fe81252ce067..9562c8582caf6 100644
--- a/package.xml
+++ b/package.xml
@@ -24,7 +24,6 @@
pkg-config
assimp
bullet
- boost
eigen
libfcl-dev
glut
diff --git a/python/dartpy/common/String.cpp b/python/dartpy/common/String.cpp
new file mode 100644
index 0000000000000..94b5b21363ce4
--- /dev/null
+++ b/python/dartpy/common/String.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011-2022, The DART development contributors
+ * All rights reserved.
+ *
+ * The list of contributors can be found at:
+ * https://github.com/dartsim/dart/blob/master/LICENSE
+ *
+ * This file is provided under the following "BSD-style" License:
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include
+#include
+#include
+
+namespace py = pybind11;
+
+namespace dart::python {
+
+void String(py::module& m)
+{
+ m.def("toUpper", &common::toUpper, py::arg("str"));
+ m.def("toLower", &common::toLower, py::arg("str"));
+ m.def(
+ "trim",
+ &common::trim,
+ py::arg("str"),
+ py::arg("whitespaces") = " \n\r\t");
+ m.def(
+ "trimLeft",
+ &common::trimLeft,
+ py::arg("str"),
+ py::arg("whitespaces") = " \n\r\t");
+ m.def(
+ "trimRight",
+ &common::trimRight,
+ py::arg("str"),
+ py::arg("whitespaces") = " \n\r\t");
+ m.def(
+ "split",
+ &common::split,
+ py::arg("str"),
+ py::arg("delimiters") = " \n\r\t");
+}
+
+} // namespace dart::python
diff --git a/python/dartpy/common/module.cpp b/python/dartpy/common/module.cpp
index 606991a64b611..6936fe94af620 100644
--- a/python/dartpy/common/module.cpp
+++ b/python/dartpy/common/module.cpp
@@ -45,6 +45,7 @@ void Composite(py::module& sm);
void Resource(py::module& sm);
void ResourceRetriever(py::module& sm);
void Stopwatch(py::module& sm);
+void String(py::module& sm);
void dart_common(py::module& m)
{
@@ -58,6 +59,7 @@ void dart_common(py::module& m)
Resource(sm);
ResourceRetriever(sm);
Stopwatch(sm);
+ String(sm);
}
} // namespace python
diff --git a/python/tests/unit/common/test_string.py b/python/tests/unit/common/test_string.py
new file mode 100644
index 0000000000000..1bcf2547d0b16
--- /dev/null
+++ b/python/tests/unit/common/test_string.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2011-2022, The DART development contributors
+# All rights reserved.
+#
+# The list of contributors can be found at:
+# https://github.com/dartsim/dart/blob/master/LICENSE
+#
+# This file is provided under the "BSD-style" License
+
+import pytest
+import dartpy as dart
+
+
+def test_case_conversions():
+ assert dart.common.toUpper("to UppEr") == "TO UPPER"
+ assert dart.common.toLower("to LowEr") == "to lower"
+
+
+def test_trim():
+ assert dart.common.trimLeft(" trim ThIs ") == "trim ThIs "
+ assert dart.common.trimRight(" trim ThIs ") == " trim ThIs"
+ assert dart.common.trim(" trim ThIs ") == "trim ThIs"
+
+ assert dart.common.trimLeft("\n trim ThIs ", " ") == "\n trim ThIs "
+ assert dart.common.trimLeft("\n trim ThIs ", "\n") == " trim ThIs "
+ assert dart.common.trimRight(" trim ThIs \n", " ") == " trim ThIs \n"
+ assert dart.common.trimRight(" trim ThIs \n", "\n") == " trim ThIs "
+ assert dart.common.trim("\n trim ThIs \n", " ") == "\n trim ThIs \n"
+ assert dart.common.trim("\n trim ThIs \n", "\n") == " trim ThIs "
+
+ assert dart.common.trimLeft("\n trim ThIs \n", " \n") == "trim ThIs \n"
+ assert dart.common.trimRight("\n trim ThIs \n", " \n") == "\n trim ThIs"
+ assert dart.common.trim("\n trim ThIs \n", " \n") == "trim ThIs"
+
+
+def test_split():
+ assert len(dart.common.split(" trim ThIs ")) == 2
+ assert dart.common.split(" trim ThIs ")[0] == "trim"
+ assert dart.common.split(" trim ThIs ")[1] == "ThIs"
+
+
+if __name__ == "__main__":
+ pytest.main()
diff --git a/unittests/unit/common/test_String.cpp b/unittests/unit/common/test_String.cpp
new file mode 100644
index 0000000000000..d9ade0b5d79e3
--- /dev/null
+++ b/unittests/unit/common/test_String.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011-2022, The DART development contributors
+ * All rights reserved.
+ *
+ * The list of contributors can be found at:
+ * https://github.com/dartsim/dart/blob/master/LICENSE
+ *
+ * This file is provided under the following "BSD-style" License:
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include
+#include
+
+using namespace dart;
+
+//==============================================================================
+TEST(StringTest, CaseConversions)
+{
+ EXPECT_EQ(common::toUpper("to UppEr"), "TO UPPER");
+ EXPECT_EQ(common::toLower("to LowEr"), "to lower");
+
+ std::string str;
+
+ str = "toUppEr";
+ common::toUpperInPlace(str);
+ EXPECT_EQ(str, "TOUPPER");
+
+ str = "toLowEr";
+ common::toLowerInPlace(str);
+ EXPECT_EQ(str, "tolower");
+}
+
+//==============================================================================
+TEST(StringTest, Trim)
+{
+ EXPECT_EQ(common::trimLeft(" trim ThIs "), "trim ThIs ");
+ EXPECT_EQ(common::trimRight(" trim ThIs "), " trim ThIs");
+ EXPECT_EQ(common::trim(" trim ThIs "), "trim ThIs");
+
+ EXPECT_EQ(common::trimLeft("\n trim ThIs ", " "), "\n trim ThIs ");
+ EXPECT_EQ(common::trimLeft("\n trim ThIs ", "\n"), " trim ThIs ");
+ EXPECT_EQ(common::trimRight(" trim ThIs \n", " "), " trim ThIs \n");
+ EXPECT_EQ(common::trimRight(" trim ThIs \n", "\n"), " trim ThIs ");
+ EXPECT_EQ(common::trim("\n trim ThIs \n", " "), "\n trim ThIs \n");
+ EXPECT_EQ(common::trim("\n trim ThIs \n", "\n"), " trim ThIs ");
+
+ EXPECT_EQ(common::trimLeft("\n trim ThIs \n", " \n"), "trim ThIs \n");
+ EXPECT_EQ(common::trimRight("\n trim ThIs \n", " \n"), "\n trim ThIs");
+ EXPECT_EQ(common::trim("\n trim ThIs \n", " \n"), "trim ThIs");
+}
+
+//==============================================================================
+TEST(StringTest, Split)
+{
+ ASSERT_EQ(common::split(" trim ThIs ").size(), 2);
+ EXPECT_EQ(common::split(" trim ThIs ")[0], "trim");
+ EXPECT_EQ(common::split(" trim ThIs ")[1], "ThIs");
+
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "a").size(), 2);
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "a")[0], "ThiSis");
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "a")[1], "NApPle ");
+
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "A").size(), 2);
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "A")[0], "ThiSisaN");
+ ASSERT_EQ(common::split("ThiSisaNApPle ", "A")[1], "pPle ");
+}