Commits

Martin Felis committed 031d33e

using urdf packages from ROS for the addon (not yet finished)

  • Participants
  • Parent commits 981dd1f

Comments (0)

Files changed (15)

File addons/urdfreader/CMake/pkg-config.cmake

+# Copyright (C) 2010 Thomas Moulard, JRL, CNRS/AIST.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+INCLUDE(CMake/shared-library.cmake)
+
+FIND_PACKAGE(PkgConfig)
+
+# Additional pkg-config variables whose value will be imported
+# during the dependency check.
+SET(PKG_CONFIG_ADDITIONAL_VARIABLES datarootdir pkgdatarootdir docdir doxygendocdir)
+
+# _SETUP_PROJECT_PKG_CONFIG
+# -------------------------
+#
+# Prepare pkg-config pc file generation step.
+#
+MACRO(_SETUP_PROJECT_PKG_CONFIG)
+  # Pkg-config related commands.
+  SET(PKG_CONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}")
+  SET(PKG_CONFIG_EXEC_PREFIX "${PKG_CONFIG_PREFIX}")
+  SET(PKG_CONFIG_LIBDIR "${PKG_CONFIG_EXEC_PREFIX}/lib")
+  SET(PKG_CONFIG_INCLUDEDIR "${PKG_CONFIG_PREFIX}/include")
+  SET(PKG_CONFIG_DATAROOTDIR "${PKG_CONFIG_PREFIX}/share")
+  SET(PKG_CONFIG_PKGDATAROOTDIR "${PKG_CONFIG_PREFIX}/share/${PROJECT_NAME}")
+  SET(PKG_CONFIG_DOCDIR "${PKG_CONFIG_DATAROOTDIR}/doc/${PROJECT_NAME}")
+  SET(PKG_CONFIG_DOXYGENDOCDIR "${PKG_CONFIG_DOCDIR}/doxygen-html")
+
+  SET(PKG_CONFIG_PROJECT_NAME "${PROJECT_NAME}")
+  SET(PKG_CONFIG_DESCRIPTION "${PROJECT_DESCRIPTION}")
+  SET(PKG_CONFIG_URL "${PROJECT_URL}")
+  SET(PKG_CONFIG_VERSION "${PROJECT_VERSION}")
+  SET(PKG_CONFIG_REQUIRES "")
+  SET(PKG_CONFIG_CONFLICTS "")
+  SET(PKG_CONFIG_LIBS "${LIBDIR_KW}${CMAKE_INSTALL_PREFIX}/lib")
+  SET(PKG_CONFIG_LIBS_PRIVATE "")
+  SET(PKG_CONFIG_CFLAGS "-I${CMAKE_INSTALL_PREFIX}/include")
+
+  SET(PKG_CONFIG_EXTRA "")
+
+  # Where to install the pkg-config file?
+  SET(PKG_CONFIG_DIR "${PKG_CONFIG_LIBDIR}/pkgconfig")
+
+  # Watch variables.
+  LIST(APPEND LOGGING_WATCHED_VARIABLES
+    PKG_CONFIG_FOUND
+    PKG_CONFIG_EXECUTABLE
+    PKG_CONFIG_PREFIX
+    PKG_CONFIG_EXEC_PREFIX
+    PKG_CONFIG_LIBDIR
+    PKG_CONFIG_INCLUDEDIR
+    PKG_CONFIG_DATAROOTDIR
+    PKG_CONFIG_PKGDATAROOTDIR
+    PKG_CONFIG_DOCDIR
+    PKG_CONFIG_DOXYGENDOCDIR
+    PKG_CONFIG_PROJECT_NAME
+    PKG_CONFIG_DESCRIPTION
+    PKG_CONFIG_URL
+    PKG_CONFIG_VERSION
+    PKG_CONFIG_REQUIRES
+    PKG_CONFIG_CONFLICTS
+    PKG_CONFIG_LIBS
+    PKG_CONFIG_LIBS_PRIVATE
+    PKG_CONFIG_CFLAGS
+    PKG_CONFIG_EXTRA
+    )
+
+  # Install it.
+  INSTALL(
+    FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
+    DESTINATION lib/pkgconfig
+    PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
+ENDMACRO(_SETUP_PROJECT_PKG_CONFIG)
+
+
+# _SETUP_PROJECT_PKG_CONFIG_FINALIZE
+# ----------------------------------
+#
+# Post-processing of the pkg-config step.
+#
+# The pkg-config file has to be generated at the end to allow end-user
+# defined variables replacement.
+#
+MACRO(_SETUP_PROJECT_PKG_CONFIG_FINALIZE)
+  # Generate the pkg-config file.
+  CONFIGURE_FILE(
+    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
+    )
+ENDMACRO(_SETUP_PROJECT_PKG_CONFIG_FINALIZE)
+
+
+# ADD_DEPENDENCY(PREFIX P_REQUIRED PKGCONFIG_STRING)
+# ------------------------------------------------
+#
+# Check for a dependency using pkg-config. Fail if the package cannot
+# be found.
+#
+# P_REQUIRED : if set to 1 the package is required, otherwise it consider
+#              as optional.
+#              WARNING for optional package:
+#              if the package is detected its compile
+#              and linking options are still put in the required fields
+#              of the generated pc file. Indeed from the binary viewpoint
+#              the package becomes required.
+#
+# PKG_CONFIG_STRING	: string passed to pkg-config to check the version.
+#			  Typically, this string looks like:
+#                         ``my-package >= 0.5''
+#
+MACRO(ADD_DEPENDENCY P_REQUIRED PKG_CONFIG_STRING)
+  # Retrieve the left part of the equation to get package name.
+  STRING(REGEX MATCH "[^<>= ]+" LIBRARY_NAME "${PKG_CONFIG_STRING}")
+  # And transform it into a valid variable prefix.
+  # 1. replace invalid characters into underscores.
+  STRING(REGEX REPLACE "[^a-zA-Z0-9]" "_" PREFIX "${LIBRARY_NAME}")
+  # 2. make it uppercase.
+  STRING(TOUPPER "${PREFIX}" "PREFIX")
+
+  # Force redetection each time CMake is launched.
+  # Rationale: these values are *NEVER* manually set, so information is never
+  # lost by overriding them. Moreover, changes in the pkg-config files are
+  # not seen as long as the cache is not destroyed, even if the .pc file
+  # is changed. This is a BAD behavior.
+  SET(${PREFIX}_FOUND 0)
+
+  # Search for the package.
+  IF(${P_REQUIRED})
+    MESSAGE(STATUS "${PKG_CONFIG_STRING} is required.")
+    PKG_CHECK_MODULES("${PREFIX}" REQUIRED "${PKG_CONFIG_STRING}")
+  ELSE(${P_REQUIRED})
+    MESSAGE(STATUS "${PKG_CONFIG_STRING} is optional.")
+    PKG_CHECK_MODULES("${PREFIX}" "${PKG_CONFIG_STRING}")
+  ENDIF(${P_REQUIRED})
+
+  # Watch variables.
+  LIST(APPEND LOGGING_WATCHED_VARIABLES
+    ${PREFIX}_FOUND
+    ${PREFIX}_LIBRARIES
+    ${PREFIX}_LIBRARY_DIRS
+    ${PREFIX}_LDFLAGS
+    ${PREFIX}_LDFLAGS_OTHER
+    ${PREFIX}_INCLUDE_DIRS
+    ${PREFIX}_CFLAGS
+    ${PREFIX}_CFLAGS_OTHER
+    ${PREFIX}
+    ${PREFIX}_STATIC
+    ${PREFIX}_VERSION
+    ${PREFIX}_PREFIX
+    ${PREFIX}_INCLUDEDIR
+    ${PREFIX}_LIBDIR
+    )
+
+  # Get the values of additional variables.
+  FOREACH(VARIABLE ${PKG_CONFIG_ADDITIONAL_VARIABLES})
+    # Upper-case version of the variable for CMake variable generation.
+    STRING(TOUPPER "${VARIABLE}" "VARIABLE_UC")
+    EXEC_PROGRAM(
+      "${PKG_CONFIG_EXECUTABLE}" ARGS
+      "--variable=${VARIABLE}" "${LIBRARY_NAME}"
+      OUTPUT_VARIABLE "${PREFIX}_${VARIABLE_UC}")
+
+    # Watch additional variables.
+    LIST(APPEND LOGGING_WATCHED_VARIABLES ${PREFIX}_${VARIABLE_UC})
+  ENDFOREACH(VARIABLE)
+
+  #FIXME: spaces are replaced by semi-colon by mistakes, revert the change.
+  #I cannot see why CMake is doing that...
+  STRING(REPLACE ";" " " PKG_CONFIG_STRING "${PKG_CONFIG_STRING}")
+
+  # Add the package to the dependency list if found
+  IF(${${PREFIX}_FOUND})
+    _ADD_TO_LIST(PKG_CONFIG_REQUIRES "${PKG_CONFIG_STRING}" ",")
+  ENDIF()
+
+  # Add the package to the cmake dependency list
+  # if cpack has been included.
+  # This is likely to disappear when Ubuntu 8.04 will
+  # disappear.
+  IF(COMMAND ADD_CMAKE_DEPENDENCY)
+    ADD_CMAKE_DEPENDENCY(${PKG_CONFIG_STRING})
+  ENDIF(COMMAND ADD_CMAKE_DEPENDENCY)
+
+  IF(${${PREFIX}_FOUND})
+   MESSAGE(STATUS
+    "Pkg-config module ${LIBRARY_NAME} v${${PREFIX}_VERSION}"
+    " has been detected with success.")
+  ENDIF()
+
+ENDMACRO(ADD_DEPENDENCY)
+
+# ADD_REQUIRED_DEPENDENCY(PREFIX PKGCONFIG_STRING)
+# ------------------------------------------------
+#
+# Check for a dependency using pkg-config. Fail if the package cannot
+# be found.
+#
+# PKG_CONFIG_STRING	: string passed to pkg-config to check the version.
+#			  Typically, this string looks like:
+#                         ``my-package >= 0.5''
+#
+MACRO(ADD_REQUIRED_DEPENDENCY PKG_CONFIG_STRING)
+  ADD_DEPENDENCY(1 ${PKG_CONFIG_STRING})
+ENDMACRO(ADD_REQUIRED_DEPENDENCY)
+
+# ADD_OPTIONAL_DEPENDENCY(PREFIX PKGCONFIG_STRING)
+# ------------------------------------------------
+#
+# Check for a dependency using pkg-config. Quiet if the package cannot
+# be found.
+#
+# PKG_CONFIG_STRING	: string passed to pkg-config to check the version.
+#			  Typically, this string looks like:
+#                         ``my-package >= 0.5''
+#
+MACRO(ADD_OPTIONAL_DEPENDENCY PKG_CONFIG_STRING)
+  ADD_DEPENDENCY(0 ${PKG_CONFIG_STRING})
+ENDMACRO(ADD_OPTIONAL_DEPENDENCY)
+
+# PKG_CONFIG_APPEND_LIBRARY_DIR
+# -----------------------------
+#
+# This macro adds library directories in a portable way
+# into the CMake file.
+MACRO(PKG_CONFIG_APPEND_LIBRARY_DIR DIRS)
+  FOREACH(DIR ${DIRS})
+    IF(DIR)
+      SET(PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} ${LIBDIR_KW}${DIR}")
+    ENDIF(DIR)
+  ENDFOREACH(DIR ${DIRS})
+ENDMACRO(PKG_CONFIG_APPEND_LIBRARY_DIR DIR)
+
+
+# PKG_CONFIG_APPEND_CFLAGS
+# ------------------------
+#
+# This macro adds CFLAGS in a portable way into the pkg-config file.
+#
+MACRO(PKG_CONFIG_APPEND_CFLAGS FLAGS)
+  FOREACH(FLAG ${FLAGS})
+    IF(FLAG)
+      SET(PKG_CONFIG_CFLAGS "${PKG_CONFIG_CFLAGS} ${FLAG}")
+    ENDIF(FLAG)
+  ENDFOREACH(FLAG ${FLAGS})
+ENDMACRO(PKG_CONFIG_APPEND_CFLAGS)
+
+
+# PKG_CONFIG_APPEND_LIBS_RAW
+# ----------------------------
+#
+# This macro adds raw value in the "Libs:" into the pkg-config file.
+#
+# Exception for mac OS X:
+# In addition to the classical static and dynamic libraries (handled like
+# unix does), mac systems can link against frameworks.
+# Frameworks are directories gathering headers, libraries, shared resources...
+#
+# The syntax used to link with a framework is particular, hence a filter is
+# added to convert the absolute path to a framework (e.g. /Path/to/Sample.framework)
+# into the correct flags (-F/Path/to/ -framework Sample).
+#
+MACRO(PKG_CONFIG_APPEND_LIBS_RAW LIBS)
+  FOREACH(LIB ${LIBS})
+    IF(LIB)
+      IF( APPLE AND ${LIB} MATCHES .framework)
+	    GET_FILENAME_COMPONENT(framework_PATH ${LIB} PATH)
+	    GET_FILENAME_COMPONENT(framework_NAME ${LIB} NAME_WE)
+        SET(PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} -F${framework_PATH} -framework ${framework_NAME}")
+      ELSE( APPLE AND ${LIB} MATCHES .framework)
+        SET(PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} ${LIB}")
+      ENDIF( APPLE AND ${LIB} MATCHES .framework)
+    ENDIF(LIB)
+  ENDFOREACH(LIB ${LIBS})
+  STRING(REPLACE "\n" "" PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS}")
+ENDMACRO(PKG_CONFIG_APPEND_LIBS_RAW)
+
+
+# PKG_CONFIG_APPEND_LIBS
+# ----------------------
+#
+# This macro adds libraries in a portable way into the pkg-config
+# file.
+#
+# Library prefix and suffix is automatically added.
+#
+MACRO(PKG_CONFIG_APPEND_LIBS LIBS)
+  FOREACH(LIB ${LIBS})
+    IF(LIB)
+      SET(PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} ${LIBINCL_KW}${LIB}${LIB_EXT}")
+    ENDIF(LIB)
+  ENDFOREACH(LIB ${LIBS})
+ENDMACRO(PKG_CONFIG_APPEND_LIBS)
+
+
+# PKG_CONFIG_USE_DEPENDENCY(TARGET DEPENDENCY)
+# --------------------------------------------
+#
+# This macro changes the target properties to properly search for
+# headers, libraries and link against the required shared libraries
+# when using a dependency detected through pkg-config.
+#
+# I.e. PKG_CONFIG_USE_DEPENDENCY(my-binary my-package)
+#
+MACRO(PKG_CONFIG_USE_DEPENDENCY TARGET DEPENDENCY)
+  # Transform the dependency into a valid variable prefix.
+  # 1. replace invalid characters into underscores.
+  STRING(REGEX REPLACE "[^a-zA-Z0-9]" "_" PREFIX "${DEPENDENCY}")
+  # 2. make it uppercase.
+  STRING(TOUPPER "${PREFIX}" "PREFIX")
+
+  # Make sure we search for a previously detected package.
+  IF(NOT DEFINED ${PREFIX}_FOUND)
+    MESSAGE(FATAL_ERROR
+      "The package ${DEPENDENCY} has not been detected correctly.\n"
+      "Have you called ADD_REQUIRED_DEPENDENCY/ADD_OPTIONAL_DEPENDENCY?")
+  ENDIF()
+  IF(NOT ${PREFIX}_FOUND)
+    MESSAGE(FATAL_ERROR
+      "The package ${DEPENDENCY} has not been found.")
+  ENDIF()
+
+  # Make sure we do not override previous flags.
+  GET_TARGET_PROPERTY(CFLAGS ${TARGET} COMPILE_FLAGS)
+  GET_TARGET_PROPERTY(LDFLAGS ${TARGET} LINK_FLAGS)
+
+  # If there were no previous flags, get rid of the XYFLAGS-NOTFOUND
+  # in the variables.
+  IF(NOT CFLAGS)
+    SET(CFLAGS "")
+  ENDIF()
+  IF(NOT LDFLAGS)
+    SET(LDFLAGS "")
+  ENDIF()
+
+  # Transform semi-colon seperated list in to space separated list.
+  FOREACH(FLAG ${${PREFIX}_CFLAGS})
+    SET(CFLAGS "${CFLAGS} ${FLAG}")
+  ENDFOREACH()
+
+  FOREACH(FLAG ${${PREFIX}_LDFLAGS})
+    SET(LDFLAGS "${LDFLAGS} ${FLAG}")
+  ENDFOREACH()
+
+  # Update the flags.
+  SET_TARGET_PROPERTIES(${TARGET}
+    PROPERTIES COMPILE_FLAGS "${CFLAGS}" LINK_FLAGS "${LDFLAGS}")
+  
+  IF(UNIX AND NOT APPLE)
+    TARGET_LINK_LIBRARIES(${TARGET} ${${PREFIX}_LDFLAGS})
+    TARGET_LINK_LIBRARIES(${TARGET} ${${PREFIX}_LDFLAGS_OTHER})
+  ENDIF(UNIX AND NOT APPLE)
+
+  # Include/libraries paths seems to be filtered on Linux, add paths
+  # again.
+  INCLUDE_DIRECTORIES(${${PREFIX}_INCLUDE_DIRS})
+  LINK_DIRECTORIES(${${PREFIX}_LIBRARY_DIRS})
+ENDMACRO(PKG_CONFIG_USE_DEPENDENCY TARGET DEPENDENCY)
+

File addons/urdfreader/CMake/ros.cmake

+# This file was taken from: 
+# https://github.com/jrl-umi3218/jrl-cmakemodules/blob/master/ros.cmake
+
+MACRO(ADD_ROSPACK_DEPENDENCY PKG)
+  IF(PKG STREQUAL "")
+    MESSAGE(FATAL_ERROR "ADD_ROS_DEPENDENCY invalid call.")
+  ENDIF()
+
+  # Transform package name into a valid variable prefix.
+  # 1. replace invalid characters into underscores.
+  STRING(REGEX REPLACE "[^a-zA-Z0-9]" "_" PREFIX "${PKG}")
+  # 2. make it uppercase.
+  STRING(TOUPPER "${PREFIX}" "PREFIX")
+
+  SET(${PREFIX}_FOUND 0)
+
+  FIND_PROGRAM(ROSPACK rospack)
+  IF(NOT ROSPACK)
+    MESSAGE(FATAL_ERROR "failed to find the rospack binary. Is ROS installed?")
+  ENDIF()
+
+  MESSAGE(STATUS "Looking for ${PKG} using rospack...")
+  EXEC_PROGRAM("${ROSPACK} find ${PKG}" OUTPUT_VARIABLE ${PKG}_ROS_PREFIX)
+  IF(NOT ${PKG}_ROS_PREFIX)
+    MESSAGE(FATAL_ERROR "Failed to detect ${PKG}.")
+  ENDIF()
+
+  SET(${PREFIX}_FOUND 1)
+  EXEC_PROGRAM("${ROSPACK} export --lang=cpp --attrib=cflags ${PKG}"
+    OUTPUT_VARIABLE "${PREFIX}_CFLAGS")
+  EXEC_PROGRAM("${ROSPACK} export --lang=cpp --attrib=lflags ${PKG}"
+    OUTPUT_VARIABLE "${PREFIX}_LIBS")
+
+  # Add flags to package pkg-config file.
+  PKG_CONFIG_APPEND_CFLAGS (${${PREFIX}_CFLAGS})
+  PKG_CONFIG_APPEND_LIBS_RAW (${${PREFIX}_LIBS})
+ENDMACRO()
+
+MACRO(ROSPACK_USE_DEPENDENCY TARGET PKG)
+  IF(PKG STREQUAL "")
+    MESSAGE(FATAL_ERROR "ADD_ROS_DEPENDENCY invalid call.")
+  ENDIF()
+
+  # Transform package name into a valid variable prefix.
+  # 1. replace invalid characters into underscores.
+  STRING(REGEX REPLACE "[^a-zA-Z0-9]" "_" PREFIX "${PKG}")
+  # 2. make it uppercase.
+  STRING(TOUPPER "${PREFIX}" "PREFIX")
+
+  # Make sure we do not override previous flags.
+  GET_TARGET_PROPERTY(CFLAGS "${TARGET}" COMPILE_FLAGS)
+  GET_TARGET_PROPERTY(LDFLAGS "${TARGET}" LINK_FLAGS)
+
+  # If there were no previous flags, get rid of the XYFLAGS-NOTFOUND
+  # in the variables.
+  IF(NOT CFLAGS)
+    SET(CFLAGS "")
+  ENDIF()
+  IF(NOT LDFLAGS)
+    SET(LDFLAGS "")
+  ENDIF()
+
+  # Transform semi-colon seperated list in to space separated list.
+  FOREACH(FLAG ${${PREFIX}_CFLAGS})
+    SET(CFLAGS "${CFLAGS} ${FLAG}")
+  ENDFOREACH()
+
+  FOREACH(FLAG ${${PREFIX}_LDFLAGS})
+    SET(LDFLAGS "${LDFLAGS} ${FLAG}")
+  ENDFOREACH()
+
+  # Filter out end of line in new flags.
+  STRING(REPLACE "\n" "" ${PREFIX}_CFLAGS "${${PREFIX}_CFLAGS}")
+  STRING(REPLACE "\n" "" ${PREFIX}_LIBS "${${PREFIX}_LIBS}")
+
+  # Append new flags.
+  SET(CFLAGS "${CFLAGS} ${${PREFIX}_CFLAGS}")
+  SET(LDFLAGS "${LDFLAGS} ${${PREFIX}_LIBS}")
+
+  # Update the flags.
+  SET_TARGET_PROPERTIES(${TARGET}
+    PROPERTIES COMPILE_FLAGS "${CFLAGS}" LINK_FLAGS "${LDFLAGS}")
+ENDMACRO()
+

File addons/urdfreader/CMake/shared-library.cmake

+# Copyright (C) 2010 Florent Lamiraux, Thomas Moulard, JRL, CNRS/AIST.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Shared library related constants
+# (used for pkg-config file generation).
+# FIXME: can't we get these information from CMake directly?
+IF(WIN32)
+  SET(LIBDIR_KW "/LIBPATH:")
+  SET(LIBINCL_KW "")
+  SET(LIB_EXT ".lib")
+ELSEIF(UNIX)
+  SET(LIBDIR_KW "-L")
+  SET(LIBINCL_KW "-l")
+  SET(LIB_EXT "")
+ENDIF(WIN32)
+

File addons/urdfreader/CMakeLists.txt

 
 LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake )
 
+INCLUDE ( CMake/ros.cmake)
+INCLUDE ( CMake/pkg-config.cmake)
+
+
+ADD_ROSPACK_DEPENDENCY ("urdf")
+ADD_ROSPACK_DEPENDENCY ("urdf_interface")
+ADD_ROSPACK_DEPENDENCY ("urdf_parser")
+
 INCLUDE_DIRECTORIES ( 
 	${CMAKE_CURRENT_BINARY_DIR}/include/rbdl
 	${CMAKE_CURRENT_SOURCE_DIR}/tinyxml/
 # Options
 SET ( URDFREADER_SOURCES 
 	rbdl_urdfreader.cc
-	tinyxml/tinystr.cpp
-	tinyxml/tinyxml.cpp
-	tinyxml/tinyxmlerror.cpp
-	tinyxml/tinyxmlparser.cpp
 	)
 
 ADD_LIBRARY ( rbdl_urdfreader SHARED ${URDFREADER_SOURCES} )
 
+ROSPACK_USE_DEPENDENCY (rbdl_urdfreader urdf)
+ROSPACK_USE_DEPENDENCY (rbdl_urdfreader urdf_interface)
+
 ADD_DEFINITIONS (-DTIXML_USE_STL)
 
 IF (BUILD_STATIC)

File addons/urdfreader/README

+urdfreader - load models from (URDF Unified Robot Description Format) files
+Copyright (c) 2012 Martin Felis <martin.felis@iwr.uni-heidelberg.de>
+
+REQUIREMENTS
+
+This addon depends on ROS, the Robot Operating System (http://www.ros.org)
+and uses its urdf_parser and urdf_interface to load and access the model
+data in the files. You therefore need to have ROS and the package
+"robot-model" installed on your system to be able to compile this addon.
+
+See http://www.ros.org/wiki/ROS/Installation for more details on how to
+install ROS.
+
+LICENSING
+
+This code is published under the zlib license, however some parts of the
+CMake scripts are taken from other projects and are licensed under
+different terms.
+
+Full license text:
+
+-------
+urdfreader - load models from URDF (Unified Robot Description Format) files
+Copyright (c) 2011-2012 Martin Felis <martin.felis@iwr.uni-heidelberg.de>
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+   1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+   3. This notice may not be removed or altered from any source
+   distribution.

File addons/urdfreader/rbdl_urdfreader.cc

 #include <assert.h>
 #include <iostream>
 #include <map>
-#include "tinyxml/tinyxml.h"
+#include <stack>
+
+#include "urdf/model.h"
 
 using namespace std;
 
-struct URDFLink {
-	URDFLink () :
-		name (""),
-		origin_x (0.), origin_y (0.), origin_z (0.),
-		origin_rot_r (0.), origin_rot_p (0.), origin_rot_y (0.),
-		mass (0.),
-		ixx(0.), ixy(0.), ixz(0.), iyy(0.), iyz(0.), izz(0.)
-	{}
-
-	string name;
-	double origin_x, origin_y, origin_z;
-	double origin_rot_r, origin_rot_p, origin_rot_y;
-	double mass;
-	double ixx, ixy, ixz, iyy, iyz, izz;
-
-	void debug_print () {
-		cout << "link '" << name << "'" << endl;
-		cout << "  origin xyz = " << origin_x << " " << origin_y << " " << origin_z << endl;
-		cout << "  origin_rot rpy = " << origin_rot_r << " " << origin_rot_p << " " << origin_rot_y << endl;
-		cout << "  mass = " << mass << endl;
-		cout << "  ixx = " << ixx << " ixy = " <<  ixy << " ixz = " << ixz << " iyy = " << iyy << " iyz = " << iyz << " izz = " << izz << endl;
-	}
-};
-
-enum URDFJointType {
-	URDFJointTypeUnknown = 0,
-	URDFJointTypeRevolute,
-	URDFJointTypeContinuous,
-	URDFJointTypePrismatic,
-	URDFJointTypeFixed,
-	URDFJointTypeFloating,
-	URDFJointTypePlanar,
-	URDFJointTypeLast
-};
-
-struct URDFJoint {
-	URDFJoint() :
-		name (""),
-		type (URDFJointTypeUnknown),
-		origin_x (0.), origin_y (0.), origin_z (0.),
-		origin_rot_r (0.), origin_rot_p (0.), origin_rot_y (0.),
-		parent(""),
-		child ("")
-	{
-		axis[0] = 0.;
-		axis[1] = 0.;
-		axis[2] = 0.;
-	}
-
-	string name;
-	URDFJointType type;
-
-	string parent;
-	string child;
-
-	double origin_x, origin_y, origin_z;
-	double origin_rot_r, origin_rot_p, origin_rot_y;
-
-	double axis[3];
-
-	void debug_print () {
-		cout << "joint '" << name << "'" << endl;
-		cout << "  type = " << type << endl;
-		cout << "  parent = " << parent << endl;
-		cout << "  child = " << child << endl;
-		cout << "  origin xyz = " << origin_x << " " << origin_y << " " << origin_z << endl;
-		cout << "  origin_rot rpy = " << origin_rot_r << " " << origin_rot_p << " " << origin_rot_y << endl;
-		cout << "  axis = " << axis[0] << " " << axis[1] << " " << axis[2] << endl;
-	}};
-
-typedef std::map<std::string, URDFLink> LinkMap;
-typedef std::map<std::string, URDFJoint> JointMap;
-typedef std::vector<std::string> JointNamesVector;
-
 namespace RigidBodyDynamics {
 
-class Model;
-
-using namespace Math;
-
 namespace Addons {
 
-bool parse_double_triple (string str, double out[3]) {
-	istringstream value_stream (str);
+typedef boost::shared_ptr<urdf::Link> LinkPtr;
+typedef boost::shared_ptr<urdf::Joint> JointPtr;
 
-	if ((value_stream >> out[0]).bad())
-		return false;
+typedef vector<LinkPtr> URDFLinkVector;
+typedef vector<JointPtr> URDFJointVector;
+typedef map<string, LinkPtr > URDFLinkMap;
+typedef map<string, JointPtr > URDFJointMap;
 
-	if ((value_stream >> out[1]).bad())
-		return false;
+bool construct_model (Model* rbdl_model, urdf::Model *urdf_model) {
+	boost::shared_ptr<urdf::Link> urdf_root_link;
 
-	if ((value_stream >> out[2]).bad())
-		return false;
+	URDFLinkMap link_map;
+	link_map = urdf_model->links_;
 
-	return true;
-}
+	URDFJointMap joint_map;
+	joint_map = urdf_model->joints_;
 
-bool read_single_link (TiXmlHandle handle, URDFLink &link) {
-	string link_name;
-	handle.ToElement()->QueryStringAttribute("name", &link_name);
-	link.name = link_name;
+	stack<LinkPtr > link_stack;
+	stack<int> joint_index_stack;
 
-	// read origin xyz and rpy
-	TiXmlElement *origin_element = handle.FirstChild("inertial").FirstChild("origin").ToElement();
-	if (origin_element) {
-		string value_str;
-		origin_element->QueryStringAttribute("xyz", &value_str);
+	// add the bodies in a depth-first order of the model tree
+	link_stack.push (link_map[(urdf_model->getRoot()->name)]);
 
-		if (value_str.size() != 0) {
-			double values[3];
-			if (!parse_double_triple (value_str, values)) {
-				cerr << "Unable to parse origin xyz: '" << value_str << "'" << endl;
-				return false;
+	if (link_stack.top()->child_joints.size() > 0) {
+		joint_index_stack.push(0);
+	}
+
+	while (link_stack.size() > 0) {
+		LinkPtr cur_link = link_stack.top();
+		int joint_idx = joint_index_stack.top();
+
+		if (joint_idx < cur_link->child_joints.size()) {
+			JointPtr cur_joint = cur_link->child_joints[joint_idx];
+
+			// increment joint index
+			joint_index_stack.pop();
+			joint_index_stack.push (joint_idx + 1);
+
+			link_stack.push (link_map[cur_joint->child_link_name]);
+			joint_index_stack.push(0);
+
+			for (int i = 1; i < joint_index_stack.size() - 1; i++) {
+				cout << "  ";
 			}
-			link.origin_x = values[0];
-			link.origin_y = values[1];
-			link.origin_z = values[2];
-		}
-		
-		origin_element->QueryStringAttribute("rpy", &value_str);
-
-		if (value_str.size() != 0) {
-			double values[3];
-			if (!parse_double_triple (value_str, values)) {
-				cerr << "Unable to parse origin rpy: '" << value_str << "'" << endl;
-				return false;
-			}
-			link.origin_rot_r = values[0];
-			link.origin_rot_p = values[1];
-			link.origin_rot_y = values[2];
+			cout << "joint '" << cur_joint->name << "' child link '" << link_stack.top()->name << " type = " << cur_joint->type << endl;
+		} else {
+			link_stack.pop();
+			joint_index_stack.pop();
 		}
 	}
 
-	// read mass
-	TiXmlElement *mass_element = handle.FirstChild("inertial").FirstChild("mass").ToElement();
-	if (mass_element) {
-		if (mass_element->QueryDoubleAttribute ("value", &(link.mass)) != TIXML_SUCCESS)
-			link.mass = 0.;
-	}
+	/*
 
-	// and inertia
-	TiXmlElement *inertia_element = handle.FirstChild("inertial").FirstChild("inertia").ToElement();
-	if (inertia_element) {
-		if (inertia_element->QueryDoubleAttribute ("ixx", &(link.ixx)) != TIXML_SUCCESS) {
-			link.ixx = 0.;
-		}
-		if (inertia_element->QueryDoubleAttribute ("ixy", &(link.ixy)) != TIXML_SUCCESS) {
-			link.ixy = 0.;
-		}
-		if (inertia_element->QueryDoubleAttribute ("ixz", &(link.ixz)) != TIXML_SUCCESS) {
-			link.ixz = 0.;
-		}
-		if (inertia_element->QueryDoubleAttribute ("iyy", &(link.iyy)) != TIXML_SUCCESS) {
-			link.iyy = 0.;
-		}
-		if (inertia_element->QueryDoubleAttribute ("iyz", &(link.iyz)) != TIXML_SUCCESS) {
-			link.iyz = 0.;
-		}
-		if (inertia_element->QueryDoubleAttribute ("izz", &(link.izz)) != TIXML_SUCCESS) {
-			link.izz = 0.;
-		}
-	}
-
-	return true;
-}
-
-bool read_links (TiXmlDocument &doc, LinkMap &links) {
-	TiXmlHandle doc_handle (&doc);
-	TiXmlHandle link_handle = doc_handle.FirstChild("robot").FirstChild("link");
-
-	TiXmlElement *child = link_handle.ToElement();
-
-	while (child) {
-		if (child->ValueStr() != "link") {
-			child = child->NextSiblingElement();
-			continue;
-		}
-
-		URDFLink link;
-		string link_name;
-		child->QueryStringAttribute("name", &link_name);
-
-		if (!read_single_link(child, link)) {
-			return false;
-		}
-
-		links[link_name] = link;
-
-		child = child->NextSiblingElement();
-	}
-
-	return true;
-}
-
-bool read_single_joint (TiXmlHandle handle, URDFJoint &joint) {
-	string joint_name;
-	handle.ToElement()->QueryStringAttribute("name", &joint_name);
-	joint.name = joint_name;
-
-	// type
-	string joint_type_string;
-	handle.ToElement()->QueryStringAttribute("type", &joint_type_string);
-	if (joint_type_string == "revolute")
-		joint.type = URDFJointTypeRevolute;
-	else if (joint_type_string == "continuous")
-		joint.type = URDFJointTypeContinuous;
-	else if (joint_type_string == "prismatic")
-		joint.type = URDFJointTypePrismatic;
-	else if (joint_type_string == "fixed")
-		joint.type = URDFJointTypeFixed;
-	else if (joint_type_string == "Floating")
-		joint.type = URDFJointTypeFloating;
-	else if (joint_type_string == "Planar")
-		joint.type = URDFJointTypePlanar;
-
-	// read origin xyz and rpy
-	TiXmlElement *origin_element = handle.FirstChild("origin").ToElement();
-	if (origin_element) {
-		string value_str;
-		origin_element->QueryStringAttribute("xyz", &value_str);
-
-		if (value_str.size() != 0) {
-			double values[3];
-			if (!parse_double_triple (value_str, values)) {
-				cerr << "Unable to parse origin xyz: '" << value_str << "'" << endl;
-				return false;
-			}
-			joint.origin_x = values[0];
-			joint.origin_y = values[1];
-			joint.origin_z = values[2];
-		}
-		
-		origin_element->QueryStringAttribute("rpy", &value_str);
-
-		if (value_str.size() != 0) {
-			double values[3];
-			if (!parse_double_triple (value_str, values)) {
-				cerr << "Unable to parse origin rpy: '" << value_str << "'" << endl;
-				return false;
-			}
-			joint.origin_rot_r = values[0];
-			joint.origin_rot_p = values[1];
-			joint.origin_rot_y = values[2];
-		}
-	}
-
-	// read parent
-	TiXmlElement *parent_element = handle.FirstChild("parent").ToElement();
-	if (!parent_element) {
-		cerr << "Could not find required parent element for joint '" << joint_name << endl;
-		return false;
-	}
-
-	if (parent_element->QueryStringAttribute ("link", &(joint.parent)) != TIXML_SUCCESS) {
-		cerr << "Could not find required parent element for joint '" << joint_name << endl;
-		return false;
-	}
-
-	// read child
-	TiXmlElement *child_element = handle.FirstChild("child").ToElement();
-	if (!child_element) {
-		cerr << "Could not find required child element for joint '" << joint_name << endl;
-		return false;
-	}
-
-	if (child_element->QueryStringAttribute ("link", &(joint.child)) != TIXML_SUCCESS) {
-		cerr << "Could not find required child element for joint '" << joint_name << endl;
-		return false;
-	}
-
-	// axis
-	joint.axis[0] = 1.;
-	joint.axis[1] = 0.;
-	joint.axis[2] = 0.;
-
-	TiXmlElement *axis_element = handle.FirstChild("axis").ToElement();
-	if (axis_element) {
-		string value_str;
-		axis_element->QueryStringAttribute("xyz", &value_str);
-
-		if (value_str.size() != 0) {
-			double values[3];
-			if (!parse_double_triple (value_str, values)) {
-				cerr << "Unable to parse origin xyz: '" << value_str << "'" << endl;
-				return false;
-			}
-			joint.axis[0] = values[0];
-			joint.axis[1] = values[1];
-			joint.axis[2] = values[2];
-		}
-	}
-
-//	joint.debug_print();
-
-	return true;
-}
-
-bool read_joints (TiXmlDocument &doc, JointMap &joints, JointNamesVector &joint_names) {
-	TiXmlHandle doc_handle (&doc);
-	TiXmlHandle joint_handle = doc_handle.FirstChild("robot").FirstChild("joint");
-
-	TiXmlElement *child = joint_handle.ToElement();
-
-	while (child) {
-		if (child->ValueStr() != "joint") {
-			child = child->NextSiblingElement();
-			continue;
-		}
-
-		URDFJoint joint;
-		string joint_name;
-		child->QueryStringAttribute("name", &joint_name);
-
-		if (!read_single_joint(child, joint)) {
-			return false;
-		}
-
-		joints[joint_name] = joint;
-		joint_names.push_back(joint_name);
-
-		child = child->NextSiblingElement();
-	}
-
-	return true;
-}
-
-bool construct_model (Model* model, LinkMap &links, JointMap &joints, JointNamesVector &joint_names) {
 	unsigned int j;
 	for (j = 0; j < joint_names.size(); j++) {
 		URDFJoint urdf_joint = joints[joint_names[j]];
 
 		model->AddBody (rbdl_parent_id, rbdl_joint_frame, rbdl_joint, rbdl_body, urdf_child.name);
 	}
+	*/
 
 	return false;
 }
 bool read_urdf_model (const char* filename, Model* model, bool verbose) {
 	assert (model);
 
-	TiXmlDocument doc (filename);
-	bool load_success = doc.LoadFile();
+	model->Init();
 
-	if (!load_success) {
+	urdf::Model urdf_model;
+
+	bool urdf_result = urdf_model.initFile (filename);
+	if (!urdf_result) {
+		cerr << "Error opening urdf file" << endl;
+	}
+
+	if (!construct_model (model, &urdf_model)) {
+		cerr << "Error constructing model from urdf file." << endl;
 		return false;
 	}
 
-	LinkMap links;
-	JointMap joints;
-	JointNamesVector joint_names; // keeps track of the ordering of the joints
-
-	if (!read_links(doc, links)) {
-		return false;
-	}
-
-	if (verbose) {
-		cout << "Read " << links.size() << " links." << endl;
-	}
-
-	if (!read_joints(doc, joints, joint_names)) {
-		return false;
-	}
-
-	if (verbose) {
-		cout << "Read " << joints.size() << " joints." << endl;
-	}
-
-	model->Init();
-	construct_model (model, links, joints, joint_names);
-
-	cout << "Created model with " << model->dof_count << " DoF" << endl;
-
-	return false;
+	return true;
 }
 
 }

File addons/urdfreader/tinyxml/changes.txt

-Changes in version 1.0.1:
-- Fixed comment tags which were outputing as '<?--' instead of 
-  the correct '<!--'.
-- Implemented the Next and Prev methods of the TiXmlAttribute class.
-- Renamed 'LastAttribtute' to 'LastAttribute'
-- Fixed bad pointer to 'isspace' that could occur while parsing text.
-- Errors finding beginning and end of tags no longer throw it into an
-  infinite loop. (Hopefully.)
-
-Changes in version 1.0.2
-- Minor documentation fixes.
-
-Changes in version 1.0.3
-- After nodes are added to a document, they return a pointer
-  to the new node instead of a bool for success.
-- Elements can be constructed with a value, which is the
-  element name. Every element must have a value or it will be
-  invalid, but the code changes to enforce this are not fully
-  in place.
-
-Changes in version 1.1.0
-- Added the	TiXmlAttributeSet class to pull the attributes into
-  a seperate container.
-- Moved the doubly liked list out of XmlBase. Now XmlBase only
-  requires the Print() function and defines some utility functions.
-- Moved errors into a seperate file. (With the idea of internationalization
-  to the other latin-1 languages.)
-- Added the "NodeType"
-- Fixed white space parsing in text to conform with the standard. 
-  Basically, all white space becomes just one space.
-- Added the TiXmlDeclaration class to read xml declarations.
-
-Changes in version 1.2.0
-- Removed the factory. The factory was not really in the spirit 
-  of small and simple, confused the code, and was of limited value.
-- Added FirstChildElement and NextSiblingElement, because they
-  are such common functions.
-- Re-wrote the example to test and demonstrate more functionality.
-
-Changes in version 1.2.1
-- Fixed a bug where comments couldn't be inside elements.
-- Loading now clears out existing XML rather than appending.
-- Added the "Clear" method on a node to delete all its children.
-
-Changes in version 1.2.2
-- Fixed TiXmlAttribute::Previous actually returning "next." Thanks
-  to Rickard Troedsson for the bug fix.
-
-Changes in version 1.2.3
-- Added the TIXML prefix to the error strings to resolve conflicts
-  with #defines in OS headers. Thanks to Steve Lhomme.
-- Fixed a delete buf that should be a delete [] buf. 
-  Thanks to Ephi Sinowitz.
-
-Changes in version 1.2.4
-- ReplaceChild() was almost guarenteed to fail. Should be fixed,
-  thanks to Joe Smith. Joe also pointed out that the Print() functions
-  should take stream references: I agree, and would like to overload
-  the Print() method to take either format, but I don't want to do 
-  this in a dot release.
-- Some compilers seem to need an extra <ctype.h> include. Thanks
-  to Steve Lhomme for that.
-
-Changes in version 2.0.0 BETA
-- Made the ToXXX() casts safe if 'this' is null. 
-  When "LoadFile" is called with a filename, the value will correctly get set.
-  Thanks to Brian Yoder.
-- Fixed bug where isalpha() and isalnum() would get called with a negative value for 
-  high ascii numbers. Thanks to Alesky Aksenov.
-- Fixed some errors codes that were not getting set.
-- Made methods "const" that were not.
-- Added a switch to enable or disable the ignoring of white space. ( TiXmlDocument::SetIgnoreWhiteSpace() )
-- Greater standardization and code re-use in the parser.
-- Added a stream out operator.
-- Added a stream in operator.
-- Entity support, of predefined entites. &#x entities are untouched by input or output.
-- Improved text out formatting.
-- Fixed ReplaceChild bug, thanks to Tao Chen.
-
-Changes in version 2.0.1
-- Fixed hanging on loading a 0 length file. Thanks to Jeff Scozzafava.
-- Fixed crashing on InsertBeforeChild and InsertAfterChild. Also possibility of bad links being
-  created by same function. Thanks to Frank De prins.
-- Added missing licence text. Thanks to Lars Willemsens.
-- Added <ctype.h> include, at the suggestion of Steve Walters.
-
-Changes in version 2.1.0
-- Yves Berquin brings us the STL switch. The forum on SourceForge, and various emails to
-  me, have long debated all out STL vs. no STL at all. And now you can have it both ways.
-  TinyXml will compile either way.
-
-Changes in version 2.1.1
-- Compilation warnings.
-
-Changes in version 2.1.2
-- Uneeded code is not compiled in the STL case.
-- Changed headers so that STL can be turned on or off in tinyxml.h
-
-Changes in version 2.1.3
-- Fixed non-const reference in API; now uses a pointer.
-- Copy constructor of TiXmlString not checking for assignment to self.
-- Nimrod Cohen found a truly evil bug in the STL implementation that occurs
-  when a string is converted to a c_str and then assigned to self. Search for
-  STL_STRING_BUG for a full description. I'm asserting this is a Microsoft STL
-  bug, since &string and string.c_str() should never be the same. Nevertheless,
-  the code works around it.
-- Urivan Saaib pointed out a compiler conflict, where the C headers define
-  the isblank macro, which was wiping out the TiXmlString::isblank() method.
-  The method was unused and has been removed.
-
-Changes in version 2.1.4
-- Reworked the entity code. Entities were not correctly surving round trip input and output.
-  Will now automatically create entities for high ascii in output.
-
-Changes in version 2.1.5
-- Bug fix by kylotan : infinite loop on some input (tinyxmlparser.cpp rev 1.27)
-- Contributed by Ivica Aracic (bytelord) : 1 new VC++ project to compile versions as static libraries (tinyxml_lib.dsp), 
-  and an example usage in xmltest.dsp
-  (Patch request ID 678605)
-- A suggestion by Ronald Fenner Jr (dormlock) to add #include <istream> and <ostream> for Apple's Project Builder 
-  (Patch request ID 697642)
-- A patch from ohommes that allows to parse correctly dots in element names and attribute names
-  (Patch request 602600 and kylotan 701728)
-- A patch from  hermitgeek ( James ) and wasteland for improper error reporting
-- Reviewed by Lee, with the following changes:
-	- Got sick of fighting the STL/non-STL thing in the windows build. Broke
-	  them out as seperate projects.
-	- I have too long not included the dsw. Added.
-	- TinyXmlText had a protected Print. Odd.
-	- Made LinkEndChild public, with docs and appropriate warnings.
-	- Updated the docs.
-
-2.2.0
-- Fixed an uninitialized pointer in the TiXmlAttributes
-- Fixed STL compilation problem in MinGW (and gcc 3?) - thanks Brian Yoder for finding this one
-- Fixed a syntax error in TiXmlDeclaration - thanks Brian Yoder
-- Fletcher Dunn proposed and submitted new error handling that tracked the row and column. Lee
-  modified it to not have performance impact.
-- General cleanup suggestions from Fletcher Dunn.
-- In error handling, general errors will no longer clear the error state of specific ones.
-- Fix error in documentation : comments starting with "<?--" instead of "<!--" (thanks ion_pulse)
-- Added the TiXmlHandle. An easy, safe way to browse XML DOMs with less code.
-- Added QueryAttribute calls which have better error messaging. (Proposed by Fletcher Dunn)
-- Nodes and attributes can now print themselves to strings. (Yves suggestion)
-- Fixed bug where entities with one character would confuse parser. (Thanks Roman)
-
-2.2.1
-- Additional testing (no more bugs found to be fixed in this release)
-- Significant performance improvement to the cursor code.
-
-2.3.0
-- User Data are now defined in TiXmlBase instead of TiXmlNode
-- Character Entities are now UCS-2
-- Character Entities can be decimal or hexadecimal
-- UTF-8 conversion.
-- Fixed many, many bugs.
-
-2.3.1
-- Fixed bug in handling nulls embedded in the input.
-- Make UTF-8 parser tolerant of bad text encoding.
-- Added encoding detection. 
-- Many fixes and input from John-Philip Leonard Johansson (JP) and Ellers, 
-  including UTF-8 feedback, bug reports, and patches. Thanks!
-- Added version # constants - a suggestion from JP and Ellers.
-- [ 979180 ] Missing ; in entity reference, fix from Rob Laveaux.
-- Copy constructors and assignment have been a long time coming. Thanks to
-  Fokke and JP.
-
-2.3.2
-- Made the IsAlpha and IsAlphaNum much more tolerant of non-UTF-8 encodings. Thanks
-  Volker Boerchers for finding the issue.
-- Ran the program though the magnificent Valgrind - http://valgrind.kde.org - to check
-  for memory errors. Fixed some minor issues.
-
-2.3.3
-- Fixed crash when test program was run from incorrect directory.
-- Fixed bug 1070717 - empty document not returned correctly - thanks Katsuhisa Yuasa.
-- Bug 1079301 resolved - deprecated stdlib calls. Thanks Adrian Boeing.
-- Bug 1035218 fixed - documentation errors. Xunji Luo
-- Other bug fixes have accumulated and been fixed on the way as well; my apologies to
-  authors not credited!
-- Big fix / addition is to correctly return const values. TinyXml could basically
-  remove const in a method like this: TiXmlElement* Foo() const, where the returned element
-  was a pointer to internal data. That is now: const TiXmlElement* Foo() const and
-  TiXmlElement* Foo().
-
-2.3.4
-- Fixed additional const errors, thanks Kent Gibson.
-- Correctly re-enable warnings after tinyxml header. Thanks Cory Nelson.
-- Variety of type cleanup and warning fixes. Thanks Warren Stevens.
-- Cleaned up unneeded constructor calls in TinyString - thanks to Geoff Carlton and
-  the discussion group on sourceforge.
-
-2.4.0
-- Improved string class, thanks Tyge Lovset (whose name gets mangled in English - sorry)
-- Type cast compiler warning, thanks Rob van den Bogaard
-- Added GetText() convenience function. Thanks Ilya Parniuk & Andrew Ellers for input.
-- Many thanks to marlonism for finding an infinite loop in bad xml.
-- A patch to cleanup warnings from Robert Gebis.
-- Added ValueStr() to get the value of a node as a string.
-- TiXmlText can now parse and output as CDATA
-- Additional string improvement from James (z2895)
-- Removed extraneous 'const', thanks David Aldrich
-- First pass at switching to the "safe" stdlib functions. Many people have suggested and
-  pushed on this, but Warren Stevens put together the first proposal.
-- TinyXml now will do EOL normalization before parsing, consistent with the W3C XML spec.
-- Documents loaded with the UTF-8 BOM will now save with the UTF-8 BOM. Good suggestion 
-  from 'instructor_'
-- Ellers submitted his very popular tutorials, which have been added to the distribution.
-
-2.4.1
-- Fixed CDATA output formatting
-- Fixed memory allocators in TinyString to work with overloaded new/delete
-
-2.4.2
-- solosnake pointed out that TIXML_LOG causes problems on an XBOX. The definition in the header
-  was superflous and was moved inside of DEBUG_PARSING
-
-2.4.3
-- Fixed a test bug that caused a crash in 'xmltest'. TinyXML was fine, but it isn't good
-  to ship with a broken test suite.
-- Started converting some functions to not cast between std::string and const char* 
-  quite as often.
-- Added FILE* versions of the document loads - good suggestion from Wade Brainerd
-- Empty documents might not always return the errors they should. [1398915] Thanks to igor v.
-- Added some asserts for multiply adding a node, regardng bug [1391937] suggested by Paco Arjonilla.
-
-2.4.4
-- Bug find thanks to andre-gross found a memory leak that occured when a document failed to load.
-- Bug find (and good analysis) by VirtualJim who found a case where attribute parsing 
-  should be throwing an error and wasn't.
-- Steve Hyatt suggested the QueryValueAttribute method, which is now implemented.
-- DavidA identified a chunk of dead code.
-- Andrew Baxter sent in some compiler warnings that were good clean up points.
-
-2.5
-- Added the Visit() API. Many thanks to both Andrew Ellerton and John-Philip for all their
-  work, code, suggestion, and just general pushing that it should be done.
-- Removed existing streaming code and use TiXmlPrinter instead.
-- [ tinyxml-Bugs-1527079 ] Compile error in tinystr.cpp fixed, thanks to Paul Suggs
-- [ tinyxml-Bugs-1522890 ] SaveFile has no error checks fixed, thanks to Ivan Dobrokotov
-- Ivan Dobrokotov also reported redundant memory allocation in the Attribute() method, which
-  upon investigation was a mess. The attribute should now be fixed for both const char* and 
-  std::string, and the return types match the input parameters.
-- Feature [ 1511105 ] Make TiXmlComment constructor accept a string / char*, implemented.
-  Thanks to Karl Itschen for the feedback.
-- [ 1480108 ] Stream parsing fails when CDATA contains tags was found by Tobias Grimm, who also
-  submitted a test case and patch. A significant bug in CDATA streaming (operator>>) has now
-  been fixed.
-
-2.5.2
-- Lieven, and others, pointed out a missing const-cast that upset the Open Watcom compiler.
-  Should now be fixed.
-- ErrorRow and ErrorCol should have been const, and weren't. Fixed thanks to Dmitry Polutov.
-
-2.5.3
-- zloe_zlo identified a missing string specialization for QueryValueAttribute() [ 1695429 ]. Worked
-  on this bug, but not sure how to fix it in a safe, cross-compiler way.
-- increased warning level to 4 and turned on detect 64 bit portability issues for VC2005.
-  May address [ 1677737 ] VS2005: /Wp64 warnings
-- grosheck identified several problems with the Document copy. Many thanks for [ 1660367 ]
-- Nice catch, and suggested fix, be Gilad Novik on the Printer dropping entities.
-  "[ 1600650 ] Bug when printing xml text" is now fixed.
-- A subtle fix from Nicos Gollan in the tinystring initializer: 
-  [ 1581449 ] Fix initialiser of TiXmlString::nullrep_
-- Great catch, although there isn't a submitter for the bug. [ 1475201 ] TinyXML parses entities in comments. 
-  Comments should not, in fact, parse entities. Fixed the code path and added tests.
-- We were not catching all the returns from ftell. Thanks to Bernard for catching that.
-  
-2.5.4
-- A TiXMLDocument can't be a sub-node. Block this from happening in the 'replace'. Thanks Noam.
-- [ 1714831 ] TiXmlBase::location is not copied by copy-ctors, fix reported and suggested by Nicola Civran.
-- Fixed possible memory overrun in the comment reading code - thanks gcarlton77
-
-2.5.5
-- Alex van der Wal spotted incorrect types (lf) being used in print and scan. robertnestor pointed out some problems with the simple solution. Types updated.
-- Johannes Hillert pointed out some bug typos.
-- Christian Mueller identified inconsistent error handling with Attributes.
-- olivier barthelemy also reported a problem with double truncation, also related to the %lf issue.
-- zaelsius came up with a great (and simple) suggestion to fix QueryValueAttribute truncating strings.
-- added some null pointer checks suggested by hansenk
-- Sami V�is�nen found a (rare) buffer overrun that could occur in parsing.
-- vi tri filed a bug that led to a refactoring of the attribute setting mess (as well as adding a missing SetDoubleAttribute() )
-- removed TIXML_ERROR_OUT_OF_MEMORY. TinyXML does not systematically address OOO, and the notion it does is misleading.
-- vanneto, keithmarshall, others all reported the warning from IsWhiteSpace() usage. Cleaned this up - many thanks to everyone who reported this one.
-- tibur found a bug in end tag parsing
-
-
-2.6.2
-- Switched over to VC 2010
-- Fixed up all the build issues arising from that. (Lots of latent build problems.)
-- Removed the old, now unmaintained and likely not working, build files.
-- Fixed some static analysis issues reported by orbitcowboy from cppcheck. 
-- Bayard 95 sent in analysis from a different analyzer - fixes applied from that as well.
-- Tim Kosse sent a patch fixing an infinite loop.
-- Ma Anguo identified a doc issue.
-- Eddie Cohen identified a missing qualifier resulting in a compilation error on some systems.
-- Fixed a line ending bug. (What year is this? Can we all agree on a format for text files? Please? ...oh well.)
-

File addons/urdfreader/tinyxml/readme.txt

-/** @mainpage
-
-<h1> TinyXML </h1>
-
-TinyXML is a simple, small, C++ XML parser that can be easily 
-integrated into other programs.
-
-<h2> What it does. </h2>
-	
-In brief, TinyXML parses an XML document, and builds from that a 
-Document Object Model (DOM) that can be read, modified, and saved.
-
-XML stands for "eXtensible Markup Language." It allows you to create 
-your own document markups. Where HTML does a very good job of marking 
-documents for browsers, XML allows you to define any kind of document 
-markup, for example a document that describes a "to do" list for an 
-organizer application. XML is a very structured and convenient format.
-All those random file formats created to store application data can 
-all be replaced with XML. One parser for everything.
-
-The best place for the complete, correct, and quite frankly hard to
-read spec is at <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
-http://www.w3.org/TR/2004/REC-xml-20040204/</a>. An intro to XML
-(that I really like) can be found at 
-<a href="http://skew.org/xml/tutorial/">http://skew.org/xml/tutorial</a>.
-
-There are different ways to access and interact with XML data.
-TinyXML uses a Document Object Model (DOM), meaning the XML data is parsed
-into a C++ objects that can be browsed and manipulated, and then 
-written to disk or another output stream. You can also construct an XML document 
-from scratch with C++ objects and write this to disk or another output
-stream.
-
-TinyXML is designed to be easy and fast to learn. It is two headers 
-and four cpp files. Simply add these to your project and off you go. 
-There is an example file - xmltest.cpp - to get you started. 
-
-TinyXML is released under the ZLib license, 
-so you can use it in open source or commercial code. The details
-of the license are at the top of every source file.
-
-TinyXML attempts to be a flexible parser, but with truly correct and
-compliant XML output. TinyXML should compile on any reasonably C++
-compliant system. It does not rely on exceptions or RTTI. It can be 
-compiled with or without STL support. TinyXML fully supports
-the UTF-8 encoding, and the first 64k character entities.
-
-
-<h2> What it doesn't do. </h2>
-
-TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs
-(eXtensible Stylesheet Language.) There are other parsers out there 
-(check out www.sourceforge.org, search for XML) that are much more fully
-featured. But they are also much bigger, take longer to set up in
-your project, have a higher learning curve, and often have a more
-restrictive license. If you are working with browsers or have more
-complete XML needs, TinyXML is not the parser for you.
-
-The following DTD syntax will not parse at this time in TinyXML:
-
-@verbatim
-	<!DOCTYPE Archiv [
-	 <!ELEMENT Comment (#PCDATA)>
-	]>
-@endverbatim
-
-because TinyXML sees this as a !DOCTYPE node with an illegally 
-embedded !ELEMENT node. This may be addressed in the future.
-
-<h2> Tutorials. </h2>
-
-For the impatient, here is a tutorial to get you going. A great way to get started, 
-but it is worth your time to read this (very short) manual completely.
-
-- @subpage tutorial0
-
-<h2> Code Status.  </h2>
-
-TinyXML is mature, tested code. It is very stable. If you find
-bugs, please file a bug report on the sourceforge web site
-(www.sourceforge.net/projects/tinyxml). We'll get them straightened 
-out as soon as possible.
-
-There are some areas of improvement; please check sourceforge if you are
-interested in working on TinyXML.
-
-<h2> Related Projects </h2>
-
-TinyXML projects you may find useful! (Descriptions provided by the projects.)
-
-<ul>
-<li> <b>TinyXPath</b> (http://tinyxpath.sourceforge.net). TinyXPath is a small footprint 
-     XPath syntax decoder, written in C++.</li>
-<li> <b>TinyXML++</b> (http://code.google.com/p/ticpp/). TinyXML++ is a completely new 
-     interface to TinyXML that uses MANY of the C++ strengths. Templates, 
-	 exceptions, and much better error handling.</li>
-</ul>
-
-<h2> Features </h2>
-
-<h3> Using STL </h3>
-
-TinyXML can be compiled to use or not use STL. When using STL, TinyXML
-uses the std::string class, and fully supports std::istream, std::ostream,
-operator<<, and operator>>. Many API methods have both 'const char*' and
-'const std::string&' forms.
-
-When STL support is compiled out, no STL files are included whatsoever. All
-the string classes are implemented by TinyXML itself. API methods
-all use the 'const char*' form for input.
-
-Use the compile time #define:
-
-	TIXML_USE_STL
-
-to compile one version or the other. This can be passed by the compiler,
-or set as the first line of "tinyxml.h".
-
-Note: If compiling the test code in Linux, setting the environment
-variable TINYXML_USE_STL=YES/NO will control STL compilation. In the
-Windows project file, STL and non STL targets are provided. In your project,
-It's probably easiest to add the line "#define TIXML_USE_STL" as the first
-line of tinyxml.h.
-
-<h3> UTF-8 </h3>
-
-TinyXML supports UTF-8 allowing to manipulate XML files in any language. TinyXML
-also supports "legacy mode" - the encoding used before UTF-8 support and
-probably best described as "extended ascii".
-
-Normally, TinyXML will try to detect the correct encoding and use it. However,
-by setting the value of TIXML_DEFAULT_ENCODING in the header file, TinyXML
-can be forced to always use one encoding.
-
-TinyXML will assume Legacy Mode until one of the following occurs:
-<ol>
-	<li> If the non-standard but common "UTF-8 lead bytes" (0xef 0xbb 0xbf)
-		 begin the file or data stream, TinyXML will read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has an encoding="UTF-8", then
-		 TinyXML will read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has no encoding specified, then TinyXML will 
-		 read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has an encoding="something else", then TinyXML 
-		 will read it as Legacy Mode. In legacy mode, TinyXML will work as it did before. It's 
-		 not clear what that mode does exactly, but old content should keep working.</li>
-	<li> Until one of the above criteria is met, TinyXML runs in Legacy Mode.</li>
-</ol>
-
-What happens if the encoding is incorrectly set or detected? TinyXML will try
-to read and pass through text seen as improperly encoded. You may get some strange results or 
-mangled characters. You may want to force TinyXML to the correct mode.
-
-You may force TinyXML to Legacy Mode by using LoadFile( TIXML_ENCODING_LEGACY ) or
-LoadFile( filename, TIXML_ENCODING_LEGACY ). You may force it to use legacy mode all
-the time by setting TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY. Likewise, you may 
-force it to TIXML_ENCODING_UTF8 with the same technique.
-
-For English users, using English XML, UTF-8 is the same as low-ASCII. You
-don't need to be aware of UTF-8 or change your code in any way. You can think
-of UTF-8 as a "superset" of ASCII.
-
-UTF-8 is not a double byte format - but it is a standard encoding of Unicode!
-TinyXML does not use or directly support wchar, TCHAR, or Microsoft's _UNICODE at this time. 
-It is common to see the term "Unicode" improperly refer to UTF-16, a wide byte encoding
-of unicode. This is a source of confusion.
-
-For "high-ascii" languages - everything not English, pretty much - TinyXML can
-handle all languages, at the same time, as long as the XML is encoded
-in UTF-8. That can be a little tricky, older programs and operating systems
-tend to use the "default" or "traditional" code page. Many apps (and almost all
-modern ones) can output UTF-8, but older or stubborn (or just broken) ones
-still output text in the default code page. 
-
-For example, Japanese systems traditionally use SHIFT-JIS encoding. 
-Text encoded as SHIFT-JIS can not be read by TinyXML. 
-A good text editor can import SHIFT-JIS and then save as UTF-8.
-
-The <a href="http://skew.org/xml/tutorial/">Skew.org link</a> does a great
-job covering the encoding issue.
-
-The test file "utf8test.xml" is an XML containing English, Spanish, Russian,
-and Simplified Chinese. (Hopefully they are translated correctly). The file
-"utf8test.gif" is a screen capture of the XML file, rendered in IE. Note that
-if you don't have the correct fonts (Simplified Chinese or Russian) on your
-system, you won't see output that matches the GIF file even if you can parse
-it correctly. Also note that (at least on my Windows machine) console output
-is in a Western code page, so that Print() or printf() cannot correctly display
-the file. This is not a bug in TinyXML - just an OS issue. No data is lost or 
-destroyed by TinyXML. The console just doesn't render UTF-8.
-
-
-<h3> Entities </h3>
-TinyXML recognizes the pre-defined "character entities", meaning special
-characters. Namely:
-
-@verbatim
-	&amp;	&
-	&lt;	<
-	&gt;	>
-	&quot;	"
-	&apos;	'
-@endverbatim
-
-These are recognized when the XML document is read, and translated to there
-UTF-8 equivalents. For instance, text with the XML of:
-
-@verbatim
-	Far &amp; Away
-@endverbatim
-
-will have the Value() of "Far & Away" when queried from the TiXmlText object,
-and will be written back to the XML stream/file as an ampersand. Older versions
-of TinyXML "preserved" character entities, but the newer versions will translate
-them into characters.
-
-Additionally, any character can be specified by its Unicode code point:
-The syntax "&#xA0;" or "&#160;" are both to the non-breaking space characher.
-
-<h3> Printing </h3>
-TinyXML can print output in several different ways that all have strengths and limitations.
-
-- Print( FILE* ). Output to a std-C stream, which includes all C files as well as stdout.
-	- "Pretty prints", but you don't have control over printing options.
-	- The output is streamed directly to the FILE object, so there is no memory overhead
-	  in the TinyXML code.
-	- used by Print() and SaveFile()
-
-- operator<<. Output to a c++ stream.
-	- Integrates with standart C++ iostreams.
-	- Outputs in "network printing" mode without line breaks. Good for network transmission
-	  and moving XML between C++ objects, but hard for a human to read.
-
-- TiXmlPrinter. Output to a std::string or memory buffer.
-	- API is less concise
-	- Future printing options will be put here.
-	- Printing may change slightly in future versions as it is refined and expanded.
-
-<h3> Streams </h3>
-With TIXML_USE_STL on TinyXML supports C++ streams (operator <<,>>) streams as well
-as C (FILE*) streams. There are some differences that you may need to be aware of.
-
-C style output:
-	- based on FILE*
-	- the Print() and SaveFile() methods
-
-	Generates formatted output, with plenty of white space, intended to be as 
-	human-readable as possible. They are very fast, and tolerant of ill formed 
-	XML documents. For example, an XML document that contains 2 root elements 
-	and 2 declarations, will still print.
-
-C style input:
-	- based on FILE*
-	- the Parse() and LoadFile() methods
-
-	A fast, tolerant read. Use whenever you don't need the C++ streams.
-
-C++ style output:
-	- based on std::ostream
-	- operator<<
-
-	Generates condensed output, intended for network transmission rather than
-	readability. Depending on your system's implementation of the ostream class,
-	these may be somewhat slower. (Or may not.) Not tolerant of ill formed XML:
-	a document should contain the correct one root element. Additional root level
-	elements will not be streamed out.
-
-C++ style input:
-	- based on std::istream
-	- operator>>
-
-	Reads XML from a stream, making it useful for network transmission. The tricky
-	part is knowing when the XML document is complete, since there will almost
-	certainly be other data in the stream. TinyXML will assume the XML data is
-	complete after it reads the root element. Put another way, documents that
-	are ill-constructed with more than one root element will not read correctly.
-	Also note that operator>> is somewhat slower than Parse, due to both 
-	implementation of the STL and limitations of TinyXML.
-
-<h3> White space </h3>
-The world simply does not agree on whether white space should be kept, or condensed.
-For example, pretend the '_' is a space, and look at "Hello____world". HTML, and 
-at least some XML parsers, will interpret this as "Hello_world". They condense white
-space. Some XML parsers do not, and will leave it as "Hello____world". (Remember
-to keep pretending the _ is a space.) Others suggest that __Hello___world__ should become
-Hello___world.
-
-It's an issue that hasn't been resolved to my satisfaction. TinyXML supports the
-first 2 approaches. Call TiXmlBase::SetCondenseWhiteSpace( bool ) to set the desired behavior.
-The default is to condense white space.
-
-If you change the default, you should call TiXmlBase::SetCondenseWhiteSpace( bool )
-before making any calls to Parse XML data, and I don't recommend changing it after
-it has been set.
-
-
-<h3> Handles </h3>
-
-Where browsing an XML document in a robust way, it is important to check
-for null returns from method calls. An error safe implementation can
-generate a lot of code like:
-
-@verbatim
-TiXmlElement* root = document.FirstChildElement( "Document" );
-if ( root )
-{
-	TiXmlElement* element = root->FirstChildElement( "Element" );
-	if ( element )
-	{
-		TiXmlElement* child = element->FirstChildElement( "Child" );
-		if ( child )
-		{
-			TiXmlElement* child2 = child->NextSiblingElement( "Child" );
-			if ( child2 )
-			{
-				// Finally do something useful.
-@endverbatim
-
-Handles have been introduced to clean this up. Using the TiXmlHandle class,
-the previous code reduces to:
-
-@verbatim
-TiXmlHandle docHandle( &document );
-TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
-if ( child2 )
-{
-	// do something useful
-@endverbatim
-
-Which is much easier to deal with. See TiXmlHandle for more information.
-
-
-<h3> Row and Column tracking </h3>
-Being able to track nodes and attributes back to their origin location
-in source files can be very important for some applications. Additionally,
-knowing where parsing errors occured in the original source can be very
-time saving.
-
-TinyXML can tracks the row and column origin of all nodes and attributes
-in a text file. The TiXmlBase::Row() and TiXmlBase::Column() methods return
-the origin of the node in the source text. The correct tabs can be 
-configured in TiXmlDocument::SetTabSize().
-
-
-<h2> Using and Installing </h2>
-
-To Compile and Run xmltest:
-
-A Linux Makefile and a Windows Visual C++ .dsw file is provided. 
-Simply compile and run. It will write the file demotest.xml to your 
-disk and generate output on the screen. It also tests walking the
-DOM by printing out the number of nodes found using different 
-techniques.
-
-The Linux makefile is very generic and runs on many systems - it 
-is currently tested on mingw and
-MacOSX. You do not need to run 'make depend'. The dependecies have been
-hard coded.
-
-<h3>Windows project file for VC6</h3>
-<ul>
-<li>tinyxml:		tinyxml library, non-STL </li>
-<li>tinyxmlSTL:		tinyxml library, STL </li>
-<li>tinyXmlTest:	test app, non-STL </li>
-<li>tinyXmlTestSTL: test app, STL </li>
-</ul>
-
-<h3>Makefile</h3>
-At the top of the makefile you can set:
-
-PROFILE, DEBUG, and TINYXML_USE_STL. Details (such that they are) are in
-the makefile.
-
-In the tinyxml directory, type "make clean" then "make". The executable
-file 'xmltest' will be created.
-
-
-
-<h3>To Use in an Application:</h3>
-
-Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, and tinystr.h to your
-project or make file. That's it! It should compile on any reasonably
-compliant C++ system. You do not need to enable exceptions or
-RTTI for TinyXML.
-
-
-<h2> How TinyXML works.  </h2>
-
-An example is probably the best way to go. Take:
-@verbatim
-	<?xml version="1.0" standalone=no>
-	<!-- Our to do list data -->
-	<ToDo>
-		<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
-		<Item priority="2"> Do bills</Item>
-	</ToDo>
-@endverbatim
-
-Its not much of a To Do list, but it will do. To read this file 
-(say "demo.xml") you would create a document, and parse it in:
-@verbatim
-	TiXmlDocument doc( "demo.xml" );
-	doc.LoadFile();
-@endverbatim
-
-And its ready to go. Now lets look at some lines and how they 
-relate to the DOM.
-
-@verbatim
-<?xml version="1.0" standalone=no>
-@endverbatim
-
-	The first line is a declaration, and gets turned into the
-	TiXmlDeclaration class. It will be the first child of the
-	document node.
-	
-	This is the only directive/special tag parsed by TinyXML.
-	Generally directive tags are stored in TiXmlUnknown so the 
-	commands wont be lost when it is saved back to disk.
-
-@verbatim
-<!-- Our to do list data -->
-@endverbatim
-
-	A comment. Will become a TiXmlComment object.
-
-@verbatim
-<ToDo>
-@endverbatim
-
-	The "ToDo" tag defines a TiXmlElement object. This one does not have 
-	any attributes, but does contain 2 other elements.
-
-@verbatim
-<Item priority="1"> 
-@endverbatim
-
-	Creates another TiXmlElement which is a child of the "ToDo" element. 
-	This element has 1 attribute, with the name "priority" and the value 
-	"1".
-
-@verbatim
-Go to the
-@endverbatim 
-
-	A TiXmlText. This is a leaf node and cannot contain other nodes. 
-	It is a child of the "Item" TiXmlElement.
-
-@verbatim
-<bold>
-@endverbatim
-
-	
-	Another TiXmlElement, this one a child of the "Item" element.
-
-Etc.
-
-Looking at the entire object tree, you end up with:
-@verbatim
-TiXmlDocument					"demo.xml"
-	TiXmlDeclaration			"version='1.0'" "standalone=no"
-	TiXmlComment				" Our to do list data"
-	TiXmlElement				"ToDo"
-		TiXmlElement			"Item" Attribtutes: priority = 1
-			TiXmlText			"Go to the "
-			TiXmlElement		"bold"
-				TiXmlText		"Toy store!"
-		TiXmlElement			"Item" Attributes: priority=2
-			TiXmlText			"Do bills"
-@endverbatim
-
-<h2> Documentation </h2>
-
-The documentation is build with Doxygen, using the 'dox' 
-configuration file.
-
-<h2> License </h2>
-
-TinyXML is released under the zlib license:
-
-This software is provided 'as-is', without any express or implied 
-warranty. In no event will the authors be held liable for any 
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any 
-purpose, including commercial applications, and to alter it and 
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must 
-not claim that you wrote the original software. If you use this 
-software in a product, an acknowledgment in the product documentation 
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and 
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source 
-distribution.
-
-<h2> References  </h2>
-
-The World Wide Web Consortium is the definitive standard body for 
-XML, and their web pages contain huge amounts of information. 
-
-The definitive spec: <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
-http://www.w3.org/TR/2004/REC-xml-20040204/</a>
-
-I also recommend "XML Pocket Reference" by Robert Eckstein and published by 
-OReilly...the book that got the whole thing started.
-
-<h2> Contributors, Contacts, and a Brief History </h2>
-
-Thanks very much to everyone who sends suggestions, bugs, ideas, and 
-encouragement. It all helps, and makes this project fun. A special thanks
-to the contributors on the web pages that keep it lively.
-
-So many people have sent in bugs and ideas, that rather than list here 
-we try to give credit due in the "changes.txt" file.
-
-TinyXML was originally written by Lee Thomason. (Often the "I" still
-in the documentation.) Lee reviews changes and releases new versions,
-with the help of Yves Berquin, Andrew Ellerton, and the tinyXml community.
-
-We appreciate your suggestions, and would love to know if you 
-use TinyXML. Hopefully you will enjoy it and find it useful. 
-Please post questions, comments, file bugs, or contact us at:
-
-www.sourceforge.net/projects/tinyxml
-
-Lee Thomason, Yves Berquin, Andrew Ellerton
-*/

File addons/urdfreader/tinyxml/tinystr.cpp

-/*
-www.sourceforge.net/projects/tinyxml
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-
-#ifndef TIXML_USE_STL
-
-#include "tinystr.h"
-
-// Error value for find primitive
-const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
-
-
-// Null rep.
-TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
-
-
-void TiXmlString::reserve (size_type cap)
-{
-	if (cap > capacity())
-	{
-		TiXmlString tmp;
-		tmp.init(length(), cap);
-		memcpy(tmp.start(), data(), length());
-		swap(tmp);
-	}
-}
-
-
-TiXmlString& TiXmlString::assign(const char* str, size_type len)
-{
-	size_type cap = capacity();
-	if (len > cap || cap > 3*(len + 8))
-	{
-		TiXmlString tmp;
-		tmp.init(len);
-		memcpy(tmp.start(), str, len);
-		swap(tmp);
-	}
-	else
-	{
-		memmove(start(), str, len);
-		set_size(len);
-	}
-	return *this;
-}
-
-
-TiXmlString& TiXmlString::append(const char* str, size_type len)
-{
-	size_type newsize = length() + len;
-	if (newsize > capacity())
-	{
-		reserve (newsize + capacity());
-	}
-	memmove(finish(), str, len);
-	set_size(newsize);
-	return *this;
-}
-
-
-TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
-{
-	TiXmlString tmp;
-	tmp.reserve(a.length() + b.length());
-	tmp += a;
-	tmp += b;
-	return tmp;
-}
-
-TiXmlString operator + (const TiXmlString & a, const char* b)
-{
-	TiXmlString tmp;
-	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
-	tmp.reserve(a.length() + b_len);
-	tmp += a;
-	tmp.append(b, b_len);
-	return tmp;
-}
-
-TiXmlString operator + (const char* a, const TiXmlString & b)
-{
-	TiXmlString tmp;
-	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
-	tmp.reserve(a_len + b.length());
-	tmp.append(a, a_len);
-	tmp += b;
-	return tmp;
-}
-
-
-#endif	// TIXML_USE_STL

File addons/urdfreader/tinyxml/tinystr.h

-/*
-www.sourceforge.net/projects/tinyxml
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-
-#ifndef TIXML_USE_STL
-