pax_global_header00006660000000000000000000000064132360663250014520gustar00rootroot0000000000000052 comment=df29bf60779f8b1dc307d7177f5a4f18333957d7 sdformat-6.0.0+dfsg/000077500000000000000000000000001323606632500142615ustar00rootroot00000000000000sdformat-6.0.0+dfsg/AUTHORS000066400000000000000000000000451323606632500153300ustar00rootroot00000000000000Nate Koenig sdformat-6.0.0+dfsg/CMakeLists.txt000066400000000000000000000261351323606632500170300ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.6 FATAL_ERROR) if(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0003 NEW) CMAKE_POLICY(SET CMP0004 NEW) endif(COMMAND CMAKE_POLICY) enable_testing() # with -fPIC if(UNIX AND NOT WIN32) set (CMAKE_INSTALL_PREFIX "/usr" CACHE STRING "Install Prefix") find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) if(CMAKE_UNAME) exec_program(uname ARGS -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR) set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR} CACHE INTERNAL "processor type (i386 and x86_64)") if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") ADD_DEFINITIONS(-fPIC) endif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") endif(CMAKE_UNAME) endif() project (SDFormat) string (TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER) # The protocol version has nothing to do with the package version set below. # It represents the current version of sdformat implement by the software set (SDF_PROTOCOL_VERSION 1.6) set (SDF_MAJOR_VERSION 6) set (SDF_MINOR_VERSION 0) set (SDF_PATCH_VERSION 0) set (SDF_VERSION ${SDF_MAJOR_VERSION}.${SDF_MINOR_VERSION}) set (SDF_VERSION_FULL ${SDF_MAJOR_VERSION}.${SDF_MINOR_VERSION}.${SDF_PATCH_VERSION}) set (project_cmake_dir ${PROJECT_SOURCE_DIR}/cmake CACHE PATH "Location of CMake scripts") message (STATUS "${PROJECT_NAME} version ${SDF_VERSION_FULL}") set (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) # Include GNUInstallDirs to get canonical paths include(GNUInstallDirs) # Default test type for test all over source set(TEST_TYPE "UNIT") # developer's option to cache PKG_CONFIG_PATH and # LD_LIBRARY_PATH for local installs if(PKG_CONFIG_PATH) set (ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_PATH}:$ENV{PKG_CONFIG_PATH}) endif() if(LD_LIBRARY_PATH) set (ENV{LD_LIBRARY_PATH} ${LD_LIBRARY_PATH}:$ENV{LD_LIBRARY_PATH}) endif() set (INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}/sdformat-${SDF_VERSION}/sdf") set (LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING "Installation directory for libraries (relative to CMAKE_INSTALL_PREFIX)") set (BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE STRING "Installation directory for binaries (relative to CMAKE_INSTALL_PREFIX)") set (USE_FULL_RPATH OFF CACHE BOOL "Set to true to enable full rpath") if (USE_FULL_RPATH) # use, i.e. don't skip the full RPATH for the build tree set(CMAKE_SKIP_BUILD_RPATH FALSE) # when building, don't use the install RPATH already # (but later on when installing) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # the RPATH to be used when installing, but only if its not a system directory list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" isSystemDir) if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") endif("${isSystemDir}" STREQUAL "-1") endif() set (BUILD_SDF ON CACHE INTERNAL "Build SDF" FORCE) set (build_errors "" CACHE INTERNAL "build errors" FORCE) set (build_warnings "" CACHE INTERNAL "build warnings" FORCE) set (sdf_cmake_dir ${PROJECT_SOURCE_DIR}/cmake CACHE PATH "Location of CMake scripts") include (${sdf_cmake_dir}/SDFUtils.cmake) message (STATUS "\n\n====== Finding 3rd Party Packages ======") # Use of tinyxml. System installation on UNIX. Internal copy on WIN if (UNIX) message (STATUS "Using system tinyxml") set (USE_EXTERNAL_TINYXML True) elseif(WIN32) message (STATUS "Using internal tinyxml code") set (USE_EXTERNAL_TINYXML False) else() message (STATUS "Unknown platform") BUILD_ERROR("Unknown platform") endif() include (${sdf_cmake_dir}/SearchForStuff.cmake) message (STATUS "----------------------------------------\n") ##################################### # Set the default build type if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo Profile Check" FORCE) endif (NOT CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPERCASE) set (BUILD_TYPE_PROFILE FALSE) set (BUILD_TYPE_RELEASE FALSE) set (BUILD_TYPE_RELWITHDEBINFO FALSE) set (BUILD_TYPE_DEBUG FALSE) if ("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "PROFILE") set (BUILD_TYPE_PROFILE TRUE) elseif ("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELEASE") set (BUILD_TYPE_RELEASE TRUE) elseif ("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELWITHDEBINFO") set (BUILD_TYPE_RELWITHDEBINFO TRUE) elseif ("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "DEBUG") set (BUILD_TYPE_DEBUG TRUE) elseif ("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "COVERAGE") include (${project_cmake_dir}/CodeCoverage.cmake) set (BUILD_TYPE_DEBUG TRUE) SETUP_TARGET_FOR_COVERAGE(coverage ctest coverage) else() build_error("CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} unknown. Valid options are: Debug Release RelWithDebInfo Profile Check") endif() ##################################### # Handle CFlags unset (CMAKE_C_FLAGS_ALL CACHE) unset (CMAKE_CXX_FLAGS CACHE) # USE_HOST_CFLAGS (default TRUE) # Will check building host machine for proper cflags if(NOT DEFINED USE_HOST_CFLAGS OR USE_HOST_CFLAGS) message(STATUS "Enable host CFlags") include (${project_cmake_dir}/HostCFlags.cmake) endif() # USE_UPSTREAM_CFLAGS (default TRUE) # Will use predefined ignition developers cflags if(NOT DEFINED USE_UPSTREAM_CFLAGS OR USE_UPSTREAM_CFLAGS) message(STATUS "Enable upstream CFlags") include(${project_cmake_dir}/DefaultCFlags.cmake) endif() # Check if warning options are avaliable for the compiler and return WARNING_CXX_FLAGS variable if (MSVC) set(WARN_LEVEL "/W4") # Unable to be filtered flags (failing due to limitations in filter_valid_compiler_warnings) # Handling exceptions rightly and ignore unknown pragmas set(UNFILTERED_FLAGS "/EHsc /wd4068") else() # Equivalent to Wall (according to man gcc) but removed the unknown pragmas since we use # MSVC only pragmas all over the code list(APPEND WARN_LEVEL -Waddress -Warray-bounds -Wcomment -Wformat -Wnonnull) list(APPEND WARN_LEVEL -Wparentheses -Wreorder -Wreturn-type) list(APPEND WARN_LEVEL -Wsequence-point -Wsign-compare -Wstrict-aliasing) list(APPEND WARN_LEVEL -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized) list(APPEND WARN_LEVEL -Wunused-function -Wunused-label -Wunused-value) list(APPEND WARN_LEVEL -Wunused-variable -Wvolatile-register-var) # Unable to be filtered flags (failing due to limitations in filter_valid_compiler_warnings) set(UNFILTERED_FLAGS "-Wc++11-compat") endif() filter_valid_compiler_warnings(${WARN_LEVEL} -Wextra -Wno-long-long -Wno-unused-value -Wno-unused-value -Wno-unused-value -Wno-unused-value -Wfloat-equal -Wshadow -Winit-self -Wswitch-default -Wmissing-include-dirs -pedantic -Wno-pragmas) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}${WARNING_CXX_FLAGS} ${UNFILTERED_FLAGS}") ################################################# # OS Specific initialization if (UNIX) sdf_setup_unix() endif () if (WIN32) sdf_setup_windows() endif () if (APPLE) sdf_setup_apple() endif () ################################################# # Print warnings and errors if ( build_warnings ) message(STATUS "BUILD WARNINGS") foreach (msg ${build_warnings}) message(STATUS ${msg}) endforeach () message(STATUS "END BUILD WARNINGS\n") endif (build_warnings) ########### Add uninstall target ############### configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake") if (build_errors) message(STATUS "BUILD ERRORS: These must be resolved before compiling.") foreach (msg ${build_errors}) message(STATUS ${msg}) endforeach () message(STATUS "END BUILD ERRORS\n") message (FATAL_ERROR "Errors encountered in build. Please see the BUILD ERRORS above.") else (buid_errors) ######################################## # Write the config.h file configure_file (${sdf_cmake_dir}/sdf_config.h.in ${PROJECT_BINARY_DIR}/sdf/sdf_config.h) sdf_install_includes("" ${PROJECT_BINARY_DIR}/sdf/sdf_config.h) message (STATUS "C Flags:${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}") message (STATUS "Build Type: ${CMAKE_BUILD_TYPE}") message (STATUS "Install path: ${CMAKE_INSTALL_PREFIX}") if (BUILD_SDF) include_directories(include ${PROJECT_BINARY_DIR} ${PROJECT_BINARY_DIR}/include ) link_directories(${PROJECT_BINARY_DIR}/src) add_subdirectory(test) add_subdirectory(src) add_subdirectory(include/sdf) add_subdirectory(sdf) add_subdirectory(conf) add_subdirectory(doc) endif(BUILD_SDF) ######################################## # Make the package config file configure_file(${CMAKE_SOURCE_DIR}/cmake/sdformat_pc.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdformat.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdformat.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig COMPONENT pkgconfig) ######################################## # Configure documentation uploader configure_file("${CMAKE_SOURCE_DIR}/cmake/upload_doc.sh.in" ${CMAKE_BINARY_DIR}/upload_doc.sh @ONLY) ######################################## # Make the cmake config files set(PKG_NAME ${PROJECT_NAME}) set(PKG_LIBRARIES sdformat) set(cmake_conf_file "cmake/sdf_config.cmake") set(cmake_conf_version_file "cmake/SDFormatConfigVersion.cmake") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${cmake_conf_file}.in" "${CMAKE_CURRENT_BINARY_DIR}/SDFormatConfig.cmake" @ONLY) # Use write_basic_package_version_file to generate a ConfigVersion file that # allow users of gazebo to specify the API or version to depend on # TODO: keep this instruction until deprecate Ubuntu/Precise and update with # https://github.com/Kitware/CMake/blob/v2.8.8/Modules/CMakePackageConfigHelpers.cmake include(WriteBasicConfigVersionFile) write_basic_config_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${cmake_conf_version_file} VERSION "${SDF_VERSION_FULL}" COMPATIBILITY SameMajorVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/SDFormatConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/${cmake_conf_version_file} DESTINATION ${LIB_INSTALL_DIR}/cmake/${PROJECT_NAME_LOWER}/ COMPONENT cmake) ######################################## # Package Creation: include (${sdf_cmake_dir}/sdf_cpack.cmake) set (CPACK_PACKAGE_VERSION "${SDF_VERSION_FULL}") set (CPACK_PACKAGE_VERSION_MAJOR "${SDF_MAJOR_VERSION}") set (CPACK_PACKAGE_VERSION_MINOR "${SDF_MINOR_VERSION}") set (CPACK_PACKAGE_VERSION_PATCH "${SDF_PATCH_VERSION}") if (CPACK_GENERATOR) message(STATUS "Found CPack generators: ${CPACK_GENERATOR}") configure_file("${sdf_cmake_dir}/cpack_options.cmake.in" ${SDF_CPACK_CFG_FILE} @ONLY) set(CPACK_PROJECT_CONFIG_FILE ${SDF_CPACK_CFG_FILE}) include (CPack) endif() message(STATUS "Configuration successful. Type make to compile sdf") endif(build_errors) sdformat-6.0.0+dfsg/COPYING000066400000000000000000000236771323606632500153330ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS sdformat-6.0.0+dfsg/Changelog.md000066400000000000000000000531051323606632500164760ustar00rootroot00000000000000## SDFormat 6.0 ### SDFormat 6.0.0 (xxxx-xx-xx) 1. SDF DOM: Added a document object model. * [Pull request 387](https://bitbucket.org/osrf/sdformat/pull-requests/387) * [Pull request 389](https://bitbucket.org/osrf/sdformat/pull-requests/389) 1. Add simplified ```readFile`` function. * [Pull request 347](https://bitbucket.org/osrf/sdformat/pull-requests/347) 1. Remove boost::lexical cast instances * [Pull request 342](https://bitbucket.org/osrf/sdformat/pull-requests/342) 1. Remove boost regex and iostreams as dependencies * [Pull request 302](https://bitbucket.org/osrf/sdformat/pull-requests/302) 1. Change certain error checks from asserts to throwing sdf::AssertionInternalError, which is more appropriate for a library. * [Pull request 315](https://bitbucket.org/osrf/sdformat/pull-requests/315) 1. Updated the internal copy of urdfdom to 1.0, removing more of boost. * [Pull request 324](https://bitbucket.org/osrf/sdformat/pull-requests/324) 1. urdfdom 1.0 is now required on all platforms. * [Pull request 324](https://bitbucket.org/osrf/sdformat/pull-requests/324) 1. Remove boost filesystem as a dependency * [Pull request 335](https://bitbucket.org/osrf/sdformat/pull-requests/335) * [Pull request 338](https://bitbucket.org/osrf/sdformat/pull-requests/338) * [Pull request 339](https://bitbucket.org/osrf/sdformat/pull-requests/339) 1. Deprecated sdf::Color, and switch to use ignition::math::Color * [Pull request 330](https://bitbucket.org/osrf/sdformat/pull-requests/330) ## SDFormat 5.x ### SDFormat 5.x.x (2017-xx-xx) ### SDFormat 5.3.0 (2017-11-13) 1. Added wrapper around root SDF for an SDF element * [Pull request 378](https://bitbucket.org/osrf/sdformat/pull-request/378) * [Pull request 372](https://bitbucket.org/osrf/sdformat/pull-request/372) 1. Add ODE parallelization parameters: threaded islands and position correction * [Pull request 380](https://bitbucket.org/osrf/sdformat/pull-request/380) 1. surface.sdf: expand documentation of friction and slip coefficients * [Pull request 343](https://bitbucket.org/osrf/sdformat/pull-request/343) 1. Add preserveFixedJoint option to the URDF parser * [Pull request 352](https://bitbucket.org/osrf/sdformat/pull-request/352) 1. Add light as child of link * [Pull request 373](https://bitbucket.org/osrf/sdformat/pull-request/373) ### SDFormat 5.2.0 (2017-08-03) 1. Added a block for DART-specific physics properties. * [Pull request 369](https://bitbucket.org/osrf/sdformat/pull-requests/369) 1. Fix parser to read plugin child elements within an `` * [Pull request 350](https://bitbucket.org/osrf/sdformat/pull-request/350) 1. Choosing models with more recent sdf version with `` tag * [Pull request 291](https://bitbucket.org/osrf/sdformat/pull-request/291) * [Issue 123](https://bitbucket.org/osrf/sdformat/issues/123) 1. Added `` to 1.6 surface contact parameters * [Pull request 318](https://bitbucket.org/osrf/sdformat/pull-request/318) 1. Support light insertion in state * [Pull request 325](https://bitbucket.org/osrf/sdformat/pull-request/325) 1. Case insensitive boolean strings * [Pull request 322](https://bitbucket.org/osrf/sdformat/pull-request/322) 1. Enable coverage testing * [Pull request 317](https://bitbucket.org/osrf/sdformat/pull-request/317) 1. Add `friction_model` parameter to ode solver * [Pull request 294](https://bitbucket.org/osrf/sdformat/pull-request/294) * [Gazebo pull request 1522](https://bitbucket.org/osrf/gazebo/pull-request/1522) 1. Add cmake `@PKG_NAME@_LIBRARY_DIRS` variable to cmake config file * [Pull request 292](https://bitbucket.org/osrf/sdformat/pull-request/292) ### SDFormat 5.1.0 (2017-02-22) 1. Fixed `sdf::convertFile` and `sdf::convertString` always converting to latest version * [Pull request 320](https://bitbucket.org/osrf/sdformat/pull-requests/320) 1. Added back the ability to set sdf version at runtime * [Pull request 307](https://bitbucket.org/osrf/sdformat/pull-requests/307) ### SDFormat 5.0.0 (2017-01-25) 1. Removed SDFormat 4 deprecations * [Pull request 295](https://bitbucket.org/osrf/sdformat/pull-requests/295) 1. Added an example * [Pull request 275](https://bitbucket.org/osrf/sdformat/pull-requests/275) 1. Move functions that use TinyXML classes in private headers A contribution from Silvio Traversaro * [Pull request 262](https://bitbucket.org/osrf/sdformat/pull-requests/262) 1. Fix issues found by the Coverity tool A contribution from Olivier Crave * [Pull request 259](https://bitbucket.org/osrf/sdformat/pull-requests/259) 1. Add tag to allow for specification of initial joint position * [Pull request 279](https://bitbucket.org/osrf/sdformat/pull-requests/279) 1. Require ignition-math3 as dependency * [Pull request 299](https://bitbucket.org/osrf/sdformat/pull-requests/299) 1. Simplifier way of retrieving a value from SDF using Get * [Pull request 285](https://bitbucket.org/osrf/sdformat/pull-requests/285) ## SDFormat 4.0 ### SDFormat 4.x.x (2017-xx-xx) ### SDFormat 4.4.0 (2017-10-26) 1. Add ODE parallelization parameters: threaded islands and position correction * [Pull request 380](https://bitbucket.org/osrf/sdformat/pull-request/380) 1. surface.sdf: expand documentation of friction and slip coefficients * [Pull request 343](https://bitbucket.org/osrf/sdformat/pull-request/343) 1. Add preserveFixedJoint option to the URDF parser * [Pull request 352](https://bitbucket.org/osrf/sdformat/pull-request/352) 1. Add light as child of link * [Pull request 373](https://bitbucket.org/osrf/sdformat/pull-request/373) ### SDFormat 4.3.2 (2017-07-19) 1. Add documentation for `Element::GetFirstElement()` and `Element::GetNextElement()` * [Pull request 341](https://bitbucket.org/osrf/sdformat/pull-request/341) 1. Fix parser to read plugin child elements within an `` * [Pull request 350](https://bitbucket.org/osrf/sdformat/pull-request/350) ### SDFormat 4.3.1 (2017-03-24) 1. Fix segmentation Fault in `sdf::getBestSupportedModelVersion` * [Pull request 327](https://bitbucket.org/osrf/sdformat/pull-requests/327) * [Issue 152](https://bitbucket.org/osrf/sdformat/issues/152) ### SDFormat 4.3.0 (2017-03-20) 1. Choosing models with more recent sdf version with `` tag * [Pull request 291](https://bitbucket.org/osrf/sdformat/pull-request/291) * [Issue 123](https://bitbucket.org/osrf/sdformat/issues/123) 1. Added `` to 1.6 surface contact parameters * [Pull request 318](https://bitbucket.org/osrf/sdformat/pull-request/318) 1. Support light insertion in state * [Pull request 325](https://bitbucket.org/osrf/sdformat/pull-request/325) 1. Case insensitive boolean strings * [Pull request 322](https://bitbucket.org/osrf/sdformat/pull-request/322) 1. Enable coverage testing * [Pull request 317](https://bitbucket.org/osrf/sdformat/pull-request/317) 1. Add `friction_model` parameter to ode solver * [Pull request 294](https://bitbucket.org/osrf/sdformat/pull-request/294) * [Gazebo pull request 1522](https://bitbucket.org/osrf/gazebo/pull-request/1522) 1. Added `sampling` parameter to `` SDF element. * [Pull request 293](https://bitbucket.org/osrf/sdformat/pull-request/293) 1. Added Migration guide * [Pull request 290](https://bitbucket.org/osrf/sdformat/pull-request/290) 1. Add cmake `@PKG_NAME@_LIBRARY_DIRS` variable to cmake config file * [Pull request 292](https://bitbucket.org/osrf/sdformat/pull-request/292) ### SDFormat 4.2.0 (2016-10-10) 1. Added tag to specify ODE friction model. * [Pull request 294](https://bitbucket.org/osrf/sdformat/pull-request/294) 1. Fix URDF to SDF `self_collide` bug. * [Pull request 287](https://bitbucket.org/osrf/sdformat/pull-request/287) 1. Added IMU orientation specification to SDF. * [Pull request 284](https://bitbucket.org/osrf/sdformat/pull-request/284) ### SDFormat 4.1.1 (2016-07-08) 1. Added documentation and animation to `` element. * [Pull request 280](https://bitbucket.org/osrf/sdformat/pull-request/280) 1. Added tag to specify initial joint position * [Pull request 279](https://bitbucket.org/osrf/sdformat/pull-request/279) ### SDFormat 4.1.0 (2016-04-01) 1. Added SDF conversion functions to parser including sdf::convertFile and sdf::convertString. * [Pull request 266](https://bitbucket.org/osrf/sdformat/pull-request/266) 1. Added an upload script * [Pull request 256](https://bitbucket.org/osrf/sdformat/pull-request/256) ### SDFormat 4.0.0 (2015-01-12) 1. Boost pointers and boost::function in the public API have been replaced by their std::equivalents (C++11 standard) 1. Move gravity and magnetic_field tags from physics to world * [Pull request 247](https://bitbucket.org/osrf/sdformat/pull-request/247) 1. Switch lump link prefix from lump:: to lump_ * [Pull request 245](https://bitbucket.org/osrf/sdformat/pull-request/245) 1. New element. A contribution from Olivier Crave * [Pull request 240](https://bitbucket.org/osrf/sdformat/pull-request/240) 1. Add scale to model state * [Pull request 246](https://bitbucket.org/osrf/sdformat/pull-request/246) 1. Use stof functions to parse hex strings as floating point params. A contribution from Rich Mattes * [Pull request 250](https://bitbucket.org/osrf/sdformat/pull-request/250) 1. Fix memory leaks. A contribution from Silvio Traversaro * [Pull request 249](https://bitbucket.org/osrf/sdformat/pull-request/249) 1. Update SDF to version 1.6: new style for representing the noise properties of an `imu` * [Pull request 243](https://bitbucket.org/osrf/sdformat/pull-request/243) * [Pull request 199](https://bitbucket.org/osrf/sdformat/pull-requests/199) ## SDFormat 3.0 ### SDFormat 3.X.X (201X-XX-XX) 1. Improve precision of floating point parameters * [Pull request 273](https://bitbucket.org/osrf/sdformat/pull-requests/273) * [Pull request 276](https://bitbucket.org/osrf/sdformat/pull-requests/276) ### SDFormat 3.7.0 (2015-11-20) 1. Add spring pass through for sdf3 * [Design document](https://bitbucket.org/osrf/gazebo_design/pull-requests/23) * [Pull request 242](https://bitbucket.org/osrf/sdformat/pull-request/242) 1. Support frame specification in SDF * [Pull request 237](https://bitbucket.org/osrf/sdformat/pull-request/237) 1. Remove boost from SDFExtension * [Pull request 229](https://bitbucket.org/osrf/sdformat/pull-request/229) ### SDFormat 3.6.0 (2015-10-27) 1. Add light state * [Pull request 227](https://bitbucket.org/osrf/sdformat/pull-request/227) 1. redo pull request #222 for sdf3 branch * [Pull request 232](https://bitbucket.org/osrf/sdformat/pull-request/232) 1. Fix links in API documentation * [Pull request 231](https://bitbucket.org/osrf/sdformat/pull-request/231) ### SDFormat 3.5.0 (2015-10-07) 1. Camera lens description (Replaces #213) * [Pull request 215](https://bitbucket.org/osrf/sdformat/pull-request/215) 1. Fix shared pointer reference loop in Element and memory leak (#104) * [Pull request 230](https://bitbucket.org/osrf/sdformat/pull-request/230) ### SDFormat 3.4.0 (2015-10-05) 1. Support nested model states * [Pull request 223](https://bitbucket.org/osrf/sdformat/pull-request/223) 1. Cleaner way to set SDF_PATH for tests * [Pull request 226](https://bitbucket.org/osrf/sdformat/pull-request/226) ### SDFormat 3.3.0 (2015-09-15) 1. Windows Boost linking errors * [Pull request 206](https://bitbucket.org/osrf/sdformat/pull-request/206) 1. Nested SDF -> sdf3 * [Pull request 221](https://bitbucket.org/osrf/sdformat/pull-request/221) 1. Pointer types * [Pull request 218](https://bitbucket.org/osrf/sdformat/pull-request/218) 1. Torsional friction default surface radius not infinity * [Pull request 217](https://bitbucket.org/osrf/sdformat/pull-request/217) ### SDFormat 3.2.2 (2015-08-24) 1. Added battery element (contribution from Olivier Crave) * [Pull request #204](https://bitbucket.org/osrf/sdformat/pull-request/204) 1. Torsional friction backport * [Pull request #211](https://bitbucket.org/osrf/sdformat/pull-request/211) 1. Allow Visual Studio 2015 * [Pull request #208](https://bitbucket.org/osrf/sdformat/pull-request/208) ### SDFormat 3.1.1 (2015-08-03) 1. Fix tinyxml linking error * [Pull request #209](https://bitbucket.org/osrf/sdformat/pull-request/209) ### SDFormat 3.1.0 (2015-08-02) 1. Added logical camera sensor to SDF * [Pull request #207](https://bitbucket.org/osrf/sdformat/pull-request/207) ### SDFormat 3.0.0 (2015-07-24) 1. Added battery to SDF * [Pull request 204](https://bitbucket.org/osrf/sdformat/pull-request/204) 1. Added altimeter sensor to SDF * [Pull request #197](https://bitbucket.org/osrf/sdformat/pull-request/197) 1. Added magnetometer sensor to SDF * [Pull request 198](https://bitbucket.org/osrf/sdformat/pull-request/198) 1. Fix detection of XML parsing errors * [Pull request 190](https://bitbucket.org/osrf/sdformat/pull-request/190) 1. Support for fixed joints * [Pull request 194](https://bitbucket.org/osrf/sdformat/pull-request/194) 1. Adding iterations to state * [Pull request 188](https://bitbucket.org/osrf/sdformat/pull-request/188) 1. Convert to use ignition-math * [Pull request 173](https://bitbucket.org/osrf/sdformat/pull-request/173) 1. Add world origin to scene * [Pull request 183](https://bitbucket.org/osrf/sdformat/pull-request/183) 1. Fix collide bitmask * [Pull request 182](https://bitbucket.org/osrf/sdformat/pull-request/182) 1. Adding meta information to visuals * [Pull request 180](https://bitbucket.org/osrf/sdformat/pull-request/180) 1. Add projection type to gui camera * [Pull request 178](https://bitbucket.org/osrf/sdformat/pull-request/178) 1. Fix print description to include attribute description * [Pull request 170](https://bitbucket.org/osrf/sdformat/pull-request/170) 1. Add -std=c++11 flag to sdf_config.cmake.in and sdformat.pc.in, needed by downstream code * [Pull request 172](https://bitbucket.org/osrf/sdformat/pull-request/172) 1. Added boost::any accessor for Param and Element * [Pull request 166](https://bitbucket.org/osrf/sdformat/pull-request/166) 1. Remove tinyxml from dependency list * [Pull request 152](https://bitbucket.org/osrf/sdformat/pull-request/152) 1. Added self_collide element for model * [Pull request 149](https://bitbucket.org/osrf/sdformat/pull-request/149) 1. Added a collision bitmask field to sdf-1.5 and c++11 support * [Pull request 145](https://bitbucket.org/osrf/sdformat/pull-request/145) 1. Fix problems with latin locales and decimal numbers (issue #60) * [Pull request 147](https://bitbucket.org/osrf/sdformat/pull-request/147) * [Issue 60](https://bitbucket.org/osrf/sdformat/issues/60) ## SDFormat 2.x 1. rename cfm_damping --> implicit_spring_damper * [Pull request 59](https://bitbucket.org/osrf/sdformat/pull-request/59) 1. add gear_ratio and reference_body for gearbox joint. * [Pull request 62](https://bitbucket.org/osrf/sdformat/pull-request/62) 1. Update joint stop stiffness and dissipation * [Pull request 61](https://bitbucket.org/osrf/sdformat/pull-request/61) 1. Support for GNUInstallDirs * [Pull request 64](https://bitbucket.org/osrf/sdformat/pull-request/64) 1. `` element used by DEM heightmaps * [Pull request 67](https://bitbucket.org/osrf/sdformat/pull-request/67) 1. Do not export urdf symbols in sdformat 1.4 * [Pull request 75](https://bitbucket.org/osrf/sdformat/pull-request/75) 1. adding deformable properties per issue #32 * [Pull request 78](https://bitbucket.org/osrf/sdformat/pull-request/78) * [Issue 32](https://bitbucket.org/osrf/sdformat/issues/32) 1. Support to use external URDF * [Pull request 77](https://bitbucket.org/osrf/sdformat/pull-request/77) 1. Add lighting element to visual * [Pull request 79](https://bitbucket.org/osrf/sdformat/pull-request/79) 1. SDF 1.5: add flag to fix joint axis frame #43 (gazebo issue 494) * [Pull request 83](https://bitbucket.org/osrf/sdformat/pull-request/83) * [Issue 43](https://bitbucket.org/osrf/sdformat/issues/43) * [Gazebo issue 494](https://bitbucket.org/osrf/gazebo/issues/494) 1. Implement SDF_PROTOCOL_VERSION (issue #51) * [Pull request 90](https://bitbucket.org/osrf/sdformat/pull-request/90) 1. Port sdformat to compile on Windows (MSVC) * [Pull request 101](https://bitbucket.org/osrf/sdformat/pull-request/101) 1. Separate material properties in material.sdf * [Pull request 104](https://bitbucket.org/osrf/sdformat/pull-request/104) 1. Add road textures (repeat pull request #104 for sdf_2.0) * [Pull request 105](https://bitbucket.org/osrf/sdformat/pull-request/105) 1. Add Extruded Polylines as a model * [Pull request 93](https://bitbucket.org/osrf/sdformat/pull-request/93) 1. Added polyline for sdf_2.0 * [Pull request 106](https://bitbucket.org/osrf/sdformat/pull-request/106) 1. Add spring_reference and spring_stiffness tags to joint axis dynamics * [Pull request 102](https://bitbucket.org/osrf/sdformat/pull-request/102) 1. Fix actor static * [Pull request 110](https://bitbucket.org/osrf/sdformat/pull-request/110) 1. New element * [Pull request 112](https://bitbucket.org/osrf/sdformat/pull-request/112) 1. Add camera distortion element * [Pull request 120](https://bitbucket.org/osrf/sdformat/pull-request/120) 1. Inclusion of magnetic field strength sensor * [Pull request 123](https://bitbucket.org/osrf/sdformat/pull-request/123) 1. Properly add URDF gazebo extensions blobs to SDF joint elements * [Pull request 125](https://bitbucket.org/osrf/sdformat/pull-request/125) 1. Allow gui plugins to be specified in SDF * [Pull request 127](https://bitbucket.org/osrf/sdformat/pull-request/127) 1. Backport magnetometer * [Pull request 128](https://bitbucket.org/osrf/sdformat/pull-request/128) 1. Add flag for MOI rescaling to sdf 1.4 * [Pull request 121](https://bitbucket.org/osrf/sdformat/pull-request/121) 1. Parse urdf joint friction parameters, add corresponding test * [Pull request 129](https://bitbucket.org/osrf/sdformat/pull-request/129) 1. Allow reading of boolean values from plugin elements. * [Pull request 132](https://bitbucket.org/osrf/sdformat/pull-request/132) 1. Implement generation of XML Schema files (issue #2) * [Pull request 91](https://bitbucket.org/osrf/sdformat/pull-request/91) 1. Fix build for OS X 10.10 * [Pull request 135](https://bitbucket.org/osrf/sdformat/pull-request/135) 1. Improve performance in loading SDF elements * [Pull request 138](https://bitbucket.org/osrf/sdformat/pull-request/138) 1. Added urdf gazebo extension option to disable fixed joint lumping * [Pull request 133](https://bitbucket.org/osrf/sdformat/pull-request/133) 1. Support urdfdom 0.3 (alternative to pull request #122) * [Pull request 141](https://bitbucket.org/osrf/sdformat/pull-request/141) 1. Update list of supported joint types * [Pull request 142](https://bitbucket.org/osrf/sdformat/pull-request/142) 1. Ignore unknown elements * [Pull request 148](https://bitbucket.org/osrf/sdformat/pull-request/148) 1. Physics preset attributes * [Pull request 146](https://bitbucket.org/osrf/sdformat/pull-request/146) 1. Backport fix for latin locales (pull request #147) * [Pull request 150](https://bitbucket.org/osrf/sdformat/pull-request/150) ## SDFormat 1.4 ### SDFormat 1.4.8 (2013-09-06) 1. Fix inertia transformations when reducing fixed joints in URDF * [Pull request 48](https://bitbucket.org/osrf/sdformat/pull-request/48/fix-for-issue-22-reducing-inertia-across/diff) 1. Add element to support terrain paging in gazebo * [Pull request 47](https://bitbucket.org/osrf/sdformat/pull-request/47/add-element-inside-heightmap/diff) 1. Further reduce console output when using URDF models * [Pull request 46](https://bitbucket.org/osrf/sdformat/pull-request/46/convert-a-few-more-sdfwarns-to-sdflog-fix/diff) * [Commit](https://bitbucket.org/osrf/sdformat/commits/b15d5a1ecc57abee6691618d02d59bbc3d1b84dc) ### SDFormat 1.4.7 (2013-08-22) 1. Direct console messages to std_err * [Pull request 44](https://bitbucket.org/osrf/sdformat/pull-request/44/fix-19-direct-all-messages-to-std_err) ### SDFormat 1.4.6 (2013-08-20) 1. Add tags for GPS sensor and sensor noise * [Pull request 36](https://bitbucket.org/osrf/sdformat/pull-request/36/gps-sensor-sensor-noise-and-spherical) 1. Add tags for wireless transmitter/receiver models * [Pull request 34](https://bitbucket.org/osrf/sdformat/pull-request/34/transceiver-support) * [Pull request 43](https://bitbucket.org/osrf/sdformat/pull-request/43/updated-description-of-the-transceiver-sdf) 1. Add tags for playback of audio files in Gazebo * [Pull request 26](https://bitbucket.org/osrf/sdformat/pull-request/26/added-audio-tags) * [Pull request 35](https://bitbucket.org/osrf/sdformat/pull-request/35/move-audio-to-link-and-playback-on-contact) 1. Add tags for simbody physics parameters * [Pull request 32](https://bitbucket.org/osrf/sdformat/pull-request/32/merging-some-updates-from-simbody-branch) 1. Log messages to a file, reduce console output * [Pull request 33](https://bitbucket.org/osrf/sdformat/pull-request/33/log-messages-to-file-8) 1. Generalize ode's element * [Pull request 38](https://bitbucket.org/osrf/sdformat/pull-request/38/add-provide_feedback-for-bullet-joint) 1. Various bug, style and test fixes ### SDFormat 1.4.5 (2013-07-23) 1. Deprecated Gazebo's internal SDF code 1. Use templatized Get functions for retrieving values from SDF files 1. Removed dependency on ROS sdformat-6.0.0+dfsg/INSTALL_WIN32.md000066400000000000000000000026251323606632500166000ustar00rootroot00000000000000# Installation on Windows This documentation describes how to set up a workspace for trying to compile sdformat on Windows. ## Supported compilers At this moment, compilation has been tested on Windows 7 and 8.1 and is supported when using Visual Studio 2013. Patches for other versions are welcome. ## Installation Totally experimental, using pre-compiled binaries in a local workspace. To make things easier, use a MinGW shell for your editing work, and only use the Windows `cmd` for configuring and building. 1. Make a directory to work in, e.g.: mkdir sdformat-ws cd sdformat-ws 1. Download boost into that directory: - [boost 1.56.0](http://packages.osrfoundation.org/win32/deps/boost_1_56_0.zip) 1. Unzip it in sdformat-ws. 1. Clone sdformat hg clone https://bitbucket.org/osrf/sdformat 1. Load your compiler setup, e.g. (note that we are asking for the 64-bit toolchain here): "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64 1. Configure and build sdformat: cd sdformat mkdir build cd build ..\configure nmake nmake install You should now have an installation of sdformat in sdformat-ws/sdformat/build/install/Release. Once this all works (which it does with tender love and care): you should now have an installation of sdformat in sdformat-ws/sdformat/build/install/Release. sdformat-6.0.0+dfsg/LICENSE000066400000000000000000000011511323606632500152640ustar00rootroot00000000000000Software License Agreement (Apache License) Copyright 2012 Open Source Robotics Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. sdformat-6.0.0+dfsg/Migration.md000066400000000000000000000151551323606632500165430ustar00rootroot00000000000000# Migration Guide for SDF Protocol This document contains information about migrating between different versions of the SDF protocol. The SDF protocol version number is specified in the `version` attribute of the `sdf` element (1.4, 1.5, 1.6, etc.) and is distinct from sdformat library version (2.3, 3.0, 4.0, etc.). # Note on backward compatibility There are `*.convert` files that allow old sdf files to be migrated forward programmatically. This document aims to contain similar information to those files but with improved human-readability.. ## SDFormat 5.x to 6.x ### Deprecations 1. **sdf/Types.hh** + ***Deprecated:*** sdf::Color class + ***Replacement:*** ignition::math::Color class ## SDFormat 4.x to 5.x ### Deletions 1. **Removed the following functions from `parser.hh`** + bool initDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf); + bool initDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf); + bool initXml(TiXmlElement *_xml, ElementPtr _sdf); + bool readDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf, const std::string &_source); + bool readDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf, const std::string &_source); + bool readXml(TiXmlElement *_xml, ElementPtr _sdf); + void copyChildren(ElementPtr _sdf, TiXmlElement *_xml); + std::string getBestSupportedModelVersion(TiXmlElement *_modelXML, std::string &_modelFileName); ### Deprecations 1. **sdf/Param.hh** + ***Deprecation:*** const std::type_info &GetType() const + ***Replacement:*** template bool IsType() const 1. **sdf/SDFImpl.hh** + ***Deprecation:*** ElementPtr root + ***Replacement:*** ElementPtr Root() const / void Root(const ElementPtr _root) + ***Deprecation:*** static std::string version + ***Replacement:*** static std::string Version() 1. **sdf/Types.hh** + ***Deprecation:*** sdf::Vector2i + ***Replacement:*** ignition::math::Vector2i + ***Deprecation:*** sdf::Vector2d + ***Replacement:*** ignition::math::Vector2d + ***Deprecation:*** sdf::Vector3 + ***Replacement:*** ignition::math::Vector3d + ***Deprecation:*** sdf::Quaternion + ***Replacement:*** ignition::math::Quaterniond + ***Deprecation:*** sdf::Pose + ***Replacement:*** ignition::math::Pose3d ## SDFormat 3.x to 4.x ### Additions 1. **New SDF protocol version 1.6** + Details about the 1.5 to 1.6 transition are explained below in this same document ### Modifications 1. **Boost pointers and boost::function** + All boost pointers, boost::function in the public API have been replaced by their std:: equivalents (C++11 standard) 1. **`gravity` and `magnetic_field` elements are moved from `physics` to `world`** + In physics element: gravity and magnetic_field tags have been moved from Physics to World element. + [pull request 247](https://bitbucket.org/osrf/sdformat/pull-requests/247) + [gazebo pull request 2090](https://bitbucket.org/osrf/gazebo/pull-requests/2090) 1. **New noise for IMU** + A new style for representing the noise properties of an `imu` was implemented in [pull request 199](https://bitbucket.org/osrf/sdformat/pull-requests/199) for sdf 1.5 and the old style was declared as deprecated. The old style has been removed from sdf 1.6 with the conversion script updating to the new style. + [pull request 199](https://bitbucket.org/osrf/sdformat/pull-requests/199) + [pull request 243](https://bitbucket.org/osrf/sdformat/pull-requests/243) + [pull request 244](https://bitbucket.org/osrf/sdformat/pull-requests/244) 1. **Lump:: prefix in link names** + Changed to \_fixed_joint_lump__ to avoid confusion with scoped names + [Pull request 245](https://bitbucket.org/osrf/sdformat/pull-request/245) ## SDF protocol 1.5 to 1.6 ### Additions 1. **physics.sdf** `dart::solver::solver_type` element + description: The DART LCP/constraint solver to use. Either dantzig or pgs (projected Gauss-Seidel) + type: string + default: dantzig + required: 0 + [pull request 369](https://bitbucket.org/osrf/sdformat/pull-requests/369) 1. **link.sdf** `enable_wind` element + description: If true, the link is affected by the wind + type: bool + default: false + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **link.sdf** `light` element + included from `light.sdf` with required="*", so a link can have any number of attached lights. + [pull request 373](https://bitbucket.org/osrf/sdformat/pull-requests/373) 1. **model.sdf** `enable_wind` element + description: If set to true, all links in the model will be affected by the wind. Can be overriden by the link wind property. + type: bool + default: false + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **model_state.sdf** `scale` element + description: Scale for the 3 dimensions of the model. + type: vector3 + default: "1 1 1" + required: 0 + [pull request 246](https://bitbucket.org/osrf/sdformat/pull-requests/246) 1. **physics.sdf** `island_threads` element under `ode::solver` + description: Number of threads to use for "islands" of disconnected models. + type: int + default: 0 + required: 0 + [pull request 380](https://bitbucket.org/osrf/sdformat/pull-requests/380) 1. **physics.sdf** `thread_position_correction` element under `ode::solver` + description: Flag to use threading to speed up position correction computation. + type: bool + default: 0 + required: 0 + [pull request 380](https://bitbucket.org/osrf/sdformat/pull-requests/380) 1. **state.sdf** allow `light` tags within `insertions` element * [pull request 325](https://bitbucket.org/osrf/sdformat/pull-request/325) 1. **surface.sdf** `category_bitmask` element + description: Bitmask for category of collision filtering. Collision happens if `((category1 & collision2) | (category2 & collision1))` is not zero. If not specified, the category_bitmask should be interpreted as being the same as collide_bitmask. + type: unsigned int + default: 65535 + required: 0 + [pull request 318](https://bitbucket.org/osrf/sdformat/pull-requests/318) 1. **world.sdf** `wind` element + description: The wind tag specifies the type and properties of the wind. + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **world.sdf** `wind::linear_velocity` element + description: Linear velocity of the wind. + type: vector3 + default: "0 0 0" + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) sdformat-6.0.0+dfsg/NEWS000066400000000000000000000000001323606632500147460ustar00rootroot00000000000000sdformat-6.0.0+dfsg/README.md000066400000000000000000000024111323606632500155360ustar00rootroot00000000000000# sdformat # SDF is an XML file format that describes environments, objects, and robots in a manner suitable for robotic applications. SDF is capable of representing and describing different physic engines, lighting properties, terrain, static or dynamic objects, and articulated robots with various sensors, and acutators. The format of SDF is also described by XML, which facilitates updates and allows conversion from previous versions. A parser is also contained within this package that reads SDF files and returns a C++ interface. Test coverage: [![codecov](https://codecov.io/bb/osrf/sdformat/branch/default/graph/badge.svg)](https://codecov.io/bb/osrf/sdformat) ## Installation ## Standard installation can be performed in UNIX systems using the following steps: - mkdir build/ - cd build/ - cmake .. - sudo make install sdformat supported cmake parameters at configuring time: - USE_INTERNAL_URDF (bool) [default False] Use an internal copy of urdfdom 1.0.0 instead of look for one installed in the system - USE_UPSTREAM_CFLAGS (bool) [default True] Use the sdformat team compilation flags instead of the common set defined by cmake. ## Uninstallation ## To uninstall the software installed with the previous steps: - cd build/ - sudo make uninstall sdformat-6.0.0+dfsg/cmake/000077500000000000000000000000001323606632500153415ustar00rootroot00000000000000sdformat-6.0.0+dfsg/cmake/CodeCoverage.cmake000066400000000000000000000117621323606632500207000ustar00rootroot00000000000000# # 2012-01-31, Lars Bilke # - Enable Code Coverage # # 2013-09-17, Joakim Söderberg # - Added support for Clang. # - Some additional usage instructions. # # USAGE: # 1. Copy this file into your cmake modules path. # # 2. Add the following line to your CMakeLists.txt: # INCLUDE(CodeCoverage) # # 3. Set compiler flags to turn off optimization and enable coverage: # SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") # SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") # # 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target # which runs your test executable and produces a lcov code coverage report: # Example: # SETUP_TARGET_FOR_COVERAGE( # my_coverage_target # Name for custom target. # test_driver # Name of the test driver executable that runs the tests. # # NOTE! This should always have a ZERO as exit code # # otherwise the coverage generation will not complete. # coverage # Name of output directory. # ) # # 4. Build a Debug build: # cmake -DCMAKE_BUILD_TYPE=Debug .. # make # make my_coverage_target # # # Check prereqs FIND_PROGRAM( GCOV_PATH gcov ) FIND_PROGRAM( LCOV_PATH lcov ) FIND_PROGRAM( GREP_PATH grep ) FIND_PROGRAM( GENHTML_PATH genhtml ) FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests) IF(NOT GCOV_PATH) MESSAGE(FATAL_ERROR "gcov not found! Aborting...") ENDIF() # NOT GCOV_PATH IF(NOT CMAKE_COMPILER_IS_GNUCXX) # Clang version 3.0.0 and greater now supports gcov as well. MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.") IF(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") ENDIF() ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX SET(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the C++ compiler during coverage builds." FORCE ) SET(CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage -fprofile-arcs -ftest-coverage" CACHE STRING "Flags used by the C compiler during coverage builds." FORCE ) SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE "" CACHE STRING "Flags used for linking binaries during coverage builds." FORCE ) SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "" CACHE STRING "Flags used by the shared libraries linker during coverage builds." FORCE ) MARK_AS_ADVANCED( CMAKE_CXX_FLAGS_COVERAGE CMAKE_C_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage")) MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" ) ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug" # Param _targetname The name of new the custom make target # Param _testrunner The name of the target which runs the tests. # MUST return ZERO always, even on errors. # If not, no coverage report will be created! # Param _outputname lcov output is generated as _outputname.info # HTML report is generated in _outputname/index.html # Optional fourth parameter is passed as arguments to _testrunner # Pass them in list form, e.g.: "-j;2" for -j 2 FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname) IF(NOT LCOV_PATH) MESSAGE(FATAL_ERROR "lcov not found! Aborting...") ENDIF() # NOT LCOV_PATH IF(NOT GENHTML_PATH) MESSAGE(FATAL_ERROR "genhtml not found! Aborting...") ENDIF() # NOT GENHTML_PATH IF(NOT GREP_PATH) MESSAGE(FATAL_ERROR "grep not found! Run code coverage on linux or mac.") ENDIF() # Setup target ADD_CUSTOM_TARGET(${_targetname} COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info.cleaned ${_outputname}.info # Capturing lcov counters and generating report COMMAND ${LCOV_PATH} -q --no-checksum --directory ${PROJECT_BINARY_DIR} --capture --output-file ${_outputname}.info 2>/dev/null COMMAND ${LCOV_PATH} -q --remove ${_outputname}.info 'test/*' '/usr/*' '*_TEST*' --output-file ${_outputname}.info.cleaned COMMAND ${GENHTML_PATH} -q --legend -o ${_outputname} ${_outputname}.info.cleaned COMMAND ${LCOV_PATH} --summary ${_outputname}.info.cleaned 2>&1 | grep "lines" | cut -d ' ' -f 4 | cut -d '%' -f 1 > coverage/lines.txt COMMAND ${LCOV_PATH} --summary ${_outputname}.info.cleaned 2>&1 | grep "functions" | cut -d ' ' -f 4 | cut -d '%' -f 1 > coverage/functions.txt COMMAND ${CMAKE_COMMAND} -E rename ${_outputname}.info.cleaned ${_outputname}.info WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Resetting code coverage counters to zero.\n" "Processing code coverage counters and generating report." ) # Show info where to find the report ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD COMMAND COMMAND ${LCOV_PATH} -q --zerocounters --directory ${PROJECT_BINARY_DIR}; COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report." ) ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE sdformat-6.0.0+dfsg/cmake/DefaultCFlags.cmake000066400000000000000000000067271323606632500210230ustar00rootroot00000000000000# Build type link flags set (CMAKE_LINK_FLAGS_RELEASE " " CACHE INTERNAL "Link flags for release" FORCE) set (CMAKE_LINK_FLAGS_RELWITHDEBINFO " " CACHE INTERNAL "Link flags for release with debug support" FORCE) set (CMAKE_LINK_FLAGS_DEBUG " " CACHE INTERNAL "Link flags for debug" FORCE) set (CMAKE_LINK_FLAGS_PROFILE " -pg" CACHE INTERNAL "Link flags for profile" FORCE) set (CMAKE_LINK_FLAGS_COVERAGE " --coverage" CACHE INTERNAL "Link flags for static code coverage" FORCE) set (CMAKE_C_FLAGS_RELEASE "") if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND NOT MSVC) # -s doesn't work with clang or Visual Studio, see alternative in link below: # http://stackoverflow.com/questions/6085491/gcc-vs-clang-symbol-strippingu set (CMAKE_C_FLAGS_RELEASE "-s") endif() if (NOT MSVC) set (CMAKE_C_FLAGS_RELEASE " ${CMAKE_C_FLAGS_RELEASE} -O3 -DNDEBUG ${CMAKE_C_FLAGS_ALL}" CACHE INTERNAL "C Flags for release" FORCE) set (CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) set (CMAKE_C_FLAGS_RELWITHDEBINFO " -g -O2 ${CMAKE_C_FLAGS_ALL}" CACHE INTERNAL "C Flags for release with debug support" FORCE) set (CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) set (CMAKE_C_FLAGS_DEBUG " -ggdb3 ${CMAKE_C_FLAGS_ALL}" CACHE INTERNAL "C Flags for debug" FORCE) set (CMAKE_CXX_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) set (CMAKE_C_FLAGS_PROFILE " -fno-omit-frame-pointer -g -pg ${CMAKE_C_FLAGS_ALL}" CACHE INTERNAL "C Flags for profile" FORCE) set (CMAKE_CXX_FLAGS_PROFILE ${CMAKE_C_FLAGS_PROFILE}) set (CMAKE_C_FLAGS_COVERAGE " -g -O0 -Wformat=2 --coverage -fno-inline ${CMAKE_C_FLAGS_ALL}" CACHE INTERNAL "C Flags for static code coverage" FORCE) set (CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE}") foreach(flag -fno-default-inline -fno-elide-constructors -fno-implicit-inline-templates) CHECK_CXX_COMPILER_FLAG(${flag} R${flag}) if (R${flag}) set (CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} ${flag}") endif() endforeach() endif() ##################################### # Set all the global build flags set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_LINK_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_LINK_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}") set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_LINK_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}") # Visual Studio enables c++11 support by default if (NOT MSVC) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}} -std=c++11") endif() if (UNIX) # Add visibility in UNIX check_gcc_visibility() if (GCC_SUPPORTS_VISIBILITY) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") endif() endif() # Compiler-specific C++11 activation. if ("${CMAKE_CXX_COMPILER_ID} " MATCHES "GNU ") execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER 4.7)) message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.8 or greater.") endif () elseif ("${CMAKE_CXX_COMPILER_ID} " MATCHES "Clang ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") elseif ("${CMAKE_CXX_COMPILER_ID} " STREQUAL "MSVC ") if (MSVC_VERSION LESS 1800) message(FATAL_ERROR "${PROJECT_NAME} requires VS 2013 or greater.") endif() else () message(FATAL_ERROR "Your C++ compiler does not support C++11.") endif () sdformat-6.0.0+dfsg/cmake/FindSSE.cmake000066400000000000000000000115361323606632500176040ustar00rootroot00000000000000# Check if SSE instructions are available on the machine where # the project is compiled. IF (ARCH MATCHES "i386" OR ARCH MATCHES "x86_64") IF(CMAKE_SYSTEM_NAME MATCHES "Linux") EXEC_PROGRAM(cat ARGS "/proc/cpuinfo" OUTPUT_VARIABLE CPUINFO) STRING(REGEX REPLACE "^.*(sse2).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "sse2" "${SSE_THERE}" SSE2_TRUE) IF (SSE2_TRUE) set(SSE2_FOUND true CACHE BOOL "SSE2 available on host") ELSE (SSE2_TRUE) set(SSE2_FOUND false CACHE BOOL "SSE2 available on host") ENDIF (SSE2_TRUE) # /proc/cpuinfo apparently omits sse3 :( STRING(REGEX REPLACE "^.*[^s](sse3).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "sse3" "${SSE_THERE}" SSE3_TRUE) IF (NOT SSE3_TRUE) STRING(REGEX REPLACE "^.*(T2300).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "T2300" "${SSE_THERE}" SSE3_TRUE) ENDIF (NOT SSE3_TRUE) STRING(REGEX REPLACE "^.*(ssse3).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "ssse3" "${SSE_THERE}" SSSE3_TRUE) IF (SSE3_TRUE OR SSSE3_TRUE) set(SSE3_FOUND true CACHE BOOL "SSE3 available on host") ELSE (SSE3_TRUE OR SSSE3_TRUE) set(SSE3_FOUND false CACHE BOOL "SSE3 available on host") ENDIF (SSE3_TRUE OR SSSE3_TRUE) IF (SSSE3_TRUE) set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host") ELSE (SSSE3_TRUE) set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host") ENDIF (SSSE3_TRUE) STRING(REGEX REPLACE "^.*(sse4_1).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "sse4_1" "${SSE_THERE}" SSE41_TRUE) IF (SSE41_TRUE) set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host") ELSE (SSE41_TRUE) set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host") ENDIF (SSE41_TRUE) STRING(REGEX REPLACE "^.*(sse4_2).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "sse4_2" "${SSE_THERE}" SSE42_TRUE) IF (SSE42_TRUE) set(SSE4_2_FOUND true CACHE BOOL "SSE4.2 available on host") ELSE (SSE42_TRUE) set(SSE4_2_FOUND false CACHE BOOL "SSE4.2 available on host") ENDIF (SSE42_TRUE) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") EXEC_PROGRAM("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE CPUINFO) STRING(REGEX REPLACE "^.*[^S](SSE2).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "SSE2" "${SSE_THERE}" SSE2_TRUE) IF (SSE2_TRUE) set(SSE2_FOUND true CACHE BOOL "SSE2 available on host") ELSE (SSE2_TRUE) set(SSE2_FOUND false CACHE BOOL "SSE2 available on host") ENDIF (SSE2_TRUE) STRING(REGEX REPLACE "^.*[^S](SSE3).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "SSE3" "${SSE_THERE}" SSE3_TRUE) IF (SSE3_TRUE) set(SSE3_FOUND true CACHE BOOL "SSE3 available on host") ELSE (SSE3_TRUE) set(SSE3_FOUND false CACHE BOOL "SSE3 available on host") ENDIF (SSE3_TRUE) STRING(REGEX REPLACE "^.*(SSSE3).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "SSSE3" "${SSE_THERE}" SSSE3_TRUE) IF (SSSE3_TRUE) set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host") ELSE (SSSE3_TRUE) set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host") ENDIF (SSSE3_TRUE) STRING(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" SSE_THERE ${CPUINFO}) STRING(COMPARE EQUAL "SSE4.1" "${SSE_THERE}" SSE41_TRUE) IF (SSE41_TRUE) set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host") ELSE (SSE41_TRUE) set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host") ENDIF (SSE41_TRUE) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows") # TODO set(SSE2_FOUND true CACHE BOOL "SSE2 available on host") set(SSE3_FOUND false CACHE BOOL "SSE3 available on host") set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host") set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host") ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux") set(SSE2_FOUND true CACHE BOOL "SSE2 available on host") set(SSE3_FOUND false CACHE BOOL "SSE3 available on host") set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host") set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host") ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") ENDIF(ARCH MATCHES "i386" OR ARCH MATCHES "x86_64") if(NOT SSE2_FOUND) MESSAGE(STATUS "Could not find hardware support for SSE2 on this machine.") endif(NOT SSE2_FOUND) if(NOT SSE3_FOUND) MESSAGE(STATUS "Could not find hardware support for SSE3 on this machine.") endif(NOT SSE3_FOUND) if(NOT SSSE3_FOUND) MESSAGE(STATUS "Could not find hardware support for SSSE3 on this machine.") endif(NOT SSSE3_FOUND) if(NOT SSE4_1_FOUND) MESSAGE(STATUS "Could not find hardware support for SSE4.1 on this machine.") endif(NOT SSE4_1_FOUND) mark_as_advanced(SSE2_FOUND SSE3_FOUND SSSE3_FOUND SSE4_1_FOUND) sdformat-6.0.0+dfsg/cmake/HostCFlags.cmake000066400000000000000000000012201323606632500203330ustar00rootroot00000000000000include (${project_cmake_dir}/FindSSE.cmake) if (SSE2_FOUND) set (CMAKE_C_FLAGS_ALL "-msse -msse2 ${CMAKE_C_FLAGS_ALL}") if (NOT APPLE) set (CMAKE_C_FLAGS_ALL "-mfpmath=sse ${CMAKE_C_FLAGS_ALL}") endif() endif() if (SSE3_FOUND) set (CMAKE_C_FLAGS_ALL "-msse3 ${CMAKE_C_FLAGS_ALL}") endif() if (SSSE3_FOUND) set (CMAKE_C_FLAGS_ALL "-mssse3 ${CMAKE_C_FLAGS_ALL}") endif() if (SSE4_1_FOUND OR SSE4_2_FOUND) if (SSE4_1_FOUND) set (CMAKE_C_FLAGS_ALL "-msse4.1 ${CMAKE_C_FLAGS_ALL}") endif() if (SSE4_2_FOUND) set (CMAKE_C_FLAGS_ALL "-msse4.2 ${CMAKE_C_FLAGS_ALL}") endif() else() message(STATUS "\nSSE4 disabled.\n") endif() sdformat-6.0.0+dfsg/cmake/SDFUtils.cmake000066400000000000000000000217231323606632500200050ustar00rootroot00000000000000################################################################################ #APPEND_TO_CACHED_STRING(_string _cacheDesc [items...]) # Appends items to a cached list. MACRO (APPEND_TO_CACHED_STRING _string _cacheDesc) FOREACH (newItem ${ARGN}) SET (${_string} "${${_string}} ${newItem}" CACHE INTERNAL ${_cacheDesc} FORCE) ENDFOREACH (newItem ${ARGN}) #STRING(STRIP ${${_string}} ${_string}) ENDMACRO (APPEND_TO_CACHED_STRING) ################################################################################ # APPEND_TO_CACHED_LIST (_list _cacheDesc [items...] # Appends items to a cached list. MACRO (APPEND_TO_CACHED_LIST _list _cacheDesc) SET (tempList ${${_list}}) FOREACH (newItem ${ARGN}) LIST (APPEND tempList ${newItem}) ENDFOREACH (newItem ${newItem}) SET (${_list} ${tempList} CACHE INTERNAL ${_cacheDesc} FORCE) ENDMACRO(APPEND_TO_CACHED_LIST) ################################################# # Macro to turn a list into a string (why doesn't CMake have this built-in?) MACRO (LIST_TO_STRING _string _list) SET (${_string}) FOREACH (_item ${_list}) SET (${_string} "${${_string}} ${_item}") ENDFOREACH (_item) #STRING(STRIP ${${_string}} ${_string}) ENDMACRO (LIST_TO_STRING) ################################################# # BUILD ERROR macro macro (BUILD_ERROR) foreach (str ${ARGN}) SET (msg "\t${str}") MESSAGE (STATUS ${msg}) APPEND_TO_CACHED_LIST(build_errors "build errors" ${msg}) endforeach () endmacro (BUILD_ERROR) ################################################# # BUILD WARNING macro macro (BUILD_WARNING) foreach (str ${ARGN}) SET (msg "\t${str}" ) MESSAGE (STATUS ${msg} ) APPEND_TO_CACHED_LIST(build_warnings "build warning" ${msg}) endforeach (str ${ARGN}) endmacro (BUILD_WARNING) ################################################# macro (sdf_add_library _name) set(LIBS_DESTINATION ${PROJECT_BINARY_DIR}/src) set_source_files_properties(${ARGN} PROPERTIES COMPILE_DEFINITIONS "BUILDING_DLL") add_library(${_name} SHARED ${ARGN}) target_link_libraries (${_name} ${general_libraries}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBS_DESTINATION}) if (MSVC) set_target_properties( ${_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${LIBS_DESTINATION}) set_target_properties( ${_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIBS_DESTINATION}) set_target_properties( ${_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIBS_DESTINATION}) endif () endmacro () ################################################# macro (sdf_add_executable _name) add_executable(${_name} ${ARGN}) target_link_libraries (${_name} ${general_libraries}) endmacro () ################################################# macro (sdf_install_includes _subdir) install(FILES ${ARGN} DESTINATION ${INCLUDE_INSTALL_DIR}/${_subdir} COMPONENT headers) endmacro() ################################################# macro (sdf_install_library _name) set_target_properties(${_name} PROPERTIES SOVERSION ${SDF_MAJOR_VERSION} VERSION ${SDF_VERSION_FULL}) install (TARGETS ${_name} DESTINATION ${LIB_INSTALL_DIR} COMPONENT shlib) endmacro () ################################################# macro (sdf_install_executable _name) set_target_properties(${_name} PROPERTIES VERSION ${SDF_VERSION_FULL}) install (TARGETS ${_name} DESTINATION ${BIN_INSTALL_DIR}) endmacro () ################################################# macro (sdf_setup_unix) endmacro() ################################################# macro (sdf_setup_windows) # Need for M_PI constant add_definitions(-D_USE_MATH_DEFINES -DWINDOWS_LEAN_AND_MEAN) # Suppress warnings caused by boost add_definitions(/wd4512 /wd4996) # Use dynamic linking for boost add_definitions(-DBOOST_ALL_DYN_LINK) # And force linking to MSVC dynamic runtime set(CMAKE_C_FLAGS_DEBUG "/MDd ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "/MD ${CMAKE_C_FLAGS_RELEASE}") if (MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) # Not need if proper cmake gnerator (-G "...Win64") is passed to cmake # Enable as a second measeure to workaround over bug # http://www.cmake.org/Bug/print_bug_page.php?bug_id=11240 set(CMAKE_SHARED_LINKER_FLAGS "/machine:x64") endif() endmacro() ################################################# macro (sdf_setup_apple) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined -Wl,dynamic_lookup") endmacro() ################################################# include_directories(${PROJECT_SOURCE_DIR}/test/gtest/include) macro (sdf_build_tests) # Build all the tests foreach(GTEST_SOURCE_file ${ARGN}) string(REGEX REPLACE ".cc" "" BINARY_NAME ${GTEST_SOURCE_file}) set(BINARY_NAME ${TEST_TYPE}_${BINARY_NAME}) if (UNIX) add_executable(${BINARY_NAME} ${GTEST_SOURCE_file}) elseif(WIN32) add_executable(${BINARY_NAME} ${GTEST_SOURCE_file} ${PROJECT_SOURCE_DIR}/src/win/tinyxml/tinystr.cpp ${PROJECT_SOURCE_DIR}/src/win/tinyxml/tinyxmlerror.cpp ${PROJECT_SOURCE_DIR}/src/win/tinyxml/tinyxml.cpp ${PROJECT_SOURCE_DIR}/src/win/tinyxml/tinyxmlparser.cpp ) else() message(FATAL_ERROR "Unsupported platform") endif() add_dependencies(${BINARY_NAME} gtest gtest_main sdformat ) link_directories(${IGNITION-MATH_LIBRARY_DIRS}) if (UNIX) target_link_libraries(${BINARY_NAME} libgtest.a libgtest_main.a sdformat pthread ${tinyxml_LIBRARIES} ${IGNITION-MATH_LIBRARIES} ) elseif(WIN32) target_link_libraries(${BINARY_NAME} gtest.lib gtest_main.lib sdformat.dll ${IGNITION-MATH_LIBRARIES} ) # Copy in sdformat library add_custom_command(TARGET ${BINARY_NAME} COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ VERBATIM) # Copy in ignition-math library add_custom_command(TARGET ${BINARY_NAME} COMMAND ${CMAKE_COMMAND} -E copy_if_different "${IGNITION-MATH_LIBRARY_DIRS}/${IGNITION-MATH_LIBRARIES}.dll" $ VERBATIM) endif() add_test(${BINARY_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/${BINARY_NAME}.xml) set (_env_vars) set (sdf_paths) # Get all the sdf protocol directory names file(GLOB dirs RELATIVE "${PROJECT_SOURCE_DIR}/sdf" "${PROJECT_SOURCE_DIR}/sdf/*") list(SORT dirs) # Add each sdf protocol to the sdf_path variable foreach(dir ${dirs}) if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/sdf/${dir}) set(sdf_paths "${PROJECT_SOURCE_DIR}/sdf/${dir}:${sdf_paths}") endif() endforeach() # Set the SDF_PATH environment variable list(APPEND _env_vars "SDF_PATH=${sdf_paths}") set_tests_properties(${BINARY_NAME} PROPERTIES TIMEOUT 240 ENVIRONMENT "${_env_vars}") if(PYTHONINTERP_FOUND) # Check that the test produced a result and create a failure if it didn't. # Guards against crashed and timed out tests. add_test(check_${BINARY_NAME} ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/check_test_ran.py ${CMAKE_BINARY_DIR}/test_results/${BINARY_NAME}.xml) endif() if(SDFORMAT_RUN_VALGRIND_TESTS AND VALGRIND_PROGRAM) add_test(memcheck_${BINARY_NAME} ${VALGRIND_PROGRAM} --leak-check=full --error-exitcode=1 --show-leak-kinds=all ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}) endif() endforeach() endmacro() ################################################# # Macro to setup supported compiler warnings # Based on work of Florent Lamiraux, Thomas Moulard, JRL, CNRS/AIST. include(CheckCXXCompilerFlag) macro(filter_valid_compiler_warnings) foreach(flag ${ARGN}) CHECK_CXX_COMPILER_FLAG(${flag} R${flag}) if(${R${flag}}) set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} ${flag}") endif() endforeach() endmacro() ################################################# # Copied from catkin/cmake/empy.cmake function(find_python_module module) # cribbed from http://www.cmake.org/pipermail/cmake/2011-January/041666.html string(TOUPPER ${module} module_upper) if(NOT PY_${module_upper}) if(ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED") set(${module}_FIND_REQUIRED TRUE) endif() # A module's location is usually a directory, but for # binary modules # it's a .so file. execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))" RESULT_VARIABLE _${module}_status OUTPUT_VARIABLE _${module}_location ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT _${module}_status) set(PY_${module_upper} ${_${module}_location} CACHE STRING "Location of Python module ${module}") endif(NOT _${module}_status) endif(NOT PY_${module_upper}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PY_${module} DEFAULT_MSG PY_${module_upper}) endfunction(find_python_module) sdformat-6.0.0+dfsg/cmake/SearchForStuff.cmake000066400000000000000000000126271323606632500212370ustar00rootroot00000000000000include (FindPkgConfig) # Detect the architecture include (${project_cmake_dir}/TargetArch.cmake) target_architecture(ARCH) message(STATUS "Building for arch: ${ARCH}") ######################################## # Find Boost, if not specified manually if (WIN32) set(Boost_USE_STATIC_LIBS OFF) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) endif() include(FindBoost) find_package(Boost ${MIN_BOOST_VERSION}) if (NOT Boost_FOUND) set (BUILD_SDF OFF CACHE INTERNAL "Build SDF" FORCE) BUILD_ERROR ("Boost not found. Please install system boost version ${MIN_BOOST_VERSION} or higher.") endif() if (USE_EXTERNAL_TINYXML) ################################################# # Find tinyxml. Only debian distributions package tinyxml with a pkg-config # Use pkg_check_modules and fallback to manual detection (needed, at least, for MacOS) pkg_check_modules(tinyxml tinyxml) if (NOT tinyxml_FOUND) find_path (tinyxml_include_dirs tinyxml.h ${tinyxml_include_dirs} ENV CPATH) find_library(tinyxml_LIBRARIES NAMES tinyxml) set (tinyxml_FAIL False) if (NOT tinyxml_include_dirs) message (STATUS "Looking for tinyxml headers - not found") set (tinyxml_FAIL True) endif() if (NOT tinyxml_LIBRARIES) message (STATUS "Looking for tinyxml library - not found") set (tinyxml_FAIL True) endif() endif() if (tinyxml_FAIL) message (STATUS "Looking for tinyxml.h - not found") BUILD_ERROR("Missing: tinyxml") endif() else() # Needed in WIN32 since in UNIX the flag is added in the code installed add_definitions(-DTIXML_USE_STL) include_directories (${PROJECT_SOURCE_DIR}/src/win/tinyxml) set (tinyxml_LIBRARIES "tinyxml") set (tinyxml_LIBRARY_DIRS "") endif() ################################################ # Find urdfdom parser. Logic: # # 1. if USE_INTERNAL_URDF is unset, try to use system installation, fallback to internal copy # 2. if USE_INTERNAL_URDF is set to True, use the internal copy # 3. if USE_INTERNAL_URDF is set to False, force to search system installation, fail on error if (NOT PKG_CONFIG_FOUND) if (NOT DEFINED USE_INTERNAL_URDF) BUILD_WARNING("Couldn't find pkg-config for urdfdom, using internal copy") set(USE_INTERNAL_URDF true) elseif(NOT USE_INTERNAL_URDF) BUILD_ERROR("Couldn't find pkg-config for urdfdom") endif() endif() if (NOT DEFINED USE_INTERNAL_URDF OR NOT USE_INTERNAL_URDF) # check for urdfdom with pkg-config pkg_check_modules(URDF urdfdom>=1.0) if (NOT URDF_FOUND) if (NOT DEFINED USE_INTERNAL_URDF) message(STATUS "Couldn't find urdfdom >= 1.0, using internal copy") set(USE_INTERNAL_URDF true) else() BUILD_ERROR("Couldn't find the urdfdom >= 1.0 system installation") endif() else() # what am I doing here? pkg-config and cmake set(URDF_INCLUDE_DIRS ${URDF_INCLUDEDIR}) set(URDF_LIBRARY_DIRS ${URDF_LIBDIR}) endif() endif() ################################################# # Find ign command line utility: find_package(ignition-tools) if (IGNITION-TOOLS_BINARY_DIRS) message(STATUS "Looking for ignition-tools-config.cmake - found") else() BUILD_WARNING ("ignition-tools not found, for command line utilities, please install ignition-tools.") endif() ################################################ # Find the Python interpreter for running the # check_test_ran.py script find_package(PythonInterp QUIET) ################################################ # Find psutil python package for memory tests find_python_module(psutil) if(NOT PY_PSUTIL) BUILD_WARNING("Python psutil package not found. Memory leak tests will be skipped") endif() ################################################ # Find Valgrind for checking memory leaks in the # tests find_program(VALGRIND_PROGRAM NAMES valgrind PATH ${VALGRIND_ROOT}/bin) option(SDFORMAT_RUN_VALGRIND_TESTS "Run sdformat tests with Valgrind" FALSE) mark_as_advanced(SDFORMAT_RUN_VALGRIND_TESTS) if (SDFORMAT_RUN_VALGRIND_TESTS AND NOT VALGRIND_PROGRAM) BUILD_WARNING("valgrind not found. Memory check tests will be skipped.") endif() ################################################ # Find ruby executable to produce xml schemas find_program(RUBY ruby) if (NOT RUBY) BUILD_ERROR ("Ruby version 1.9 is needed to build xml schemas") else() message(STATUS "Found ruby executable: ${RUBY}") endif() ################################################# # Macro to check for visibility capability in compiler # Original idea from: https://gitorious.org/ferric-cmake-stuff/ macro (check_gcc_visibility) include (CheckCXXCompilerFlag) check_cxx_compiler_flag(-fvisibility=hidden GCC_SUPPORTS_VISIBILITY) endmacro() ######################################## # Find ignition math # Set a variable for generating ProjectConfig.cmake set(IGNITION-MATH_REQUIRED_MAJOR_VERSION 4) find_package(ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION} QUIET) if (NOT ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION}_FOUND) message(STATUS "Looking for ignition-math4-config.cmake - not found") find_package(ignition-math3 QUIET) if (NOT ignition-math3_FOUND) message(STATUS "Looking for ignition-math3-config.cmake - not found") BUILD_ERROR ("Missing: Ignition math (libignition-math4-dev or libignition-math3-dev)") else() message(STATUS "Looking for ignition-math3-config.cmake - found") endif() else() message(STATUS "Looking for ignition-math${IGNITION-MATH_REQUIRED_MAJOR_VERSION}-config.cmake - found") endif() sdformat-6.0.0+dfsg/cmake/TargetArch.cmake000066400000000000000000000153711323606632500203760ustar00rootroot00000000000000# Copyright (c) 2012 Petroules Corporation. All rights reserved. # # 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 OWNER 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. # Based on the Qt 5 processor detection code, so should be very accurate # https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h # Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64) # Regarding POWER/PowerPC, just as is noted in the Qt source, # "There are many more known variants/revisions that we do not handle/detect." set(archdetect_c_code " #if defined(__arm__) || defined(__TARGET_ARCH_ARM) #if defined(__ARM_ARCH_7__) \\ || defined(__ARM_ARCH_7A__) \\ || defined(__ARM_ARCH_7R__) \\ || defined(__ARM_ARCH_7M__) \\ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) #error cmake_ARCH armv7 #elif defined(__ARM_ARCH_6__) \\ || defined(__ARM_ARCH_6J__) \\ || defined(__ARM_ARCH_6T2__) \\ || defined(__ARM_ARCH_6Z__) \\ || defined(__ARM_ARCH_6K__) \\ || defined(__ARM_ARCH_6ZK__) \\ || defined(__ARM_ARCH_6M__) \\ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) #error cmake_ARCH armv6 #elif defined(__ARM_ARCH_5TEJ__) \\ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) #error cmake_ARCH armv5 #else #error cmake_ARCH arm #endif #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) #error cmake_ARCH i386 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) #error cmake_ARCH x86_64 #elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) #error cmake_ARCH ia64 #elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\ || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\ || defined(_M_MPPC) || defined(_M_PPC) #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) #error cmake_ARCH ppc64 #else #error cmake_ARCH ppc #endif #endif #error cmake_ARCH unknown ") # Set ppc_support to TRUE before including this file or ppc and ppc64 # will be treated as invalid architectures since they are no longer supported by Apple function(target_architecture output_var) if(APPLE AND CMAKE_OSX_ARCHITECTURES) # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set # First let's normalize the order of the values # Note that it's not possible to compile PowerPC applications if you are using # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we # disable it by default # See this page for more information: # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) if("${osx_arch}" STREQUAL "ppc" AND ppc_support) set(osx_arch_ppc TRUE) elseif("${osx_arch}" STREQUAL "i386") set(osx_arch_i386 TRUE) elseif("${osx_arch}" STREQUAL "x86_64") set(osx_arch_x86_64 TRUE) elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) set(osx_arch_ppc64 TRUE) else() message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}") endif() endforeach() # Now add all the architectures in our normalized order if(osx_arch_ppc) list(APPEND ARCH ppc) endif() if(osx_arch_i386) list(APPEND ARCH i386) endif() if(osx_arch_x86_64) list(APPEND ARCH x86_64) endif() if(osx_arch_ppc64) list(APPEND ARCH ppc64) endif() else() file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") enable_language(C) # Detect the architecture in a rather creative way... # This compiles a small C program which is a series of ifdefs that selects a # particular #error preprocessor directive whose message string contains the # target architecture. The program will always fail to compile (both because # file is not a valid C program, and obviously because of the presence of the # #error preprocessor directives... but by exploiting the preprocessor in this # way, we can detect the correct target architecture even when cross-compiling, # since the program itself never needs to be run (only the compiler/preprocessor) try_run( run_result_unused compile_result_unused "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/arch.c" COMPILE_OUTPUT_VARIABLE ARCH CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} ) # Parse the architecture name from the compiler output string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") # Get rid of the value marker leaving just the architecture name string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}") # If we are compiling with an unknown architecture this variable should # already be set to "unknown" but in the case that it's empty (i.e. due # to a typo in the code), then set it to unknown if (NOT ARCH) set(ARCH unknown) endif() endif() set(${output_var} "${ARCH}" PARENT_SCOPE) endfunction() sdformat-6.0.0+dfsg/cmake/cmake_uninstall.cmake.in000066400000000000000000000020131323606632500221150ustar00rootroot00000000000000if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file) sdformat-6.0.0+dfsg/cmake/cpack_options.cmake.in000066400000000000000000000023301323606632500216020ustar00rootroot00000000000000set(CPACK_PACKAGE_NAME "@PROJECT_NAME@") set(CPACK_PACKAGE_VENDOR "sdformat.org") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Scene Description Format (SDF)") set(CPACK_PACKAGE_INSTALL_DIRECTORY "@PROJECT_NAME_LOWER@") set(CPACK_RESOURCE_FILE_LICENSE "@CMAKE_CURRENT_SOURCE_DIR@/LICENSE") set(CPACK_RESOURCE_FILE_README "@CMAKE_CURRENT_SOURCE_DIR@/README.md") set(CPACK_PACKAGE_DESCRIPTION_FILE "@CMAKE_CURRENT_SOURCE_DIR@/README.md") set(CPACK_PACKAGE_MAINTAINER "Nate Koenig ") set(CPACK_PACKAGE_CONTACT "Nate Koenig ") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "@DPKG_ARCH@") set(CPACK_DEBIAN_PACKAGE_DEPENDS "@DEBIAN_PACKAGE_DEPENDS@") set(CPACK_DEBIAN_PACKAGE_SECTION "devel") set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Format and parser for scene description files.") set(CPACK_RPM_PACKAGE_ARCHITECTURE "@DPKG_ARCH@") set(CPACK_RPM_PACKAGE_REQUIRES "@DEBIAN_PACKAGE_DEPENDS@") set(CPACK_RPM_PACKAGE_DESCRIPTION "Format and parser for scene description files.") set (CPACK_PACKAGE_FILE_NAME "@PROJECT_NAME_LOWER@-@SDF_VERSION_FULL@") set (CPACK_SOURCE_PACKAGE_FILE_NAME "@PROJECT_NAME_LOWER@-@SDF_VERSION_FULL@") sdformat-6.0.0+dfsg/cmake/sdf_config.cmake.in000066400000000000000000000023051323606632500210510ustar00rootroot00000000000000if (@PKG_NAME@_CONFIG_INCLUDED) return() endif() set(@PKG_NAME@_CONFIG_INCLUDED TRUE) list(APPEND @PKG_NAME@_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/include/sdformat-@SDF_VERSION@") list(APPEND @PKG_NAME@_CFLAGS "-I@CMAKE_INSTALL_PREFIX@/include/sdformat-@SDF_VERSION@") if (NOT WIN32) list(APPEND @PKG_NAME@_CXX_FLAGS "${@PKG_NAME@_CFLAGS} -std=c++11") endif() list(APPEND @PKG_NAME@_LIBRARY_DIRS "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@") foreach(lib @PKG_LIBRARIES@) set(onelib "${lib}-NOTFOUND") find_library(onelib ${lib} PATHS "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@" NO_DEFAULT_PATH ) if(NOT onelib) message(FATAL_ERROR "Library '${lib}' in package @PKG_NAME@ is not installed properly") endif() list(APPEND @PKG_NAME@_LIBRARIES "${onelib}") endforeach() find_package(ignition-math@IGNITION-MATH_REQUIRED_MAJOR_VERSION@) list(APPEND @PKG_NAME@_INCLUDE_DIRS ${IGNITION-MATH_INCLUDE_DIRS}) list(APPEND @PKG_NAME@_LIBRARIES ${IGNITION-MATH_LIBRARIES}) list(APPEND @PKG_NAME@_LIBRARY_DIRS ${IGNITION-MATH_LIBRARY_DIRS}) find_package(Boost) list(APPEND @PKG_NAME@_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}) list(APPEND @PKG_NAME@_LDFLAGS "-L@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@") sdformat-6.0.0+dfsg/cmake/sdf_config.h.in000066400000000000000000000023431323606632500202220ustar00rootroot00000000000000/* config.h. Generated by CMake for @PROJECT_NAME@. */ /* Protocol version */ #define SDF_PROTOCOL_VERSION "${SDF_PROTOCOL_VERSION}" /* \deprecated SDF_VERSION is deprecated. Please * use SDF_PROTOCOL_VERSION or SDF_PKG_VERSION * * SDF_VERSION is here to keep backwards compatibility. It was used * when the package version and protocol version were the same */ #define SDF_VERSION "${SDF_PROTOCOL_VERSION}" /* Package version number */ #define SDF_MAJOR_VERSION ${SDF_MAJOR_VERSION} #define SDF_MINOR_VERSION ${SDF_MINOR_VERSION} #define SDF_PATCH_VERSION ${SDF_PATCH_VERSION} #define SDF_PKG_VERSION "${SDF_VERSION}" #define SDF_VERSION_FULL "${SDF_VERSION_FULL}" #define SDF_VERSION_NAME ${SDF_VERSION_NAME} #define SDF_VERSION_HEADER "Simulation Description Format (SDF), version ${SDF_PROTOCOL_VERSION}\nCopyright (C) 2014 Open Source Robotics Foundation.\nReleased under the Apache 2 License.\nhttp://gazebosim.org/sdf\n\n" #cmakedefine BUILD_TYPE_PROFILE 1 #cmakedefine BUILD_TYPE_DEBUG 1 #cmakedefine BUILD_TYPE_RELEASE 1 #cmakedefine HAVE_URDFDOM 1 #cmakedefine USE_INTERNAL_URDF 1 #define SDF_SHARE_PATH "${CMAKE_INSTALL_FULL_DATAROOTDIR}/" #define SDF_VERSION_PATH "${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/${SDF_PKG_VERSION}" sdformat-6.0.0+dfsg/cmake/sdf_cpack.cmake000066400000000000000000000014441323606632500202630ustar00rootroot00000000000000################################################################################ #Find available package generators # DEB if ("${CMAKE_SYSTEM}" MATCHES "Linux") find_program(DPKG_PROGRAM dpkg) if (EXISTS ${DPKG_PROGRAM}) list (APPEND CPACK_GENERATOR "DEB") endif(EXISTS ${DPKG_PROGRAM}) find_program(RPMBUILD_PROGRAM rpmbuild) endif() list (APPEND CPACK_SOURCE_GENERATOR "TBZ2") list (APPEND CPACK_SOURCE_GENERATOR "ZIP") list (APPEND CPACK_SOURCE_IGNORE_FILES ";TODO;/.hg/;.swp$;/build/") include (InstallRequiredSystemLibraries) #execute_process(COMMAND dpkg --print-architecture _NPROCE) set (DEBIAN_PACKAGE_DEPENDS "libboost-all-dev, libtinyxml-dev") set (RPM_PACKAGE_DEPENDS "libboost-all-dev, libtinyxml-dev") set (SDF_CPACK_CFG_FILE "${PROJECT_BINARY_DIR}/cpack_options.cmake") sdformat-6.0.0+dfsg/cmake/sdformat_pc.in000066400000000000000000000005321323606632500201720ustar00rootroot00000000000000prefix="@CMAKE_INSTALL_PREFIX@" libdir=${prefix}/@LIB_INSTALL_DIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: SDF Description: Robot Modeling Language (SDF) Version: @SDF_VERSION_FULL@ Requires: ignition-math@IGNITION-MATH_REQUIRED_MAJOR_VERSION@ Libs: -L${libdir} -lsdformat CFlags: -I${includedir}/sdformat-@SDF_VERSION@ -std=c++11 sdformat-6.0.0+dfsg/cmake/upload_doc.sh.in000066400000000000000000000016111323606632500204120ustar00rootroot00000000000000#!/bin/sh # Usage: Only an administrator of OSRF's amazon s3 bucket will be able to use # this script. # # sh build/upload_doc.sh # Check if the node was configured to use s3cmd # This is done by running s3cmd --configure if [ ! -f "${HOME}/.s3cfg" ]; then echo "No $HOME/.s3cfg file found. Please config the software first in your system" exit 1 fi # Make documentation if not build make doc if [ ! -f "@CMAKE_BINARY_DIR@/doxygen/html/index.html" ]; then echo "Documentation not present. Install doxygen, and run `make doc` in the build directory" exit 1 fi # The code API s3cmd sync @CMAKE_BINARY_DIR@/doxygen/html/* s3://osrf-distributions/sdformat/api/@SDF_VERSION_FULL@/ --dry-run -v echo -n "Upload code API(Y/n)? " read ans if [ "$ans" = "y" ] || [ "$ans" = "Y" ]; then s3cmd sync @CMAKE_BINARY_DIR@/doxygen/html/* s3://osrf-distributions/sdformat/api/@SDF_VERSION_FULL@/ -v fi sdformat-6.0.0+dfsg/codecov.yml000066400000000000000000000000331323606632500164220ustar00rootroot00000000000000codecov: branch: default sdformat-6.0.0+dfsg/conf/000077500000000000000000000000001323606632500152065ustar00rootroot00000000000000sdformat-6.0.0+dfsg/conf/CMakeLists.txt000066400000000000000000000016401323606632500177470ustar00rootroot00000000000000include (${project_cmake_dir}/SDFUtils.cmake) set(ign_library_path "${CMAKE_BINARY_DIR}/src/cmd/cmdsdformat${SDF_MAJOR_VERSION}") # Generate a configuration file for internal testing. # Note that the major version of the library is included in the name. # Ex: sdformat0.yaml configure_file( "sdformat.yaml.in" "${CMAKE_BINARY_DIR}/test/conf/sdformat${SDF_MAJOR_VERSION}.yaml" @ONLY) set(ign_library_path "${CMAKE_INSTALL_PREFIX}/lib/ruby/ignition/cmdsdformat${SDF_MAJOR_VERSION}") # Generate a configuration file. # Note that the major version of the library is included in the name. # Ex: sdformat0.yaml configure_file( "sdformat.yaml.in" "${CMAKE_CURRENT_BINARY_DIR}/sdformat${SDF_MAJOR_VERSION}.yaml" @ONLY) # Install the yaml configuration files in an unversioned location. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdformat${SDF_MAJOR_VERSION}.yaml DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/ignition/) sdformat-6.0.0+dfsg/conf/sdformat.yaml.in000066400000000000000000000003411323606632500203140ustar00rootroot00000000000000--- # Subcommands available inside ignition-transport. format: 1.0.0 library_name: @PROJECT_NAME_LOWER@ library_version: @SDF_VERSION_FULL@ library_path: @ign_library_path@ commands: - sdf : Utilities for SDF files. ---sdformat-6.0.0+dfsg/configure.bat000066400000000000000000000007601323606632500167350ustar00rootroot00000000000000@set build_type=Release @if not "%1"=="" set build_type=%1 @echo Configuring for build type %build_type% @set IGN_MATH_PATH=%cd%\..\..\ign-math\build\install\%build_type% cmake -G "NMake Makefiles"^ -DUSE_INTERNAL_URDF:BOOL=True^ -DCMAKE_PREFIX_PATH="%IGN_MATH_PATH%"^ -DBOOST_ROOT:STRING="%cd%\..\..\boost_1_56_0"^ -DBOOST_LIBRARYDIR:STRING="%cd%\..\..\boost_1_56_0\lib64-msvc-12.0"^ -DCMAKE_INSTALL_PREFIX="install/%build_type%"^ -DCMAKE_BUILD_TYPE="%build_type%" .. sdformat-6.0.0+dfsg/doc/000077500000000000000000000000001323606632500150265ustar00rootroot00000000000000sdformat-6.0.0+dfsg/doc/CMakeLists.txt000066400000000000000000000013621323606632500175700ustar00rootroot00000000000000find_package(Doxygen) if (DOXYGEN_FOUND) configure_file(${CMAKE_SOURCE_DIR}/doc/sdf.in ${CMAKE_BINARY_DIR}/sdf.dox @ONLY) add_custom_target(doc # Generate the API documentation ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/sdf.dox WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND cp ${CMAKE_SOURCE_DIR}/doc/sdf_logo.png ${CMAKE_BINARY_DIR}/doxygen/html COMMAND cp ${CMAKE_SOURCE_DIR}/doc/search.js ${CMAKE_BINARY_DIR}/doxygen/html/search COMMAND make -C ${CMAKE_BINARY_DIR}/doxygen/latex COMMAND mv ${CMAKE_BINARY_DIR}/doxygen/latex/refman.pdf ${CMAKE_BINARY_DIR}/doxygen/latex/sdf-${SDF_VERSION_FULL}.pdf COMMENT "Generating API documentation with Doxygen" VERBATIM) endif() sdformat-6.0.0+dfsg/doc/doxygen.css000066400000000000000000000261371323606632500172260ustar00rootroot00000000000000/* The standard CSS for doxygen */ body, table, div, p, dl { font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; font-size: 12px; } /* @group Heading Levels */ h1 { font-size: 150%; } h2 { font-size: 120%; } h3 { font-size: 100%; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd, p.starttd { margin-top: 2px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; padding: 2px; } div.qindex { width: 100%; line-height: 140%; } div.navpath { margin-left: 20em; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code { color: #4665A2; } a.codeRef { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } .fragment { font-family: monospace, fixed; font-size: 105%; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 20em; margin-right: 10px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memItemLeft, .memItemRight, .memTemplParams { border-top: 1px solid #C4CFE5; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memTemplParams { color: #4665A2; white-space: nowrap; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 3px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 0; margin-bottom: 10px; } .memname { white-space: nowrap; font-weight: bold; margin-left: 6px; } .memproto { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 8px; -moz-border-radius-topleft: 8px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; } .memdoc { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 2px 5px; background-color: #FBFCFD; border-top-width: 0; /* firefox specific markup */ -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); /* webkit specific markup */ -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } /* @end */ /* @group Directory (tree) */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin: 0px; } /* these are for tree view when used as main index */ .directory { font-size: 9pt; font-weight: bold; margin: 5px; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } /* The following two styles can be used to replace the root node title with an image of your choice. Simply uncomment the next two styles, specify the name of your image and be sure to set 'height' to the proper pixel height of your image. */ /* .directory h3.swap { height: 61px; background-repeat: no-repeat; background-image: url("yourimage.gif"); } .directory h3.swap span { display: none; } */ .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } /* these are for tree view when not used as main index */ .directory-alt { font-size: 100%; font-weight: bold; } .directory-alt h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory-alt > h3 { margin-top: 0; } .directory-alt p { margin: 0px; white-space: nowrap; } .directory-alt div { display: none; margin: 0px; } .directory-alt img { vertical-align: -30%; } /* @end */ div.dynheader { margin-top: 8px; } address { font-style: normal; color: #2A3D61; } table.doxtable { border-collapse:collapse; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; text-align:left; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right: 15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath a { height:32px; display:block; text-decoration: none; outline: none; } .navpath a:hover { color:#6884BD; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; margin-left: 20em; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } #content { /*position: absolute; */ left:12em; top:0em; padding-left:3em; padding-right:3em; padding-bottom:2em; margin-top:1em; margin-right:2em; } .floatright { float: right; margin: 0 0 1em 1em; } .timestamp { text-align:right; background-color: #DDD; font-size:75%; } #MSearchBox { border: 1px solid black; position: static; margin: 10px; display: block; height: 20px; } #MSearchField { background:none; } /*iframe#MSearchResults { height: 500px; text-wrap: unrestricted; border: none; } */ /* #MSearchResultsWindow { display: block; position: fixed; }*/ div.leftbar { text-align:left; float: left; border-right: 1px solid #dddddd; width: 18em; margin: 5 5 5 5; padding: 4 4 4 4; background-color: #ffffff; position: fixed; height: 100%; } div.menu { #display:block; background:#ffffff; font-size: 90%; /*border-top: 2px solid #000000; border-bottom: 2px solid #000000; */ margin: 0 0 10px 0; } div.menu dl { margin-top: 0px; margin-bottom: 5px; } div.menu dt { font-weight:bold; padding:0 4px 4px 4px; font-size: 110%; text-align: left; text-decoration:none; } div.menu dd { font-weight: bold; margin-left: 0px; padding-left: 20px; padding-bottom: 2px; font-size: 100%; } div.leftbar img { border:0; } div.submenu dd { font-size: 70%; margin-left: 8px; padding-left: 10px; padding-bottom: 3px; } div.submenu dd .secondline { margin-left: 12px; } sdformat-6.0.0+dfsg/doc/footer.html000066400000000000000000000000321323606632500172050ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/doc/header.html000066400000000000000000000052541323606632500171520ustar00rootroot00000000000000 SDF: $title
sdformat-6.0.0+dfsg/doc/mainpage.html000066400000000000000000000023241323606632500174760ustar00rootroot00000000000000 /** \mainpage SDF API Reference This documentation provides useful information about the Simulation Desctiption Format API. The code reference is divided into the groups below. Should you find problems with this documentation - typos, unclear phrases, or insufficient detail - please create a new bitbucket issue. Include sufficient detail to quickly locate the problematic documentation, and set the issue's fields accordingly: Assignee - blank; Kind - bug; Priority - minor; Version - blank.
Class
List - Index of all classes in Gazebo, organized alphabetically
Hierarchy - Index of classes, organized hierachically according to their inheritance
Links
Website: The main SDF website.
Specification: Documentation of sdformat elements.
Tutorials: Tutorials that describe how to use SDF.
Download: How to download and install SDF
*/ sdformat-6.0.0+dfsg/doc/sdf.in000066400000000000000000002274101323606632500161400ustar00rootroot00000000000000# Doxyfile 1.8.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = SDF # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @SDF_VERSION_FULL@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = YES # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = /tmp/sdf_dox.warn #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_SOURCE_DIR@/doc/mainpage.html \ @CMAKE_SOURCE_DIR@/include/sdf # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.hh \ *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = *.cc *.hh # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed 's/boost::shared_ptr<\(.*\)>/\1*/'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 3 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = "@CMAKE_SOURCE_DIR@/doc/header.html" # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = "@CMAKE_SOURCE_DIR@/doc/footer.html" # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = "@CMAKE_SOURCE_DIR@/doc/doxygen.css" # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Gazebo API Documentation" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = YES # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = YES # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = . # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = NO # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans.ttf # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sdformat-6.0.0+dfsg/doc/sdf_logo.png000066400000000000000000000060671323606632500173410ustar00rootroot00000000000000‰PNG  IHDRff9ßäbsBIT|dˆ pHYs&&¢ï%ütEXtSoftwarewww.inkscape.org›î< ´IDATxœíyEÀ»Yä´!H9º %X $\I!P\V¡, U”€´Es)`HɕȡP4rHŠ€ …@L.AlÂa’% ûü£{6³“÷Þ¾7Ós~US;³oæëÞý^Owý}_÷4 ªŽTb,°°cìç`4°qìX,ŽK׋FÛ7 þº¦§ŠŠ‘JlLôǾÀ–Å7€yÀ_€9À#FÛ÷ÊBe#•Ø88øTE/æâ”4Çhk ,»%¥*F*ñ`Š?¶/­"ÃYL®5Ú¾[V%JQŒTbpp,ÐSx:ãàgÀ•eôI…*F*±pp*°~agc9ðsà £í+EZˆb¤Ss€Mr/0V³€K¶Ïæ]X®Š‘Jôâú )¶CÏ“•€.7ÚæUHnŠ‘JL¦»äR@ù< L1Úþ7á½y•JœÜǺ«€½§¥Sò´ÅH%Öfà^_&nN6Ú¾J`0ÅH%¶î¾D`ýxø–Ñö¾‚(F*±ð`ëÌÂêÍjàFÛ[³ ÊÜÇH%Žâ#¥ô³¤Çf”ºÅH%z€‹qs“Î p¼Ñö—idi1)¥5½ÀMR‰ãÓ HÕbüëkVÚB?D4€¶3»}°kÅøŽþ!`Ãn ûÒ¾k´½®›‡ºRŒÿƒæýjà-`À+bçñã}_Ù$£€]Iu-Îi&mçvú@ÇŠñ“ǹ´ž§4€€™ÀiW¥›‡çÛ¥‘QQ_4Ú¾ÝÉÍÝ(æt>£ ¸˜a´ýW‡Ï$Ëë¾ \l•FF¹Ýh{t'7v¤oûº,EEq–eÖë1~ìŸæù òm£í #Ý4¢b¼•ø>² ­ïŽ5Ú.Ió°_>8gnÏÅðZ ï»mŸowS[ÅøÈ<ÂX‰û Y™¤ûáZOH¯™2xØÓh»ªÕ #}û¦Ît¿p»T"õ0Ûh{?näö` :•Ån€nwCKÅøåà Wèó8‡ÔmûqýÍÅ4v×…3½—PSÚµ˜©ä³|‚·¤ÆhûÑö8´Ê9ëuHðýV6íc¼7Ë‹äç8ñ*°ƒÑvEVAR‰®fÕb%°ÑöÕä­ZÌyäëͲ pzAFÛëCÈ*g5û`­ãñ¿ß—Å}[–fäûÃGqƒº±—œJ4k1QŒ3ž.!Èh;@øJQl|/ùËa-Æ^¤8#âÀ—Œ¶Og$•ØxØ(s­Šg°mÜ™#Ùb¦P¬ewpeAFÛåÀŸCÈ*q£à!š)¦hö•JtdØë€ß’SæCŠññ)e…BL÷k=Yy*€Œ²Ø!>ጷ˜ãJ¨LÄ–À­ÞÔŸ…TFÒ 19:‰+æà*g/àGe¼I½Í4“¢“žF£Å<¶5CÈ‘FÛÔ}…Tb)°yÀúÉ2`s£íʨÅL,³6 n”JìžáùÊG$·acÜ›ƒ**FH%Hù|]š“ÀY8Á…lW‰wJ%¦¤ð.r…s)p n…öYÜ,~S`3ÄÏ“×ÑyrB<8»gçóGÅ%&¨"ƒÀ©FÛk;}@*ñ nÝ'O€Ó³ZȽ÷QRawöá2MT•^à©Ä£íE>“·åâ1\¸Å‚¼›×" •ìÔ‹KÿQu.”JÜî=fF"¯WÙJœ¯Ûž¡”G*±‡Tâœâw¯z‹‰s$°Tâ£ímmîË£Å<ƒ‹{y&´`©Ä^8ïŸø`g‹>êÑb"Æà,·âúžfk9ËœSʲB¥ûàú© M>Û‹ûcëÆ×ùR‰#š|ö^Àr.©©Ä~R‰¹8OŸfJßbF‡*´`Æ¿“Jü8-¶–⟸8Éh{SYÀ‘ø:›šŒíÃÍ6ëLd.Âë²*f)®•ü5£¤»àV…éâ±-ÖÅŒgy•Í1Ú¾”±>‘ýñܧÛɽ¬ŠÙ^*±©?OÛbîÆ …3)E*±µTâ:àߤÏ.56ëúG•ø,ðéóSàÌ,¹a|\Ï9¸ÌR¤•ãìÃý!›eT"ŸhÛÅ3+q‡i •JŒÎÀyº„Hõ¯‹ŠYÔáý p¡!óÒ&•ø4p®•„žr,êJK/˜È®„ûÀõÀÞ³¦-¾EH\ÔCüÈÓSu¨Å¬ ¼ã¶k1Î7Ú®å´á2qìL9yÖúû¨÷Š_œH!ɳ—çær£ícÑ/½ƒà¸@܃¨Vœç¢>Ü»öke×$‘B–àÖqáRt]o´}=ºÉÏÀÏÆ)£ª¹ úûp+ouç]£í{àbg¤‡÷mWG7H%¾ŒóožÜBF•èZLÝÖ¯mïŠÎ½¯ÚÕÀwŠ®T­+Ši:óá¿-¶:™y­×¯iä’p³@Ö‰I%ÎɼnJ1FÛ7£eØÙ¥V%;ÍZÌÀ>EW$wÚõñº+f˜áQ*±%pRIuÉÊ]°F1sY3A«#Ï%®Ï¦ºCávXàðŠñî)³Fò»ö3ø“K¬KæDÙ2â®>,©2YY¼»O=ÃýÀ÷/0\1÷àÌàuã¥øDøBi5ÉFƒØ[kH1F[K=s´$ÃGꪘ'¶CÃþ¤×b_gÉŽ¿®Š¹3~‘TÌlœ°NÄ;þQ8s}ÝÀ­ 1L1>§É-EÖ(ñó9²¯·—Áuq 84wÀVÔ+ø'ÞÇlSZ-Ò³¸4ù˵ã7ª¹ºˆ`—5¢Ž¾ Wm׊Oj²p1Ýy›”Å FÛx”rݳ øq³š*Æhû&鲯Í‹‰ëºE+Oo•}ª]Ï4:w*‹¤Ãbv ´À­>l©¿TÛ6¡føDâºNCýií¶Î),nðBØú%ÙBêbRz¸¼Ý mãmP§SÝ4 ÉS‡aþ àè‘‚¡F $5ÚÞ›ÛT‘:*æ´NçuáëC¹Û¤–ÅhŸM=¢êй¹“¼þÐ]èõñÀ?SU'?zîa2þ24óS:½¹cÅxìèžKm<öaË»ÊepT'Nì]%+ðÛ¦‰[5¬ ÛÆÎ_.«#pR·IºÎ"a´}8­Ûçrd\ìüª7‚ü‰Ñ¶ëöR¥÷ðÙÁ3mž¡ãó/W)a‘2Úž™æÁ,yW¦’=Ub¶M\¿\F%|€Ûf1u’îÔŠ1ÚmÏÁ%9-s˜šTÌJ©Åpé#SÇuB€LE~ÛÚ ”÷ —¸NSˆ·Œ¶™}'‚¤2Úþ ØròoH üD ux Ø;TF`¹½üPú«¸°º"Åð%å')~dö.yÃüPƒ&]óKGÐd ;g†2|mÿGqñ¸pòñþ‹Œà™1üRï¹R‰q¦íP›Ïµc\âúqœÇLžÜ œb´Íe°‘[ÆU£íÜF;'඾ʓä&lϱ¬ÅÀ1FÛIy)rN…ë‡Ô7;àòIæåà‘TL‘ Ü^h;m“ƒüat½m|¤cpk;'ëýˆÑv¯DYÏâ¾!˜ œk´}4¼)4û’÷™*•¸ 7@87ªÊʸ&¿»‹lŠYÜ Ì4Ú&ý£s§Ð“Ä· Cq#¹ýI¿7ZØ0¾U½Tb".ƒx7 s€™Àìv[îæM©Š‰ã“éŒSÒdºOp·cü›-•X—FQtðìBàà†ÐÃÞ´TF1q||þ¸WÝ$à“ image/svg+xml sdformat-6.0.0+dfsg/doc/search.js000066400000000000000000000612471323606632500166430ustar00rootroot00000000000000// Search script generated by doxygen // Copyright (C) 2009 by Dimitri van Heesch. // The code in this file is loosly based on main.js, part of Natural Docs, // which is Copyright (C) 2003-2008 Greg Valure // Natural Docs is licensed under the GPL. var indexSectionsWithContent = { 0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000101101110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111110000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 5: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111101111111101110111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 6: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 7: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010010000000101000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 8: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111010010101100101111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 9: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 10: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011010100000101001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 11: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }; var indexSectionNames = { 0: "all", 1: "classes", 2: "namespaces", 3: "files", 4: "functions", 5: "variables", 6: "typedefs", 7: "enums", 8: "enumvalues", 9: "related", 10: "groups", 11: "pages" }; function convertToId(search) { var result = ''; for (i=0;i do a search { this.Search(); } } this.OnSearchSelectKey = function(evt) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==40 && this.searchIndex0) // Up { this.searchIndex--; this.OnSelectItem(this.searchIndex); } else if (e.keyCode==13 || e.keyCode==27) { this.OnSelectItem(this.searchIndex); this.CloseSelectionWindow(); this.DOMSearchField().focus(); } return false; } // --------- Actions // Closes the results window. this.CloseResultsWindow = function() { this.DOMPopupSearchResultsWindow().style.display = 'none'; this.DOMSearchClose().style.display = 'none'; this.Activate(false); } this.CloseSelectionWindow = function() { this.DOMSearchSelectWindow().style.display = 'none'; } // Performs a search. this.Search = function() { this.keyTimeout = 0; // strip leading whitespace var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); var code = searchValue.toLowerCase().charCodeAt(0); var hexCode; if (code<16) { hexCode="0"+code.toString(16); } else { hexCode=code.toString(16); } var resultsPage; var resultsPageWithSearch; var hasResultsPage; if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') { resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; resultsPageWithSearch = resultsPage+'?'+escape(searchValue); hasResultsPage = true; } else // nothing available for this search term { resultsPage = this.resultsPath + '/nomatches.html'; resultsPageWithSearch = resultsPage; hasResultsPage = false; } window.frames.MSearchResults.location = resultsPageWithSearch; var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); if (domPopupSearchResultsWindow.style.display!='block') { var domSearchBox = this.DOMSearchBox(); this.DOMSearchClose().style.display = 'inline'; if (this.insideFrame) { var domPopupSearchResults = this.DOMPopupSearchResults(); domPopupSearchResultsWindow.style.position = 'relative'; domPopupSearchResultsWindow.style.display = 'block'; var width = document.body.clientWidth - 8; // the -8 is for IE :-( domPopupSearchResultsWindow.style.width = width + 'px'; domPopupSearchResults.style.width = width + 'px'; } else { var domPopupSearchResults = this.DOMPopupSearchResults(); var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; domPopupSearchResultsWindow.style.display = 'block'; left -= domPopupSearchResults.offsetWidth; domPopupSearchResultsWindow.style.top = top + 'px'; domPopupSearchResultsWindow.style.left = left + 'px'; } } this.lastSearchValue = searchValue; this.lastResultsPage = resultsPage; } // -------- Activation Functions // Activates or deactivates the search panel, resetting things to // their default values if necessary. this.Activate = function(isActive) { if (isActive || // open it this.DOMPopupSearchResultsWindow().style.display == 'block' ) { this.DOMSearchBox().className = 'MSearchBoxActive'; var searchField = this.DOMSearchField(); if (searchField.value == this.searchLabel) // clear "Search" term upon entry { searchField.value = ''; this.searchActive = true; } } else if (!isActive) // directly remove the panel { this.DOMSearchBox().className = 'MSearchBoxInactive'; this.DOMSearchField().value = this.searchLabel; this.searchActive = false; this.lastSearchValue = '' this.lastResultsPage = ''; } } } // ----------------------------------------------------------------------- // The class that handles everything on the search results page. function SearchResults(name) { // The number of matches from the last run of . this.lastMatchCount = 0; this.lastKey = 0; this.repeatOn = false; // Toggles the visibility of the passed element ID. this.FindChildElement = function(id) { var parentElement = document.getElementById(id); var element = parentElement.firstChild; while (element && element!=parentElement) { if (element.nodeName == 'DIV' && element.className == 'SRChildren') { return element; } if (element.nodeName == 'DIV' && element.hasChildNodes()) { element = element.firstChild; } else if (element.nextSibling) { element = element.nextSibling; } else { do { element = element.parentNode; } while (element && element!=parentElement && !element.nextSibling); if (element && element!=parentElement) { element = element.nextSibling; } } } } this.Toggle = function(id) { var element = this.FindChildElement(id); if (element) { if (element.style.display == 'block') { element.style.display = 'none'; } else { element.style.display = 'block'; } } } // Searches for the passed string. If there is no parameter, // it takes it from the URL query. // // Always returns true, since other documents may try to call it // and that may or may not be possible. this.Search = function(search) { if (!search) // get search word from URL { search = window.location.search; search = search.substring(1); // Remove the leading '?' search = unescape(search); } search = search.replace(/^ +/, ""); // strip leading spaces search = search.replace(/ +$/, ""); // strip trailing spaces search = search.toLowerCase(); search = convertToId(search); var resultRows = document.getElementsByTagName("div"); var matches = 0; var i = 0; while (i < resultRows.length) { var row = resultRows.item(i); if (row.className == "SRResult") { var rowMatchName = row.id.toLowerCase(); rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' if (search.length<=rowMatchName.length && rowMatchName.substr(0, search.length)==search) { row.style.display = 'block'; matches++; } else { row.style.display = 'none'; } } i++; } document.getElementById("Searching").style.display='none'; if (matches == 0) // no results { document.getElementById("NoMatches").style.display='block'; } else // at least one result { document.getElementById("NoMatches").style.display='none'; } this.lastMatchCount = matches; return true; } // return the first item with index index or higher that is visible this.NavNext = function(index) { var focusItem; while (1) { var focusName = 'Item'+index; focusItem = document.getElementById(focusName); if (focusItem && focusItem.parentNode.parentNode.style.display=='block') { break; } else if (!focusItem) // last element { break; } focusItem=null; index++; } return focusItem; } this.NavPrev = function(index) { var focusItem; while (1) { var focusName = 'Item'+index; focusItem = document.getElementById(focusName); if (focusItem && focusItem.parentNode.parentNode.style.display=='block') { break; } else if (!focusItem) // last element { break; } focusItem=null; index--; } return focusItem; } this.ProcessKeys = function(e) { if (e.type == "keydown") { this.repeatOn = false; this.lastKey = e.keyCode; } else if (e.type == "keypress") { if (!this.repeatOn) { if (this.lastKey) this.repeatOn = true; return false; // ignore first keypress after keydown } } else if (e.type == "keyup") { this.lastKey = 0; this.repeatOn = false; } return this.lastKey!=0; } this.Nav = function(evt,itemIndex) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==13) return true; if (!this.ProcessKeys(e)) return false; if (this.lastKey==38) // Up { var newIndex = itemIndex-1; var focusItem = this.NavPrev(newIndex); if (focusItem) { var child = this.FindChildElement(focusItem.parentNode.parentNode.id); if (child && child.style.display == 'block') // children visible { var n=0; var tmpElem; while (1) // search for last child { tmpElem = document.getElementById('Item'+newIndex+'_c'+n); if (tmpElem) { focusItem = tmpElem; } else // found it! { break; } n++; } } } if (focusItem) { focusItem.focus(); } else // return focus to search field { parent.document.getElementById("MSearchField").focus(); } } else if (this.lastKey==40) // Down { var newIndex = itemIndex+1; var focusItem; var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem && elem.style.display == 'block') // children visible { focusItem = document.getElementById('Item'+itemIndex+'_c0'); } if (!focusItem) focusItem = this.NavNext(newIndex); if (focusItem) focusItem.focus(); } else if (this.lastKey==39) // Right { var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem) elem.style.display = 'block'; } else if (this.lastKey==37) // Left { var item = document.getElementById('Item'+itemIndex); var elem = this.FindChildElement(item.parentNode.parentNode.id); if (elem) elem.style.display = 'none'; } else if (this.lastKey==27) // Escape { parent.searchBox.CloseResultsWindow(); parent.document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { return true; } return false; } this.NavChild = function(evt,itemIndex,childIndex) { var e = (evt) ? evt : window.event; // for IE if (e.keyCode==13) return true; if (!this.ProcessKeys(e)) return false; if (this.lastKey==38) // Up { if (childIndex>0) { var newIndex = childIndex-1; document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); } else // already at first child, jump to parent { document.getElementById('Item'+itemIndex).focus(); } } else if (this.lastKey==40) // Down { var newIndex = childIndex+1; var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); if (!elem) // last child, jump to parent next parent { elem = this.NavNext(itemIndex+1); } if (elem) { elem.focus(); } } else if (this.lastKey==27) // Escape { parent.searchBox.CloseResultsWindow(); parent.document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { return true; } return false; } } function setKeyActions(elem,action) { elem.setAttribute('onkeydown',action); elem.setAttribute('onkeypress',action); elem.setAttribute('onkeyup',action); } function setClassAttr(elem,attr) { elem.setAttribute('class',attr); elem.setAttribute('className',attr); } function createResults() { var results = document.getElementById("SRResults"); for (var e=0; e #include int main(int argc, char **argv) { // Check for a second argument, which should be the sdf file to parse if (argc != 2) { std::cerr << "Usage: dom \n"; return -1; } /// [rootUsage] sdf::Root root; if (root.Load(argv[1])) { root.Print(); std::cerr << "Valid SDF file. Parsed values shown above.\n"; return 0; } /// [rootUsage] std::cerr << "Invalid SDF file.\n"; return -1; } sdformat-6.0.0+dfsg/examples/simple.cc000066400000000000000000000026661323606632500177110ustar00rootroot00000000000000/* * Copyright 2016 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include int main(int argc, char **argv) { // Check for a second argument, which should be the sdf file to parse if (argc != 2) { std::cerr << "Usage: simple \n"; return -1; } // Read an SDF file, and store the result in sdf. auto sdf = sdf::readFile(argv[1]); if (sdf) { // Get a pointer to the model element sdf::ElementPtr model = sdf->Root()->GetElement("model"); // Get the "name" attribute from the model std::string modelName = model->Get("name"); std::cout << "Model name = " << modelName << "\n"; // Get the child "link" element, and its name auto link = model->GetElement("link"); auto linkName = link->Get("name"); std::cout << "Link name = " << linkName << "\n"; return 0; } return -1; } sdformat-6.0.0+dfsg/examples/simple.sdf000066400000000000000000000001511323606632500200630ustar00rootroot00000000000000 " sdformat-6.0.0+dfsg/include/000077500000000000000000000000001323606632500157045ustar00rootroot00000000000000sdformat-6.0.0+dfsg/include/sdf/000077500000000000000000000000001323606632500164605ustar00rootroot00000000000000sdformat-6.0.0+dfsg/include/sdf/Assert.hh000066400000000000000000000023101323606632500202360ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_ASSERT_HH_ #define _SDF_ASSERT_HH_ #include "sdf/Exception.hh" /// \brief This macro define the standard way of launching an exception /// inside SDF. #define SDF_ASSERT(_expr, _msg) ((!!(_expr)) ? ((void)0) : \ throw sdf::AssertionInternalError(__FILE__, \ __LINE__, \ #_expr, \ __FUNCTION__, \ _msg)) #endif sdformat-6.0.0+dfsg/include/sdf/CMakeLists.txt000066400000000000000000000011241323606632500212160ustar00rootroot00000000000000include (${sdf_cmake_dir}/SDFUtils.cmake) set (headers Assert.hh Console.hh Element.hh Error.hh Exception.hh Filesystem.hh Param.hh parser.hh Root.hh SDFImpl.hh Types.hh system_util.hh World.hh ) set (sdf_headers "" CACHE INTERNAL "SDF headers" FORCE) foreach (hdr ${headers}) APPEND_TO_CACHED_STRING(sdf_headers "SDF Headers" "#include \n") endforeach() configure_file (${CMAKE_CURRENT_SOURCE_DIR}/sdf.hh.in ${CMAKE_CURRENT_BINARY_DIR}/sdf.hh) sdf_install_includes("" ${headers} parser_urdf.hh ${CMAKE_CURRENT_BINARY_DIR}/sdf.hh) sdformat-6.0.0+dfsg/include/sdf/Console.hh000066400000000000000000000122101323606632500203770ustar00rootroot00000000000000/* * Copyright 2011 Nate Koenig * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_CONSOLE_HH_ #define _SDF_CONSOLE_HH_ #include #include #include #include #include "sdf/system_util.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::unique_ptr #pragma warning(push) #pragma warning(disable: 4251) #endif namespace sdf { /// \addtogroup sdf SDF /// \{ /// \brief Output a debug message #define sdfdbg (sdf::Console::Instance()->Log("Dbg", __FILE__, __LINE__)) /// \brief Output a message #define sdfmsg (sdf::Console::Instance()->ColorMsg("Msg", \ __FILE__, __LINE__, 32)) /// \brief Output a warning message #define sdfwarn (sdf::Console::Instance()->ColorMsg("Warning", \ __FILE__, __LINE__, 33)) /// \brief Output an error message #define sdferr (sdf::Console::Instance()->ColorMsg("Error", \ __FILE__, __LINE__, 31)) class ConsolePrivate; class Console; /// \def ConsolePtr /// \brief Shared pointer to a Console Element typedef std::shared_ptr ConsolePtr; /// \brief Message, error, warning, and logging functionality class SDFORMAT_VISIBLE Console { /// \brief An ostream-like class that we'll use for logging. public: class SDFORMAT_VISIBLE ConsoleStream { /// \brief Constructor. /// \param[in] _stream Pointer to an output stream operator. Can be /// NULL/nullptr. public: ConsoleStream(std::ostream *_stream) : stream(_stream) {} /// \brief Redirect whatever is passed in to both our ostream /// (if non-NULL) and the log file (if open). /// \param[in] _rhs Content to be logged. /// \return Reference to myself. public: template ConsoleStream &operator<<(const T &_rhs); /// \brief Print a prefix to both terminal and log file. /// \param[in] _lbl Text label /// \param[in] _file File containing the error /// \param[in] _line Line containing the error /// \param[in] _color Color to make the label. Used only on terminal. public: void Prefix(const std::string &_lbl, const std::string &_file, unsigned int _line, int _color); /// \brief The ostream to log to; can be NULL/nullptr. private: std::ostream *stream; }; /// \brief Default constructor private: Console(); /// \brief Destructor public: virtual ~Console(); /// \brief Return an instance to this class. public: static ConsolePtr Instance(); /// \brief Clear out the current console to make room for a new one. public: static void Clear(); /// \brief Set quiet output /// \param[in] q True to prevent warning public: void SetQuiet(bool _q); /// \brief Use this to output a colored message to the terminal /// \param[in] _lbl Text label /// \param[in] _file File containing the error /// \param[in] _line Line containing the error /// \param[in] _color Color to make the label /// \return Reference to an output stream public: ConsoleStream &ColorMsg(const std::string &lbl, const std::string &file, unsigned int line, int color); /// \brief Use this to output a message to a log file /// \return Reference to output stream public: ConsoleStream &Log(const std::string &lbl, const std::string &file, unsigned int line); /// \internal /// \brief Pointer to private data. private: std::unique_ptr dataPtr; }; /// \internal /// \brief Private data for Console class ConsolePrivate { /// \brief Constructor public: ConsolePrivate() : msgStream(&std::cerr), logStream(nullptr) {} /// \brief message stream public: Console::ConsoleStream msgStream; /// \brief log stream public: Console::ConsoleStream logStream; /// \brief logfile stream public: std::ofstream logFileStream; }; /////////////////////////////////////////////// template Console::ConsoleStream &Console::ConsoleStream::operator<<(const T &_rhs) { if (this->stream) { *this->stream << _rhs; } if (Console::Instance()->dataPtr->logFileStream.is_open()) { Console::Instance()->dataPtr->logFileStream << _rhs; Console::Instance()->dataPtr->logFileStream.flush(); } return *this; } /// \} } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/Converter.hh000066400000000000000000000065661323606632500207650ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_CONVERTER_HH_ #define _SDF_CONVERTER_HH_ #include #include #include "sdf/system_util.hh" namespace sdf { /// \brief Convert from one version of SDF to another class SDFORMAT_VISIBLE Converter { /// \brief Convert SDF to the specified version. /// \param[in] _doc SDF xml doc /// \param[in] _toVersion Version number in string format /// \param[in] _quiet False to be more verbose public: static bool Convert(TiXmlDocument *_doc, const std::string &_toVersion, bool _quiet = false); /// \cond /// This is an internal function. /// \brief Generic convert function that converts the SDF based on the /// given Convert file. /// \param[in] _doc SDF xml doc /// \param[in] _convertDoc Convert xml doc public: static void Convert(TiXmlDocument *_doc, TiXmlDocument *_convertDoc); /// \endcond private: static void ConvertImpl(TiXmlElement *_elem, TiXmlElement *_convert); /// \brief Rename an element or attribute. /// \param[in] _elem The element to be renamed, or the element which /// has the attribute to be renamed. /// \param[in] _renameElem A 'convert' element that describes the rename /// operation. private: static void Rename(TiXmlElement *_elem, TiXmlElement *_renameElem); /// \brief Move an element or attribute within a common ancestor element. /// \param[in] _elem Ancestor element of the element or attribute to /// be moved. /// \param[in] _moveElem A 'convert' element that describes the move /// operation. /// \param[in] _copy True to copy the element private: static void Move(TiXmlElement *_elem, TiXmlElement *_moveElem, const bool _copy); /// \brief Add an element or attribute to an element. /// \param[in] _elem The element to receive the value. /// \param[in] _addElem A 'convert' element that describes the add /// operation. private: static void Add(TiXmlElement *_elem, TiXmlElement *_addElem); /// \brief Remove an element. /// \param[in] _elem The element that has the _removeElem child. /// \param[in] _removeElem The element to remove. private: static void Remove(TiXmlElement *_elem, TiXmlElement *_removeElem); private: static const char *GetValue(const char *_valueElem, const char *_valueAttr, TiXmlElement *_elem); private: static void CheckDeprecation(TiXmlElement *_elem, TiXmlElement *_convert); }; } #endif sdformat-6.0.0+dfsg/include/sdf/Element.hh000066400000000000000000000443761323606632500204100ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_ELEMENT_HH_ #define _SDF_ELEMENT_HH_ #include #include #include #include #include "sdf/Param.hh" #include "sdf/system_util.hh" #include "sdf/Types.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::enable_shared_from_this #pragma warning(push) #pragma warning(disable: 4251) #endif /// \ingroup sdf_parser /// \brief namespace for Simulation Description Format parser namespace sdf { class ElementPrivate; class SDFORMAT_VISIBLE Element; /// \def ElementPtr /// \brief Shared pointer to an SDF Element typedef std::shared_ptr ElementPtr; /// \def ElementWeakPtr /// \brief Weak pointer to an SDF Element typedef std::weak_ptr ElementWeakPtr; /// \def ElementPtr_V /// \brief Vector of ElementPtr typedef std::vector ElementPtr_V; /// \addtogroup sdf /// \{ /// \class Element Element.hh sdf/sdf.hh /// \brief SDF Element class class SDFORMAT_VISIBLE Element : public std::enable_shared_from_this { /// \brief Constructor. public: Element(); /// \brief Destructor. public: virtual ~Element(); /// \brief Create a copy of this Element. /// \return A copy of this Element. public: ElementPtr Clone() const; /// \brief Copy values from an Element. /// \param[in] _elem Element to copy value from. public: void Copy(const ElementPtr _elem); /// \brief Get a pointer to this Element's parent. /// \return Pointer to this Element's parent, NULL if there is no /// parent. public: ElementPtr GetParent() const; /// \brief Set the parent of this Element. /// \param[in] _parent Paren for this element. public: void SetParent(const ElementPtr _parent); /// \brief Set the name of the Element. /// \param[in] _name The new name for this Element. public: void SetName(const std::string &_name); /// \brief Get the Element's name. /// \return The name of this Element. public: const std::string &GetName() const; /// \brief Set the requirement type. /// \param[in] _req Requirement type for this element: /// 0: Not required. /// 1: Exactly one element is required. /// +: One or more elements are required. /// *: Zero or more elements are required. public: void SetRequired(const std::string &_req); /// \brief Get the requirement string. /// \return The requirement string. /// \sa Element::SetRequired public: const std::string &GetRequired() const; /// \brief Set whether this element should copy its child elements /// during parsing. /// \param[in] _value True to copy Element's children. public: void SetCopyChildren(bool _value); /// \brief Return true if this Element's child elements should be copied /// during parsing. /// \return True to copy child elements during parsing. public: bool GetCopyChildren() const; /// \brief Set reference SDF element. /// \param[in] _value Name of the reference sdf element. public: void SetReferenceSDF(const std::string &_value); /// \brief Get the name of the reference SDF element. /// \return Name of the reference SDF element. public: std::string ReferenceSDF() const; /// \brief Output Element's description to stdout. /// \param[in] _prefix String value to prefix to the output. public: void PrintDescription(const std::string &_prefix) const; /// \brief Output Element's values to stdout. /// \param[in] _prefix String value to prefix to the output. public: void PrintValues(std::string _prefix) const; /// \brief Helper function for SDF::PrintDoc /// /// This generates the SDF html documentation. /// \param[out] _html Accumulated HTML for output. /// \param[in] _spacing Amount of spacing for this element. /// \param[in] _index Unique index for this element. public: void PrintDocLeftPane(std::string &_html, int _spacing, int &_index) const; /// \brief Helper function for SDF::PrintDoc /// /// This generates the SDF html documentation. /// \param[out] _html Accumulated HTML for output. /// \param[in] _spacing Amount of spacing for this element. public: void PrintDocRightPane(std::string &_html, int _spacing, int &_index) const; /// \brief Convert the element values to a string representation. /// \param[in] _prefix String value to prefix to the output. /// \return The string representation. public: std::string ToString(const std::string &_prefix) const; /// \brief Add an attribute value. /// \param[in] _key Key value. /// \param[in] _type Type of data the attribute will hold. /// \param[in] _defaultValue Default value for the attribute. /// \param[in] _required Requirement string. \as Element::SetRequired. /// \param[in] _description A text description of the attribute. /// \throws sdf::AssertionInternalError if an invalid type is given. public: void AddAttribute(const std::string &_key, const std::string &_type, const std::string &_defaultvalue, bool _required, const std::string &_description=""); /// \brief Add a value to this Element. /// \param[in] _type Type of data the attribute will hold. /// \param[in] _defaultValue Default value for the attribute. /// \param[in] _required Requirement string. \as Element::SetRequired. /// \param[in] _description A text description of the attribute. /// \throws sdf::AssertionInternalError if an invalid type is given. public: void AddValue(const std::string &_type, const std::string &_defaultValue, bool _required, const std::string &_description=""); /// \brief Get the param of an attribute. /// \param[in] _key the name of the attribute. /// \return The parameter attribute value. NULL if the key is invalid. public: ParamPtr GetAttribute(const std::string &_key) const; /// \brief Get the number of attributes. /// \return The number of attributes. public: size_t GetAttributeCount() const; /// \brief Get an attribute using an index. /// \param[in] _index the index of the attribute to get. /// \return A Param pointer to the attribute. public: ParamPtr GetAttribute(unsigned int _index) const; /// \brief Get the number of element descriptions. /// \return The number of element descriptions. public: size_t GetElementDescriptionCount() const; /// \brief Get an element description using an index /// \param[in] _index the index of the element description to get. /// \return An Element pointer to the found element. public: ElementPtr GetElementDescription(unsigned int _index) const; /// \brief Get an element description using a key /// \param[in] _key the key to use to find the element. /// \return An Element pointer to the found element. public: ElementPtr GetElementDescription(const std::string &_key) const; /// \brief Return true if an element description exists. /// \param[in] _name the name of the element to find. /// \return True if the element description exists, false otherwise. public: bool HasElementDescription(const std::string &_name) const; /// \brief Return true if an attribute exists. /// \param[in] _key the key to use to find the attribute. /// \return True if the attribute exists, false otherwise. public: bool HasAttribute(const std::string &_key) const; /// \brief Return true if the attribute was set (i.e. not default value) /// \param[in] _key the key to use to find the attribute. /// \return True if the attribute is set, false otherwise. public: bool GetAttributeSet(const std::string &_key) const; /// \brief Get the param of the elements value /// return A Param pointer to the value of this element. public: ParamPtr GetValue() const; /// \brief Get the element value/attribute as a boost::any. /// \param[in] _key The key of the attribute. If empty, get the value of /// the element. Defaults to empty. /// \return The element as a boost::any. public: boost::any GetAny(const std::string &_key = "") const; /// \brief Get the value of a key. This function assumes the _key /// exists. /// \param[in] _key the name of a child attribute or element. /// \return The value of the _key. /// \sa std::pair Get(const std::string &_key, /// const T &_defaultValue) public: template T Get(const std::string &_key = "") const; /// \brief Get the value of a key. /// \param[in] _key the name of a child attribute or element. /// \param[in] _defaultValue a default value to use if _key is not /// found. /// \return A pair where the first element is the value of _key, and the /// second element is true when the _key was found and false otherwise. public: template std::pair Get(const std::string &_key, const T &_defaultValue) const; /// \brief Get the value of a key. /// \param[in] _key the name of a child attribute or element. /// \param[out] _param the parameter output /// \param[in] _defaultValue a default value to use if _key is not /// found. /// \return True when the _key was found and false otherwise. public: template bool Get(const std::string &_key, T &_param, const T &_defaultValue) const; /// \brief Set the value of this element. /// \param[in] _value the value to set. /// \return True if the value was successfully set, false otherwise. public: template bool Set(const T &_value); /// \brief Return true if the named element exists. /// \param[in] _name the name of the element to look for. /// \return True if the named element was found, false otherwise. public: bool HasElement(const std::string &_name) const; /// \brief Get the first child element. /// \return A smart pointer to the first child of this element, or /// sdf::ElementPtr(nullptr) if there are no children. public: ElementPtr GetFirstElement() const; /// \brief Get the next sibling of this element. /// \param[in] _name if given then filter siblings by their xml tag. /// \remarks This function does not alter or store any state /// Repeated calls to "GetNextElement()" with the same string will /// always return a pointer to the same element. /// \return A pointer to the next element if it exists, /// sdf::ElementPtr(nullptr) otherwise. /// /// This can be used in combination with GetFirstElement() to walk the SDF /// tree. First call parent->GetFirstElement() to get the first child. Call /// child = child->GetNextElement() to iterate through the children. public: ElementPtr GetNextElement(const std::string &_name = "") const; /// \brief Return a pointer to the child element with the provided name. /// /// A new child element, with the provided name, is added to this element /// if there is no existing child element. /// \remarks If there are multiple elements with the given tag, it returns /// the first one. /// \param[in] _name Name of the child element to retreive. /// \return Pointer to the existing child element, or a new child /// element if an existing child element did not exist. public: ElementPtr GetElement(const std::string &_name); /// \brief Add a named element. /// \param[in] _name the name of the element to add. /// \return A pointer to the newly created Element object. public: ElementPtr AddElement(const std::string &_name); /// \brief Add an element object. /// \param[in] _elem the element object to add. public: void InsertElement(ElementPtr _elem); /// \brief Remove this element from its parent. public: void RemoveFromParent(); /// \brief Remove a child element. /// \param[in] _child Pointer to the child to remove. public: void RemoveChild(ElementPtr _child); /// \brief Remove all child elements. public: void ClearElements(); /// \brief Call the Update() callback on each element, as well as /// the embedded Param. public: void Update(); /// \brief Call reset on each element and element description /// before deleting all of them. Also clear out the /// embedded Param. public: void Reset(); /// \brief Set the include filename to the passed in filename. /// \param[in] _filename the filename to set the include filename to. public: void SetInclude(const std::string &_filename); /// \brief Get the include filename. /// \return The include filename. public: std::string GetInclude() const; /// \brief Get a text description of the element. /// \return The text description of the element. public: std::string GetDescription() const; /// \brief Set a text description for the element. /// \param[in] _desc the text description to set for the element. public: void SetDescription(const std::string &_desc); /// \brief Add a new element description /// \param[in] _elem the Element object to add to the descriptions. public: void AddElementDescription(ElementPtr _elem); /// \brief Get a pointer to the named element. /// \param[in] _name the name of the element to look for. /// \return A pointer to the named element if found, nullptr otherwise. public: ElementPtr GetElementImpl(const std::string &_name) const; /// \brief Generate a string (XML) representation of this object. /// \param[in] _prefix arbitrary prefix to put on the string. /// \param[out] _out the std::ostreamstream to write output to. private: void ToString(const std::string &_prefix, std::ostringstream &_out) const; /// \brief Generate a string (XML) representation of this object. /// \param[in] _prefix arbitrary prefix to put on the string. /// \param[out] _out the std::ostreamstream to write output to. private: void PrintValuesImpl(const std::string &_prefix, std::ostringstream &_out) const; /// \brief Create a new Param object and return it. /// \param[in] _key Key for the parameter. /// \param[in] _type String name for the value type (double, /// int,...). /// \param[in] _defaultValue Default value. /// \param[in] _required True if the parameter is required to be set. /// \param[in] _description Description of the parameter. /// \return A pointer to the new Param object. private: ParamPtr CreateParam(const std::string &_key, const std::string &_type, const std::string &_defaultValue, bool _required, const std::string &_description=""); /// \brief Private data pointer private: std::unique_ptr dataPtr; }; /// \internal /// \brief Private data for Element class ElementPrivate { /// \brief Element name public: std::string name; /// \brief True if element is required public: std::string required; /// \brief Element description public: std::string description; /// \brief True if element's children should be copied. public: bool copyChildren; /// \brief Element's parent public: ElementWeakPtr parent; // Attributes of this element public: Param_V attributes; // Value of this element public: ParamPtr value; // The existing child elements public: ElementPtr_V elements; // The possible child elements public: ElementPtr_V elementDescriptions; /// name of the include file that was used to create this element public: std::string includeFilename; /// \brief Name of reference sdf. public: std::string referenceSDF; }; /////////////////////////////////////////////// template T Element::Get(const std::string &_key) const { T result = T(); std::pair ret = this->Get(_key, result); return ret.first; } /////////////////////////////////////////////// template bool Element::Get(const std::string &_key, T &_param, const T &_defaultValue) const { std::pair ret = this->Get(_key, _defaultValue); _param = ret.first; return ret.second; } /////////////////////////////////////////////// template std::pair Element::Get(const std::string &_key, const T &_defaultValue) const { std::pair result(_defaultValue, true); if (_key.empty() && this->dataPtr->value) { this->dataPtr->value->Get(result.first); } else if (!_key.empty()) { ParamPtr param = this->GetAttribute(_key); if (param) { param->Get(result.first); } else if (this->HasElement(_key)) { result.first = this->GetElementImpl(_key)->Get(); } else if (this->HasElementDescription(_key)) { result.first = this->GetElementDescription(_key)->Get(); } else { result.second = false; } } else { result.second = false; } return result; } /////////////////////////////////////////////// template bool Element::Set(const T &_value) { if (this->dataPtr->value) { this->dataPtr->value->Set(_value); return true; } return false; } /// \} } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/Error.hh000066400000000000000000000110571323606632500200760ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_ERROR_HH_ #define SDF_ERROR_HH_ #include #include #include "sdf/system_util.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::string #pragma warning(push) #pragma warning(disable: 4251) #endif namespace sdf { /// \enum ErrorCode /// \brief Set of error codes. Usually one or more errors are returned in /// an Errors vector. The collection of Errors should be take as a whole, /// where an error toward the beginning of the vector can inform errors /// toward the end of the vector. /// \sa Errors enum class ErrorCode { // \brief No error NONE = 0, /// \brief Indicates that reading an SDF file failed. FILE_READ, /// \brief A duplicate name was found for an element where unique names /// are required. DUPLICATE_NAME, /// \brief Indicates that a required SDF attribute is missing. ATTRIBUTE_MISSING, /// \brief This error indicates that an SDF attribute is invalid. ATTRIBUTE_INVALID, /// \brief This error indicates that an SDF attribute is deprecated. ATTRIBUTE_DEPRECATED, /// \brief Indicates that a required SDF element is missing. ELEMENT_MISSING, /// \brief This error indicates that an SDF element is invalid. ELEMENT_INVALID, /// \brief This error indicates that an SDF element is deprecated. ELEMENT_DEPRECATED, /// \brief Indicates that an incorrect SDF element type was /// encountered. This error is used when an element of certain type is /// expected, and an element of a different type was received. ELEMENT_INCORRECT_TYPE, /// \brief A URI is invalid. URI_INVALID, /// \brief A error occured while trying to resolve a URI. URI_LOOKUP, /// \brief A filesystem directory does not exist. DIRECTORY_NONEXISTANT, }; class SDFORMAT_VISIBLE Error { /// \brief default constructor public: Error() = default; /// \brief Constructor. /// \param[in] _code The error code. /// \param[in] _message A description of the error. /// \sa ErrorCode. public: Error(const ErrorCode _code, const std::string &_message); /// \brief Get the error code. /// \return An error code. /// \sa ErrorCode. public: ErrorCode Code() const; /// \brief Get the error message, which is a description of the error. /// \return Error message. public: std::string Message() const; /// \brief Safe bool conversion. /// \return True if this Error's Code() != NONE. In otherwords, this is /// true when there is an error. public: explicit operator bool() const; /// \brief Compare this Error to a boolean value. /// \return True if the boolean evaluation of this Error equals _value. /// If _value == false, then true is returned when this Error's Code() is /// equal to NONE and false is returned otherwise. If _value == true, /// then true is returned when this Error's Code() is not equal to NONE /// and false is returned otherwise. /// \sa explicit operator bool() const public: bool operator==(const bool _value) const; /// \brief Output operator for an error. /// \param[in,out] _out The output stream. /// \param[in] _err The error to output. /// \return Reference to the given output stream public: friend std::ostream &operator<<(std::ostream &_out, const sdf::Error &_err) { _out << "Error Code: " << static_cast::type>(_err.Code()) << " Msg: " << _err.Message(); return _out; } /// \brief The error code value. private: ErrorCode code = ErrorCode::NONE; #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::string #pragma warning(push) #pragma warning(disable: 4251) #endif /// \brief Description of the error. private: std::string message = ""; #ifdef _WIN32 #pragma warning(pop) #endif }; } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/Exception.hh000066400000000000000000000110141323606632500207340ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_EXCEPTION_HH_ #define _SDF_EXCEPTION_HH_ #include #include #include #include #include #include "sdf/system_util.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::unique_ptr #pragma warning(push) #pragma warning(disable: 4251) #endif namespace sdf { /// \addtogroup sdf /// \{ /// \brief This macro logs an error to the throw stream and throws /// an exception that contains the file name and line number. #define sdfthrow(msg) {std::ostringstream throwStream;\ throwStream << msg << std::endl << std::flush;\ throw sdf::Exception(__FILE__, __LINE__, throwStream.str()); } class ExceptionPrivate; /// \class Exception Exception.hh common/common.hh /// \brief Class for generating exceptions class SDFORMAT_VISIBLE Exception { /// \brief Constructor public: Exception(); /// \brief Default constructor /// \param[in] _file File name /// \param[in] _line Line number where the error occurred /// \param[in] _msg Error message public: Exception(const char *_file, std::int64_t _line, std::string _msg); /// \brief Copy constructor /// \param[in] _e Exception to copy. public: Exception(const Exception &_e); /// \brief Destructor public: virtual ~Exception(); /// \brief Return the error function /// \return The error function name public: std::string GetErrorFile() const; /// \brief Return the error string /// \return The error string public: std::string GetErrorStr() const; /// \brief Print the exception to std out. public: void Print() const; /// \brief stream insertion operator for Gazebo Error /// \param[in] _out the output stream /// \param[in] _err the exception public: friend std::ostream &operator<<(std::ostream& _out, const sdf::Exception &_err) { return _out << _err.GetErrorStr(); } /// \brief Private data pointer. private: std::unique_ptr dataPtr; }; /// \class InternalError Exception.hh common/common.hh /// \brief Class for generating Internal Gazebo Errors: /// those errors which should never happend and /// represent programming bugs. class SDFORMAT_VISIBLE InternalError : public Exception { /// \brief Constructor public: InternalError(); /// \brief Default constructor /// \param[in] _file File name /// \param[in] _line Line number where the error occurred /// \param[in] _msg Error message public: InternalError(const char *_file, std::int64_t _line, const std::string _msg); /// \brief Destructor public: virtual ~InternalError(); }; /// \class AssertionInternalError Exception.hh common/common.hh /// \brief Class for generating Exceptions which come from /// sdf assertions. They include information about the /// assertion expression violated, function where problem /// appeared and assertion debug message. class SDFORMAT_VISIBLE AssertionInternalError : public InternalError { /// \brief Constructor for assertions /// \param[in] _file File name /// \param[in] _line Line number where the error occurred /// \param[in] _expr Assertion expression failed resulting in an /// internal error /// \param[in] _function Function where assertion failed /// \param[in] _msg Function where assertion failed public: AssertionInternalError(const char *_file, std::int64_t _line, const std::string _expr, const std::string _function, const std::string _msg = ""); /// \brief Destructor public: virtual ~AssertionInternalError(); }; /// \} } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/ExceptionPrivate.hh000066400000000000000000000020231323606632500222670ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_EXCEPTION_PRIVATE_HH_ #define _SDF_EXCEPTION_PRIVATE_HH_ #include #include namespace sdf { /// \internal /// \brief Private data for Exception class ExceptionPrivate { /// \brief The error function public: std::string file; /// \brief Line the error occured on public: std::int64_t line; /// \brief The error string public: std::string str; }; } #endif sdformat-6.0.0+dfsg/include/sdf/Filesystem.hh000066400000000000000000000112041323606632500211230ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_FILESYSTEM_HH_ #define _SDF_FILESYSTEM_HH_ #include #include #include "sdf/system_util.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::unique_ptr #pragma warning(push) #pragma warning(disable: 4251) #endif namespace sdf { namespace filesystem { /// \brief Determine whether the given path exists on the filesystem. /// \param[in] _path The path to check for existence /// \return True if the path exists on the filesystem, false otherwise. SDFORMAT_VISIBLE bool exists(const std::string &_path); /// \brief Determine whether the given path is a directory. /// \param[in] _path The path to check /// \return True if given path exists and is a directory, false otherwise. SDFORMAT_VISIBLE bool is_directory(const std::string &_path); /// \brief Create a new directory on the filesystem. Intermediate /// directories must already exist. /// \param[in] _path The new directory path to create /// \return True if directory creation was successful, false otherwise. SDFORMAT_VISIBLE bool create_directory(const std::string &_path); // The below is C++ variadic template magic to allow an append // method that takes 1-n number of arguments to append together. /// \brief Append the preferred path separator character for this platform /// onto the passed-in string. /// \param[in] _s The path to start with. /// \return The original path with the platform path separator appended. SDFORMAT_VISIBLE std::string const separator(std::string const &_s); /// \brief Append one or more additional path elements to the first /// passed in argument. /// \param[in] args The paths to append together /// \return A new string with the paths appended together. template std::string append(Args const &... args) { std::string result; int unpack[] { 0, (result += separator(args), 0)...}; static_cast(unpack); return result.substr(0, result.length() - 1); } /// \brief Get the current working path. /// \return Current working path if successful, the empty path on error. SDFORMAT_VISIBLE std::string current_path(); /// \brief Given a path, get just the basename portion. /// \param[in] _path The full path. /// \return A new string with just the basename portion of the path. SDFORMAT_VISIBLE std::string basename(const std::string &_path); /// \internal class DirIterPrivate; /// \class DirIter Filesystem.hh /// \brief A class for iterating over all items in a directory. class SDFORMAT_VISIBLE DirIter { /// \brief Constructor. /// \param[in] _in Directory to iterate over. public: explicit DirIter(const std::string &_in); /// \brief Constructor for end element. public: DirIter(); /// \brief Dereference operator; returns current directory record. /// \return A string representing the entire path of the directory record. public: std::string operator*() const; /// \brief Pre-increment operator; moves to next directory record. /// \return This iterator. public: const DirIter& operator++(); /// \brief Comparison operator to see if this iterator is at the /// same point as another iterator. /// \param[in] _other The other iterator to compare against. /// \return true if the iterators are equal, false otherwise. public: bool operator!=(const DirIter &_other) const; /// \brief Destructor public: ~DirIter(); /// \brief Move to the next directory record, skipping . and .. records. private: void next(); /// \brief Set the internal variable to the empty string. private: void set_internal_empty(); /// \brief Close an open directory handle. private: void close_handle(); /// \brief Private data. private: std::unique_ptr dataPtr; }; } } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/Param.hh000066400000000000000000000244351323606632500200510ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDFORMAT_PARAM_HH_ #define SDFORMAT_PARAM_HH_ // See: https://bugreports.qt-project.org/browse/QTBUG-22829 #ifndef Q_MOC_RUN #include #include #endif #include #include #include #include #include #include #include #include #include #include "sdf/Console.hh" #include "sdf/system_util.hh" #include "sdf/Types.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::unique_ptr #pragma warning(push) #pragma warning(disable: 4251) #endif namespace sdf { class SDFORMAT_VISIBLE Param; /// \def ParamPtr /// \brief Shared pointer to a Param typedef std::shared_ptr ParamPtr; /// \def Param_V /// \brief vector of shared pointers to a Param typedef std::vector Param_V; /// \internal class ParamPrivate; /// \class Param Param.hh sdf/sdf.hh /// \brief A parameter class class SDFORMAT_VISIBLE Param { /// \brief Constructor. /// \param[in] _key Key for the parameter. /// \param[in] _typeName String name for the value type (double, /// int,...). /// \param[in] _default Default value. /// \param[in] _required True if the parameter is required to be set. /// \param[in] _description Description of the parameter. /// \throws sdf::AssertionInternalError if an invalid type is given. public: Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_description = ""); /// \brief Destructor public: virtual ~Param(); /// \brief Get the value as a string. /// \return String containing the value of the parameter. public: std::string GetAsString() const; /// \brief Get the default value as a string. /// \return String containing the default value of the parameter. public: std::string GetDefaultAsString() const; /// \brief Set the parameter value from a string. /// \param[in] _value New value for the parameter in string form. public: bool SetFromString(const std::string &_value); /// \brief Reset the parameter to the default value. public: void Reset(); /// \brief Get the key value. /// \return The key. public: const std::string &GetKey() const; /// \brief Return true if the param is a particular type /// \return True if the type held by this Param matches the Type /// template parameter. public: template bool IsType() const; /// \brief Get the type name value. /// \return The type name. public: const std::string &GetTypeName() const; /// \brief Return whether the parameter is required. /// \return True if the parameter is required. public: bool GetRequired() const; /// \brief Return true if the parameter has been set. /// \return True if the parameter has been set. public: bool GetSet() const; /// \brief Clone the parameter. /// \return A new parameter that is the clone of this. public: ParamPtr Clone() const; /// \brief Set the update function. The updateFunc will be used to /// set the parameter's value when Param::Update is called. /// \param[in] _updateFunc Function pointer to an update function. public: template void SetUpdateFunc(T _updateFunc); /// \brief Set the parameter's value using the updateFunc. /// \sa Param::SetUpdateFunc public: void Update(); /// \brief Set the parameter's value. /// /// The passed in value value must have an input and output stream operator. /// \param[in] _value The value to set the parameter to. /// \return True if the value was successfully set. public: template bool Set(const T &_value); /// \brief Get the value of the parameter as a boost::any. /// \param[out] _anyVal The boost::any object to set. /// \return True if successfully fetched _anyVal, false otherwise. public: bool GetAny(boost::any &_anyVal) const; /// \brief Get the value of the parameter. /// \param[out] _value The value of the parameter. /// \return True if parameter was successfully cast to the value type /// passed in. public: template bool Get(T &_value) const; /// \brief Get the default value of the parameter. /// \param[out] _value The default value of the parameter. /// \return True if parameter was successfully cast to the value type /// passed in. public: template bool GetDefault(T &_value) const; /// \brief Equal operator. Set's the value and default value from the /// provided Param. /// \param[in] _param The parameter to set values from. /// \return *This public: Param &operator=(const Param &_param); /// \brief Set the description of the parameter. /// \param[in] _desc New description for the parameter. public: void SetDescription(const std::string &_desc); /// \brief Get the description of the parameter. /// \return The description of the parameter. public: std::string GetDescription() const; /// \brief Ostream operator. Outputs the parameter's value. /// \param[in] _out Output stream. /// \param[in] _p The parameter to output. /// \return The output stream. public: friend std::ostream &operator<<(std::ostream &_out, const Param &_p) { _out << _p.GetAsString(); return _out; } /// \brief Private method to set the Element from a passed-in string. /// \param[in] _value Value to set the parameter to. private: bool ValueFromString(const std::string &_value); /// \brief Private data private: std::unique_ptr dataPtr; }; /// \internal /// \brief Private data for the param class class ParamPrivate { /// \brief Key value public: std::string key; /// \brief True if the parameter is required. public: bool required; /// \brief True if the parameter is set. public: bool set; //// \brief Name of the type. public: std::string typeName; /// \brief Description of the parameter. public: std::string description; /// \brief Update function pointer. public: std::function updateFunc; /// \def ParamVariant /// \brief Variant type def. public: typedef boost::variant ParamVariant; /// \brief This parameter's value public: ParamVariant value; /// \brief This parameter's default value public: ParamVariant defaultValue; }; /////////////////////////////////////////////// template void Param::SetUpdateFunc(T _updateFunc) { this->dataPtr->updateFunc = _updateFunc; } /////////////////////////////////////////////// template bool Param::Set(const T &_value) { try { std::stringstream ss; ss << _value; return this->SetFromString(ss.str()); } catch(...) { sdferr << "Unable to set parameter[" << this->dataPtr->key << "]." << "Type used must have a stream input and output operator," << "which allows proper functioning of Param.\n"; return false; } } /////////////////////////////////////////////// template bool Param::Get(T &_value) const { try { if (typeid(T) == typeid(bool) && this->dataPtr->typeName == "string") { std::stringstream ss; ss << this->dataPtr->value; std::string strValue; ss >> strValue; std::transform(strValue.begin(), strValue.end(), strValue.begin(), ::tolower); std::stringstream tmp; if (strValue == "true" || strValue == "1") { tmp << "1"; } else { tmp << "0"; } tmp >> _value; } else if (typeid(T) == this->dataPtr->value.type()) { #if BOOST_VERSION < 105800 _value = boost::get(this->dataPtr->value); #else _value = boost::relaxed_get(this->dataPtr->value); #endif } else { std::stringstream ss; ss << this->dataPtr->value; ss >> _value; } } catch(...) { sdferr << "Unable to convert parameter[" << this->dataPtr->key << "] " << "whose type is[" << this->dataPtr->typeName << "], to " << "type[" << typeid(T).name() << "]\n"; return false; } return true; } /////////////////////////////////////////////// template bool Param::GetDefault(T &_value) const { std::stringstream ss; try { ss << this->dataPtr->defaultValue; ss >> _value; } catch(...) { sdferr << "Unable to convert parameter[" << this->dataPtr->key << "] " << "whose type is[" << this->dataPtr->typeName << "], to " << "type[" << typeid(T).name() << "]\n"; return false; } return true; } /////////////////////////////////////////////// template bool Param::IsType() const { return this->dataPtr->value.type() == typeid(Type); } } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/Root.hh000066400000000000000000000054301323606632500177260ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_ROOT_HH_ #define SDF_ROOT_HH_ #include #include "sdf/Types.hh" #include "sdf/system_util.hh" namespace sdf { // Forward declarations. class RootPrivate; class World; /// \brief Root class that acts as an entry point to the SDF document /// model. /// /// # Usage /// /// In this example, a root object is loaded from a file specified in /// the first command line argument to a program. /// /// \snippet examples/dom.cc rootUsage /// class SDFORMAT_VISIBLE Root { /// \brief Default constructor public: Root(); /// \brief Destructor public: ~Root(); /// \brief Parse the given SDF file, and generate objects based on types /// specified in the SDF file. /// \param[in] _filename Name of the SDF file to parse. /// \return Errors, which is a vector of Error objects. Each Error includes /// an error code and message. An empty vector indicates no error. public: Errors Load(const std::string &_filename); /// \brief Get the SDF version specified in the parsed file or SDF /// pointer. /// \return SDF version string. /// \sa void SetVersion(const std::string &_version) public: std::string Version() const; /// \brief Set the SDF version string. /// \param[in] _version The new SDF version. /// \sa std::string Version() public: void SetVersion(const std::string &_version); /// \brief Get the number of worlds. /// \return Number of worlds contained in this Root object. public: uint64_t WorldCount() const; /// \brief Get a world based on an index. /// \param[in] _index Index of the world. The index should be in the /// range [0..WorldCount()). /// \return Pointer to the world. Nullptr if the index does not exist. /// \sa uint64_t WorldCount() const public: const World *WorldByIndex(const uint64_t _index) const; /// \brief Get whether a world name exists. /// \param[in] _name Name of the world to check. /// \return True if there exists a world with the given name. public: bool WorldNameExists(const std::string &_name) const; /// \brief Private data pointer private: RootPrivate *dataPtr = nullptr; }; } #endif sdformat-6.0.0+dfsg/include/sdf/SDFExtension.hh000066400000000000000000000067551323606632500213270ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDFORMAT_SDFEXTENSION_HH_ #define _SDFORMAT_SDFEXTENSION_HH_ #include #include #include #include #include #include "sdf/Types.hh" namespace sdf { /// \internal /// \brief A class for holding sdf extension elements in urdf class SDFExtension { /// \brief Constructor public: SDFExtension(); /// \brief Copy constructor /// \param[in] _ge SDFExtension to copy. public: SDFExtension(const SDFExtension &_ge); /// \brief Destructor public: virtual ~SDFExtension() = default; // for reducing fixed joints and removing links public: std::string oldLinkName; public: ignition::math::Pose3d reductionTransform; // visual material public: std::string material; /// \brief blobs of xml to be copied into the visual sdf element public: std::vector > visual_blobs; /// \brief blobs of xml to be copied into the collision sdf element /// An example might be: /// /// /// 10 /// /// /// /// 1e+06 /// 100 /// 100 /// 0.001 /// /// /// /// /// 1 /// 1 /// /// /// /// /// /// where all the contents of `` element is copied into the /// resulting collision sdf. public: std::vector > collision_blobs; // body, default off public: bool setStaticFlag; public: bool gravity; public: bool isDampingFactor; public: double dampingFactor; public: bool isMaxContacts; public: int maxContacts; public: bool isMaxVel; public: double maxVel; public: bool isMinDepth; public: double minDepth; public: bool isSelfCollide; public: bool selfCollide; // geom, contact dynamics public: bool isMu1, isMu2, isKp, isKd; public: double mu1, mu2, kp, kd; public: std::string fdir1; public: bool isLaserRetro; public: double laserRetro; // joint, joint limit dynamics public: bool isStopCfm, isStopErp, isFudgeFactor; public: double stopCfm, stopErp, fudgeFactor; public: bool isSpringReference, isSpringStiffness; public: double springReference, springStiffness; public: bool isProvideFeedback; public: bool provideFeedback; public: bool isImplicitSpringDamper; public: bool implicitSpringDamper; // blobs into body or robot public: std::vector > blobs; friend class SDFORMAT_VISIBLE URDF2SDF; }; } #endif sdformat-6.0.0+dfsg/include/sdf/SDFImpl.hh000066400000000000000000000076371323606632500202540ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDFIMPL_HH_ #define _SDFIMPL_HH_ #include #include #include #include "sdf/Param.hh" #include "sdf/Element.hh" #include "sdf/system_util.hh" #include "sdf/Types.hh" #ifdef _WIN32 // Disable warning C4251 which is triggered by // std::unique_ptr #pragma warning(push) #pragma warning(disable: 4251) #endif /// \ingroup sdf_parser /// \brief namespace for Simulation Description Format parser namespace sdf { class SDFORMAT_VISIBLE SDF; /// \def SDFPtr /// \brief Shared pointer to SDF typedef std::shared_ptr SDFPtr; /// \addtogroup sdf /// \{ /// \brief Find the absolute path of a file. /// \param[in] _filename Name of the file to find. /// \param[in] _searchLocalPath True to search for the file in the current /// working directory. /// \param[in] _useCallback True to find a file based on a registered /// callback if the file is not found via the normal mechanism. /// \return File's full path. SDFORMAT_VISIBLE std::string findFile(const std::string &_filename, bool _searchLocalPath = true, bool _useCallback = false); /// \brief Associate paths to a URI. /// Example paramters: "model://", "/usr/share/models:~/.gazebo/models" /// \param[in] _uri URI that will be mapped to _path /// \param[in] _path Colon separated set of paths. SDFORMAT_VISIBLE void addURIPath(const std::string &_uri, const std::string &_path); /// \brief Set the callback to use when SDF can't find a file. /// The callback should return a complete path to the requested file, or /// and empty string if the file was not found in the callback. /// \param[in] _cb The callback function. SDFORMAT_VISIBLE void setFindCallback(std::function _cb); class SDFPrivate; /// \brief Base SDF class class SDFORMAT_VISIBLE SDF { public: SDF(); /// \brief Destructor public: ~SDF(); public: void PrintDescription(); public: void PrintValues(); public: void PrintDoc(); public: void Write(const std::string &_filename); public: std::string ToString() const; /// \brief Set SDF values from a string public: void SetFromString(const std::string &_sdfData); /// \brief Get a pointer to the root element /// \return Pointer to the root element public: ElementPtr Root() const; /// \brief Set the root pointer /// \param[in] _root Root element public: void Root(const ElementPtr _root); /// \brief Get the version /// \return The version as a string public: static std::string Version(); /// \brief Set the version string /// \param[in] _version SDF version string. public: static void Version(const std::string &_version); /// \brief wraps the SDF element into a root element with the version info. /// \param[in] _sdf the sdf element. Will be cloned by this function. /// \return a wrapped clone of the SDF element public: static ElementPtr WrapInRoot(const ElementPtr &_sdf); /// \internal /// \brief Pointer to private data. private: std::unique_ptr dataPtr; /// \brief The SDF version. Set to SDF_VERSION by default, or through /// the Version function at runtime. private: static std::string version; }; /// \} } #ifdef _WIN32 #pragma warning(pop) #endif #endif sdformat-6.0.0+dfsg/include/sdf/SDFImplPrivate.hh000066400000000000000000000021071323606632500215720ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDFIMPLPRIVATE_HH_ #define _SDFIMPLPRIVATE_HH_ #include "sdf/Types.hh" /// \ingroup sdf_parser /// \brief namespace for Simulation Description Format parser namespace sdf { /// \brief Private data for base SDF class class SDFPrivate { public: SDFPrivate() : root(new Element) { }; /// \brief Store the root element. /// \sa ElementPtr Root() /// \sa void Root(const ElementPtr _root) public: ElementPtr root; }; /// \} } #endif sdformat-6.0.0+dfsg/include/sdf/Types.hh000066400000000000000000000127711323606632500201150ustar00rootroot00000000000000/* * Copyright 2011 Nate Koenig * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDFORMAT_TYPES_HH_ #define SDFORMAT_TYPES_HH_ #include #include #include #include #include #include #include "sdf/system_util.hh" #include "sdf/Error.hh" #if defined(__GNUC__) #define SDF_DEPRECATED(version) __attribute__((deprecated)) #define SDF_FORCEINLINE __attribute__((always_inline)) #elif defined(MSVC) #define SDF_DEPRECATED(version) #define SDF_FORCEINLINE __forceinline #else #define SDF_DEPRECATED(version) #define SDF_FORCEINLINE #endif namespace sdf { /// \brief Split a string using the delimiter in splitter. /// \param[in] str The string to split. /// \param[in] splitter The delimiter to use. /// \return A vector of strings containing the split tokens. SDFORMAT_VISIBLE std::vector split(const std::string &_str, const std::string &_splitter); /// \brief Trim leading and trailing whitespace from a string. /// \param[in] _in The string to trim. /// \return A string containing the trimmed value. SDFORMAT_VISIBLE std::string trim(const char *_in); /// \brief check if two values are equal, within a tolerance /// \param[in] _a the first value /// \param[in] _b the second value /// \param[in] _epsilon the tolerance template inline bool equal(const T &_a, const T &_b, const T &_epsilon = 1e-6f) { return std::fabs(_a - _b) <= _epsilon; } /// \brief A vector of Error. using Errors = std::vector; /// \brief Defines a color class SDFORMAT_VISIBLE Color { /// \brief Constructor /// \param[in] _r Red value (range 0 to 1) /// \param[in] _g Green value (range 0 to 1 /// \param[in] _b Blue value (range 0 to 1 /// \param[in] _a Alpha value (0=transparent, 1=opaque) /// \deprecated Use ignition::math::Color public: Color(float _r = 0.0f, float _g = 0.0f, float _b = 0.0f, float _a = 1.0f) SDF_DEPRECATED(6.0) : r(_r), g(_g), b(_b), a(_a) {} /// \brief Stream insertion operator /// \param[in] _out the output stream /// \param[in] _pt the color /// \return the output stream public: friend std::ostream &operator<< (std::ostream &_out, const Color &_pt) { _out << _pt.r << " " << _pt.g << " " << _pt.b << " " << _pt.a; return _out; } /// \brief Stream insertion operator /// \param[in] _in the input stream /// \param[in] _pt public: friend std::istream &operator>> (std::istream &_in, Color &_pt) { // Skip white spaces _in.setf(std::ios_base::skipws); _in >> _pt.r >> _pt.g >> _pt.b >> _pt.a; return _in; } /// \brief Equality operator /// \param[in] _clr The color to check for equality /// \return True if the this color equals _clf public: bool operator ==(const Color &_clr) const { return equal(this->r, _clr.r) && equal(this->g, _clr.g) && equal(this->b, _clr.b) && equal(this->a, _clr.a); } /// \brief Red value public: float r; /// \brief Green value public: float g; /// \brief Blue value public: float b; /// \brief Alpha value public: float a; }; /// \brief A Time class, can be used to hold wall- or sim-time. /// stored as sec and nano-sec. class SDFORMAT_VISIBLE Time { /// \brief Constructor public: Time() : sec(0), nsec(0) { } /// \brief Constructor /// \param[in] _sec Seconds /// \param[in] _nsec Nanoseconds public: Time(int32_t _sec, int32_t _nsec) : sec(_sec), nsec(_nsec) { } /// \brief Stream insertion operator /// \param[in] _out the output stream /// \param[in] _time time to write to the stream /// \return the output stream public: friend std::ostream &operator<<(std::ostream &_out, const Time &_time) { _out << _time.sec << " " << _time.nsec; return _out; } /// \brief Stream extraction operator /// \param[in] _in the input stream /// \param[in] _time time to read from to the stream /// \return the input stream public: friend std::istream &operator>>(std::istream &_in, Time &_time) { // Skip white spaces _in.setf(std::ios_base::skipws); _in >> _time.sec >> _time.nsec; return _in; } /// \brief Equal to operator. /// \param[in] _time the time to compare to. /// \return true if values are the same, false otherwise. public: bool operator ==(const Time &_time) const { return this->sec == _time.sec && this->nsec == _time.nsec; } /// \brief Seconds. public: int32_t sec; /// \brief Nanoseconds. public: int32_t nsec; }; /// \brief A class for inertial information about a link. class SDFORMAT_VISIBLE Inertia { public: double mass; }; } #endif sdformat-6.0.0+dfsg/include/sdf/World.hh000066400000000000000000000105561323606632500200770ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_WORLD_HH_ #define SDF_WORLD_HH_ #include #include "sdf/Element.hh" #include "sdf/Types.hh" #include "sdf/system_util.hh" namespace sdf { // Forward declare private data class. class WorldPrivate; class SDFORMAT_VISIBLE World { /// \brief Default constructor public: World(); /// \brief Move constructor /// \param[in] _world World to move. public: World(World &&_world); /// \brief Destructor public: ~World(); /// \brief Load the world based on a element pointer. This is *not* the /// usual entry point. Typical usage of the SDF DOM is through the Root /// object. /// \param[in] _sdf The SDF Element pointer /// \return Errors, which is a vector of Error objects. Each Error includes /// an error code and message. An empty vector indicates no error. public: Errors Load(ElementPtr _sdf); /// \brief Get the name of the world. /// \return Name of the world. public: std::string Name() const; /// \brief Set the name of the world. /// \param[in] _name Name of the world. public: void SetName(const std::string &_name) const; /// \brief Get the audio device name. The audio device can be used to /// playback audio files. A value of "default" or an empty string /// indicates that the system's default audio device should be used. /// \return Audio device name. public: std::string AudioDevice() const; /// \brief Set the audio device name. See std::string AudioDevice() const /// for more information. /// \param[in] _device The new audio device name. /// \sa std::string AudioDevice() const public: void SetAudioDevice(const std::string &_device); /// \brief Get the wind linear velocity in the global/world coordinate /// frame. Units are meters per second \f$(\frac{m}{s})\f$ /// \return Linear velocity of wind in the global/world coordinate frame. /// \sa void SetWindLinearVelocity(const ignition::math::Vector3d &_wind) public: ignition::math::Vector3d WindLinearVelocity() const; /// \brief Set the wind linear velocity in the global/world coordinate /// frame. Units are meters per second \f$(\frac{m}{s})\f$ /// \param[in] _win The new linear velocity of wind. /// \sa ignition::math::Vector3d WindLinearVelocity() const public: void SetWindLinearVelocity(const ignition::math::Vector3d &_wind); /// \brief Get the acceleration due to gravity. The default value is /// Earth's standard gravity at sea level, which equals /// [0, 0, -9.80665] \f$(\frac{m}{s^2})\f$ /// \return Gravity vector in meters per second squared /// \f$(\frac{m}{s^2})\f$ public: ignition::math::Vector3d Gravity() const; /// \brief Set the acceleration due to gravity. Units are meters per /// second squared \f$(\frac{m}{s^2})\f$ /// \param[in] _gravity The new gravity vector. public: void SetGravity(const ignition::math::Vector3d &_gravity); /// \brief Get the magnetic vector in Tesla, expressed in /// a coordinate frame defined by the SphericalCoordinates property. /// A spherical coordindate can be specified in SDF using the /// element. /// \return Magnetic field vector. /// \sa SphericalCoordinates public: ignition::math::Vector3d MagneticField() const; /// \brief Set the magnetic vector in Tesla, expressed in /// a coordinate frame defined by the SphericalCoordinate. /// A spherical coordindate can be specified in SDF using the /// element. /// \param[in] _mag The new magnetic field vector. /// \sa SphericalCoordinates public: void SetMagneticField(const ignition::math::Vector3d &_mag); /// \brief Private data pointer. private: WorldPrivate *dataPtr = nullptr; }; } #endif sdformat-6.0.0+dfsg/include/sdf/ign.hh000066400000000000000000000021451323606632500175600ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_IGN_HH_ #define SDF_IGN_HH_ #include #include "sdf/system_util.hh" /// \brief External hook to execute 'ign sdf -k' from the command line. /// \param[in] _path Path to the file to validate. /// \return Zero on success, negative one otherwise. extern "C" SDFORMAT_VISIBLE int cmdCheck(const char *_path); /// \brief External hook to read the library version. /// \return C-string representing the version. Ex.: 0.1.2 extern "C" SDFORMAT_VISIBLE char *ignitionVersion(); #endif sdformat-6.0.0+dfsg/include/sdf/parser.hh000066400000000000000000000127721323606632500203060ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_PARSER_HH_ #define _SDF_PARSER_HH_ #include #include "sdf/SDFImpl.hh" #include "sdf/system_util.hh" /// \ingroup sdf_parser /// \brief namespace for Simulation Description Format parser namespace sdf { /// \brief Init based on the installed sdf_format.xml file SDFORMAT_VISIBLE bool init(SDFPtr _sdf); /// \brief Initialize the SDF interface using a file SDFORMAT_VISIBLE bool initFile(const std::string &_filename, SDFPtr _sdf); /// \brief Initialize an SDFElement interface using a file SDFORMAT_VISIBLE bool initFile(const std::string &_filename, ElementPtr _sdf); /// \brief Initialize the SDF interface using a string SDFORMAT_VISIBLE bool initString(const std::string &_xmlString, SDFPtr _sdf); /// \brief Populate the SDF values from a file /// \param[in] _filename Name of the SDF file /// \return Populated SDF pointer. SDFORMAT_VISIBLE sdf::SDFPtr readFile(const std::string &_filename); /// \brief Populate the SDF values from a file /// \param[in] _filename Name of the SDF file /// \param[out] _errors Parsing errors will be appended to this variable. /// \return Populated SDF pointer. SDFORMAT_VISIBLE sdf::SDFPtr readFile(const std::string &_filename, Errors &_errors); /// \brief Populate the SDF values from a file /// /// This populates the given sdf pointer from a file. If the file is a URDF /// file it is converted to SDF first. All files are converted to the latest /// SDF version /// \param[in] _filename Name of the SDF file /// \param[in] _sdf Pointer to an SDF object. /// \param[out] _errors Parsing errors will be appended to this variable. /// \return True if successful. SDFORMAT_VISIBLE bool readFile(const std::string &_filename, SDFPtr _sdf, Errors &_errors); /// \brief Populate the SDF values from a file /// /// This populates the given sdf pointer from a file. If the file is a URDF /// file it is converted to SDF first. All files are converted to the latest /// SDF version /// \param[in] _filename Name of the SDF file /// \param[in] _sdf Pointer to an SDF object. /// \return True if successful. SDFORMAT_VISIBLE bool readFile(const std::string &_filename, SDFPtr _sdf); /// \brief Populate the SDF values from a string /// /// This populates the sdf pointer from a string. If the string is a URDF /// string it is converted to SDF first. All string are converted to the /// latest SDF version /// \param[out] _errors Parsing errors will be appended to this variable. SDFORMAT_VISIBLE bool readString(const std::string &_xmlString, SDFPtr _sdf, Errors &_errors); /// \brief Populate the SDF values from a string /// /// This populates the sdf pointer from a string. If the string is a URDF /// string it is converted to SDF first. All string are converted to the /// latest SDF version SDFORMAT_VISIBLE bool readString(const std::string &_xmlString, SDFPtr _sdf); /// \brief Populate the SDF values from a string /// /// This populates the sdf pointer from a string. If the string is a URDF /// string it is converted to SDF first. All strings are converted to the /// latest SDF version /// \param[out] _errors Parsing errors will be appended to this variable. SDFORMAT_VISIBLE bool readString(const std::string &_xmlString, ElementPtr _sdf, Errors &_errors); /// \brief Populate the SDF values from a string /// /// This populates the sdf pointer from a string. If the string is a URDF /// string it is converted to SDF first. All strings are converted to the /// latest SDF version SDFORMAT_VISIBLE bool readString(const std::string &_xmlString, ElementPtr _sdf); /// \brief Get the file path to the model file /// \param[in] _modelDirPath directory system path of the model /// \return string with the full filesystem path to the best version (greater /// SDF protocol supported by this sdformat version) of the .sdf /// model files hosted by _modelDirPath. SDFORMAT_VISIBLE std::string getModelFilePath(const std::string &_modelDirPath); SDFORMAT_VISIBLE void addNestedModel(ElementPtr _sdf, ElementPtr _includeSDF); /// \brief Convert an SDF file to a specific SDF version. /// \param[in] _filename Name of the SDF file to convert. /// \param[in] _version Version to convert _filename to. /// \param[out] _sdf Pointer to the converted SDF document. /// \return True on success. SDFORMAT_VISIBLE bool convertFile(const std::string &_filename, const std::string &_version, SDFPtr _sdf); /// \brief Convert an SDF string to a specific SDF version. /// \param[in] _sdfString The SDF string to convert. /// \param[in] _version Version to convert _filename to. /// \param[out] _sdf Pointer to the converted SDF document. /// \return True on success. SDFORMAT_VISIBLE bool convertString(const std::string &_sdfString, const std::string &_version, SDFPtr _sdf); } #endif sdformat-6.0.0+dfsg/include/sdf/parser_private.hh000066400000000000000000000045511323606632500220340ustar00rootroot00000000000000/* * Copyright 2016 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_PARSER_PRIVATE_HH_ #define SDF_PARSER_PRIVATE_HH_ #include #include #include "sdf/SDFImpl.hh" #include "sdf/system_util.hh" /// \ingroup sdf_parser /// \brief namespace for Simulation Description Format parser namespace sdf { /// \brief Get the best SDF version from models supported by this sdformat /// \param[in] _modelXML XML element from config file pointing to the /// model XML tag /// \param[out] _modelFileName file name of the best model file /// \return string with the best SDF version supported std::string getBestSupportedModelVersion(TiXmlElement *_modelXML, std::string &_modelFileName); /// \brief Initialize the SDF interface using a TinyXML document bool initDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf); /// \brief Initialize and SDF Element using a TinyXML document bool initDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf); /// \brief For internal use only. Do not use this function. bool initXml(TiXmlElement *_xml, ElementPtr _sdf); /// \brief Populate the SDF values from a TinyXML document bool readDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf, const std::string &_source, bool _convert, Errors &_errors); bool readDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf, const std::string &_source, bool _convert, Errors &_errors); /// \brief For internal use only. Do not use this function. /// \param[in] _xml Pointer to the XML document /// \param[in,out] _sdf SDF pointer to parse data into. /// \param[out] _errors Captures errors found during parsing. /// \return True on success, false on error. bool readXml(TiXmlElement *_xml, ElementPtr _sdf, Errors &_errors); void copyChildren(ElementPtr _sdf, TiXmlElement *_xml); } #endif sdformat-6.0.0+dfsg/include/sdf/parser_urdf.hh000066400000000000000000000047611323606632500213250ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDFORMAT_URDF2SDF_HH_ #define _SDFORMAT_URDF2SDF_HH_ #include #include #include "sdf/Console.hh" #include "sdf/system_util.hh" namespace sdf { /// \brief URDF to SDF converter class SDFORMAT_VISIBLE URDF2SDF { /// \brief constructor public: URDF2SDF(); /// \brief destructor public: ~URDF2SDF(); /// \brief convert urdf xml document string to sdf xml document /// \param[in] _xmlDoc a tinyxml document containing the urdf model /// \return a tinyxml document containing sdf of the model public: TiXmlDocument InitModelDoc(TiXmlDocument* _xmlDoc); /// \brief convert urdf file to sdf xml document /// \param[in] _urdfStr a string containing filename of the urdf model /// \return a tinyxml document containing sdf of the model public: TiXmlDocument InitModelFile(const std::string &_filename); /// \brief convert urdf string to sdf xml document, with option to enforce /// limits. /// \param[in] _urdfStr a string containing model urdf /// \param[in] _enforceLimits option to enforce joint limits /// \return a tinyxml document containing sdf of the model public: TiXmlDocument InitModelString(const std::string &_urdfStr, bool _enforceLimits = true); /// \brief Return true if the filename is a URDF model. /// \param[in] _filename File to check. /// \return True if _filename is a URDF model. public: static bool IsURDF(const std::string &_filename); /// things that do not belong in urdf but should be mapped into sdf /// @todo: do this using sdf definitions, not hard coded stuff private: void ParseSDFExtension(TiXmlDocument &_urdfXml); /// list extensions for debugging private: void ListSDFExtensions(); /// list extensions for debugging private: void ListSDFExtensions(const std::string &_reference); }; } #endif sdformat-6.0.0+dfsg/include/sdf/sdf.hh.in000066400000000000000000000001061323606632500201570ustar00rootroot00000000000000// Automatically generated ${sdf_headers} #include sdformat-6.0.0+dfsg/include/sdf/system_util.hh000066400000000000000000000031511323606632500213620ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _SDF_VISIBLE_HH_ #define _SDF_VISIBLE_HH_ /** \def SDFORMAT_VISIBLE * Use to represent "symbol visible" if supported */ /** \def SDFORMAT_HIDDEN * Use to represent "symbol hidden" if supported */ #if defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_DLL #ifdef __GNUC__ #define SDFORMAT_VISIBLE __attribute__ ((dllexport)) #else #define SDFORMAT_VISIBLE __declspec(dllexport) #endif #else #ifdef __GNUC__ #define SDFORMAT_VISIBLE __attribute__ ((dllimport)) #else #define SDFORMAT_VISIBLE __declspec(dllimport) #endif #endif #define SDFORMAT_HIDDEN #else #if __GNUC__ >= 4 #define SDFORMAT_VISIBLE __attribute__ ((visibility ("default"))) #define SDFORMAT_HIDDEN __attribute__ ((visibility ("hidden"))) #else #define SDFORMAT_VISIBLE #define SDFORMAT_HIDDEN #endif #endif // Use safer functions on Windows #ifdef _MSC_VER #define sdf_strdup _strdup #else #define sdf_strdup strdup #endif #endif /* SDFORMAT_VISIBLE_HH */ sdformat-6.0.0+dfsg/sdf/000077500000000000000000000000001323606632500150355ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.0/000077500000000000000000000000001323606632500153335ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.0/CMakeLists.txt000066400000000000000000000006561323606632500201020ustar00rootroot00000000000000set (sdfs actor.sdf camera.sdf collision.sdf contact.sdf gazebo.sdf geometry.sdf gripper.sdf gui.sdf inertial.sdf joint.sdf light.sdf link.sdf model.sdf physics.sdf plugin.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf scene.sdf sensor.sdf state.sdf surface.sdf visual.sdf world.sdf ) install(FILES ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.0/) sdformat-6.0.0+dfsg/sdf/1.0/actor.sdf000066400000000000000000000035371323606632500171510ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/camera.sdf000066400000000000000000000020761323606632500172660ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/collision.sdf000066400000000000000000000011631323606632500200250ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/contact.sdf000066400000000000000000000004631323606632500174670ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/gazebo.sdf000066400000000000000000000005111323606632500172750ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/geometry.sdf000066400000000000000000000042151323606632500176660ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/gripper.sdf000066400000000000000000000011231323606632500174760ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/gui.sdf000066400000000000000000000013771323606632500166250ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/inertial.sdf000066400000000000000000000015421323606632500176420ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/joint.sdf000066400000000000000000000060741323606632500171630ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/light.sdf000066400000000000000000000030361323606632500171420ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/link.sdf000066400000000000000000000017341323606632500167730ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/model.sdf000066400000000000000000000010701323606632500171270ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/physics.sdf000066400000000000000000000027131323606632500175160ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/plugin.sdf000066400000000000000000000004331323606632500173270ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/projector.sdf000066400000000000000000000010501323606632500200340ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/ray.sdf000066400000000000000000000022361323606632500166270ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/rfid.sdf000066400000000000000000000001061323606632500167520ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/rfidtag.sdf000066400000000000000000000001001323606632500174400ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/road.sdf000066400000000000000000000004221323606632500167540ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/scene.sdf000066400000000000000000000021761323606632500171340ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/sensor.sdf000066400000000000000000000017051323606632500173450ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/state.sdf000066400000000000000000000022701323606632500171520ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/surface.sdf000066400000000000000000000026051323606632500174640ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/visual.sdf000066400000000000000000000027211323606632500173360ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.0/world.sdf000066400000000000000000000011471323606632500171630ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.2/000077500000000000000000000000001323606632500153355ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.2/1_0.convert000066400000000000000000001236621323606632500173300ustar00rootroot00000000000000 background/sky/rgba background/sky/material sdformat-6.0.0+dfsg/sdf/1.2/CMakeLists.txt000066400000000000000000000006731323606632500201030ustar00rootroot00000000000000set (sdfs 1_0.convert actor.sdf camera.sdf collision.sdf contact.sdf gazebo.sdf geometry.sdf gripper.sdf gui.sdf inertial.sdf joint.sdf light.sdf link.sdf model.sdf physics.sdf plugin.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf scene.sdf sensor.sdf state.sdf surface.sdf visual.sdf world.sdf ) install(FILES ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.2) sdformat-6.0.0+dfsg/sdf/1.2/actor.sdf000066400000000000000000000053701323606632500171500ustar00rootroot00000000000000 Origin of the actor sdformat-6.0.0+dfsg/sdf/1.2/camera.sdf000066400000000000000000000042621323606632500172670ustar00rootroot00000000000000 These elements are specific to camera sensors. Horizontal field of view The image size in pixels and format. Width in pixels Height in pixels (L8|R8G8B8|B8G8R8|BAYER_RGGB8|BAYER_BGGR8|BAYER_GBRG8|BAYER_GRBG8) The near and far clip planes. Objects closer or farther than these planes are not rendered. Near clipping plane Far clipping plane Enable or disable saving of camera frames. True = saving enabled The path name which will hold the frame data. If path name is relative, then directory is relative to current working directory. Depth camera parameters Type of output sdformat-6.0.0+dfsg/sdf/1.2/collision.sdf000066400000000000000000000022701323606632500200270ustar00rootroot00000000000000 The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time. Unique name for the collision element within the scope of the parent link. intensity value returned by laser sensor. Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics. The reference frame of the collision element, relative to the reference frame of the link. sdformat-6.0.0+dfsg/sdf/1.2/contact.sdf000066400000000000000000000010351323606632500174650ustar00rootroot00000000000000 These elements are specific to the contact sensor. name of the collision element within a link that acts as the contact sensor. Topic on which contact data is published. sdformat-6.0.0+dfsg/sdf/1.2/gazebo.sdf000066400000000000000000000007171323606632500173070ustar00rootroot00000000000000 Gazebo SDF base element. Version number of the SDF format. sdformat-6.0.0+dfsg/sdf/1.2/geometry.sdf000066400000000000000000000115631323606632500176740ustar00rootroot00000000000000 The shape of the visual or collision object. Box shape The three side lengths of the box. The origin of the box is in its geometric center (inside the center of the box). Sphere shape radius of the sphere Cylinder shape Radius of the cylinder Length of the cylinder Mesh shape Mesh filename. DEPRECATED Mesh uri Scaling factor applied to the mesh Plane shape Normal direction for the plane Length of each side of the plane Extrude a set of boxes from a grayscale image. URI of the grayscale image file Scaling factor applied to the image Grayscale threshold Height of the extruded boxes The amount of error in the model A heightmap based on a 2d grayscale image. URI to a grayscale image file The size of the heightmap in world units A position offset. The heightmap can contain multiple textures. The order of the texture matters. The first texture will appear at the lowest height, and the last texture at the highest height. Use blend to control the height thresholds and fade between textures. Size of the applied texture in meters. Diffuse texture image filename Normalmap texture image filename The blend tag controls how two adjacent textures are mixed. The number of blend elements should equal one less than the number of textures. Min height of a blend layer Distance over which the blend occurs sdformat-6.0.0+dfsg/sdf/1.2/gripper.sdf000066400000000000000000000016461323606632500175120ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.2/gui.sdf000066400000000000000000000021451323606632500166210ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.2/inertial.sdf000066400000000000000000000032201323606632500176370ustar00rootroot00000000000000 The inertial properties of the link. The mass of the link. This is the pose of the inertial reference frame, relative to the link reference frame. The origin of the inertial reference frame needs to be at the center of gravity. The axes of the inertial reference frame do not need to be aligned with the principal axes of the inertia. The 3x3 rotational inertia matrix. Because the rotational inertia matrix is symmetric, only 6 above-diagonal elements of this matrix are specified here, using the attributes ixx, ixy, ixz, iyy, iyz, izz. sdformat-6.0.0+dfsg/sdf/1.2/joint.sdf000066400000000000000000000200571323606632500171620ustar00rootroot00000000000000 A joint connections two links with kinematic and dynamic properties. A unique name for the joint within the scope of the model. The type of joint, which must be one of the following: (revolute) a hinge joint that rotates on a single axis with either a fixed or continuous range of motion, (revolute2) same as two revolute joints connected in series, (prismatic) a sliding joint that slides along an axis with a limited range specified by upper and lower limits, (ball) a ball and socket joint, (universal), like a ball joint, but constrains one degree of freedom, (piston) similar to a Slider joint except that rotation around the translation axis is possible. Name of the parent link Name of the child link offset from child link origin in child link frame. The joint axis specified in the model frame. This is the axis of rotation for revolute joints, the axis of translation for prismatic joints. The axis is currently specified in the model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. specifies the limits of this joint An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. (not implemented) An attribute for enforcing the maximum joint effort. (not implemented) An attribute for enforcing the maximum joint velocity. The second joint axis specified in the model frame. This is the second axis of rotation for revolute2 joints and universal joints. The axis is currently specified in the model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. (not implemented) An attribute for enforcing the maximum joint effort. (not implemented) An attribute for enforcing the maximum joint velocity. Parameters that are specific to a certain physics engine. ODE specific parameters Scale the excess for in a joint motor at joint limits. Should be between zero and one. Constraint force mixing used when not at a stop Bounciness of the limits Maximum force or torque used to reach the desired velocity. The desired velocity of the joint. Should only be set if you want the joint to move on load. Constraint force mixing parameter used by the joint stop Error reduction parameter used by the joint stop Suspension constraint force mixing parameter Suspension error reduction parameter sdformat-6.0.0+dfsg/sdf/1.2/light.sdf000066400000000000000000000054331323606632500171470ustar00rootroot00000000000000 The light element describes a light source. A unique name for the light. The light type: point, directional, spot. When true, the light will cast shadows. A position and orientation in the global coordinate frame for the light. Diffuse light color Specular light color Light attenuation Range of the light The linear attenuation factor: 1 means attenuate evenly over the distance. The constant attenuation factor: 1.0 means never attenuate, 0.0 is complete attenutation. The quadratic attenuation factor: adds a curvature to the attenuation. Direction of the light, only applicable for spot and directional lights. Spot light parameters Angle covered by the bright inner cone Angle covered by the outer cone The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff. sdformat-6.0.0+dfsg/sdf/1.2/link.sdf000066400000000000000000000034051323606632500167720ustar00rootroot00000000000000 A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model. A unique name for the link within the scope of the model. If true, the link is affected by gravity. If true, the link can collide with other links in the model. If true, the link is kinematic only This is the pose of the link reference frame, relative to the model reference frame. Exponential damping of the link's velocity. Linear damping Angular damping sdformat-6.0.0+dfsg/sdf/1.2/model.sdf000066400000000000000000000025121323606632500171330ustar00rootroot00000000000000 The model element defines a complete robot or any other physical object. A unique name for the model. This name must not match another model in the world. If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. Allows a model to auto-disable, which is means the physics engine can skip updating the model when the model is at rest. This parameter is only used by models with no joints. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.2/physics.sdf000066400000000000000000000065771323606632500175340ustar00rootroot00000000000000 The physics tag specifies the type and properties of the dynamics engine. The type of the dynamics engine. Currently must be set to ode Rate at which to update the physics engine Maximum number of contacts allowed between two entities. This value can be over ridden by a max_contacts element in a collision element. The gravity vector Bullet specific physics properties Time step ODE specific physics properties One of the following types: world, quick The time duration which advances with each iteration of the dynamics engine. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Set the successive over-relaxation parameter. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The maximum correcting velocities allowed when resolving contacts. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. sdformat-6.0.0+dfsg/sdf/1.2/plugin.sdf000066400000000000000000000016061323606632500173340ustar00rootroot00000000000000 A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor. A unique name for the plugin, scoped to its parent. Name of the shared library to load. If the filename is not a full path name, the file will be searched for in the configuration paths. This is a special element that should not be specified in an SDF file. It automatically copies child elements into the SDF element so that a plugin can access the data. sdformat-6.0.0+dfsg/sdf/1.2/projector.sdf000066400000000000000000000016421323606632500200450ustar00rootroot00000000000000 Name of the projector Texture name Pose of the projector Field of view Near clip distance far clip distance sdformat-6.0.0+dfsg/sdf/1.2/ray.sdf000066400000000000000000000052561323606632500166360ustar00rootroot00000000000000 These elements are specific to the ray (laser) sensor. The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle specifies range properties of each simulated ray The minimum distance for each ray. The maximum distance for each ray. Linear resolution of each ray. sdformat-6.0.0+dfsg/sdf/1.2/rfid.sdf000066400000000000000000000001061323606632500167540ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.2/rfidtag.sdf000066400000000000000000000001001323606632500174420ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.2/road.sdf000066400000000000000000000007531323606632500167650ustar00rootroot00000000000000 Name of the road Width of the road A series of points define the path of the road. sdformat-6.0.0+dfsg/sdf/1.2/scene.sdf000066400000000000000000000057201323606632500171340ustar00rootroot00000000000000 Specifies the look of the environment. Color of the ambient light. Color of the background. Properties for the sky Time of day [0..24] Sunrise time [0..24] Sunset time [0..24] Sunset time [0..24] Speed of the clouds Direction of the cloud movement Density of clouds Average size of the clouds Ambient cloud color Enable/disable shadows Controls fog Fog color Fog type: constant, linear, quadratic Distance to start of fog Distance to end of fog Density of fog Enable/disable the grid sdformat-6.0.0+dfsg/sdf/1.2/sensor.sdf000066400000000000000000000035271323606632500173530ustar00rootroot00000000000000 The sensor tag describes the type and properties of a sensor. A unique name for the sensor. This name must not match another model in the model. The type name of the sensor. By default, gazebo supports types camera, depth, stereocamera, contact, imu, ir and ray. If true the sensor will always be updated according to the update rate. The frequency at which the sensor data is generated. If left unspecified, the sensor will generate data every cycle. If true, the sensor is visualized in the GUI This is the pose of the sensor, relative to the parent link reference frame. Name of the topic on which data is published. This is necessary for visualization sdformat-6.0.0+dfsg/sdf/1.2/state.sdf000066400000000000000000000037151323606632500171610ustar00rootroot00000000000000 Name of the world this state applies to Time stamp of the state [seconds nanoseconds] Model state Name of the model Pose of the model Link state Name of the link Pose of the link relative to the model Velocity of the link Force applied to the link Position of the force. Magnitude of the force. sdformat-6.0.0+dfsg/sdf/1.2/surface.sdf000066400000000000000000000062341323606632500174700ustar00rootroot00000000000000 The surface parameters Bounciness coefficient of restitution, from [0...1], where 0=no bounciness. Bounce velocity threshold, below which effective coefficient of restitution is 0. ODE friction parameters Coefficient of friction in the range of [0..1]. Second coefficient of friction in the range of [0..1] 3-tuple specifying direction of mu1 in the collision local reference frame. Force dependent slip direction 1 in collision local frame, between the range of [0..1]. Force dependent slip direction 2 in collision local frame, between the range of [0..1]. ODE contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints maximum contact correction velocity truncation term. minimum allowable depth before contact correction impulse is applied sdformat-6.0.0+dfsg/sdf/1.2/urdf.sdf000066400000000000000000000015401323606632500167730ustar00rootroot00000000000000 The robot element defines a complete robot or any other physical object using URDF. A unique name for the model. This name must not match another model in the world. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.2/visual.sdf000066400000000000000000000062711323606632500173440ustar00rootroot00000000000000 The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes. Unique name for the visual element within the scope of the parent link. If true the visual will cast shadows. will be implemented in the future release. The amount of transparency( 0=opaque, 1 = fully transparent) Origin of the visual relative to its parent. The material of the visual element. Name of material from an installed script file. This will override the color element if the script exists. URI of the material script file Name of the script within the script file vertex, pixel, normal_map_objectspace, normal_map_tangentspace filename of the normal map The ambient color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. The diffuse color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The specular color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The emissive color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. sdformat-6.0.0+dfsg/sdf/1.2/world.sdf000066400000000000000000000014751323606632500171710ustar00rootroot00000000000000 The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins Unique name of the world sdformat-6.0.0+dfsg/sdf/1.3/000077500000000000000000000000001323606632500153365ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.3/1_2.convert000066400000000000000000000000641323606632500173210ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.3/CMakeLists.txt000066400000000000000000000007031323606632500200760ustar00rootroot00000000000000set (sdfs 1_2.convert actor.sdf camera.sdf collision.sdf contact.sdf geometry.sdf gripper.sdf gui.sdf imu.sdf inertial.sdf joint.sdf light.sdf link.sdf model.sdf physics.sdf plugin.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf root.sdf scene.sdf sensor.sdf state.sdf surface.sdf visual.sdf world.sdf ) install(FILES ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.3) sdformat-6.0.0+dfsg/sdf/1.3/actor.sdf000066400000000000000000000053701323606632500171510ustar00rootroot00000000000000 Origin of the actor sdformat-6.0.0+dfsg/sdf/1.3/camera.sdf000066400000000000000000000050131323606632500172630ustar00rootroot00000000000000 These elements are specific to camera sensors. An optional name for the camera. A position and orientation in the parent coordinate frame for the camera. Horizontal field of view The image size in pixels and format. Width in pixels Height in pixels (L8|R8G8B8|B8G8R8|BAYER_RGGB8|BAYER_BGGR8|BAYER_GBRG8|BAYER_GRBG8) The near and far clip planes. Objects closer or farther than these planes are not rendered. Near clipping plane Far clipping plane Enable or disable saving of camera frames. True = saving enabled The path name which will hold the frame data. If path name is relative, then directory is relative to current working directory. Depth camera parameters Type of output sdformat-6.0.0+dfsg/sdf/1.3/collision.sdf000066400000000000000000000022701323606632500200300ustar00rootroot00000000000000 The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time. Unique name for the collision element within the scope of the parent link. intensity value returned by laser sensor. Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics. The reference frame of the collision element, relative to the reference frame of the link. sdformat-6.0.0+dfsg/sdf/1.3/contact.sdf000066400000000000000000000010351323606632500174660ustar00rootroot00000000000000 These elements are specific to the contact sensor. name of the collision element within a link that acts as the contact sensor. Topic on which contact data is published. sdformat-6.0.0+dfsg/sdf/1.3/geometry.sdf000066400000000000000000000130171323606632500176710ustar00rootroot00000000000000 The shape of the visual or collision object. Box shape The three side lengths of the box. The origin of the box is in its geometric center (inside the center of the box). Sphere shape radius of the sphere Cylinder shape Radius of the cylinder Length of the cylinder Mesh shape Mesh uri Use a named submesh. The submesh must exist in the mesh specified by the uri Name of the submesh within the parent mesh Set to true to center the vertices of the submesh at 0,0,0. This will effectively remove any transformations on the submesh before the poses from parent links and models are applied. Scaling factor applied to the mesh Plane shape Normal direction for the plane Length of each side of the plane Extrude a set of boxes from a grayscale image. URI of the grayscale image file Scaling factor applied to the image Grayscale threshold Height of the extruded boxes The amount of error in the model A heightmap based on a 2d grayscale image. URI to a grayscale image file The size of the heightmap in world units A position offset. The heightmap can contain multiple textures. The order of the texture matters. The first texture will appear at the lowest height, and the last texture at the highest height. Use blend to control the height thresholds and fade between textures. Size of the applied texture in meters. Diffuse texture image filename Normalmap texture image filename The blend tag controls how two adjacent textures are mixed. The number of blend elements should equal one less than the number of textures. Min height of a blend layer Distance over which the blend occurs You can use the empty tag to make empty geometries. sdformat-6.0.0+dfsg/sdf/1.3/gripper.sdf000066400000000000000000000016461323606632500175130ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.3/gui.sdf000066400000000000000000000021451323606632500166220ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.3/imu.sdf000066400000000000000000000004311323606632500166240ustar00rootroot00000000000000 These elements are specific to the IMU sensor. Topic on which data is published. sdformat-6.0.0+dfsg/sdf/1.3/inertial.sdf000066400000000000000000000032201323606632500176400ustar00rootroot00000000000000 The inertial properties of the link. The mass of the link. This is the pose of the inertial reference frame, relative to the link reference frame. The origin of the inertial reference frame needs to be at the center of gravity. The axes of the inertial reference frame do not need to be aligned with the principal axes of the inertia. The 3x3 rotational inertia matrix. Because the rotational inertia matrix is symmetric, only 6 above-diagonal elements of this matrix are specified here, using the attributes ixx, ixy, ixz, iyy, iyz, izz. sdformat-6.0.0+dfsg/sdf/1.3/joint.sdf000066400000000000000000000212701323606632500171610ustar00rootroot00000000000000 A joint connections two links with kinematic and dynamic properties. A unique name for the joint within the scope of the model. The type of joint, which must be one of the following: (revolute) a hinge joint that rotates on a single axis with either a fixed or continuous range of motion, (revolute2) same as two revolute joints connected in series, (prismatic) a sliding joint that slides along an axis with a limited range specified by upper and lower limits, (ball) a ball and socket joint, (universal), like a ball joint, but constrains one degree of freedom, (piston) similar to a Slider joint except that rotation around the translation axis is possible. Name of the parent link Name of the child link offset from child link origin in child link frame. The joint axis specified in the model frame. This is the axis of rotation for revolute joints, the axis of translation for prismatic joints. The axis is currently specified in the model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. specifies the limits of this joint An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. The second joint axis specified in the model frame. This is the second axis of rotation for revolute2 joints and universal joints. The axis is currently specified in the model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Parameters that are specific to a certain physics engine. ODE specific parameters If provide feedback is set to true, ODE will compute the constraint forces at this joint. If cfm damping is set to true, ODE will use CFM to simulate damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. Scale the excess for in a joint motor at joint limits. Should be between zero and one. Constraint force mixing used when not at a stop Bounciness of the limits Maximum force or torque used to reach the desired velocity. The desired velocity of the joint. Should only be set if you want the joint to move on load. Constraint force mixing parameter used by the joint stop Error reduction parameter used by the joint stop Suspension constraint force mixing parameter Suspension error reduction parameter sdformat-6.0.0+dfsg/sdf/1.3/light.sdf000066400000000000000000000054331323606632500171500ustar00rootroot00000000000000 The light element describes a light source. A unique name for the light. The light type: point, directional, spot. When true, the light will cast shadows. A position and orientation in the global coordinate frame for the light. Diffuse light color Specular light color Light attenuation Range of the light The linear attenuation factor: 1 means attenuate evenly over the distance. The constant attenuation factor: 1.0 means never attenuate, 0.0 is complete attenutation. The quadratic attenuation factor: adds a curvature to the attenuation. Direction of the light, only applicable for spot and directional lights. Spot light parameters Angle covered by the bright inner cone Angle covered by the outer cone The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff. sdformat-6.0.0+dfsg/sdf/1.3/link.sdf000066400000000000000000000034051323606632500167730ustar00rootroot00000000000000 A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model. A unique name for the link within the scope of the model. If true, the link is affected by gravity. If true, the link can collide with other links in the model. If true, the link is kinematic only This is the pose of the link reference frame, relative to the model reference frame. Exponential damping of the link's velocity. Linear damping Angular damping sdformat-6.0.0+dfsg/sdf/1.3/model.sdf000066400000000000000000000025121323606632500171340ustar00rootroot00000000000000 The model element defines a complete robot or any other physical object. A unique name for the model. This name must not match another model in the world. If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. Allows a model to auto-disable, which is means the physics engine can skip updating the model when the model is at rest. This parameter is only used by models with no joints. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.3/physics.sdf000066400000000000000000000065771323606632500175350ustar00rootroot00000000000000 The physics tag specifies the type and properties of the dynamics engine. The type of the dynamics engine. Currently must be set to ode Rate at which to update the physics engine Maximum number of contacts allowed between two entities. This value can be over ridden by a max_contacts element in a collision element. The gravity vector Bullet specific physics properties Time step ODE specific physics properties One of the following types: world, quick The time duration which advances with each iteration of the dynamics engine. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Set the successive over-relaxation parameter. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The maximum correcting velocities allowed when resolving contacts. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. sdformat-6.0.0+dfsg/sdf/1.3/plugin.sdf000066400000000000000000000016061323606632500173350ustar00rootroot00000000000000 A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor. A unique name for the plugin, scoped to its parent. Name of the shared library to load. If the filename is not a full path name, the file will be searched for in the configuration paths. This is a special element that should not be specified in an SDF file. It automatically copies child elements into the SDF element so that a plugin can access the data. sdformat-6.0.0+dfsg/sdf/1.3/projector.sdf000066400000000000000000000016421323606632500200460ustar00rootroot00000000000000 Name of the projector Texture name Pose of the projector Field of view Near clip distance far clip distance sdformat-6.0.0+dfsg/sdf/1.3/ray.sdf000066400000000000000000000052561323606632500166370ustar00rootroot00000000000000 These elements are specific to the ray (laser) sensor. The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle specifies range properties of each simulated ray The minimum distance for each ray. The maximum distance for each ray. Linear resolution of each ray. sdformat-6.0.0+dfsg/sdf/1.3/rfid.sdf000066400000000000000000000001061323606632500167550ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.3/rfidtag.sdf000066400000000000000000000001001323606632500174430ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.3/road.sdf000066400000000000000000000007531323606632500167660ustar00rootroot00000000000000 Name of the road Width of the road A series of points define the path of the road. sdformat-6.0.0+dfsg/sdf/1.3/root.sdf000066400000000000000000000007021323606632500170160ustar00rootroot00000000000000 SDF base element. Version number of the SDF format. sdformat-6.0.0+dfsg/sdf/1.3/scene.sdf000066400000000000000000000057201323606632500171350ustar00rootroot00000000000000 Specifies the look of the environment. Color of the ambient light. Color of the background. Properties for the sky Time of day [0..24] Sunrise time [0..24] Sunset time [0..24] Sunset time [0..24] Speed of the clouds Direction of the cloud movement Density of clouds Average size of the clouds Ambient cloud color Enable/disable shadows Controls fog Fog color Fog type: constant, linear, quadratic Distance to start of fog Distance to end of fog Density of fog Enable/disable the grid sdformat-6.0.0+dfsg/sdf/1.3/sensor.sdf000066400000000000000000000036021323606632500173460ustar00rootroot00000000000000 The sensor tag describes the type and properties of a sensor. A unique name for the sensor. This name must not match another model in the model. The type name of the sensor. By default, SDF supports types camera, depth, multicamera, contact, imu, ir and ray. If true the sensor will always be updated according to the update rate. The frequency at which the sensor data is generated. If left unspecified, the sensor will generate data every cycle. If true, the sensor is visualized in the GUI This is the pose of the sensor, relative to the parent link reference frame. Name of the topic on which data is published. This is necessary for visualization sdformat-6.0.0+dfsg/sdf/1.3/state.sdf000066400000000000000000000070611323606632500171600ustar00rootroot00000000000000 Name of the world this state applies to Simulation time stamp of the state [seconds nanoseconds] Wall time stamp of the state [seconds nanoseconds] Real time stamp of the state [seconds nanoseconds] A list of new model names A list of deleted model names The name of a deleted model Model state Name of the model Pose of the model Joint angle Name of the joint Index of the axis. Angle of an axis Link state Name of the link Pose of the link relative to the model Velocity of the link Acceleration of the link Force applied to the link Collision state Name of the collision Pose of the link relative to the model sdformat-6.0.0+dfsg/sdf/1.3/surface.sdf000066400000000000000000000062341323606632500174710ustar00rootroot00000000000000 The surface parameters Bounciness coefficient of restitution, from [0...1], where 0=no bounciness. Bounce velocity threshold, below which effective coefficient of restitution is 0. ODE friction parameters Coefficient of friction in the range of [0..1]. Second coefficient of friction in the range of [0..1] 3-tuple specifying direction of mu1 in the collision local reference frame. Force dependent slip direction 1 in collision local frame, between the range of [0..1]. Force dependent slip direction 2 in collision local frame, between the range of [0..1]. ODE contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints maximum contact correction velocity truncation term. minimum allowable depth before contact correction impulse is applied sdformat-6.0.0+dfsg/sdf/1.3/urdf.sdf000066400000000000000000000015401323606632500167740ustar00rootroot00000000000000 The robot element defines a complete robot or any other physical object using URDF. A unique name for the model. This name must not match another model in the world. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.3/visual.sdf000066400000000000000000000063511323606632500173440ustar00rootroot00000000000000 The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes. Unique name for the visual element within the scope of the parent link. If true the visual will cast shadows. will be implemented in the future release. The amount of transparency( 0=opaque, 1 = fully transparent) Origin of the visual relative to its parent. The material of the visual element. Name of material from an installed script file. This will override the color element if the script exists. URI of the material script file Name of the script within the script file vertex, pixel, normal_map_objectspace, normal_map_tangentspace filename of the normal map The ambient color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. The diffuse color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The specular color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The emissive color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. sdformat-6.0.0+dfsg/sdf/1.3/world.sdf000066400000000000000000000014751323606632500171720ustar00rootroot00000000000000 The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins Unique name of the world sdformat-6.0.0+dfsg/sdf/1.4/000077500000000000000000000000001323606632500153375ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.4/1_3.convert000066400000000000000000000022741323606632500173300ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.4/CMakeLists.txt000066400000000000000000000013141323606632500200760ustar00rootroot00000000000000set (sdfs 1_3.convert actor.sdf audio_source.sdf audio_sink.sdf box_shape.sdf camera.sdf collision.sdf contact.sdf cylinder_shape.sdf forcetorque.sdf geometry.sdf gps.sdf gripper.sdf gui.sdf heightmap_shape.sdf image_shape.sdf imu.sdf inertial.sdf joint.sdf light.sdf link.sdf mesh_shape.sdf model.sdf noise.sdf physics.sdf plane_shape.sdf plugin.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf root.sdf scene.sdf sensor.sdf spherical_coordinates.sdf sphere_shape.sdf sonar.sdf state.sdf surface.sdf transceiver.sdf visual.sdf world.sdf ) install(FILES ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.4) sdformat-6.0.0+dfsg/sdf/1.4/actor.sdf000066400000000000000000000053701323606632500171520ustar00rootroot00000000000000 Origin of the actor sdformat-6.0.0+dfsg/sdf/1.4/audio_sink.sdf000066400000000000000000000001641323606632500201630ustar00rootroot00000000000000 An audio sink. sdformat-6.0.0+dfsg/sdf/1.4/audio_source.sdf000066400000000000000000000024501323606632500205170ustar00rootroot00000000000000 An audio source. URI of the audio media. Pitch for the audio media, in Hz Gain for the audio media, in dB. List of collision objects that will trigger audio playback. Name of child collision element that will trigger audio playback. True to make the audio source loop playback. A position and orientation in the parent coordinate frame for the audio source. Position(x,y,z) and rotation (roll, pitch yaw) in the parent coordinate frame. sdformat-6.0.0+dfsg/sdf/1.4/box_shape.sdf000066400000000000000000000004701323606632500200060ustar00rootroot00000000000000 Box shape The three side lengths of the box. The origin of the box is in its geometric center (inside the center of the box). sdformat-6.0.0+dfsg/sdf/1.4/camera.sdf000066400000000000000000000065761323606632500173030ustar00rootroot00000000000000 These elements are specific to camera sensors. An optional name for the camera. A position and orientation in the parent coordinate frame for the camera. Horizontal field of view The image size in pixels and format. Width in pixels Height in pixels (L8|R8G8B8|B8G8R8|BAYER_RGGB8|BAYER_BGGR8|BAYER_GBRG8|BAYER_GRBG8) The near and far clip planes. Objects closer or farther than these planes are not rendered. Near clipping plane Far clipping plane Enable or disable saving of camera frames. True = saving enabled The path name which will hold the frame data. If path name is relative, then directory is relative to current working directory. Depth camera parameters Type of output The properties of the noise model that should be applied to generated images The type of noise. Currently supported types are: "gaussian" (draw additive noise values independently for each pixel from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. sdformat-6.0.0+dfsg/sdf/1.4/collision.sdf000066400000000000000000000022701323606632500200310ustar00rootroot00000000000000 The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time. Unique name for the collision element within the scope of the parent link. intensity value returned by laser sensor. Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics. The reference frame of the collision element, relative to the reference frame of the link. sdformat-6.0.0+dfsg/sdf/1.4/collision_engine.sdf000066400000000000000000000013111323606632500213510ustar00rootroot00000000000000 The collision_engine tag specifies the type and properties of the collision detection engine. The type of the collision detection engine. Current default in ODE is OPCODE. The type of the collision detection engine. sdformat-6.0.0+dfsg/sdf/1.4/contact.sdf000066400000000000000000000010351323606632500174670ustar00rootroot00000000000000 These elements are specific to the contact sensor. name of the collision element within a link that acts as the contact sensor. Topic on which contact data is published. sdformat-6.0.0+dfsg/sdf/1.4/cylinder_shape.sdf000066400000000000000000000005461323606632500210330ustar00rootroot00000000000000 Cylinder shape Radius of the cylinder Length of the cylinder sdformat-6.0.0+dfsg/sdf/1.4/forcetorque.sdf000066400000000000000000000004501323606632500203720ustar00rootroot00000000000000 These elements are specific to the force torque sensor. Frame in which to report the wrench values. sdformat-6.0.0+dfsg/sdf/1.4/geometry.sdf000066400000000000000000000012671323606632500176760ustar00rootroot00000000000000 The shape of the visual or collision object. You can use the empty tag to make empty geometries. sdformat-6.0.0+dfsg/sdf/1.4/gps.sdf000066400000000000000000000025341323606632500166320ustar00rootroot00000000000000 These elements are specific to the GPS sensor. Parameters related to GPS position measurement. Noise parameters for horizontal position measurement, in units of meters. Noise parameters for vertical position measurement, in units of meters. Parameters related to GPS position measurement. Noise parameters for horizontal velocity measurement, in units of meters/second. Noise parameters for vertical velocity measurement, in units of meters/second. sdformat-6.0.0+dfsg/sdf/1.4/gripper.sdf000066400000000000000000000016461323606632500175140ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.4/gui.sdf000066400000000000000000000021451323606632500166230ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.4/heightmap_shape.sdf000066400000000000000000000042671323606632500211740ustar00rootroot00000000000000 A heightmap based on a 2d grayscale image. URI to a grayscale image file The size of the heightmap in world units. When loading an image: "size" is used if present, otherwise defaults to 1x1x1. When loading a DEM: "size" is used if present, otherwise defaults to true size of DEM. A position offset. The heightmap can contain multiple textures. The order of the texture matters. The first texture will appear at the lowest height, and the last texture at the highest height. Use blend to control the height thresholds and fade between textures. Size of the applied texture in meters. Diffuse texture image filename Normalmap texture image filename The blend tag controls how two adjacent textures are mixed. The number of blend elements should equal one less than the number of textures. Min height of a blend layer Distance over which the blend occurs Set if the rendering engine will use terrain paging sdformat-6.0.0+dfsg/sdf/1.4/image_shape.sdf000066400000000000000000000014741323606632500203050ustar00rootroot00000000000000 Extrude a set of boxes from a grayscale image. URI of the grayscale image file Scaling factor applied to the image Grayscale threshold Height of the extruded boxes The amount of error in the model sdformat-6.0.0+dfsg/sdf/1.4/imu.sdf000066400000000000000000000053721323606632500166360ustar00rootroot00000000000000 These elements are specific to the IMU sensor. Topic on which data is published. The properties of the noise model that should be applied to generated data The type of noise. Currently supported types are: "gaussian" (draw noise values independently for each beam from a Gaussian distribution). Noise parameters for angular rates. For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian," the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which bias values are drawn. Noise parameters for linear accelerations. For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian," the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which bias values are drawn. sdformat-6.0.0+dfsg/sdf/1.4/inertial.sdf000066400000000000000000000032201323606632500176410ustar00rootroot00000000000000 The inertial properties of the link. The mass of the link. This is the pose of the inertial reference frame, relative to the link reference frame. The origin of the inertial reference frame needs to be at the center of gravity. The axes of the inertial reference frame do not need to be aligned with the principal axes of the inertia. The 3x3 rotational inertia matrix. Because the rotational inertia matrix is symmetric, only 6 above-diagonal elements of this matrix are specified here, using the attributes ixx, ixy, ixz, iyy, iyz, izz. sdformat-6.0.0+dfsg/sdf/1.4/joint.sdf000066400000000000000000000275071323606632500171730ustar00rootroot00000000000000 A joint connections two links with kinematic and dynamic properties. A unique name for the joint within the scope of the model. The type of joint, which must be one of the following: (revolute) a hinge joint that rotates on a single axis with either a fixed or continuous range of motion, (gearbox) geared revolute joints, (revolute2) same as two revolute joints connected in series, (prismatic) a sliding joint that slides along an axis with a limited range specified by upper and lower limits, (ball) a ball and socket joint, (universal), like a ball joint, but constrains one degree of freedom, (piston) similar to a Slider joint except that rotation around the translation axis is possible. Name of the parent link Name of the child link offset from child link origin in child link frame. Parameter for gearbox joints. Given theta_1 and theta_2 defined in description for gearbox_reference_body, theta_2 = -gearbox_ratio * theta_1. Parameter for gearbox joints. Gearbox ratio is enforced over two joint angles. First joint angle (theta_1) is the angle from the gearbox_reference_body to the parent link in the direction of the axis element and the second joint angle (theta_2) is the angle from the gearbox_reference_body to the child link in the direction of the axis2 element. Parameter for screw joints. The joint axis specified in the parent model frame. This is the axis of rotation for revolute joints, the axis of translation for prismatic joints. The axis is currently specified in the parent model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. specifies the limits of this joint An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Support physics engines: SimBody. Joint stop dissipation. The second joint axis specified in the parent model frame. This is the second axis of rotation for revolute2 joints and universal joints. The axis is currently specified in the parent model frame of reference, but this will be changed to the joint frame in future version of sdf (see gazebo issue #494). Represents the x,y,z components of a vector. The vector should be normalized. An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. EXPERIMENTAL: if damping coefficient is negative and implicit_spring_damper is true, adaptive damping is used. The physical static friction value of the joint. An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Supported physics engines: SimBody. Joint stop dissipation. Supported physics engines: SimBody. Parameters that are specific to a certain physics engine. Simbody specific parameters Force cut in the multibody graph at this joint. ODE specific parameters (DEPRECATION WARNING: In SDF 1.5 this tag will be replaced by the same tag directly under the physics-block. For now, this tag overrides the one outside of ode-block, but in SDF 1.5 this tag will be removed completely.) If provide feedback is set to true, ODE will compute the constraint forces at this joint. If cfm damping is set to true, ODE will use CFM to simulate damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. If implicit_spring_damper is set to true, ODE will use CFM, ERP to simulate stiffness and damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. This replaces cfm_damping parameter in sdf 1.4. Scale the excess for in a joint motor at joint limits. Should be between zero and one. Constraint force mixing for constrained directions Error reduction parameter for constrained directions Bounciness of the limits Maximum force or torque used to reach the desired velocity. The desired velocity of the joint. Should only be set if you want the joint to move on load. Constraint force mixing parameter used by the joint stop Error reduction parameter used by the joint stop Suspension constraint force mixing parameter Suspension error reduction parameter If provide feedback is set to true, physics engine will compute the constraint forces at this joint. For now, provide_feedback under ode block will override this tag and given user warning about the migration. provide_feedback under ode is scheduled to be removed in SDF 1.5. sdformat-6.0.0+dfsg/sdf/1.4/light.sdf000066400000000000000000000054331323606632500171510ustar00rootroot00000000000000 The light element describes a light source. A unique name for the light. The light type: point, directional, spot. When true, the light will cast shadows. A position and orientation in the global coordinate frame for the light. Diffuse light color Specular light color Light attenuation Range of the light The linear attenuation factor: 1 means attenuate evenly over the distance. The constant attenuation factor: 1.0 means never attenuate, 0.0 is complete attenutation. The quadratic attenuation factor: adds a curvature to the attenuation. Direction of the light, only applicable for spot and directional lights. Spot light parameters Angle covered by the bright inner cone Angle covered by the outer cone The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff. sdformat-6.0.0+dfsg/sdf/1.4/link.sdf000066400000000000000000000040531323606632500167740ustar00rootroot00000000000000 A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model. A unique name for the link within the scope of the model. If true, the link is affected by gravity. If true, the link can collide with other links in the model. If true, the link is kinematic only This is the pose of the link reference frame, relative to the model reference frame. If true, the link will have 6DOF and be a direct child of world. Exponential damping of the link's velocity. Linear damping Angular damping sdformat-6.0.0+dfsg/sdf/1.4/mesh_shape.sdf000066400000000000000000000017611323606632500201560ustar00rootroot00000000000000 Mesh shape Mesh uri Use a named submesh. The submesh must exist in the mesh specified by the uri Name of the submesh within the parent mesh Set to true to center the vertices of the submesh at 0,0,0. This will effectively remove any transformations on the submesh before the poses from parent links and models are applied. Scaling factor applied to the mesh sdformat-6.0.0+dfsg/sdf/1.4/model.sdf000066400000000000000000000025121323606632500171350ustar00rootroot00000000000000 The model element defines a complete robot or any other physical object. A unique name for the model. This name must not match another model in the world. If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. Allows a model to auto-disable, which is means the physics engine can skip updating the model when the model is at rest. This parameter is only used by models with no joints. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.4/noise.sdf000066400000000000000000000031231323606632500171510ustar00rootroot00000000000000 The properties of a sensor noise model. The type of noise. Currently supported types are: "none" (no noise). "gaussian" (draw noise values independently for each measurement from a Gaussian distribution). "gaussian_quantized" ("gaussian" plus quantization of outputs (ie. rounding)) For type "gaussian*", the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which bias values are drawn. For type "gaussian_quantized", the precision of output signals. A value of zero implies infinite precision / no quantization. sdformat-6.0.0+dfsg/sdf/1.4/physics.sdf000066400000000000000000000271221323606632500175230ustar00rootroot00000000000000 The physics tag specifies the type and properties of the dynamics engine. The type of the dynamics engine. Current options are ode, bullet, simbody and rtql8. Defaults to ode if left unspecified. Maximum time step size at which every system in simulation can interact with the states of the world. (was physics.sdf's dt). target simulation speedup factor, defined by ratio of simulation time to real-time. Rate at which to update the physics engine (UpdatePhysics calls per real-time second). (was physics.sdf's update_rate). Maximum number of contacts allowed between two entities. This value can be over ridden by a max_contacts element in a collision element. The gravity vector Simbody specific physics properties (Currently not used in simbody) The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Roughly the relative error of the system. -LOG(accuracy) is roughly the number of significant digits. Tolerable "slip" velocity allowed by the solver when static friction is supposed to hold object in place. vc Assume real COR=1 when v=0. e_min = given minimum COR, at v >= vp (a.k.a. plastic_coef_restitution) d = slope = (1-e_min)/vp OR, e_min = 1 - d*vp e_max = maximum COR = 1-d*vc, reached at v=vc e = 0, v <= vc = 1 - d*v, vc < v < vp = e_min, v >= vp dissipation factor = d*min(v,vp) [compliant] cor = e [rigid] Combining rule e = 0, e1==e2==0 = 2*e1*e2/(e1+e2), otherwise]]> Default contact material stiffness (force/dist or torque/radian). dissipation coefficient to be used in compliant contact; if not given it is (1-min_cor)/plastic_impact_velocity this is the COR to be used at high velocities for rigid impacts; if not given it is 1 - dissipation*plastic_impact_velocity smallest impact velocity at which min COR is reached; set to zero if you want the min COR always to be used static friction (mu_s) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png dynamic friction (mu_d) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png viscous friction (mu_v) with units of (1/velocity) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png for rigid impacts only, impact velocity at which COR is set to zero; normally inherited from global default but can be overridden here. Combining rule: use larger velocity This is the largest slip velocity at which we'll consider a transition to stiction. Normally inherited from a global default setting. For a continuous friction model this is the velocity at which the max static friction force is reached. Combining rule: use larger velocity Bullet specific physics properties One of the following types: sequential_impulse only. The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Set the successive over-relaxation parameter. Bullet constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. ODE specific physics properties One of the following types: world, quick The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Experimental parameter. Set the successive over-relaxation parameter. Flag to enable dynamic rescaling of moment of inertia in constrained directions. See gazebo pull request 1114 for the implementation of this feature. https://bitbucket.org/osrf/gazebo/pull-request/1114 ODE constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The maximum correcting velocities allowed when resolving contacts. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. sdformat-6.0.0+dfsg/sdf/1.4/plane_shape.sdf000066400000000000000000000006031323606632500203130ustar00rootroot00000000000000 Plane shape Normal direction for the plane Length of each side of the plane sdformat-6.0.0+dfsg/sdf/1.4/plugin.sdf000066400000000000000000000016061323606632500173360ustar00rootroot00000000000000 A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor. A unique name for the plugin, scoped to its parent. Name of the shared library to load. If the filename is not a full path name, the file will be searched for in the configuration paths. This is a special element that should not be specified in an SDF file. It automatically copies child elements into the SDF element so that a plugin can access the data. sdformat-6.0.0+dfsg/sdf/1.4/projector.sdf000066400000000000000000000016421323606632500200470ustar00rootroot00000000000000 Name of the projector Texture name Pose of the projector Field of view Near clip distance far clip distance sdformat-6.0.0+dfsg/sdf/1.4/ray.sdf000066400000000000000000000070261323606632500166350ustar00rootroot00000000000000 These elements are specific to the ray (laser) sensor. The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle specifies range properties of each simulated ray The minimum distance for each ray. The maximum distance for each ray. Linear resolution of each ray. The properties of the noise model that should be applied to generated scans The type of noise. Currently supported types are: "gaussian" (draw noise values independently for each beam from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. sdformat-6.0.0+dfsg/sdf/1.4/rfid.sdf000066400000000000000000000001061323606632500167560ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.4/rfidtag.sdf000066400000000000000000000001001323606632500174440ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.4/road.sdf000066400000000000000000000007531323606632500167670ustar00rootroot00000000000000 Name of the road Width of the road A series of points define the path of the road. sdformat-6.0.0+dfsg/sdf/1.4/root.sdf000066400000000000000000000007021323606632500170170ustar00rootroot00000000000000 SDF base element. Version number of the SDF format. sdformat-6.0.0+dfsg/sdf/1.4/scene.sdf000066400000000000000000000057201323606632500171360ustar00rootroot00000000000000 Specifies the look of the environment. Color of the ambient light. Color of the background. Properties for the sky Time of day [0..24] Sunrise time [0..24] Sunset time [0..24] Sunset time [0..24] Speed of the clouds Direction of the cloud movement Density of clouds Average size of the clouds Ambient cloud color Enable/disable shadows Controls fog Fog color Fog type: constant, linear, quadratic Distance to start of fog Distance to end of fog Density of fog Enable/disable the grid sdformat-6.0.0+dfsg/sdf/1.4/sensor.sdf000066400000000000000000000041151323606632500173470ustar00rootroot00000000000000 The sensor tag describes the type and properties of a sensor. A unique name for the sensor. This name must not match another model in the model. The type name of the sensor. By default, SDF supports types camera, depth, multicamera, contact, gps, imu, ir and ray. If true the sensor will always be updated according to the update rate. The frequency at which the sensor data is generated. If left unspecified, the sensor will generate data every cycle. If true, the sensor is visualized in the GUI This is the pose of the sensor, relative to the parent link reference frame. Name of the topic on which data is published. This is necessary for visualization sdformat-6.0.0+dfsg/sdf/1.4/sonar.sdf000066400000000000000000000010021323606632500171500ustar00rootroot00000000000000 These elements are specific to the sonar sensor. Minimum range Max range Radius of the sonar cone at max range. sdformat-6.0.0+dfsg/sdf/1.4/sphere_shape.sdf000066400000000000000000000003341323606632500205030ustar00rootroot00000000000000 Sphere shape radius of the sphere sdformat-6.0.0+dfsg/sdf/1.4/spherical_coordinates.sdf000066400000000000000000000026061323606632500224050ustar00rootroot00000000000000 Name of planetary surface model, used to determine the surface altitude at a given latitude and longitude. The default is an ellipsoid model of the earth based on the WGS-84 standard. It is used in Gazebo's GPS sensor implementation. Geodetic latitude at origin of gazebo reference frame, specified in units of degrees. Longitude at origin of gazebo reference frame, specified in units of degrees. Elevation of origin of gazebo reference frame, specified in meters. Heading offset of gazebo reference frame, measured as angle between East and gazebo x axis, or equivalently, the angle between North and gazebo y axis. The angle is specified in degrees. sdformat-6.0.0+dfsg/sdf/1.4/state.sdf000066400000000000000000000070611323606632500171610ustar00rootroot00000000000000 Name of the world this state applies to Simulation time stamp of the state [seconds nanoseconds] Wall time stamp of the state [seconds nanoseconds] Real time stamp of the state [seconds nanoseconds] A list of new model names A list of deleted model names The name of a deleted model Model state Name of the model Pose of the model Joint angle Name of the joint Index of the axis. Angle of an axis Link state Name of the link Pose of the link relative to the model Velocity of the link Acceleration of the link Force applied to the link Collision state Name of the collision Pose of the link relative to the model sdformat-6.0.0+dfsg/sdf/1.4/surface.sdf000066400000000000000000000160731323606632500174740ustar00rootroot00000000000000 The surface parameters Bounciness coefficient of restitution, from [0...1], where 0=no bounciness. Bounce capture velocity, below which effective coefficient of restitution is 0. ODE friction parameters Coefficient of friction in the range of [0..1]. Second coefficient of friction in the range of [0..1] 3-tuple specifying direction of mu1 in the collision local reference frame. Force dependent slip direction 1 in collision local frame, between the range of [0..1]. Force dependent slip direction 2 in collision local frame, between the range of [0..1]. Coefficient of friction in the range of [0..1]. Coefficient of friction in the range of [0..1]. 3-tuple specifying direction of mu1 in the collision local reference frame. coefficient of friction in the range of [0..1] Flag to disable contact force generation, while still allowing collision checks and contact visualization to occur. Bitmask for collision filtering when collide_without_contact is on Bitmask for collision filtering. This will override collide_without_contact ODE contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints maximum contact correction velocity truncation term. minimum allowable depth before contact correction impulse is applied Bullet contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. soft contact pamameters based on paper: http://www.cc.gatech.edu/graphics/projects/Sumit/homepage/papers/sigasia11/jain_softcontacts_siga11.pdf This is variable k_v in the soft contacts paper. Its unit is N/m. This is variable k_e in the soft contacts paper. Its unit is N/m. Viscous damping of point velocity in body frame. Its unit is N/m/s. Fraction of mass to be distributed among deformable nodes. sdformat-6.0.0+dfsg/sdf/1.4/transceiver.sdf000066400000000000000000000027111323606632500203630ustar00rootroot00000000000000 These elements are specific to a wireless transceiver. Service set identifier (network name) Specifies the frequency of transmission in MHz Only a frequency range is filtered. Here we set the lower bound (MHz). Only a frequency range is filtered. Here we set the upper bound (MHz). Specifies the antenna gain in dBi Specifies the transmission power in dBm Mininum received signal power in dBm sdformat-6.0.0+dfsg/sdf/1.4/urdf.sdf000066400000000000000000000015401323606632500167750ustar00rootroot00000000000000 The robot element defines a complete robot or any other physical object using URDF. A unique name for the model. This name must not match another model in the world. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.4/visual.sdf000066400000000000000000000066671323606632500173570ustar00rootroot00000000000000 The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes. Unique name for the visual element within the scope of the parent link. If true the visual will cast shadows. will be implemented in the future release. The amount of transparency( 0=opaque, 1 = fully transparent) The reference frame of the visual element, relative to the reference frame of the link. The material of the visual element. Name of material from an installed script file. This will override the color element if the script exists. URI of the material script file Name of the script within the script file vertex, pixel, normal_map_objectspace, normal_map_tangentspace filename of the normal map If false, dynamic lighting will be disabled The ambient color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. The diffuse color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The specular color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The emissive color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. sdformat-6.0.0+dfsg/sdf/1.4/world.sdf000066400000000000000000000030001323606632500171550ustar00rootroot00000000000000 The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins Unique name of the world Global audio properties. Device to use for audio playback. A value of "default" will use the system's default audio device. Otherwise, specify a an audio device file" Include resources from a URI URI to a resource, such as a model sdformat-6.0.0+dfsg/sdf/1.5/000077500000000000000000000000001323606632500153405ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.5/1_4.convert000066400000000000000000000020461323606632500173270ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.5/CMakeLists.txt000066400000000000000000000031741323606632500201050ustar00rootroot00000000000000set (sdfs actor.sdf altimeter.sdf audio_source.sdf audio_sink.sdf battery.sdf box_shape.sdf camera.sdf collision.sdf contact.sdf cylinder_shape.sdf frame.sdf forcetorque.sdf geometry.sdf gps.sdf gripper.sdf gui.sdf heightmap_shape.sdf image_shape.sdf imu.sdf inertial.sdf joint.sdf light.sdf light_state.sdf link.sdf link_state.sdf logical_camera.sdf magnetometer.sdf material.sdf mesh_shape.sdf model.sdf model_state.sdf noise.sdf physics.sdf plane_shape.sdf plugin.sdf polyline_shape.sdf population.sdf pose.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf root.sdf scene.sdf sensor.sdf spherical_coordinates.sdf sphere_shape.sdf sonar.sdf state.sdf surface.sdf transceiver.sdf visual.sdf world.sdf ) set (SDF_SCHEMA) foreach(FIL ${sdfs}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) list(APPEND SDF_SCHEMA "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.xsd") add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.xsd" COMMAND ${RUBY} ${CMAKE_SOURCE_DIR}/tools/xmlschema.rb ARGS -s ${CMAKE_CURRENT_SOURCE_DIR} -i ${ABS_FIL} -o ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${ABS_FIL} COMMENT "Running xml schema compiler on ${FIL}" VERBATIM) endforeach() add_custom_target(schema1_5 ALL DEPENDS ${SDF_SCHEMA}) set_source_files_properties(${SDF_SCHEMA} PROPERTIES GENERATED TRUE) install(FILES 1_4.convert ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.5) install(FILES ${SDF_SCHEMA} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.5) sdformat-6.0.0+dfsg/sdf/1.5/actor.sdf000066400000000000000000000054011323606632500171460ustar00rootroot00000000000000 Actors should be static, in terms of physics simulation. sdformat-6.0.0+dfsg/sdf/1.5/altimeter.sdf000066400000000000000000000010131323606632500200170ustar00rootroot00000000000000 These elements are specific to an altimeter sensor. Noise parameters for vertical position Noise parameters for vertical velocity sdformat-6.0.0+dfsg/sdf/1.5/audio_sink.sdf000066400000000000000000000001641323606632500201640ustar00rootroot00000000000000 An audio sink. sdformat-6.0.0+dfsg/sdf/1.5/audio_source.sdf000066400000000000000000000021631323606632500205210ustar00rootroot00000000000000 An audio source. URI of the audio media. Pitch for the audio media, in Hz Gain for the audio media, in dB. List of collision objects that will trigger audio playback. Name of child collision element that will trigger audio playback. True to make the audio source loop playback. sdformat-6.0.0+dfsg/sdf/1.5/battery.sdf000066400000000000000000000006331323606632500175120ustar00rootroot00000000000000 Description of a battery. Unique name for the battery. Initial voltage in volts. sdformat-6.0.0+dfsg/sdf/1.5/box_shape.sdf000066400000000000000000000004701323606632500200070ustar00rootroot00000000000000 Box shape The three side lengths of the box. The origin of the box is in its geometric center (inside the center of the box). sdformat-6.0.0+dfsg/sdf/1.5/camera.sdf000066400000000000000000000152351323606632500172740ustar00rootroot00000000000000 These elements are specific to camera sensors. An optional name for the camera. Horizontal field of view The image size in pixels and format. Width in pixels Height in pixels (L8|R8G8B8|B8G8R8|BAYER_RGGB8|BAYER_BGGR8|BAYER_GBRG8|BAYER_GRBG8) The near and far clip planes. Objects closer or farther than these planes are not rendered. Near clipping plane Far clipping plane Enable or disable saving of camera frames. True = saving enabled The path name which will hold the frame data. If path name is relative, then directory is relative to current working directory. Depth camera parameters Type of output The properties of the noise model that should be applied to generated images The type of noise. Currently supported types are: "gaussian" (draw additive noise values independently for each pixel from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. Lens distortion to be applied to camera images. See http://en.wikipedia.org/wiki/Distortion_(optics)#Software_correction The radial distortion coefficient k1 The radial distortion coefficient k2 The radial distortion coefficient k3 The tangential distortion coefficient p1 The tangential distortion coefficient p2 The distortion center or principal point Lens projection description Type of the lens mapping. Supported values are gnomonical, stereographic, equidistant, equisolid_angle, orthographic, custom. For gnomonical (perspective) projection, it is recommended to specify a horizontal_fov of less than or equal to 90° If true the image will be scaled to fit horizontal FOV, otherwise it will be shown according to projection type parameters Definition of custom mapping function in a form of r=c1*f*fun(theta/c2 + c3). See https://en.wikipedia.org/wiki/Fisheye_lens#Mapping_function Linear scaling constant Angle scaling constant Angle offset constant Focal length of the optical system. Note: It's not a focal length of the lens in a common sense! This value is ignored if 'scale_to_fov' is set to true Possible values are 'sin', 'tan' and 'id' Everything outside of the specified angle will be hidden, 90° by default Resolution of the environment cube map used to draw the world sdformat-6.0.0+dfsg/sdf/1.5/collision.sdf000066400000000000000000000021071323606632500200310ustar00rootroot00000000000000 The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time. Unique name for the collision element within the scope of the parent link. intensity value returned by laser sensor. Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics. sdformat-6.0.0+dfsg/sdf/1.5/collision_engine.sdf000066400000000000000000000013111323606632500213520ustar00rootroot00000000000000 The collision_engine tag specifies the type and properties of the collision detection engine. The type of the collision detection engine. Current default in ODE is OPCODE. The type of the collision detection engine. sdformat-6.0.0+dfsg/sdf/1.5/contact.sdf000066400000000000000000000010351323606632500174700ustar00rootroot00000000000000 These elements are specific to the contact sensor. name of the collision element within a link that acts as the contact sensor. Topic on which contact data is published. sdformat-6.0.0+dfsg/sdf/1.5/cylinder_shape.sdf000066400000000000000000000005461323606632500210340ustar00rootroot00000000000000 Cylinder shape Radius of the cylinder Length of the cylinder sdformat-6.0.0+dfsg/sdf/1.5/forcetorque.sdf000066400000000000000000000022301323606632500203710ustar00rootroot00000000000000 These elements are specific to the force torque sensor. Frame in which to report the wrench values. Currently supported frames are: "parent" report the wrench expressed in the orientation of the parent link frame, "child" report the wrench expressed in the orientation of the child link frame, "sensor" report the wrench expressed in the orientation of the joint sensor frame. Note that for each option the point with respect to which the torque component of the wrench is expressed is the joint origin. Direction of the wrench measured by the sensor. The supported options are: "parent_to_child" if the measured wrench is the one applied by parent link on the child link, "child_to_parent" if the measured wrench is the one applied by the child link on the parent link. sdformat-6.0.0+dfsg/sdf/1.5/frame.sdf000066400000000000000000000006631323606632500171350ustar00rootroot00000000000000 A frame of reference to which a pose is relative. Name of the frame. This name must not match another frame defined inside the parent that this frame is attached to. sdformat-6.0.0+dfsg/sdf/1.5/geometry.sdf000066400000000000000000000013571323606632500176770ustar00rootroot00000000000000 The shape of the visual or collision object. You can use the empty tag to make empty geometries. sdformat-6.0.0+dfsg/sdf/1.5/gps.sdf000066400000000000000000000025341323606632500166330ustar00rootroot00000000000000 These elements are specific to the GPS sensor. Parameters related to GPS position measurement. Noise parameters for horizontal position measurement, in units of meters. Noise parameters for vertical position measurement, in units of meters. Parameters related to GPS position measurement. Noise parameters for horizontal velocity measurement, in units of meters/second. Noise parameters for vertical velocity measurement, in units of meters/second. sdformat-6.0.0+dfsg/sdf/1.5/gripper.sdf000066400000000000000000000016461323606632500175150ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.5/gui.sdf000066400000000000000000000025431323606632500166260ustar00rootroot00000000000000 Set the type of projection for the camera. Valid values are "perspective" and "orthographic". sdformat-6.0.0+dfsg/sdf/1.5/heightmap_shape.sdf000066400000000000000000000042671323606632500211750ustar00rootroot00000000000000 A heightmap based on a 2d grayscale image. URI to a grayscale image file The size of the heightmap in world units. When loading an image: "size" is used if present, otherwise defaults to 1x1x1. When loading a DEM: "size" is used if present, otherwise defaults to true size of DEM. A position offset. The heightmap can contain multiple textures. The order of the texture matters. The first texture will appear at the lowest height, and the last texture at the highest height. Use blend to control the height thresholds and fade between textures. Size of the applied texture in meters. Diffuse texture image filename Normalmap texture image filename The blend tag controls how two adjacent textures are mixed. The number of blend elements should equal one less than the number of textures. Min height of a blend layer Distance over which the blend occurs Set if the rendering engine will use terrain paging sdformat-6.0.0+dfsg/sdf/1.5/image_shape.sdf000066400000000000000000000014741323606632500203060ustar00rootroot00000000000000 Extrude a set of boxes from a grayscale image. URI of the grayscale image file Scaling factor applied to the image Grayscale threshold Height of the extruded boxes The amount of error in the model sdformat-6.0.0+dfsg/sdf/1.5/imu.sdf000066400000000000000000000103431323606632500166310ustar00rootroot00000000000000 These elements are specific to the IMU sensor. Topic on which data is published. These elements are specific to body-frame angular velocity, which is expressed in radians per second Angular velocity about the X axis Angular velocity about the Y axis Angular velocity about the Z axis These elements are specific to body-frame linear acceleration, which is expressed in meters per second squared Linear acceleration about the X axis Linear acceleration about the Y axis Linear acceleration about the Z axis The properties of the noise model that should be applied to generated data The type of noise. Currently supported types are: "gaussian" (draw noise values independently for each beam from a Gaussian distribution). Noise parameters for angular rates. For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian," the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which bias values are drawn. Noise parameters for linear accelerations. For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian," the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which bias values are drawn. sdformat-6.0.0+dfsg/sdf/1.5/inertial.sdf000066400000000000000000000032531323606632500176500ustar00rootroot00000000000000 The inertial properties of the link. The mass of the link. This is the pose of the inertial reference frame, relative to the specified reference frame. The origin of the inertial reference frame needs to be at the center of gravity. The axes of the inertial reference frame do not need to be aligned with the principal axes of the inertia. The 3x3 rotational inertia matrix. Because the rotational inertia matrix is symmetric, only 6 above-diagonal elements of this matrix are specified here, using the attributes ixx, ixy, ixz, iyy, iyz, izz. sdformat-6.0.0+dfsg/sdf/1.5/joint.sdf000066400000000000000000000321671323606632500171720ustar00rootroot00000000000000 A joint connections two links with kinematic and dynamic properties. A unique name for the joint within the scope of the model. The type of joint, which must be one of the following: (revolute) a hinge joint that rotates on a single axis with either a fixed or continuous range of motion, (gearbox) geared revolute joints, (revolute2) same as two revolute joints connected in series, (prismatic) a sliding joint that slides along an axis with a limited range specified by upper and lower limits, (ball) a ball and socket joint, (screw) a single degree of freedom joint with coupled sliding and rotational motion, (universal) like a ball joint, but constrains one degree of freedom, (fixed) a joint with zero degrees of freedom that rigidly connects two links. Name of the parent link Name of the child link Parameter for gearbox joints. Given theta_1 and theta_2 defined in description for gearbox_reference_body, theta_2 = -gearbox_ratio * theta_1. Parameter for gearbox joints. Gearbox ratio is enforced over two joint angles. First joint angle (theta_1) is the angle from the gearbox_reference_body to the parent link in the direction of the axis element and the second joint angle (theta_2) is the angle from the gearbox_reference_body to the child link in the direction of the axis2 element. Parameter for screw joints. Parameters related to the axis of rotation for revolute joints, the axis of translation for prismatic joints. Represents the x,y,z components of the axis unit vector. The axis is expressed in the joint frame unless the use_parent_model_frame flag is set to true. The vector should be normalized. Flag to interpret the axis xyz element in the parent model frame instead of joint frame. Provided for Gazebo compatibility (see https://bitbucket.org/osrf/gazebo/issue/494 ). An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. The spring reference position for this joint axis. The spring stiffness for this joint axis. specifies the limits of this joint An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Support physics engines: SimBody. Joint stop dissipation. Parameters related to the second axis of rotation for revolute2 joints and universal joints. Represents the x,y,z components of the axis unit vector. The axis is expressed in the joint frame unless the use_parent_model_frame flag is set to true. The vector should be normalized. Flag to interpret the axis xyz element in the parent model frame instead of joint frame. Provided for Gazebo compatibility (see https://bitbucket.org/osrf/gazebo/issue/494 ). An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. EXPERIMENTAL: if damping coefficient is negative and implicit_spring_damper is true, adaptive damping is used. The physical static friction value of the joint. The spring reference position for this joint axis. The spring stiffness for this joint axis. An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Supported physics engines: SimBody. Joint stop dissipation. Supported physics engines: SimBody. Parameters that are specific to a certain physics engine. Simbody specific parameters Force cut in the multibody graph at this joint. ODE specific parameters (DEPRECATION WARNING: In SDF 1.5 this tag will be replaced by the same tag directly under the physics-block. For now, this tag overrides the one outside of ode-block, but in SDF 1.5 this tag will be removed completely.) If provide feedback is set to true, ODE will compute the constraint forces at this joint. If cfm damping is set to true, ODE will use CFM to simulate damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. If implicit_spring_damper is set to true, ODE will use CFM, ERP to simulate stiffness and damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. This replaces cfm_damping parameter in sdf 1.4. Scale the excess for in a joint motor at joint limits. Should be between zero and one. Constraint force mixing for constrained directions Error reduction parameter for constrained directions Bounciness of the limits Maximum force or torque used to reach the desired velocity. The desired velocity of the joint. Should only be set if you want the joint to move on load. Constraint force mixing parameter used by the joint stop Error reduction parameter used by the joint stop Suspension constraint force mixing parameter Suspension error reduction parameter If provide feedback is set to true, physics engine will compute the constraint forces at this joint. For now, provide_feedback under ode block will override this tag and given user warning about the migration. provide_feedback under ode is scheduled to be removed in SDF 1.5. sdformat-6.0.0+dfsg/sdf/1.5/light.sdf000066400000000000000000000052741323606632500171550ustar00rootroot00000000000000 The light element describes a light source. A unique name for the light. The light type: point, directional, spot. When true, the light will cast shadows. Diffuse light color Specular light color Light attenuation Range of the light The linear attenuation factor: 1 means attenuate evenly over the distance. The constant attenuation factor: 1.0 means never attenuate, 0.0 is complete attenutation. The quadratic attenuation factor: adds a curvature to the attenuation. Direction of the light, only applicable for spot and directional lights. Spot light parameters Angle covered by the bright inner cone Angle covered by the outer cone The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff. sdformat-6.0.0+dfsg/sdf/1.5/light_state.sdf000066400000000000000000000005741323606632500203530ustar00rootroot00000000000000 Light state Name of the light sdformat-6.0.0+dfsg/sdf/1.5/link.sdf000066400000000000000000000041621323606632500167760ustar00rootroot00000000000000 A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model. A unique name for the link within the scope of the model. If true, the link is affected by gravity. If true, the link can collide with other links in the model. Two links within a model will collide if link1.self_collide OR link2.self_collide. Links connected by a joint will never collide. If true, the link is kinematic only If true, the link will have 6DOF and be a direct child of world. Exponential damping of the link's velocity. Linear damping Angular damping sdformat-6.0.0+dfsg/sdf/1.5/link_state.sdf000066400000000000000000000031331323606632500201730ustar00rootroot00000000000000 Link state Name of the link Velocity of the link. The x, y, z components of the pose correspond to the linear velocity of the link, and the roll, pitch, yaw components correspond to the angular velocity of the link Acceleration of the link. The x, y, z components of the pose correspond to the linear acceleration of the link, and the roll, pitch, yaw components correspond to the angular acceleration of the link Force and torque applied to the link. The x, y, z components of the pose correspond to the force applied to the link, and the roll, pitch, yaw components correspond to the torque applied to the link Collision state Name of the collision sdformat-6.0.0+dfsg/sdf/1.5/logical_camera.sdf000066400000000000000000000020031323606632500207530ustar00rootroot00000000000000 These elements are specific to logical camera sensors. A logical camera reports objects that fall within a frustum. Computation should be performed on the CPU. Near clipping distance of the view frustum Far clipping distance of the view frustum Aspect ratio of the near and far planes. This is the width divided by the height of the near or far planes. Horizontal field of view of the frustum, in radians. This is the angle between the frustum's vertex and the edges of the near or far plane. sdformat-6.0.0+dfsg/sdf/1.5/magnetometer.sdf000066400000000000000000000013511323606632500205250ustar00rootroot00000000000000 These elements are specific to a Magnetometer sensor. Parameters related to the body-frame X axis of the magnetometer Parameters related to the body-frame Y axis of the magnetometer Parameters related to the body-frame Z axis of the magnetometer sdformat-6.0.0+dfsg/sdf/1.5/material.sdf000066400000000000000000000042141323606632500176350ustar00rootroot00000000000000 The material of the visual element. Name of material from an installed script file. This will override the color element if the script exists. URI of the material script file Name of the script within the script file vertex, pixel, normal_map_objectspace, normal_map_tangentspace filename of the normal map If false, dynamic lighting will be disabled The ambient color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. The diffuse color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The specular color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The emissive color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. sdformat-6.0.0+dfsg/sdf/1.5/mesh_shape.sdf000066400000000000000000000017611323606632500201570ustar00rootroot00000000000000 Mesh shape Mesh uri Use a named submesh. The submesh must exist in the mesh specified by the uri Name of the submesh within the parent mesh Set to true to center the vertices of the submesh at 0,0,0. This will effectively remove any transformations on the submesh before the poses from parent links and models are applied. Scaling factor applied to the mesh sdformat-6.0.0+dfsg/sdf/1.5/model.sdf000066400000000000000000000055241323606632500171440ustar00rootroot00000000000000 The model element defines a complete robot or any other physical object. A unique name for the model. This name must not match another model in the world. If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. If set to true, all links in the model will collide with each other (except those connected by a joint). Can be overridden by the link or collision element self_collide property. Two links within a model will collide if link1.self_collide OR link2.self_collide. Links connected by a joint will never collide. Allows a model to auto-disable, which is means the physics engine can skip updating the model when the model is at rest. This parameter is only used by models with no joints. Include resources from a URI. This can be used to nest models. URI to a resource, such as a model Override the pose of the included model. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. Override the name of the included model. Override the static value of the included model. A nested model element A unique name for the model. This name must not match another nested model in the same level as this model. sdformat-6.0.0+dfsg/sdf/1.5/model_state.sdf000066400000000000000000000023211323606632500203340ustar00rootroot00000000000000 Model state Name of the model Joint angle Name of the joint Index of the axis. Angle of an axis A nested model state element Name of the model. sdformat-6.0.0+dfsg/sdf/1.5/noise.sdf000066400000000000000000000031231323606632500171520ustar00rootroot00000000000000 The properties of a sensor noise model. The type of noise. Currently supported types are: "none" (no noise). "gaussian" (draw noise values independently for each measurement from a Gaussian distribution). "gaussian_quantized" ("gaussian" plus quantization of outputs (ie. rounding)) For type "gaussian*", the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which bias values are drawn. For type "gaussian_quantized", the precision of output signals. A value of zero implies infinite precision / no quantization. sdformat-6.0.0+dfsg/sdf/1.5/physics.sdf000066400000000000000000000307221323606632500175240ustar00rootroot00000000000000 The physics tag specifies the type and properties of the dynamics engine. The name of this set of physics parameters. If true, this physics element is set as the default physics profile for the world. If multiple default physics elements exist, the first element marked as default is chosen. If no default physics element exists, the first physics element is chosen. The type of the dynamics engine. Current options are ode, bullet, simbody and rtql8. Defaults to ode if left unspecified. Maximum time step size at which every system in simulation can interact with the states of the world. (was physics.sdf's dt). target simulation speedup factor, defined by ratio of simulation time to real-time. Rate at which to update the physics engine (UpdatePhysics calls per real-time second). (was physics.sdf's update_rate). Maximum number of contacts allowed between two entities. This value can be over ridden by a max_contacts element in a collision element. The gravity vector in m/s^2, expressed in a coordinate frame defined by the spherical_coordinates tag. The magnetic vector in Tesla, expressed in a coordinate frame defined by the spherical_coordinates tag. Simbody specific physics properties (Currently not used in simbody) The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Roughly the relative error of the system. -LOG(accuracy) is roughly the number of significant digits. Tolerable "slip" velocity allowed by the solver when static friction is supposed to hold object in place. vc Assume real COR=1 when v=0. e_min = given minimum COR, at v >= vp (a.k.a. plastic_coef_restitution) d = slope = (1-e_min)/vp OR, e_min = 1 - d*vp e_max = maximum COR = 1-d*vc, reached at v=vc e = 0, v <= vc = 1 - d*v, vc < v < vp = e_min, v >= vp dissipation factor = d*min(v,vp) [compliant] cor = e [rigid] Combining rule e = 0, e1==e2==0 = 2*e1*e2/(e1+e2), otherwise]]> Default contact material stiffness (force/dist or torque/radian). dissipation coefficient to be used in compliant contact; if not given it is (1-min_cor)/plastic_impact_velocity this is the COR to be used at high velocities for rigid impacts; if not given it is 1 - dissipation*plastic_impact_velocity smallest impact velocity at which min COR is reached; set to zero if you want the min COR always to be used static friction (mu_s) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png dynamic friction (mu_d) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png viscous friction (mu_v) with units of (1/velocity) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png for rigid impacts only, impact velocity at which COR is set to zero; normally inherited from global default but can be overridden here. Combining rule: use larger velocity This is the largest slip velocity at which we'll consider a transition to stiction. Normally inherited from a global default setting. For a continuous friction model this is the velocity at which the max static friction force is reached. Combining rule: use larger velocity Bullet specific physics properties One of the following types: sequential_impulse only. The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Set the successive over-relaxation parameter. Bullet constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. ODE specific physics properties One of the following types: world, quick The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Experimental parameter. Set the successive over-relaxation parameter. Flag to enable dynamic rescaling of moment of inertia in constrained directions. See gazebo pull request 1114 for the implementation of this feature. https://bitbucket.org/osrf/gazebo/pull-request/1114 ODE constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The maximum correcting velocities allowed when resolving contacts. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. sdformat-6.0.0+dfsg/sdf/1.5/plane_shape.sdf000066400000000000000000000006031323606632500203140ustar00rootroot00000000000000 Plane shape Normal direction for the plane Length of each side of the plane sdformat-6.0.0+dfsg/sdf/1.5/plugin.sdf000066400000000000000000000016061323606632500173370ustar00rootroot00000000000000 A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor. A unique name for the plugin, scoped to its parent. Name of the shared library to load. If the filename is not a full path name, the file will be searched for in the configuration paths. This is a special element that should not be specified in an SDF file. It automatically copies child elements into the SDF element so that a plugin can access the data. sdformat-6.0.0+dfsg/sdf/1.5/polyline_shape.sdf000066400000000000000000000006601323606632500210530ustar00rootroot00000000000000 Defines an extruded polyline shape A series of points that define the path of the polyline. Height of the polyline sdformat-6.0.0+dfsg/sdf/1.5/population.sdf000066400000000000000000000045211323606632500202320ustar00rootroot00000000000000 The population element defines how and where a set of models will be automatically populated in Gazebo. A unique name for the population. This name must not match another population in the world. The number of models to place. Specifies the type of object distribution and its optional parameters. Define how the objects will be placed in the specified region. - random: Models placed at random. - uniform: Models approximately placed in a 2D grid pattern with control over the number of objects. - grid: Models evenly placed in a 2D grid pattern. The number of objects is not explicitly specified, it is based on the number of rows and columns of the grid. - linear-x: Models evently placed in a row along the global x-axis. - linear-y: Models evently placed in a row along the global y-axis. - linear-z: Models evently placed in a row along the global z-axis. Number of rows in the grid. Number of columns in the grid. Distance between elements of the grid. sdformat-6.0.0+dfsg/sdf/1.5/pose.sdf000066400000000000000000000006131323606632500170040ustar00rootroot00000000000000 A position(x,y,z) and orientation(roll, pitch yaw) with respect to the specified frame. Name of frame which the pose is defined relative to. sdformat-6.0.0+dfsg/sdf/1.5/projector.sdf000066400000000000000000000015641323606632500200530ustar00rootroot00000000000000 Name of the projector Texture name Field of view Near clip distance far clip distance sdformat-6.0.0+dfsg/sdf/1.5/ray.sdf000066400000000000000000000070261323606632500166360ustar00rootroot00000000000000 These elements are specific to the ray (laser) sensor. The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle specifies range properties of each simulated ray The minimum distance for each ray. The maximum distance for each ray. Linear resolution of each ray. The properties of the noise model that should be applied to generated scans The type of noise. Currently supported types are: "gaussian" (draw noise values independently for each beam from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. sdformat-6.0.0+dfsg/sdf/1.5/rfid.sdf000066400000000000000000000001061323606632500167570ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.5/rfidtag.sdf000066400000000000000000000001001323606632500174450ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.5/road.sdf000066400000000000000000000010421323606632500167600ustar00rootroot00000000000000 Name of the road Width of the road A series of points that define the path of the road. sdformat-6.0.0+dfsg/sdf/1.5/root.sdf000066400000000000000000000007021323606632500170200ustar00rootroot00000000000000 SDF base element. Version number of the SDF format. sdformat-6.0.0+dfsg/sdf/1.5/scene.sdf000066400000000000000000000061471323606632500171430ustar00rootroot00000000000000 Specifies the look of the environment. Color of the ambient light. Color of the background. Properties for the sky Time of day [0..24] Sunrise time [0..24] Sunset time [0..24] Sunset time [0..24] Speed of the clouds Direction of the cloud movement Density of clouds Average size of the clouds Ambient cloud color Enable/disable shadows Controls fog Fog color Fog type: constant, linear, quadratic Distance to start of fog Distance to end of fog Density of fog Enable/disable the grid Show/hide world origin indicator sdformat-6.0.0+dfsg/sdf/1.5/schema/000077500000000000000000000000001323606632500166005ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.5/schema/types.xsd000066400000000000000000000032701323606632500204660ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.5/sensor.sdf000066400000000000000000000050671323606632500173570ustar00rootroot00000000000000 The sensor tag describes the type and properties of a sensor. A unique name for the sensor. This name must not match another model in the model. The type name of the sensor. By default, SDF supports types altimeter, camera, contact, depth, force_torque, gps, gpu_ray, imu, logical_camera, magnetometer, multicamera, ray, rfid, rfidtag, sonar, wireless_receiver, and wireless_transmitter. If true the sensor will always be updated according to the update rate. The frequency at which the sensor data is generated. If left unspecified, the sensor will generate data every cycle. If true, the sensor is visualized in the GUI Name of the topic on which data is published. This is necessary for visualization sdformat-6.0.0+dfsg/sdf/1.5/sonar.sdf000066400000000000000000000010021323606632500171510ustar00rootroot00000000000000 These elements are specific to the sonar sensor. Minimum range Max range Radius of the sonar cone at max range. sdformat-6.0.0+dfsg/sdf/1.5/sphere_shape.sdf000066400000000000000000000003341323606632500205040ustar00rootroot00000000000000 Sphere shape radius of the sphere sdformat-6.0.0+dfsg/sdf/1.5/spherical_coordinates.sdf000066400000000000000000000026061323606632500224060ustar00rootroot00000000000000 Name of planetary surface model, used to determine the surface altitude at a given latitude and longitude. The default is an ellipsoid model of the earth based on the WGS-84 standard. It is used in Gazebo's GPS sensor implementation. Geodetic latitude at origin of gazebo reference frame, specified in units of degrees. Longitude at origin of gazebo reference frame, specified in units of degrees. Elevation of origin of gazebo reference frame, specified in meters. Heading offset of gazebo reference frame, measured as angle between East and gazebo x axis, or equivalently, the angle between North and gazebo y axis. The angle is specified in degrees. sdformat-6.0.0+dfsg/sdf/1.5/state.sdf000066400000000000000000000027261323606632500171650ustar00rootroot00000000000000 Name of the world this state applies to Simulation time stamp of the state [seconds nanoseconds] Wall time stamp of the state [seconds nanoseconds] Real time stamp of the state [seconds nanoseconds] Number of simulation iterations. A list of new model names A list of deleted model names The name of a deleted model sdformat-6.0.0+dfsg/sdf/1.5/surface.sdf000066400000000000000000000234731323606632500174770ustar00rootroot00000000000000 The surface parameters Bounciness coefficient of restitution, from [0...1], where 0=no bounciness. Bounce capture velocity, below which effective coefficient of restitution is 0. Parameters for torsional friction Torsional friction coefficient in the range of [0..1]. If this flag is true, torsional friction is calculated using the "patch_radius" parameter. If this flag is set to false, "surface_radius" (R) and contact depth (d) are used to compute the patch radius as sqrt(R*d). Radius of contact patch surface. Surface radius on the point of contact. Torsional friction parameters for ODE Force dependent slip for torsional friction, between the range of [0..1]. ODE friction parameters Coefficient of friction in the range of [0..1]. Second coefficient of friction in the range of [0..1] 3-tuple specifying direction of mu1 in the collision local reference frame. Force dependent slip direction 1 in collision local frame, between the range of [0..1]. Force dependent slip direction 2 in collision local frame, between the range of [0..1]. Coefficient of friction in the range of [0..1]. Coefficient of friction in the range of [0..1]. 3-tuple specifying direction of mu1 in the collision local reference frame. coefficient of friction in the range of [0..1] Flag to disable contact force generation, while still allowing collision checks and contact visualization to occur. Bitmask for collision filtering when collide_without_contact is on Bitmask for collision filtering. This will override collide_without_contact Poisson's ratio is the ratio between transverse and axial strain. This value must lie between (-1, 0.5). Defaults to 0.3 for typical steel. Note typical silicone elastomers have Poisson's ratio near 0.49 ~ 0.50. For reference, approximate values for Material:(Young's Modulus, Poisson's Ratio) for some of the typical materials are: Plastic: (1e8 ~ 3e9 Pa, 0.35 ~ 0.41), Wood: (4e9 ~ 1e10 Pa, 0.22 ~ 0.50), Aluminum: (7e10 Pa, 0.32 ~ 0.35), Steel: (2e11 Pa, 0.26 ~ 0.31). Young's Modulus in SI derived unit Pascal. Defaults to -1. If value is less or equal to zero, contact using elastic modulus (with Poisson's Ratio) is disabled. For reference, approximate values for Material:(Young's Modulus, Poisson's Ratio) for some of the typical materials are: Plastic: (1e8 ~ 3e9 Pa, 0.35 ~ 0.41), Wood: (4e9 ~ 1e10 Pa, 0.22 ~ 0.50), Aluminum: (7e10 Pa, 0.32 ~ 0.35), Steel: (2e11 Pa, 0.26 ~ 0.31). ODE contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints maximum contact correction velocity truncation term. minimum allowable depth before contact correction impulse is applied Bullet contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. soft contact pamameters based on paper: http://www.cc.gatech.edu/graphics/projects/Sumit/homepage/papers/sigasia11/jain_softcontacts_siga11.pdf This is variable k_v in the soft contacts paper. Its unit is N/m. This is variable k_e in the soft contacts paper. Its unit is N/m. Viscous damping of point velocity in body frame. Its unit is N/m/s. Fraction of mass to be distributed among deformable nodes. sdformat-6.0.0+dfsg/sdf/1.5/transceiver.sdf000066400000000000000000000027111323606632500203640ustar00rootroot00000000000000 These elements are specific to a wireless transceiver. Service set identifier (network name) Specifies the frequency of transmission in MHz Only a frequency range is filtered. Here we set the lower bound (MHz). Only a frequency range is filtered. Here we set the upper bound (MHz). Specifies the antenna gain in dBi Specifies the transmission power in dBm Mininum received signal power in dBm sdformat-6.0.0+dfsg/sdf/1.5/urdf.sdf000066400000000000000000000015401323606632500167760ustar00rootroot00000000000000 The robot element defines a complete robot or any other physical object using URDF. A unique name for the model. This name must not match another model in the world. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.5/visual.sdf000066400000000000000000000032271323606632500173450ustar00rootroot00000000000000 The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes. Unique name for the visual element within the scope of the parent link. If true the visual will cast shadows. will be implemented in the future release. The amount of transparency( 0=opaque, 1 = fully transparent) Optional meta information for the visual. The information contained within this element should be used to provide additional feedback to an end user. The layer in which this visual is displayed. The layer number is useful for programs, such as Gazebo, that put visuals in different layers for enhanced visualization. sdformat-6.0.0+dfsg/sdf/1.5/world.sdf000066400000000000000000000036461323606632500171760ustar00rootroot00000000000000 The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins Unique name of the world Global audio properties. Device to use for audio playback. A value of "default" will use the system's default audio device. Otherwise, specify a an audio device file" Include resources from a URI URI to a resource, such as a model Override the name of the included model. Override the static value of the included model. sdformat-6.0.0+dfsg/sdf/1.6/000077500000000000000000000000001323606632500153415ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.6/1_5.convert000066400000000000000000000274751323606632500173460ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.6/CMakeLists.txt000066400000000000000000000032151323606632500201020ustar00rootroot00000000000000set (sdfs actor.sdf altimeter.sdf atmosphere.sdf audio_source.sdf audio_sink.sdf battery.sdf box_shape.sdf camera.sdf collision.sdf contact.sdf cylinder_shape.sdf frame.sdf forcetorque.sdf geometry.sdf gps.sdf gripper.sdf gui.sdf heightmap_shape.sdf image_shape.sdf imu.sdf inertial.sdf joint.sdf light.sdf light_state.sdf link.sdf link_state.sdf logical_camera.sdf magnetometer.sdf material.sdf mesh_shape.sdf model.sdf model_state.sdf noise.sdf physics.sdf plane_shape.sdf plugin.sdf polyline_shape.sdf population.sdf pose.sdf projector.sdf ray.sdf rfidtag.sdf rfid.sdf road.sdf root.sdf scene.sdf sensor.sdf spherical_coordinates.sdf sphere_shape.sdf sonar.sdf state.sdf surface.sdf transceiver.sdf visual.sdf world.sdf ) set (SDF_SCHEMA) foreach(FIL ${sdfs}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) list(APPEND SDF_SCHEMA "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.xsd") add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.xsd" COMMAND ${RUBY} ${CMAKE_SOURCE_DIR}/tools/xmlschema.rb ARGS -s ${CMAKE_CURRENT_SOURCE_DIR} -i ${ABS_FIL} -o ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${ABS_FIL} COMMENT "Running xml schema compiler on ${FIL}" VERBATIM) endforeach() add_custom_target(schema1_6 ALL DEPENDS ${SDF_SCHEMA}) set_source_files_properties(${SDF_SCHEMA} PROPERTIES GENERATED TRUE) install(FILES 1_5.convert ${sdfs} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.6) install(FILES ${SDF_SCHEMA} DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/sdformat/1.6) sdformat-6.0.0+dfsg/sdf/1.6/actor.sdf000066400000000000000000000103431323606632500171500ustar00rootroot00000000000000 A special kind of model which can have a scripted motion. This includes both global waypoint type animations and skeleton animations. A unique name for the actor. (DEPRECATION WARNING: This is deprecated in 1.6 and removed in 1.7. Actors should be static, so this is always true. Skin file which defines a visual and the underlying skeleton which moves it. Path to skin file, accepted formats: COLLADA, BVH. Scale the skin's size. Animation file defines an animation for the skeleton in the skin. The skeleton must be compatible with the skin skeleton. Unique name for animation. Path to animation file. Accepted formats: COLLADA, BVH. Scale for the animation skeleton. Set to true so the animation is interpolated on X. Adds scripted trajectories to the actor. Set this to true for the script to be repeated in a loop. For a fluid continuous motion, make sure the last waypoint matches the first one. This is the time to wait before starting the script. If running in a loop, this time will be waited before starting each cycle. Set to true if the animation should start as soon as the simulation starts playing. It is useful to set this to false if the animation should only start playing only when triggered by a plugin, for example. The trajectory contains a series of keyframes to be followed. Unique id for a trajectory. If it matches the type of an animation, they will be played at the same time. Each point in the trajectory. The time in seconds, counted from the beginning of the script, when the pose should be reached. The pose which should be reached at the given time. sdformat-6.0.0+dfsg/sdf/1.6/altimeter.sdf000066400000000000000000000010131323606632500200200ustar00rootroot00000000000000 These elements are specific to an altimeter sensor. Noise parameters for vertical position Noise parameters for vertical velocity sdformat-6.0.0+dfsg/sdf/1.6/atmosphere.sdf000066400000000000000000000016731323606632500202150ustar00rootroot00000000000000 The atmosphere tag specifies the type and properties of the atmosphere model. The type of the atmosphere engine. Current options are adiabatic. Defaults to adiabatic if left unspecified. Temperature at sea level in kelvins. Pressure at sea level in pascals. Temperature gradient with respect to increasing altitude at sea level in units of K/m. sdformat-6.0.0+dfsg/sdf/1.6/audio_sink.sdf000066400000000000000000000001641323606632500201650ustar00rootroot00000000000000 An audio sink. sdformat-6.0.0+dfsg/sdf/1.6/audio_source.sdf000066400000000000000000000021631323606632500205220ustar00rootroot00000000000000 An audio source. URI of the audio media. Pitch for the audio media, in Hz Gain for the audio media, in dB. List of collision objects that will trigger audio playback. Name of child collision element that will trigger audio playback. True to make the audio source loop playback. sdformat-6.0.0+dfsg/sdf/1.6/battery.sdf000066400000000000000000000006331323606632500175130ustar00rootroot00000000000000 Description of a battery. Unique name for the battery. Initial voltage in volts. sdformat-6.0.0+dfsg/sdf/1.6/box_shape.sdf000066400000000000000000000004701323606632500200100ustar00rootroot00000000000000 Box shape The three side lengths of the box. The origin of the box is in its geometric center (inside the center of the box). sdformat-6.0.0+dfsg/sdf/1.6/camera.sdf000066400000000000000000000152351323606632500172750ustar00rootroot00000000000000 These elements are specific to camera sensors. An optional name for the camera. Horizontal field of view The image size in pixels and format. Width in pixels Height in pixels (L8|R8G8B8|B8G8R8|BAYER_RGGB8|BAYER_BGGR8|BAYER_GBRG8|BAYER_GRBG8) The near and far clip planes. Objects closer or farther than these planes are not rendered. Near clipping plane Far clipping plane Enable or disable saving of camera frames. True = saving enabled The path name which will hold the frame data. If path name is relative, then directory is relative to current working directory. Depth camera parameters Type of output The properties of the noise model that should be applied to generated images The type of noise. Currently supported types are: "gaussian" (draw additive noise values independently for each pixel from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. Lens distortion to be applied to camera images. See http://en.wikipedia.org/wiki/Distortion_(optics)#Software_correction The radial distortion coefficient k1 The radial distortion coefficient k2 The radial distortion coefficient k3 The tangential distortion coefficient p1 The tangential distortion coefficient p2 The distortion center or principal point Lens projection description Type of the lens mapping. Supported values are gnomonical, stereographic, equidistant, equisolid_angle, orthographic, custom. For gnomonical (perspective) projection, it is recommended to specify a horizontal_fov of less than or equal to 90° If true the image will be scaled to fit horizontal FOV, otherwise it will be shown according to projection type parameters Definition of custom mapping function in a form of r=c1*f*fun(theta/c2 + c3). See https://en.wikipedia.org/wiki/Fisheye_lens#Mapping_function Linear scaling constant Angle scaling constant Angle offset constant Focal length of the optical system. Note: It's not a focal length of the lens in a common sense! This value is ignored if 'scale_to_fov' is set to true Possible values are 'sin', 'tan' and 'id' Everything outside of the specified angle will be hidden, 90° by default Resolution of the environment cube map used to draw the world sdformat-6.0.0+dfsg/sdf/1.6/collision.sdf000066400000000000000000000021071323606632500200320ustar00rootroot00000000000000 The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time. Unique name for the collision element within the scope of the parent link. intensity value returned by laser sensor. Maximum number of contacts allowed between two entities. This value overrides the max_contacts element defined in physics. sdformat-6.0.0+dfsg/sdf/1.6/collision_engine.sdf000066400000000000000000000013111323606632500213530ustar00rootroot00000000000000 The collision_engine tag specifies the type and properties of the collision detection engine. The type of the collision detection engine. Current default in ODE is OPCODE. The type of the collision detection engine. sdformat-6.0.0+dfsg/sdf/1.6/contact.sdf000066400000000000000000000010351323606632500174710ustar00rootroot00000000000000 These elements are specific to the contact sensor. name of the collision element within a link that acts as the contact sensor. Topic on which contact data is published. sdformat-6.0.0+dfsg/sdf/1.6/cylinder_shape.sdf000066400000000000000000000005461323606632500210350ustar00rootroot00000000000000 Cylinder shape Radius of the cylinder Length of the cylinder sdformat-6.0.0+dfsg/sdf/1.6/forcetorque.sdf000066400000000000000000000022301323606632500203720ustar00rootroot00000000000000 These elements are specific to the force torque sensor. Frame in which to report the wrench values. Currently supported frames are: "parent" report the wrench expressed in the orientation of the parent link frame, "child" report the wrench expressed in the orientation of the child link frame, "sensor" report the wrench expressed in the orientation of the joint sensor frame. Note that for each option the point with respect to which the torque component of the wrench is expressed is the joint origin. Direction of the wrench measured by the sensor. The supported options are: "parent_to_child" if the measured wrench is the one applied by parent link on the child link, "child_to_parent" if the measured wrench is the one applied by the child link on the parent link. sdformat-6.0.0+dfsg/sdf/1.6/frame.sdf000066400000000000000000000006631323606632500171360ustar00rootroot00000000000000 A frame of reference to which a pose is relative. Name of the frame. This name must not match another frame defined inside the parent that this frame is attached to. sdformat-6.0.0+dfsg/sdf/1.6/geometry.sdf000066400000000000000000000013571323606632500177000ustar00rootroot00000000000000 The shape of the visual or collision object. You can use the empty tag to make empty geometries. sdformat-6.0.0+dfsg/sdf/1.6/gps.sdf000066400000000000000000000025341323606632500166340ustar00rootroot00000000000000 These elements are specific to the GPS sensor. Parameters related to GPS position measurement. Noise parameters for horizontal position measurement, in units of meters. Noise parameters for vertical position measurement, in units of meters. Parameters related to GPS position measurement. Noise parameters for horizontal velocity measurement, in units of meters/second. Noise parameters for vertical velocity measurement, in units of meters/second. sdformat-6.0.0+dfsg/sdf/1.6/gripper.sdf000066400000000000000000000016461323606632500175160ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.6/gui.sdf000066400000000000000000000064771323606632500166410ustar00rootroot00000000000000 Set the type of projection for the camera. Valid values are "perspective" and "orthographic". Name of the tracked visual. If no name is provided, the remaining settings will be applied whenever tracking is triggered in the GUI. Minimum distance between the camera and the tracked visual. This parameter is only used if static is set to false. Maximum distance between the camera and the tracked visual. This parameter is only used if static is set to false. If set to true, the position of the camera is fixed relatively to the model or to the world, depending on the value of the use_model_frame element. Otherwise, the position of the camera may vary but the distance between the camera and the model will depend on the value of the min_dist and max_dist elements. In any case, the camera will always follow the model by changing its orientation. If set to true, the position of the camera is relative to the model reference frame, which means that its position relative to the model will not change. Otherwise, the position of the camera is relative to the world reference frame, which means that its position relative to the world will not change. This parameter is only used if static is set to true. The position of the camera's reference frame. This parameter is only used if static is set to true. If use_model_frame is set to true, the position is relative to the model reference frame, otherwise it represents world coordinates. If set to true, the camera will inherit the yaw rotation of the tracked model. This parameter is only used if static and use_model_frame are set to true. sdformat-6.0.0+dfsg/sdf/1.6/heightmap_shape.sdf000066400000000000000000000050271323606632500211710ustar00rootroot00000000000000 A heightmap based on a 2d grayscale image. URI to a grayscale image file The size of the heightmap in world units. When loading an image: "size" is used if present, otherwise defaults to 1x1x1. When loading a DEM: "size" is used if present, otherwise defaults to true size of DEM. A position offset. The heightmap can contain multiple textures. The order of the texture matters. The first texture will appear at the lowest height, and the last texture at the highest height. Use blend to control the height thresholds and fade between textures. Size of the applied texture in meters. Diffuse texture image filename Normalmap texture image filename The blend tag controls how two adjacent textures are mixed. The number of blend elements should equal one less than the number of textures. Min height of a blend layer Distance over which the blend occurs Set if the rendering engine will use terrain paging Samples per heightmap datum. For rasterized heightmaps, this indicates the number of samples to take per pixel. Using a lower value, e.g. 1, will generally improve the performance of the heightmap but lower the heightmap quality. sdformat-6.0.0+dfsg/sdf/1.6/image_shape.sdf000066400000000000000000000014741323606632500203070ustar00rootroot00000000000000 Extrude a set of boxes from a grayscale image. URI of the grayscale image file Scaling factor applied to the image Grayscale threshold Height of the extruded boxes The amount of error in the model sdformat-6.0.0+dfsg/sdf/1.6/imu.sdf000066400000000000000000000161201323606632500166310ustar00rootroot00000000000000 These elements are specific to the IMU sensor. This string represents special hardcoded use cases that are commonly seen with typical robot IMU's: - CUSTOM: use Euler angle custom_rpy orientation specification. The orientation of the IMU's reference frame is defined by adding the custom_rpy rotation to the parent_frame. - NED: The IMU XYZ aligns with NED, where NED orientation relative to Gazebo world is defined by the SphericalCoordinates class. - ENU: The IMU XYZ aligns with ENU, where ENU orientation relative to Gazebo world is defined by the SphericalCoordinates class. - NWU: The IMU XYZ aligns with NWU, where NWU orientation relative to Gazebo world is defined by the SphericalCoordinates class. - GRAV_UP: where direction of gravity maps to IMU reference frame Z-axis with Z-axis pointing in the opposite direction of gravity. IMU reference frame X-axis direction is defined by grav_dir_x. Note if grav_dir_x is parallel to gravity direction, this configuration fails. Otherwise, IMU reference frame X-axis is defined by projection of grav_dir_x onto a plane normal to the gravity vector. IMU reference frame Y-axis is a vector orthogonal to both X and Z axis following the right hand rule. - GRAV_DOWN: where direction of gravity maps to IMU reference frame Z-axis with Z-axis pointing in the direction of gravity. IMU reference frame X-axis direction is defined by grav_dir_x. Note if grav_dir_x is parallel to gravity direction, this configuration fails. Otherwise, IMU reference frame X-axis is defined by projection of grav_dir_x onto a plane normal to the gravity vector. IMU reference frame Y-axis is a vector orthogonal to both X and Z axis following the right hand rule. This field and parent_frame are used when localization is set to CUSTOM. Orientation (fixed axis roll, pitch yaw) transform from parent_frame to this IMU's reference frame. Some common examples are: - IMU reports in its local frame on boot. IMU sensor frame is the reference frame. Example: parent_frame="", custom_rpy="0 0 0" - IMU reports in Gazebo world frame. Example sdf: parent_frame="world", custom_rpy="0 0 0" - IMU reports in NWU frame. Uses SphericalCoordinates class to determine world frame in relation to magnetic north and gravity; i.e. rotation between North-West-Up and world (+X,+Y,+Z) frame is defined by SphericalCoordinates class. Example sdf given world is NWU: parent_frame="world", custom_rpy="0 0 0" - IMU reports in NED frame. Uses SphericalCoordinates class to determine world frame in relation to magnetic north and gravity; i.e. rotation between North-East-Down and world (+X,+Y,+Z) frame is defined by SphericalCoordinates class. Example sdf given world is NWU: parent_frame="world", custom_rpy="M_PI 0 0" - IMU reports in ENU frame. Uses SphericalCoordinates class to determine world frame in relation to magnetic north and gravity; i.e. rotation between East-North-Up and world (+X,+Y,+Z) frame is defined by SphericalCoordinates class. Example sdf given world is NWU: parent_frame="world", custom_rpy="0 0 -0.5*M_PI" - IMU reports in ROS optical frame as described in http://www.ros.org/reps/rep-0103.html#suffix-frames, which is (z-forward, x-left to right when facing +z, y-top to bottom when facing +z). (default gazebo camera is +x:view direction, +y:left, +z:up). Example sdf: parent_frame="local", custom_rpy="-0.5*M_PI 0 -0.5*M_PI" Name of parent frame which the custom_rpy transform is defined relative to. It can be any valid fully scoped Gazebo Link name or the special reserved "world" frame. If left empty, use the sensor's own local frame. Used when localization is set to GRAV_UP or GRAV_DOWN, a projection of this vector into a plane that is orthogonal to the gravity vector defines the direction of the IMU reference frame's X-axis. grav_dir_x is defined in the coordinate frame as defined by the parent_frame element. Name of parent frame in which the grav_dir_x vector is defined. It can be any valid fully scoped Gazebo Link name or the special reserved "world" frame. If left empty, use the sensor's own local frame. Topic on which data is published. These elements are specific to body-frame angular velocity, which is expressed in radians per second Angular velocity about the X axis Angular velocity about the Y axis Angular velocity about the Z axis These elements are specific to body-frame linear acceleration, which is expressed in meters per second squared Linear acceleration about the X axis Linear acceleration about the Y axis Linear acceleration about the Z axis sdformat-6.0.0+dfsg/sdf/1.6/inertial.sdf000066400000000000000000000032531323606632500176510ustar00rootroot00000000000000 The inertial properties of the link. The mass of the link. This is the pose of the inertial reference frame, relative to the specified reference frame. The origin of the inertial reference frame needs to be at the center of gravity. The axes of the inertial reference frame do not need to be aligned with the principal axes of the inertia. The 3x3 rotational inertia matrix. Because the rotational inertia matrix is symmetric, only 6 above-diagonal elements of this matrix are specified here, using the attributes ixx, ixy, ixz, iyy, iyz, izz. sdformat-6.0.0+dfsg/sdf/1.6/joint.sdf000066400000000000000000000327511323606632500171720ustar00rootroot00000000000000 A joint connections two links with kinematic and dynamic properties. A unique name for the joint within the scope of the model. The type of joint, which must be one of the following: (revolute) a hinge joint that rotates on a single axis with either a fixed or continuous range of motion, (gearbox) geared revolute joints, (revolute2) same as two revolute joints connected in series, (prismatic) a sliding joint that slides along an axis with a limited range specified by upper and lower limits, (ball) a ball and socket joint, (screw) a single degree of freedom joint with coupled sliding and rotational motion, (universal) like a ball joint, but constrains one degree of freedom, (fixed) a joint with zero degrees of freedom that rigidly connects two links. Name of the parent link Name of the child link Parameter for gearbox joints. Given theta_1 and theta_2 defined in description for gearbox_reference_body, theta_2 = -gearbox_ratio * theta_1. Parameter for gearbox joints. Gearbox ratio is enforced over two joint angles. First joint angle (theta_1) is the angle from the gearbox_reference_body to the parent link in the direction of the axis element and the second joint angle (theta_2) is the angle from the gearbox_reference_body to the child link in the direction of the axis2 element. Parameter for screw joints. Parameters related to the axis of rotation for revolute joints, the axis of translation for prismatic joints. Default joint position for this joint axis. Represents the x,y,z components of the axis unit vector. The axis is expressed in the joint frame unless the use_parent_model_frame flag is set to true. The vector should be normalized. Flag to interpret the axis xyz element in the parent model frame instead of joint frame. Provided for Gazebo compatibility (see https://bitbucket.org/osrf/gazebo/issue/494 ). An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. The physical static friction value of the joint. The spring reference position for this joint axis. The spring stiffness for this joint axis. specifies the limits of this joint An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Support physics engines: SimBody. Joint stop dissipation. Parameters related to the second axis of rotation for revolute2 joints and universal joints. Default joint position for this joint axis. Represents the x,y,z components of the axis unit vector. The axis is expressed in the joint frame unless the use_parent_model_frame flag is set to true. The vector should be normalized. Flag to interpret the axis xyz element in the parent model frame instead of joint frame. Provided for Gazebo compatibility (see https://bitbucket.org/osrf/gazebo/issue/494 ). An element specifying physical properties of the joint. These values are used to specify modeling properties of the joint, particularly useful for simulation. The physical velocity dependent viscous damping coefficient of the joint. EXPERIMENTAL: if damping coefficient is negative and implicit_spring_damper is true, adaptive damping is used. The physical static friction value of the joint. The spring reference position for this joint axis. The spring stiffness for this joint axis. An attribute specifying the lower joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute specifying the upper joint limit (radians for revolute joints, meters for prismatic joints). Omit if joint is continuous. An attribute for enforcing the maximum joint effort applied by Joint::SetForce. Limit is not enforced if value is negative. (not implemented) An attribute for enforcing the maximum joint velocity. Joint stop stiffness. Supported physics engines: SimBody. Joint stop dissipation. Supported physics engines: SimBody. Parameters that are specific to a certain physics engine. Simbody specific parameters Force cut in the multibody graph at this joint. ODE specific parameters (DEPRECATION WARNING: In SDF 1.5 this tag will be replaced by the same tag directly under the physics-block. For now, this tag overrides the one outside of ode-block, but in SDF 1.5 this tag will be removed completely.) If provide feedback is set to true, ODE will compute the constraint forces at this joint. If cfm damping is set to true, ODE will use CFM to simulate damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. If implicit_spring_damper is set to true, ODE will use CFM, ERP to simulate stiffness and damping, allows for infinite damping, and one additional constraint row (previously used for joint limit) is always active. This replaces cfm_damping parameter in sdf 1.4. Scale the excess for in a joint motor at joint limits. Should be between zero and one. Constraint force mixing for constrained directions Error reduction parameter for constrained directions Bounciness of the limits Maximum force or torque used to reach the desired velocity. The desired velocity of the joint. Should only be set if you want the joint to move on load. Constraint force mixing parameter used by the joint stop Error reduction parameter used by the joint stop Suspension constraint force mixing parameter Suspension error reduction parameter If provide feedback is set to true, physics engine will compute the constraint forces at this joint. For now, provide_feedback under ode block will override this tag and given user warning about the migration. provide_feedback under ode is scheduled to be removed in SDF 1.5. sdformat-6.0.0+dfsg/sdf/1.6/light.sdf000066400000000000000000000052741323606632500171560ustar00rootroot00000000000000 The light element describes a light source. A unique name for the light. The light type: point, directional, spot. When true, the light will cast shadows. Diffuse light color Specular light color Light attenuation Range of the light The linear attenuation factor: 1 means attenuate evenly over the distance. The constant attenuation factor: 1.0 means never attenuate, 0.0 is complete attenutation. The quadratic attenuation factor: adds a curvature to the attenuation. Direction of the light, only applicable for spot and directional lights. Spot light parameters Angle covered by the bright inner cone Angle covered by the outer cone The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff. sdformat-6.0.0+dfsg/sdf/1.6/light_state.sdf000066400000000000000000000005741323606632500203540ustar00rootroot00000000000000 Light state Name of the light sdformat-6.0.0+dfsg/sdf/1.6/link.sdf000066400000000000000000000045011323606632500167740ustar00rootroot00000000000000 A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model. A unique name for the link within the scope of the model. If true, the link is affected by gravity. If true, the link is affected by the wind. If true, the link can collide with other links in the model. Two links within a model will collide if link1.self_collide OR link2.self_collide. Links connected by a joint will never collide. If true, the link is kinematic only If true, the link will have 6DOF and be a direct child of world. Exponential damping of the link's velocity. Linear damping Angular damping sdformat-6.0.0+dfsg/sdf/1.6/link_state.sdf000066400000000000000000000031331323606632500201740ustar00rootroot00000000000000 Link state Name of the link Velocity of the link. The x, y, z components of the pose correspond to the linear velocity of the link, and the roll, pitch, yaw components correspond to the angular velocity of the link Acceleration of the link. The x, y, z components of the pose correspond to the linear acceleration of the link, and the roll, pitch, yaw components correspond to the angular acceleration of the link Force and torque applied to the link. The x, y, z components of the pose correspond to the force applied to the link, and the roll, pitch, yaw components correspond to the torque applied to the link Collision state Name of the collision sdformat-6.0.0+dfsg/sdf/1.6/logical_camera.sdf000066400000000000000000000020031323606632500207540ustar00rootroot00000000000000 These elements are specific to logical camera sensors. A logical camera reports objects that fall within a frustum. Computation should be performed on the CPU. Near clipping distance of the view frustum Far clipping distance of the view frustum Aspect ratio of the near and far planes. This is the width divided by the height of the near or far planes. Horizontal field of view of the frustum, in radians. This is the angle between the frustum's vertex and the edges of the near or far plane. sdformat-6.0.0+dfsg/sdf/1.6/magnetometer.sdf000066400000000000000000000013511323606632500205260ustar00rootroot00000000000000 These elements are specific to a Magnetometer sensor. Parameters related to the body-frame X axis of the magnetometer Parameters related to the body-frame Y axis of the magnetometer Parameters related to the body-frame Z axis of the magnetometer sdformat-6.0.0+dfsg/sdf/1.6/material.sdf000066400000000000000000000042141323606632500176360ustar00rootroot00000000000000 The material of the visual element. Name of material from an installed script file. This will override the color element if the script exists. URI of the material script file Name of the script within the script file vertex, pixel, normal_map_objectspace, normal_map_tangentspace filename of the normal map If false, dynamic lighting will be disabled The ambient color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. The diffuse color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The specular color of a material specified by set of four numbers representing red/green/blue/alpha, each in the range of [0,1]. The emissive color of a material specified by set of four numbers representing red/green/blue, each in the range of [0,1]. sdformat-6.0.0+dfsg/sdf/1.6/mesh_shape.sdf000066400000000000000000000017611323606632500201600ustar00rootroot00000000000000 Mesh shape Mesh uri Use a named submesh. The submesh must exist in the mesh specified by the uri Name of the submesh within the parent mesh Set to true to center the vertices of the submesh at 0,0,0. This will effectively remove any transformations on the submesh before the poses from parent links and models are applied. Scaling factor applied to the mesh sdformat-6.0.0+dfsg/sdf/1.6/model.sdf000066400000000000000000000060721323606632500171440ustar00rootroot00000000000000 The model element defines a complete robot or any other physical object. A unique name for the model. This name must not match another model in the world. If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine. If set to true, all links in the model will collide with each other (except those connected by a joint). Can be overridden by the link or collision element self_collide property. Two links within a model will collide if link1.self_collide OR link2.self_collide. Links connected by a joint will never collide. Allows a model to auto-disable, which is means the physics engine can skip updating the model when the model is at rest. This parameter is only used by models with no joints. Include resources from a URI. This can be used to nest models. URI to a resource, such as a model Override the pose of the included model. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. Override the name of the included model. Override the static value of the included model. A nested model element A unique name for the model. This name must not match another nested model in the same level as this model. If set to true, all links in the model will be affected by the wind. Can be overriden by the link wind property. sdformat-6.0.0+dfsg/sdf/1.6/model_state.sdf000066400000000000000000000025541323606632500203450ustar00rootroot00000000000000 Model state Name of the model Joint angle Name of the joint Index of the axis. Angle of an axis A nested model state element Name of the model. Scale for the 3 dimensions of the model. sdformat-6.0.0+dfsg/sdf/1.6/noise.sdf000066400000000000000000000031231323606632500171530ustar00rootroot00000000000000 The properties of a sensor noise model. The type of noise. Currently supported types are: "none" (no noise). "gaussian" (draw noise values independently for each measurement from a Gaussian distribution). "gaussian_quantized" ("gaussian" plus quantization of outputs (ie. rounding)) For type "gaussian*", the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which noise values are drawn. For type "gaussian*", the mean of the Gaussian distribution from which bias values are drawn. For type "gaussian*", the standard deviation of the Gaussian distribution from which bias values are drawn. For type "gaussian_quantized", the precision of output signals. A value of zero implies infinite precision / no quantization. sdformat-6.0.0+dfsg/sdf/1.6/physics.sdf000066400000000000000000000326711323606632500175320ustar00rootroot00000000000000 The physics tag specifies the type and properties of the dynamics engine. The name of this set of physics parameters. If true, this physics element is set as the default physics profile for the world. If multiple default physics elements exist, the first element marked as default is chosen. If no default physics element exists, the first physics element is chosen. The type of the dynamics engine. Current options are ode, bullet, simbody and dart. Defaults to ode if left unspecified. Maximum time step size at which every system in simulation can interact with the states of the world. (was physics.sdf's dt). target simulation speedup factor, defined by ratio of simulation time to real-time. Rate at which to update the physics engine (UpdatePhysics calls per real-time second). (was physics.sdf's update_rate). Maximum number of contacts allowed between two entities. This value can be over ridden by a max_contacts element in a collision element. DART specific physics properties One of the following types: pgs, dantzig. PGS stands for Projected Gauss-Seidel. Simbody specific physics properties (Currently not used in simbody) The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Roughly the relative error of the system. -LOG(accuracy) is roughly the number of significant digits. Tolerable "slip" velocity allowed by the solver when static friction is supposed to hold object in place. vc Assume real COR=1 when v=0. e_min = given minimum COR, at v >= vp (a.k.a. plastic_coef_restitution) d = slope = (1-e_min)/vp OR, e_min = 1 - d*vp e_max = maximum COR = 1-d*vc, reached at v=vc e = 0, v <= vc = 1 - d*v, vc < v < vp = e_min, v >= vp dissipation factor = d*min(v,vp) [compliant] cor = e [rigid] Combining rule e = 0, e1==e2==0 = 2*e1*e2/(e1+e2), otherwise]]> Default contact material stiffness (force/dist or torque/radian). dissipation coefficient to be used in compliant contact; if not given it is (1-min_cor)/plastic_impact_velocity this is the COR to be used at high velocities for rigid impacts; if not given it is 1 - dissipation*plastic_impact_velocity smallest impact velocity at which min COR is reached; set to zero if you want the min COR always to be used static friction (mu_s) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png dynamic friction (mu_d) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png viscous friction (mu_v) with units of (1/velocity) as described by this plot: http://gazebosim.org/wiki/File:Stribeck_friction.png for rigid impacts only, impact velocity at which COR is set to zero; normally inherited from global default but can be overridden here. Combining rule: use larger velocity This is the largest slip velocity at which we'll consider a transition to stiction. Normally inherited from a global default setting. For a continuous friction model this is the velocity at which the max static friction force is reached. Combining rule: use larger velocity Bullet specific physics properties One of the following types: sequential_impulse only. The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Set the successive over-relaxation parameter. Bullet constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://web.archive.org/web/20120430155635/http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. ODE specific physics properties One of the following types: world, quick The time duration which advances with each iteration of the dynamics engine, this has to be no bigger than max_step_size under physics block. If left unspecified, min_step_size defaults to max_step_size. Number of threads to use for "islands" of disconnected models. Number of iterations for each step. A higher number produces greater accuracy at a performance cost. Experimental parameter. Set the successive over-relaxation parameter. Flag to use threading to speed up position correction computation. Flag to enable dynamic rescaling of moment of inertia in constrained directions. See gazebo pull request 1114 for the implementation of this feature. https://bitbucket.org/osrf/gazebo/pull-request/1114 Name of ODE friction model to use. Valid values include: pyramid_model: (default) friction forces limited in two directions in proportion to normal force. box_model: friction forces limited to constant in two directions. cone_model: friction force magnitude limited in proportion to normal force. See gazebo pull request 1522 for the implementation of this feature. https://bitbucket.org/osrf/gazebo/pull-request/1522 https://bitbucket.org/osrf/gazebo/commits/8c05ad64967c ODE constraint parameters. Constraint force mixing parameter. See the ODE page for more information. Error reduction parameter. See the ODE page for more information. The maximum correcting velocities allowed when resolving contacts. The depth of the surface layer around all geometry objects. Contacts are allowed to sink into the surface layer up to the given depth before coming to rest. The default value is zero. Increasing this to some small value (e.g. 0.001) can help prevent jittering problems due to contacts being repeatedly made and broken. sdformat-6.0.0+dfsg/sdf/1.6/plane_shape.sdf000066400000000000000000000006031323606632500203150ustar00rootroot00000000000000 Plane shape Normal direction for the plane Length of each side of the plane sdformat-6.0.0+dfsg/sdf/1.6/plugin.sdf000066400000000000000000000016061323606632500173400ustar00rootroot00000000000000 A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor. A unique name for the plugin, scoped to its parent. Name of the shared library to load. If the filename is not a full path name, the file will be searched for in the configuration paths. This is a special element that should not be specified in an SDF file. It automatically copies child elements into the SDF element so that a plugin can access the data. sdformat-6.0.0+dfsg/sdf/1.6/polyline_shape.sdf000066400000000000000000000006601323606632500210540ustar00rootroot00000000000000 Defines an extruded polyline shape A series of points that define the path of the polyline. Height of the polyline sdformat-6.0.0+dfsg/sdf/1.6/population.sdf000066400000000000000000000045211323606632500202330ustar00rootroot00000000000000 The population element defines how and where a set of models will be automatically populated in Gazebo. A unique name for the population. This name must not match another population in the world. The number of models to place. Specifies the type of object distribution and its optional parameters. Define how the objects will be placed in the specified region. - random: Models placed at random. - uniform: Models approximately placed in a 2D grid pattern with control over the number of objects. - grid: Models evenly placed in a 2D grid pattern. The number of objects is not explicitly specified, it is based on the number of rows and columns of the grid. - linear-x: Models evently placed in a row along the global x-axis. - linear-y: Models evently placed in a row along the global y-axis. - linear-z: Models evently placed in a row along the global z-axis. Number of rows in the grid. Number of columns in the grid. Distance between elements of the grid. sdformat-6.0.0+dfsg/sdf/1.6/pose.sdf000066400000000000000000000006131323606632500170050ustar00rootroot00000000000000 A position(x,y,z) and orientation(roll, pitch yaw) with respect to the specified frame. Name of frame which the pose is defined relative to. sdformat-6.0.0+dfsg/sdf/1.6/projector.sdf000066400000000000000000000015641323606632500200540ustar00rootroot00000000000000 Name of the projector Texture name Field of view Near clip distance far clip distance sdformat-6.0.0+dfsg/sdf/1.6/ray.sdf000066400000000000000000000070261323606632500166370ustar00rootroot00000000000000 These elements are specific to the ray (laser) sensor. The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle The number of simulated rays to generate per complete laser sweep cycle. This number is multiplied by samples to determine the number of range data points returned. If resolution is less than one, range data is interpolated. If resolution is greater than one, range data is averaged. Must be greater or equal to min_angle specifies range properties of each simulated ray The minimum distance for each ray. The maximum distance for each ray. Linear resolution of each ray. The properties of the noise model that should be applied to generated scans The type of noise. Currently supported types are: "gaussian" (draw noise values independently for each beam from a Gaussian distribution). For type "gaussian," the mean of the Gaussian distribution from which noise values are drawn. For type "gaussian," the standard deviation of the Gaussian distribution from which noise values are drawn. sdformat-6.0.0+dfsg/sdf/1.6/rfid.sdf000066400000000000000000000001061323606632500167600ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.6/rfidtag.sdf000066400000000000000000000001001323606632500174460ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.6/road.sdf000066400000000000000000000010421323606632500167610ustar00rootroot00000000000000 Name of the road Width of the road A series of points that define the path of the road. sdformat-6.0.0+dfsg/sdf/1.6/root.sdf000066400000000000000000000007021323606632500170210ustar00rootroot00000000000000 SDF base element. Version number of the SDF format. sdformat-6.0.0+dfsg/sdf/1.6/scene.sdf000066400000000000000000000061471323606632500171440ustar00rootroot00000000000000 Specifies the look of the environment. Color of the ambient light. Color of the background. Properties for the sky Time of day [0..24] Sunrise time [0..24] Sunset time [0..24] Sunset time [0..24] Speed of the clouds Direction of the cloud movement Density of clouds Average size of the clouds Ambient cloud color Enable/disable shadows Controls fog Fog color Fog type: constant, linear, quadratic Distance to start of fog Distance to end of fog Density of fog Enable/disable the grid Show/hide world origin indicator sdformat-6.0.0+dfsg/sdf/1.6/schema/000077500000000000000000000000001323606632500166015ustar00rootroot00000000000000sdformat-6.0.0+dfsg/sdf/1.6/schema/types.xsd000066400000000000000000000032701323606632500204670ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/sdf/1.6/sensor.sdf000066400000000000000000000050671323606632500173600ustar00rootroot00000000000000 The sensor tag describes the type and properties of a sensor. A unique name for the sensor. This name must not match another model in the model. The type name of the sensor. By default, SDF supports types altimeter, camera, contact, depth, force_torque, gps, gpu_ray, imu, logical_camera, magnetometer, multicamera, ray, rfid, rfidtag, sonar, wireless_receiver, and wireless_transmitter. If true the sensor will always be updated according to the update rate. The frequency at which the sensor data is generated. If left unspecified, the sensor will generate data every cycle. If true, the sensor is visualized in the GUI Name of the topic on which data is published. This is necessary for visualization sdformat-6.0.0+dfsg/sdf/1.6/sonar.sdf000066400000000000000000000010021323606632500171520ustar00rootroot00000000000000 These elements are specific to the sonar sensor. Minimum range Max range Radius of the sonar cone at max range. sdformat-6.0.0+dfsg/sdf/1.6/sphere_shape.sdf000066400000000000000000000003341323606632500205050ustar00rootroot00000000000000 Sphere shape radius of the sphere sdformat-6.0.0+dfsg/sdf/1.6/spherical_coordinates.sdf000066400000000000000000000047271323606632500224150ustar00rootroot00000000000000 Name of planetary surface model, used to determine the surface altitude at a given latitude and longitude. The default is an ellipsoid model of the earth based on the WGS-84 standard. It is used in Gazebo's GPS sensor implementation. This field identifies how Gazebo world frame is aligned in Geographical sense. The final Gazebo world frame orientation is obtained by rotating a frame aligned with following notation by the field heading_deg (Note that heading_deg corresponds to positive yaw rotation in the NED frame, so it's inverse specifies positive Z-rotation in ENU or NWU). Options are: - ENU (East-North-Up) - NED (North-East-Down) - NWU (North-West-Up) For example, world frame specified by setting world_orientation="ENU" and heading_deg=-90° is effectively equivalent to NWU with heading of 0°. Geodetic latitude at origin of gazebo reference frame, specified in units of degrees. Longitude at origin of gazebo reference frame, specified in units of degrees. Elevation of origin of gazebo reference frame, specified in meters. Heading offset of gazebo reference frame, measured as angle between Gazebo world frame and the world_frame_orientation type (ENU/NED/NWU). Rotations about the downward-vector (e.g. North to East) are positive. The direction of rotation is chosen to be consistent with compass heading convention (e.g. 0 degrees points North and 90 degrees points East, positive rotation indicates counterclockwise rotation when viewed from top-down direction). The angle is specified in degrees. sdformat-6.0.0+dfsg/sdf/1.6/state.sdf000066400000000000000000000030651323606632500171630ustar00rootroot00000000000000 Name of the world this state applies to Simulation time stamp of the state [seconds nanoseconds] Wall time stamp of the state [seconds nanoseconds] Real time stamp of the state [seconds nanoseconds] Number of simulation iterations. A list containing the entire description of entities inserted. A list of names of deleted entities/ The name of a deleted entity. sdformat-6.0.0+dfsg/sdf/1.6/surface.sdf000066400000000000000000000304501323606632500174710ustar00rootroot00000000000000 The surface parameters Bounciness coefficient of restitution, from [0...1], where 0=no bounciness. Bounce capture velocity, below which effective coefficient of restitution is 0. Parameters for torsional friction Torsional friction coefficient, unitless maximum ratio of tangential stress to normal stress. If this flag is true, torsional friction is calculated using the "patch_radius" parameter. If this flag is set to false, "surface_radius" (R) and contact depth (d) are used to compute the patch radius as sqrt(R*d). Radius of contact patch surface. Surface radius on the point of contact. Torsional friction parameters for ODE Force dependent slip for torsional friction, equivalent to inverse of viscous damping coefficient with units of rad/s/(Nm). A slip value of 0 is infinitely viscous. ODE friction parameters Coefficient of friction in first friction pyramid direction, the unitless maximum ratio of force in first friction pyramid direction to normal force. Coefficient of friction in second friction pyramid direction, the unitless maximum ratio of force in second friction pyramid direction to normal force. Unit vector specifying first friction pyramid direction in collision-fixed reference frame. If the friction pyramid model is in use, and this value is set to a unit vector for one of the colliding surfaces, the ODE Collide callback function will align the friction pyramid directions with a reference frame fixed to that collision surface. If both surfaces have this value set to a vector of zeros, the friction pyramid directions will be aligned with the world frame. If this value is set for both surfaces, the behavior is undefined. Force dependent slip in first friction pyramid direction, equivalent to inverse of viscous damping coefficient with units of m/s/N. A slip value of 0 is infinitely viscous. Force dependent slip in second friction pyramid direction, equivalent to inverse of viscous damping coefficient with units of m/s/N. A slip value of 0 is infinitely viscous. Coefficient of friction in first friction pyramid direction, the unitless maximum ratio of force in first friction pyramid direction to normal force. Coefficient of friction in second friction pyramid direction, the unitless maximum ratio of force in second friction pyramid direction to normal force. Unit vector specifying first friction pyramid direction in collision-fixed reference frame. If the friction pyramid model is in use, and this value is set to a unit vector for one of the colliding surfaces, the friction pyramid directions will be aligned with a reference frame fixed to that collision surface. If both surfaces have this value set to a vector of zeros, the friction pyramid directions will be aligned with the world frame. If this value is set for both surfaces, the behavior is undefined. Coefficient of rolling friction Flag to disable contact force generation, while still allowing collision checks and contact visualization to occur. Bitmask for collision filtering when collide_without_contact is on Bitmask for collision filtering. This will override collide_without_contact Poisson's ratio is the unitless ratio between transverse and axial strain. This value must lie between (-1, 0.5). Defaults to 0.3 for typical steel. Note typical silicone elastomers have Poisson's ratio near 0.49 ~ 0.50. For reference, approximate values for Material:(Young's Modulus, Poisson's Ratio) for some of the typical materials are: Plastic: (1e8 ~ 3e9 Pa, 0.35 ~ 0.41), Wood: (4e9 ~ 1e10 Pa, 0.22 ~ 0.50), Aluminum: (7e10 Pa, 0.32 ~ 0.35), Steel: (2e11 Pa, 0.26 ~ 0.31). Young's Modulus in SI derived unit Pascal. Defaults to -1. If value is less or equal to zero, contact using elastic modulus (with Poisson's Ratio) is disabled. For reference, approximate values for Material:(Young's Modulus, Poisson's Ratio) for some of the typical materials are: Plastic: (1e8 ~ 3e9 Pa, 0.35 ~ 0.41), Wood: (4e9 ~ 1e10 Pa, 0.22 ~ 0.50), Aluminum: (7e10 Pa, 0.32 ~ 0.35), Steel: (2e11 Pa, 0.26 ~ 0.31). ODE contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints maximum contact correction velocity truncation term. minimum allowable depth before contact correction impulse is applied Bullet contact parameters Soft constraint force mixing. Soft error reduction parameter dynamically "stiffness"-equivalent coefficient for contact joints dynamically "damping"-equivalent coefficient for contact joints Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. Similar to ODE's max_vel implementation. See http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo#Split_Impulse for more information. soft contact pamameters based on paper: http://www.cc.gatech.edu/graphics/projects/Sumit/homepage/papers/sigasia11/jain_softcontacts_siga11.pdf This is variable k_v in the soft contacts paper. Its unit is N/m. This is variable k_e in the soft contacts paper. Its unit is N/m. Viscous damping of point velocity in body frame. Its unit is N/m/s. Fraction of mass to be distributed among deformable nodes. sdformat-6.0.0+dfsg/sdf/1.6/transceiver.sdf000066400000000000000000000027111323606632500203650ustar00rootroot00000000000000 These elements are specific to a wireless transceiver. Service set identifier (network name) Specifies the frequency of transmission in MHz Only a frequency range is filtered. Here we set the lower bound (MHz). Only a frequency range is filtered. Here we set the upper bound (MHz). Specifies the antenna gain in dBi Specifies the transmission power in dBm Mininum received signal power in dBm sdformat-6.0.0+dfsg/sdf/1.6/urdf.sdf000066400000000000000000000015401323606632500167770ustar00rootroot00000000000000 The robot element defines a complete robot or any other physical object using URDF. A unique name for the model. This name must not match another model in the world. A position and orientation in the global coordinate frame for the model. Position(x,y,z) and rotation (roll, pitch yaw) in the global coordinate frame. sdformat-6.0.0+dfsg/sdf/1.6/visual.sdf000066400000000000000000000032271323606632500173460ustar00rootroot00000000000000 The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes. Unique name for the visual element within the scope of the parent link. If true the visual will cast shadows. will be implemented in the future release. The amount of transparency( 0=opaque, 1 = fully transparent) Optional meta information for the visual. The information contained within this element should be used to provide additional feedback to an end user. The layer in which this visual is displayed. The layer number is useful for programs, such as Gazebo, that put visuals in different layers for enhanced visualization. sdformat-6.0.0+dfsg/sdf/1.6/world.sdf000066400000000000000000000054151323606632500171730ustar00rootroot00000000000000 The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins Unique name of the world Global audio properties. Device to use for audio playback. A value of "default" will use the system's default audio device. Otherwise, specify a an audio device file" The wind tag specifies the type and properties of the wind. Linear velocity of the wind. Include resources from a URI URI to a resource, such as a model Override the name of the included model. Override the static value of the included model. The gravity vector in m/s^2, expressed in a coordinate frame defined by the spherical_coordinates tag. The magnetic vector in Tesla, expressed in a coordinate frame defined by the spherical_coordinates tag. sdformat-6.0.0+dfsg/sdf/CMakeLists.txt000066400000000000000000000003011323606632500175670ustar00rootroot00000000000000add_subdirectory(1.0) add_subdirectory(1.2) add_subdirectory(1.3) add_subdirectory(1.4) add_subdirectory(1.5) add_subdirectory(1.6) add_custom_target(schema) add_dependencies(schema schema1_6)sdformat-6.0.0+dfsg/sdf/Migration.md000066400000000000000000000075221323606632500173160ustar00rootroot00000000000000# Migration Guide for SDF Protocol This document contains information about migrating between different versions of the SDF protocol. The SDF protocol version number is specified in the `version` attribute of the `sdf` element (1.4, 1.5, 1.6, etc.) and is distinct from sdformat library version (2.3, 3.0, 4.0, etc.). # Note on backward compatibility There are `*.convert` files that allow old sdf files to be migrated forward programmatically. This document aims to contain similar information to those files but with improved human-readability. ## SDF protocol 1.5 to 1.6 ### Additions 1. **heightmap_shape.sdf** `sampling` element + description: Samples per heightmap datum. For rasterized heightmaps, this indicates the number of samples to take per pixel. Using a lower value, e.g. 1, will generally improve the performance of the heightmap but lower the heightmap quality. + type: unsigned int + default: 2 + required: 0 + [pull request 293](https://bitbucket.org/osrf/sdformat/pull-requests/293) 1. **link.sdf** `enable_wind` element + description: If true, the link is affected by the wind + type: bool + default: false + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **model.sdf** `enable_wind` element + description: If set to true, all links in the model will be affected by the wind. Can be overriden by the link wind property. + type: bool + default: false + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **model_state.sdf** `scale` element + description: Scale for the 3 dimensions of the model. + type: vector3 + default: "1 1 1" + required: 0 + [pull request 246](https://bitbucket.org/osrf/sdformat/pull-requests/246) 1. **physics.sdf** `friction_model` element + description: Name of ODE friction model to use. Valid values include: + pyramid_model: (default) friction forces limited in two directions in proportion to normal force. + box_model: friction forces limited to constant in two directions. + cone_model: friction force magnitude limited in proportion to normal force. See [gazebo pull request 1522](https://bitbucket.org/osrf/gazebo/pull-request/1522) (merged in [gazebo 8c05ad64967c](https://bitbucket.org/osrf/gazebo/commits/8c05ad64967c)) for the implementation of this feature. + type: string + default: "pyramid_model" + required: 0 + [pull request 294](https://bitbucket.org/osrf/sdformat/pull-requests/294) 1. **world.sdf** `wind` element + description: The wind tag specifies the type and properties of the wind. + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) 1. **world.sdf** `wind::linear_velocity` element + description: Linear velocity of the wind. + type: vector3 + default: "0 0 0" + required: 0 + [pull request 240](https://bitbucket.org/osrf/sdformat/pull-requests/240) ### Modifications 1. `gravity` and `magnetic_field` elements are moved from `physics` to `world` + [pull request 247](https://bitbucket.org/osrf/sdformat/pull-requests/247) + [gazebo pull request 2090](https://bitbucket.org/osrf/gazebo/pull-requests/2090) 1. A new style for representing the noise properties of an `imu` was implemented in [pull request 199](https://bitbucket.org/osrf/sdformat/pull-requests/199) for sdf 1.5 and the old style was declared as deprecated. The old style has been removed from sdf 1.6 with the conversion script updating to the new style. + [pull request 199](https://bitbucket.org/osrf/sdformat/pull-requests/199) + [pull request 243](https://bitbucket.org/osrf/sdformat/pull-requests/243) + [pull request 244](https://bitbucket.org/osrf/sdformat/pull-requests/244) sdformat-6.0.0+dfsg/src/000077500000000000000000000000001323606632500150505ustar00rootroot00000000000000sdformat-6.0.0+dfsg/src/CMakeLists.txt000066400000000000000000000045041323606632500176130ustar00rootroot00000000000000include (${sdf_cmake_dir}/SDFUtils.cmake) include_directories( ${Boost_INCLUDE_DIRS} ${IGNITION-MATH_INCLUDE_DIRS} ) link_directories( ${PROJECT_BINARY_DIR}/test ${IGNITION-MATH_LIBRARY_DIRS} ) if (NOT USE_INTERNAL_URDF) link_directories(${URDF_LIBRARY_DIRS}) endif() if (USE_EXTERNAL_TINYXML) link_directories(${tinyxml_LIBRARY_DIRS}) endif() set (sources Console.cc Converter.cc Element.cc Error.cc Exception.cc Filesystem.cc ign.cc parser.cc parser_urdf.cc Param.cc Root.cc SDF.cc SDFExtension.cc Types.cc Utils.cc World.cc ) if (USE_EXTERNAL_TINYXML) include_directories(${tinyxml_INCLUDE_DIRS}) else() set(sources ${sources} win/tinyxml/tinystr.cpp win/tinyxml/tinyxmlerror.cpp win/tinyxml/tinyxml.cpp win/tinyxml/tinyxmlparser.cpp) install (FILES win/tinyxml/tinyxml.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sdformat-${SDF_VERSION}) endif() if (USE_INTERNAL_URDF) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/urdf) set(sources ${sources} urdf/urdf_parser/model.cpp urdf/urdf_parser/link.cpp urdf/urdf_parser/joint.cpp urdf/urdf_parser/pose.cpp urdf/urdf_parser/twist.cpp urdf/urdf_parser/urdf_model_state.cpp urdf/urdf_parser/urdf_sensor.cpp urdf/urdf_parser/world.cpp) else() include_directories(${URDF_INCLUDE_DIRS}) endif() set (gtest_sources SDF_TEST.cc Console_TEST.cc Converter_TEST.cc Element_TEST.cc Error_TEST.cc Exception_TEST.cc Filesystem_TEST.cc parser_urdf_TEST.cc Param_TEST.cc parser_TEST.cc Root_TEST.cc Types_TEST.cc World_TEST.cc ) # Build this test file only if Ignition Tools is installed. if (IGNITION-TOOLS_BINARY_DIRS) set (gtest_sources ${gtest_sources} ign_TEST.cc ) endif() sdf_build_tests(${gtest_sources}) sdf_add_library(sdformat ${sources}) target_link_libraries(sdformat ${IGNITION-MATH_LIBRARIES}) if (USE_EXTERNAL_TINYXML) target_link_libraries(sdformat ${tinyxml_LIBRARIES}) else() # Ignore the warnings from the internal library set_target_properties(sdformat PROPERTIES LINK_FLAGS "/IGNORE:4049 /IGNORE:4217") endif() message (STATUS "URDF_LIBRARY_DIRS=${URDF_LIBRARY_DIRS}") message (STATUS "URDF_LIBRARIES=${URDF_LIBRARIES}") if (NOT USE_INTERNAL_URDF) target_link_libraries(sdformat ${URDF_LIBRARIES}) endif() sdf_install_library(sdformat) add_subdirectory(cmd) sdformat-6.0.0+dfsg/src/Console.cc000066400000000000000000000102101323606632500167530ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include "sdf/Console.hh" #include "sdf/Filesystem.hh" #include "sdf/Types.hh" using namespace sdf; /// Static pointer to the console. static std::shared_ptr myself; static std::mutex g_instance_mutex; /// \todo Output disabled for windows, to allow tests to pass. We should /// disable output just for tests on windows. #ifndef _WIN32 static bool g_quiet = false; #else static bool g_quiet = true; #endif static Console::ConsoleStream g_NullStream(nullptr); ////////////////////////////////////////////////// Console::Console() : dataPtr(new ConsolePrivate) { // Set up the file that we'll log to. #ifndef _WIN32 const char *home = std::getenv("HOME"); #else const char *home = std::getenv("HOMEPATH"); #endif if (!home) { std::cerr << "No HOME defined in the environment. Will not log." << std::endl; return; } std::string logDir = sdf::filesystem::append(home, ".sdformat"); if (!sdf::filesystem::exists(logDir)) { sdf::filesystem::create_directory(logDir); } else if (!sdf::filesystem::is_directory(logDir)) { std::cerr << logDir << " exists but is not a directory. Will not log." << std::endl; return; } std::string logFile = sdf::filesystem::append(logDir, "sdformat.log"); this->dataPtr->logFileStream.open(logFile.c_str(), std::ios::out); } ////////////////////////////////////////////////// Console::~Console() { } ////////////////////////////////////////////////// ConsolePtr Console::Instance() { std::lock_guard lock(g_instance_mutex); if (!myself) { myself.reset(new Console()); } return myself; } ////////////////////////////////////////////////// void Console::Clear() { std::lock_guard lock(g_instance_mutex); myself = nullptr; } ////////////////////////////////////////////////// void Console::SetQuiet(bool _quiet) { g_quiet = _quiet; } ////////////////////////////////////////////////// Console::ConsoleStream &Console::ColorMsg(const std::string &lbl, const std::string &file, unsigned int line, int color) { if (!g_quiet) { this->dataPtr->msgStream.Prefix(lbl, file, line, color); return this->dataPtr->msgStream; } else { return g_NullStream; } } ////////////////////////////////////////////////// Console::ConsoleStream &Console::Log(const std::string &lbl, const std::string &file, unsigned int line) { this->dataPtr->logStream.Prefix(lbl, file, line, 0); return this->dataPtr->logStream; } ////////////////////////////////////////////////// void Console::ConsoleStream::Prefix(const std::string &_lbl, const std::string &_file, unsigned int _line, int _color) { size_t index = _file.find_last_of("/") + 1; (void)_color; if (this->stream) { #ifndef _WIN32 *this->stream << "\033[1;" << _color << "m" << _lbl << " [" << _file.substr(index , _file.size() - index) << ":" << _line << "]\033[0m "; #else *this->stream << _lbl << " [" << _file.substr(index , _file.size() - index) << ":" << _line << "] "; #endif } if (Console::Instance()->dataPtr->logFileStream.is_open()) { Console::Instance()->dataPtr->logFileStream << _lbl << " [" << _file.substr(index , _file.size() - index)<< ":" << _line << "] "; } } sdformat-6.0.0+dfsg/src/Console_TEST.cc000066400000000000000000000053101323606632500176170ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #ifndef _WIN32 #include #include #endif #include "sdf/Console.hh" #ifndef _WIN32 bool create_new_temp_dir(std::string &_new_temp_path) { std::string tmppath; const char *tmp = getenv("TMPDIR"); if (tmp) { tmppath = std::string(tmp); } else { tmppath = std::string("/tmp"); } tmppath += "/XXXXXX"; char *dtemp = mkdtemp(const_cast(tmppath.c_str())); if (dtemp == nullptr) { return false; } _new_temp_path = std::string(dtemp); return true; } //////////////////////////////////////////////////// TEST(Console, nohome) { sdf::Console::Clear(); unsetenv("HOME"); sdferr << "Error.\n"; } //////////////////////////////////////////////////// TEST(Console, logdir_is_file) { sdf::Console::Clear(); std::string temp_dir; ASSERT_TRUE(create_new_temp_dir(temp_dir)); ASSERT_EQ(setenv("HOME", temp_dir.c_str(), 1), 0); std::string sdf_file = temp_dir + "/.sdformat"; FILE *fp = fopen(sdf_file.c_str(), "w"); ASSERT_NE(fp, nullptr); ASSERT_EQ(fwrite("hello", 5, 1, fp), 1UL); fclose(fp); sdferr << "Error.\n"; } //////////////////////////////////////////////////// TEST(Console, logdir_doesnt_exist) { sdf::Console::Clear(); std::string temp_dir; ASSERT_TRUE(create_new_temp_dir(temp_dir)); temp_dir += "/foobarbaz"; ASSERT_EQ(setenv("HOME", temp_dir.c_str(), 1), 0); sdferr << "Error.\n"; } #endif // _WIN32 //////////////////////////////////////////////////// /// Test out the different console messages. TEST(Console, Messages) { sdferr << "Error.\n"; sdfwarn << "Warning.\n"; sdfmsg << "Message.\n"; sdfdbg << "Debug.\n"; } //////////////////////////////////////////////////// TEST(Console, quiet) { sdf::ConsolePtr con = sdf::Console::Instance(); con->SetQuiet(true); sdferr << "Error.\n"; sdfwarn << "Warning.\n"; sdfmsg << "Message.\n"; sdfdbg << "Debug.\n"; con->SetQuiet(false); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Converter.cc000066400000000000000000000357041323606632500173370ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include "sdf/Assert.hh" #include "sdf/Console.hh" #include "sdf/Converter.hh" #include "sdf/Filesystem.hh" #include "sdf/SDFImpl.hh" #include "sdf/Types.hh" using namespace sdf; ///////////////////////////////////////////////// static bool case_insensitive_cmp(const char &_a, const char &_b) { return tolower(_a) < tolower(_b); } ///////////////////////////////////////////////// bool Converter::Convert(TiXmlDocument *_doc, const std::string &_toVersion, bool _quiet) { SDF_ASSERT(_doc != nullptr, "SDF XML doc is NULL"); TiXmlElement *elem = _doc->FirstChildElement("gazebo"); // Replace with if (elem && std::stod(_toVersion) >= 1.3) { elem->SetValue("sdf"); } else if (!elem) { elem = _doc->FirstChildElement("sdf"); } if (!elem || !elem->Attribute("version")) { sdferr << " Unable to determine original SDF version\n"; return false; } std::string origVersion = elem->Attribute("version"); if (origVersion == _toVersion) { return true; } if (!_quiet) { sdfdbg << "Version[" << origVersion << "] to Version[" << _toVersion << "]\n" << " Please use the gz sdf tool to update your SDF files.\n" << " $ gz sdf -c [sdf_file]\n"; } elem->SetAttribute("version", _toVersion); std::string currFilenameVersion = origVersion; std::replace(currFilenameVersion.begin(), currFilenameVersion.end(), '.', '_'); std::string filename = sdf::findFile(currFilenameVersion + ".convert"); // Use convert file in the current sdf version folder for conversion. If file // does not exist, then find intermediate convert files and iteratively // convert the sdf elem. Ideally, users should use gzsdf convert so that the // latest sdf versioned file is written and no subsequent conversions are // necessary. TiXmlDocument xmlDoc; if (!xmlDoc.LoadFile(filename)) { std::string sdfPath = sdf::findFile("sdformat/"); // find all sdf version dirs in resource path sdf::filesystem::DirIter endIter; // Using a set here seems like overkill, since we mostly use it as a simple // iterator. However, we have to make sure that anything we insert is // lexicographical order, and a set fits the bill. std::set> sdfDirs; if (sdf::filesystem::is_directory(sdfPath)) { for (sdf::filesystem::DirIter dirIter(sdfPath); dirIter != endIter ; ++dirIter) { if (sdf::filesystem::is_directory(*dirIter)) { std::string fname = sdf::filesystem::basename(*dirIter); if (std::lexicographical_compare(origVersion.begin(), origVersion.end(), fname.begin(), fname.end(), case_insensitive_cmp)) { sdfDirs.insert(std::make_pair(*dirIter, fname)); } } } } // loop through sdf dirs and do the intermediate conversions for (std::set >::iterator it = sdfDirs.begin(); it != sdfDirs.end(); ++it) { std::string convertFile = sdf::filesystem::append((*it).first, currFilenameVersion + ".convert"); if (sdf::filesystem::exists(convertFile)) { if (!xmlDoc.LoadFile(convertFile)) { sdferr << "Unable to load file[" << convertFile << "]\n"; return false; } ConvertImpl(elem, xmlDoc.FirstChildElement("convert")); if ((*it).second == _toVersion) { return true; } currFilenameVersion = (*it).second; std::replace(currFilenameVersion.begin(), currFilenameVersion.end(), '.', '_'); } else { continue; } } sdferr << "Unable to convert from SDF version " << origVersion << " to " << _toVersion << "\n"; return false; } ConvertImpl(elem, xmlDoc.FirstChildElement("convert")); return true; } ///////////////////////////////////////////////// void Converter::Convert(TiXmlDocument *_doc, TiXmlDocument *_convertDoc) { SDF_ASSERT(_doc != NULL, "SDF XML doc is NULL"); SDF_ASSERT(_convertDoc != NULL, "Convert XML doc is NULL"); ConvertImpl(_doc->FirstChildElement(), _convertDoc->FirstChildElement()); } ///////////////////////////////////////////////// void Converter::ConvertImpl(TiXmlElement *_elem, TiXmlElement *_convert) { SDF_ASSERT(_elem != NULL, "SDF element is NULL"); SDF_ASSERT(_convert != NULL, "Convert element is NULL"); CheckDeprecation(_elem, _convert); for (TiXmlElement *convertElem = _convert->FirstChildElement("convert"); convertElem; convertElem = convertElem->NextSiblingElement("convert")) { TiXmlElement *elem = _elem->FirstChildElement( convertElem->Attribute("name")); while (elem) { ConvertImpl(elem, convertElem); elem = elem->NextSiblingElement(convertElem->Attribute("name")); } } for (TiXmlElement *childElem = _convert->FirstChildElement(); childElem; childElem = childElem->NextSiblingElement()) { if (childElem->ValueStr() == "rename") { Rename(_elem, childElem); } else if (childElem->ValueStr() == "copy") { Move(_elem, childElem, true); } else if (childElem->ValueStr() == "move") { Move(_elem, childElem, false); } else if (childElem->ValueStr() == "add") { Add(_elem, childElem); } else if (childElem->ValueStr() == "remove") { Remove(_elem, childElem); } else if (childElem->ValueStr() != "convert") { sdferr << "Unknown convert element[" << childElem->ValueStr() << "]\n"; } } } ///////////////////////////////////////////////// void Converter::Rename(TiXmlElement *_elem, TiXmlElement *_renameElem) { SDF_ASSERT(_elem != NULL, "SDF element is NULL"); SDF_ASSERT(_renameElem != NULL, "Rename element is NULL"); TiXmlElement *fromConvertElem = _renameElem->FirstChildElement("from"); TiXmlElement *toConvertElem = _renameElem->FirstChildElement("to"); const char *fromElemName = fromConvertElem->Attribute("element"); const char *fromAttrName = fromConvertElem->Attribute("attribute"); const char *toElemName = toConvertElem->Attribute("element"); const char *toAttrName = toConvertElem->Attribute("attribute"); const char *value = GetValue(fromElemName, fromAttrName, _elem); if (!value) { return; } if (!toElemName) { sdferr << "No 'to' element name specified\n"; return; } TiXmlElement *replaceTo = new TiXmlElement(toElemName); if (toAttrName) { replaceTo->SetAttribute(toAttrName, value); } else { TiXmlText *text = new TiXmlText(value); replaceTo->LinkEndChild(text); } if (fromElemName) { TiXmlElement *replaceFrom = _elem->FirstChildElement(fromElemName); _elem->ReplaceChild(replaceFrom, *replaceTo); } else if (fromAttrName) { _elem->RemoveAttribute(fromAttrName); _elem->LinkEndChild(replaceTo); } } ///////////////////////////////////////////////// void Converter::Add(TiXmlElement *_elem, TiXmlElement *_addElem) { SDF_ASSERT(_elem != NULL, "SDF element is NULL"); SDF_ASSERT(_addElem != NULL, "Add element is NULL"); const char *attributeName = _addElem->Attribute("attribute"); const char *elementName = _addElem->Attribute("element"); const char *value = _addElem->Attribute("value"); if (!((attributeName == nullptr) ^ (elementName == nullptr))) { sdferr << "Exactly one 'element' or 'attribute'" << " must be specified in \n"; return; } if (attributeName) { if (value) { _elem->SetAttribute(attributeName, value); } else { sdferr << "No 'value' specified in \n"; return; } } else { TiXmlElement *addElem = new TiXmlElement(elementName); if (value) { TiXmlText *addText = new TiXmlText(value); addElem->LinkEndChild(addText); } _elem->LinkEndChild(addElem); } } ///////////////////////////////////////////////// void Converter::Remove(TiXmlElement *_elem, TiXmlElement *_removeElem) { SDF_ASSERT(_elem != NULL, "SDF element is NULL"); SDF_ASSERT(_removeElem != NULL, "Move element is NULL"); const char *attributeName = _removeElem->Attribute("attribute"); const char *elementName = _removeElem->Attribute("element"); if (!((attributeName == nullptr) ^ (elementName == nullptr))) { sdferr << "Exactly one 'element' or 'attribute'" << " must be specified in \n"; return; } if (attributeName) { _elem->RemoveAttribute(attributeName); } else { _elem->RemoveChild(_elem->FirstChildElement(elementName)); } } ///////////////////////////////////////////////// void Converter::Move(TiXmlElement *_elem, TiXmlElement *_moveElem, const bool _copy) { SDF_ASSERT(_elem != NULL, "SDF element is NULL"); SDF_ASSERT(_moveElem != NULL, "Move element is NULL"); TiXmlElement *fromConvertElem = _moveElem->FirstChildElement("from"); TiXmlElement *toConvertElem = _moveElem->FirstChildElement("to"); const char *fromElemStr = fromConvertElem->Attribute("element"); const char *fromAttrStr = fromConvertElem->Attribute("attribute"); const char *toElemStr = toConvertElem->Attribute("element"); const char *toAttrStr = toConvertElem->Attribute("attribute"); // tokenize 'from' and 'to' strs std::string fromStr = ""; if (fromElemStr) { fromStr = fromElemStr; } else if (fromAttrStr) { fromStr = fromAttrStr; } std::string toStr = ""; if (toElemStr) { toStr = toElemStr; } else if (toAttrStr) { toStr = toAttrStr; } std::vector fromTokens = split(fromStr, "::"); std::vector toTokens = split(toStr, "::"); // split() always returns at least one element, even with the // empty string. Thus we don't check if the fromTokens or toTokens are empty. // get value of the 'from' element/attribute TiXmlElement *fromElem = _elem; for (unsigned int i = 0; i < fromTokens.size()-1; ++i) { fromElem = fromElem->FirstChildElement(fromTokens[i]); if (!fromElem) { // Return when the tokens don't match. Don't output an error message // because it spams the console. return; } } const char *fromName = fromTokens[fromTokens.size()-1].c_str(); const char *value = NULL; unsigned int newDirIndex = 0; // get the new element/attribute name const char *toName = toTokens[toTokens.size()-1].c_str(); TiXmlElement *toElem = _elem; TiXmlElement *childElem = NULL; for (unsigned int i = 0; i < toTokens.size()-1; ++i) { childElem = toElem->FirstChildElement(toTokens[i]); if (!childElem) { newDirIndex = i; break; } toElem = childElem; } // found elements in 'to' string that is not present, so create new // elements if (!childElem) { int offset = toElemStr != NULL && toAttrStr != NULL ? 0 : 1; while (newDirIndex < (toTokens.size()-offset)) { TiXmlElement *newElem = new TiXmlElement(toTokens[newDirIndex]); toElem->LinkEndChild(newElem); toElem = newElem; newDirIndex++; } } // Get value, or return if no element/attribute found as they don't have to // be specified in the sdf. if (fromElemStr) { TiXmlElement *moveFrom = fromElem->FirstChildElement(fromName); // No matching element, so return. if (!moveFrom) { return; } if (toElemStr && !toAttrStr) { TiXmlElement *moveTo = static_cast(moveFrom->Clone()); moveTo->SetValue(toName); toElem->LinkEndChild(moveTo); } else { value = GetValue(fromName, NULL, fromElem); if (!value) { return; } std::string valueStr = value; toElem->SetAttribute(toAttrStr, valueStr); } if (!_copy) { fromElem->RemoveChild(moveFrom); } } else if (fromAttrStr) { value = GetValue(NULL, fromName, fromElem); if (!value) { return; } std::string valueStr = value; if (toElemStr) { TiXmlElement *moveTo = new TiXmlElement(toName); TiXmlText *text = new TiXmlText(valueStr); moveTo->LinkEndChild(text); toElem->LinkEndChild(moveTo); } else if (toAttrStr) { toElem->SetAttribute(toName, valueStr); } if (!_copy && fromAttrStr) { fromElem->RemoveAttribute(fromName); } } } ///////////////////////////////////////////////// const char *Converter::GetValue(const char *_valueElem, const char *_valueAttr, TiXmlElement *_elem) { if (_valueElem) { // Check to see if the element that is being converted has the value if (!_elem->FirstChildElement(_valueElem)) { return NULL; } if (_valueAttr) { return _elem->FirstChildElement(_valueElem)->Attribute(_valueAttr); } else { return _elem->FirstChildElement(_valueElem)->GetText(); } } else if (_valueAttr) { return _elem->Attribute(_valueAttr); } return NULL; } ///////////////////////////////////////////////// void Converter::CheckDeprecation(TiXmlElement *_elem, TiXmlElement *_convert) { // Process deprecated elements for (TiXmlElement *deprecatedElem = _convert->FirstChildElement("deprecated"); deprecatedElem; deprecatedElem = deprecatedElem->NextSiblingElement("deprecated")) { std::string value = deprecatedElem->GetText(); std::vector valueSplit = split(value, "/"); bool found = false; TiXmlElement *e = _elem; std::ostringstream stream; std::string prefix = ""; for (unsigned int i = 0; i < valueSplit.size() && !found; ++i) { if (e->FirstChildElement(valueSplit[i])) { if (stream.str().size() != 0) { stream << ">\n"; prefix += " "; } stream << prefix << "<" << valueSplit[i]; e = e->FirstChildElement(valueSplit[i]); } else if (e->Attribute(valueSplit[i])) { stream << " " << valueSplit[i] << "='" << e->Attribute(valueSplit[i].c_str()) << "'"; found = true; } } sdfwarn << "Deprecated SDF Values in original file:\n" << stream.str() << "\n\n"; } } sdformat-6.0.0+dfsg/src/Converter_TEST.cc000066400000000000000000001013311323606632500201640ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/Exception.hh" #include "sdf/Converter.hh" //////////////////////////////////////////////////// /// Set up an xml string for testing std::string getXmlString() { std::stringstream stream; stream << "" << " " << " " << " D" << " " << " " << ""; return stream.str(); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from elem to elem TEST(Converter, MoveElemElem) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test moving from elem to elem // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->FirstChildElement("elemC") != nullptr); EXPECT_TRUE(convertedElem->FirstChildElement("elemE") != nullptr); std::string elemValue = convertedElem->FirstChildElement("elemE")->GetText(); EXPECT_EQ(elemValue, "D"); convertedElem = convertedElem->FirstChildElement("elemC"); ASSERT_TRUE(convertedElem != nullptr); EXPECT_FALSE(convertedElem->FirstChildElement("elemD")); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from elem to attr TEST(Converter, MoveElemAttr) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from elem to attr TiXmlDocument xmlDoc2; xmlDoc2.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc2; convertXmlDoc2.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc2, &convertXmlDoc2); TiXmlElement *convertedElem = xmlDoc2.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->Attribute("attrE") != nullptr); std::string attrValue = convertedElem->Attribute("attrE"); EXPECT_EQ(attrValue, "D"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->FirstChildElement("elemD")); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from attr to attr TEST(Converter, MoveAttrAttr) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from attr to attr TiXmlDocument xmlDoc3; xmlDoc3.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc3; convertXmlDoc3.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc3, &convertXmlDoc3); TiXmlElement *convertedElem = xmlDoc3.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->Attribute("attrE") != nullptr); std::string attrValue = convertedElem->Attribute("attrE"); EXPECT_EQ(attrValue, "C"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->Attribute("attrC")); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from attr to elem TEST(Converter, MoveAttrElem) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from attr to elem TiXmlDocument xmlDoc4; xmlDoc4.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc4; convertXmlDoc4.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc4, &convertXmlDoc4); TiXmlElement *convertedElem = xmlDoc4.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->FirstChildElement("elemE") != nullptr); std::string elemValue = convertedElem->FirstChildElement("elemE")->GetText(); EXPECT_EQ(elemValue, "C"); EXPECT_TRUE(convertedElem->FirstChildElement("elemC") != nullptr); convertedElem = convertedElem->FirstChildElement("elemC"); ASSERT_TRUE(convertedElem != nullptr); EXPECT_FALSE(convertedElem->Attribute("attrC")); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from elem to elem across multiple levels TEST(Converter, MoveElemElemMultipleLevels) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from elem to elem across multiple levels TiXmlDocument xmlDoc5; xmlDoc5.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc5; convertXmlDoc5.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc5, &convertXmlDoc5); TiXmlElement *convertedElem = xmlDoc5.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); EXPECT_TRUE(convertedElem->FirstChildElement("elemE") != nullptr); std::string elemValue = convertedElem->FirstChildElement("elemE")->GetText(); EXPECT_EQ(elemValue, "D"); convertedElem = convertedElem->FirstChildElement("elemB"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->FirstChildElement("elemD")); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from attr to attr across multiple levels TEST(Converter, MoveAttrAttrMultipleLevels) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from attr to attr across multiple levels TiXmlDocument xmlDoc6; xmlDoc6.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc6; convertXmlDoc6.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc6, &convertXmlDoc6); TiXmlElement *convertedElem = xmlDoc6.FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); std::string attrValue = convertedElem->Attribute("attrE"); EXPECT_EQ(attrValue, "C"); convertedElem = convertedElem->FirstChildElement("elemB"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->Attribute("attrC")); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from elem to attr across multiple levels TEST(Converter, MoveElemAttrMultipleLevels) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from elem to attr across multiple levels TiXmlDocument xmlDoc7; xmlDoc7.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc7; convertXmlDoc7.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc7, &convertXmlDoc7); TiXmlElement *convertedElem = xmlDoc7.FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); std::string attrValue = convertedElem->Attribute("attrE"); EXPECT_EQ(attrValue, "D"); convertedElem = convertedElem->FirstChildElement("elemB"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->FirstChildElement("elemD")); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from attr to elem across multiple levels TEST(Converter, MoveAttrElemMultipleLevels) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from attr to elem across multiple levels TiXmlDocument xmlDoc8; xmlDoc8.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc8; convertXmlDoc8.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc8, &convertXmlDoc8); TiXmlElement *convertedElem = xmlDoc8.FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); EXPECT_TRUE(convertedElem->FirstChildElement("elemE") != nullptr); std::string elemValue = convertedElem->FirstChildElement("elemE")->GetText(); EXPECT_EQ(elemValue, "C"); convertedElem = convertedElem->FirstChildElement("elemB"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); EXPECT_FALSE(convertedElem->Attribute("attrC")); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Add function is working /// Test adding element and attribute TEST(Converter, Add) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test adding element // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->FirstChildElement("elemC") != nullptr); EXPECT_TRUE(convertedElem->FirstChildElement("elemBB") != nullptr); std::string elemValue = convertedElem->FirstChildElement("elemBB")->GetText(); EXPECT_EQ(elemValue, "BB"); convertedElem = convertedElem->FirstChildElement("elemC"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement("elemD"); ASSERT_TRUE(convertedElem != nullptr); std::string attrValue = convertedElem->Attribute("attrDD"); EXPECT_EQ(attrValue, "DD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Remove function is working /// Test removing element TEST(Converter, RemoveElement) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test adding element // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->FirstChildElement("elemC") != nullptr); convertedElem = convertedElem->FirstChildElement("elemC"); ASSERT_TRUE(convertedElem != nullptr); convertedElem = convertedElem->FirstChildElement("elemD"); ASSERT_TRUE(convertedElem == nullptr); } //////////////////////////////////////////////////// /// Ensure that Converter::Remove function is working /// Test removing element and sub-elements TEST(Converter, RemoveElementSubElement) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test adding element // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); ASSERT_TRUE(convertedElem->FirstChildElement("elemC") == nullptr); } //////////////////////////////////////////////////// /// Ensure that Converter::Remove function is working /// Test removing attribute TEST(Converter, RemoveAttr) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test adding element // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); EXPECT_TRUE(convertedElem->FirstChildElement("elemC") != nullptr); convertedElem = convertedElem->FirstChildElement("elemC"); ASSERT_TRUE(convertedElem != nullptr); EXPECT_TRUE(convertedElem->Attribute("attrC") == nullptr); convertedElem = convertedElem->FirstChildElement("elemD"); ASSERT_TRUE(convertedElem != nullptr); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test an invalid move TEST(Converter, MoveInvalid) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); // In this case, we had an invalid elemC:: in the conversion, which // means that the conversion quietly failed. Make sure the new // document is the same as the original. // Verify the xml TiXmlElement *convertElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemA"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemB"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemC"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test an invalid move TEST(Converter, MoveInvalidPrefix) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); // In this case, we had an invalid elemC:: in the conversion, which // means that the conversion quietly failed. Make sure the new // document is the same as the original. // Verify the xml TiXmlElement *convertElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemA"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemB"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemC"); convertElem = convertElem->FirstChildElement(); EXPECT_TRUE(convertElem != nullptr); EXPECT_EQ(convertElem->ValueStr(), "elemD"); } //////////////////////////////////////////////////// /// Ensure that Converter::Move function is working /// Test moving from elem to elem TEST(Converter, CopyElemElem) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test moving from elem to elem // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); TiXmlElement *elemB = convertedElem->FirstChildElement(); ASSERT_TRUE(elemB != nullptr); EXPECT_EQ(elemB->ValueStr(), "elemB"); TiXmlElement *elemC = elemB->FirstChild("elemC")->ToElement(); EXPECT_TRUE(elemC != nullptr); TiXmlElement *elemD = elemC->FirstChildElement(); EXPECT_TRUE(elemD != nullptr); std::string elemValue = elemD->GetText(); EXPECT_EQ(elemValue, "D"); TiXmlElement *elemE = elemB->FirstChild("elemE")->ToElement(); EXPECT_TRUE(elemE != nullptr); elemValue = elemE->GetText(); EXPECT_EQ(elemValue, "D"); } //////////////////////////////////////////////////// TEST(Converter, RenameElemElem) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Verify the xml TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); TiXmlElement *childElem = xmlDoc.FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemA"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemB"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemC"); childElem = childElem->FirstChildElement(); EXPECT_TRUE(childElem != nullptr); EXPECT_EQ(childElem->ValueStr(), "elemD"); // Test moving from elem to elem // Set up a convert file std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc; convertXmlDoc.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc, &convertXmlDoc); TiXmlElement *convertedElem = xmlDoc.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); TiXmlElement *elemB = convertedElem->FirstChildElement(); ASSERT_TRUE(elemB != nullptr); EXPECT_EQ(elemB->ValueStr(), "elemB"); TiXmlElement *elemC = elemB->FirstChild("elemC")->ToElement(); EXPECT_TRUE(elemC != nullptr); TiXmlElement *elemE = elemC->FirstChildElement(); EXPECT_TRUE(elemE != nullptr); EXPECT_EQ(elemE->ValueStr(), "elemE"); std::string elemValue = elemE->GetText(); ASSERT_EQ(elemValue, "D"); } //////////////////////////////////////////////////// TEST(Converter, RenameAttrAttr) { // Set up an xml string for testing std::string xmlString = getXmlString(); // Test moving from attr to attr TiXmlDocument xmlDoc3; xmlDoc3.Parse(xmlString.c_str()); std::stringstream convertStream; convertStream << "" << " " << " " << " " << " " << " " << " " << " " << " " << ""; TiXmlDocument convertXmlDoc3; convertXmlDoc3.Parse(convertStream.str().c_str()); sdf::Converter::Convert(&xmlDoc3, &convertXmlDoc3); TiXmlElement *convertedElem = xmlDoc3.FirstChildElement(); EXPECT_EQ(convertedElem->ValueStr(), "elemA"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemB"); convertedElem = convertedElem->FirstChildElement(); ASSERT_TRUE(convertedElem != nullptr); EXPECT_EQ(convertedElem->ValueStr(), "elemC"); convertedElem = convertedElem->FirstChild("elemE")->ToElement(); std::string attrValue = convertedElem->Attribute("attrE"); EXPECT_EQ(attrValue, "C"); } //////////////////////////////////////////////////// TEST(Converter, GazeboToSDF) { std::stringstream stream; stream << "" << ""; std::string xmlString = stream.str(); TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); sdf::Converter::Convert(&xmlDoc, "1.3"); TiXmlElement *convertedElem = xmlDoc.FirstChild("sdf")->ToElement(); EXPECT_TRUE(convertedElem != nullptr); } //////////////////////////////////////////////////// TEST(Converter, NullDoc) { TiXmlDocument xmlDoc; TiXmlDocument convertXmlDoc; ASSERT_THROW(sdf::Converter::Convert(nullptr, &convertXmlDoc), sdf::AssertionInternalError); ASSERT_THROW(sdf::Converter::Convert(&xmlDoc, nullptr), sdf::AssertionInternalError); ASSERT_THROW(sdf::Converter::Convert(nullptr, "1.4"), sdf::AssertionInternalError); } //////////////////////////////////////////////////// TEST(Converter, NoVersion) { std::string xmlString(""); TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); ASSERT_FALSE(sdf::Converter::Convert(&xmlDoc, "1.3")); } //////////////////////////////////////////////////// TEST(Converter, SameVersion) { std::string xmlString(""); TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); ASSERT_TRUE(sdf::Converter::Convert(&xmlDoc, "1.3")); } //////////////////////////////////////////////////// TEST(Converter, NewerVersion) { std::string xmlString(""); TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); ASSERT_TRUE(sdf::Converter::Convert(&xmlDoc, "1.6")); } //////////////////////////////////////////////////// TEST(Converter, MuchNewerVersion) { std::string xmlString(""); TiXmlDocument xmlDoc; xmlDoc.Parse(xmlString.c_str()); ASSERT_TRUE(sdf::Converter::Convert(&xmlDoc, "1.6")); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Element.cc000066400000000000000000000554341323606632500167630ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/Assert.hh" #include "sdf/Element.hh" using namespace sdf; ///////////////////////////////////////////////// Element::Element() : dataPtr(new ElementPrivate) { this->dataPtr->copyChildren = false; this->dataPtr->referenceSDF = ""; } ///////////////////////////////////////////////// Element::~Element() { } ///////////////////////////////////////////////// ElementPtr Element::GetParent() const { return this->dataPtr->parent.lock(); } ///////////////////////////////////////////////// void Element::SetParent(const ElementPtr _parent) { this->dataPtr->parent = _parent; } ///////////////////////////////////////////////// void Element::SetName(const std::string &_name) { this->dataPtr->name = _name; } ///////////////////////////////////////////////// const std::string &Element::GetName() const { return this->dataPtr->name; } ///////////////////////////////////////////////// void Element::SetRequired(const std::string &_req) { this->dataPtr->required = _req; } ///////////////////////////////////////////////// const std::string &Element::GetRequired() const { return this->dataPtr->required; } ///////////////////////////////////////////////// void Element::SetCopyChildren(bool _value) { this->dataPtr->copyChildren = _value; } ///////////////////////////////////////////////// bool Element::GetCopyChildren() const { return this->dataPtr->copyChildren; } ///////////////////////////////////////////////// void Element::SetReferenceSDF(const std::string &_value) { this->dataPtr->referenceSDF = _value; } ///////////////////////////////////////////////// std::string Element::ReferenceSDF() const { return this->dataPtr->referenceSDF; } ///////////////////////////////////////////////// void Element::AddValue(const std::string &_type, const std::string &_defaultValue, bool _required, const std::string &_description) { this->dataPtr->value = this->CreateParam(this->dataPtr->name, _type, _defaultValue, _required, _description); } ///////////////////////////////////////////////// ParamPtr Element::CreateParam(const std::string &_key, const std::string &_type, const std::string &_defaultValue, bool _required, const std::string &_description) { return ParamPtr( new Param(_key, _type, _defaultValue, _required, _description)); } ///////////////////////////////////////////////// void Element::AddAttribute(const std::string &_key, const std::string &_type, const std::string &_defaultValue, bool _required, const std::string &_description) { this->dataPtr->attributes.push_back( this->CreateParam(_key, _type, _defaultValue, _required, _description)); } ///////////////////////////////////////////////// ElementPtr Element::Clone() const { ElementPtr clone(new Element); clone->dataPtr->description = this->dataPtr->description; clone->dataPtr->name = this->dataPtr->name; clone->dataPtr->required = this->dataPtr->required; clone->dataPtr->copyChildren = this->dataPtr->copyChildren; clone->dataPtr->includeFilename = this->dataPtr->includeFilename; clone->dataPtr->referenceSDF = this->dataPtr->referenceSDF; Param_V::const_iterator aiter; for (aiter = this->dataPtr->attributes.begin(); aiter != this->dataPtr->attributes.end(); ++aiter) { clone->dataPtr->attributes.push_back((*aiter)->Clone()); } ElementPtr_V::const_iterator eiter; for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { clone->dataPtr->elementDescriptions.push_back((*eiter)->Clone()); } for (eiter = this->dataPtr->elements.begin(); eiter != this->dataPtr->elements.end(); ++eiter) { clone->dataPtr->elements.push_back((*eiter)->Clone()); clone->dataPtr->elements.back()->dataPtr->parent = clone; } if (this->dataPtr->value) { clone->dataPtr->value = this->dataPtr->value->Clone(); } return clone; } ///////////////////////////////////////////////// void Element::Copy(const ElementPtr _elem) { this->dataPtr->name = _elem->GetName(); this->dataPtr->description = _elem->GetDescription(); this->dataPtr->required = _elem->GetRequired(); this->dataPtr->copyChildren = _elem->GetCopyChildren(); this->dataPtr->includeFilename = _elem->dataPtr->includeFilename; this->dataPtr->referenceSDF = _elem->ReferenceSDF(); for (Param_V::iterator iter = _elem->dataPtr->attributes.begin(); iter != _elem->dataPtr->attributes.end(); ++iter) { if (!this->HasAttribute((*iter)->GetKey())) { this->dataPtr->attributes.push_back((*iter)->Clone()); } ParamPtr param = this->GetAttribute((*iter)->GetKey()); (*param) = (**iter); } if (_elem->GetValue()) { if (!this->dataPtr->value) { this->dataPtr->value = _elem->GetValue()->Clone(); } else { *(this->dataPtr->value) = *(_elem->GetValue()); } } this->dataPtr->elementDescriptions.clear(); for (ElementPtr_V::const_iterator iter = _elem->dataPtr->elementDescriptions.begin(); iter != _elem->dataPtr->elementDescriptions.end(); ++iter) { this->dataPtr->elementDescriptions.push_back((*iter)->Clone()); } this->dataPtr->elements.clear(); for (ElementPtr_V::iterator iter = _elem->dataPtr->elements.begin(); iter != _elem->dataPtr->elements.end(); ++iter) { ElementPtr elem = (*iter)->Clone(); elem->Copy(*iter); elem->dataPtr->parent = shared_from_this(); this->dataPtr->elements.push_back(elem); } } ///////////////////////////////////////////////// void Element::PrintDescription(const std::string &_prefix) const { std::cout << _prefix << "dataPtr->value) { std::cout << " type ='" << this->dataPtr->value->GetTypeName() << "'" << " default ='" << this->dataPtr->value->GetDefaultAsString() << "'"; } std::cout << ">\n"; std::cout << _prefix << " " << this->dataPtr->description << "\n"; Param_V::iterator aiter; for (aiter = this->dataPtr->attributes.begin(); aiter != this->dataPtr->attributes.end(); ++aiter) { std::cout << _prefix << " \n"; std::cout << _prefix << " " << (*aiter)->GetDescription() << "\n"; std::cout << _prefix << " \n"; } if (this->GetCopyChildren()) { std::cout << _prefix << " \n"; } std::string refSDF = this->ReferenceSDF(); if (!refSDF.empty()) { std::cout << _prefix << " \n"; } ElementPtr_V::iterator eiter; for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { (*eiter)->PrintDescription(_prefix + " "); } std::cout << _prefix << "\n"; } ///////////////////////////////////////////////// void Element::PrintDocRightPane(std::string &_html, int _spacing, int &_index) const { std::ostringstream stream; ElementPtr_V::iterator eiter; int start = _index++; std::string childHTML; for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { (*eiter)->PrintDocRightPane(childHTML, _spacing + 4, _index); } stream << "dataPtr->name << start << "\"><" << this->dataPtr->name << ">"; stream << "
\n"; stream << "
\n"; stream << "Description: "; if (!this->dataPtr->description.empty()) { stream << this->dataPtr->description << "
\n"; } else { stream << "none
\n"; } stream << "Required: " << this->dataPtr->required << "   \n"; stream << "Type: "; if (this->dataPtr->value) { stream << this->dataPtr->value->GetTypeName() << "   \n" << "Default: " << this->dataPtr->value->GetDefaultAsString() << '\n'; } else { stream << "n/a\n"; } stream << "
"; if (this->dataPtr->attributes.size() > 0) { stream << "
\n"; stream << "Attributes
"; Param_V::iterator aiter; for (aiter = this->dataPtr->attributes.begin(); aiter != this->dataPtr->attributes.end(); ++aiter) { stream << "
\n"; stream << "
\n"; stream << "" << (*aiter)->GetKey() << ": "; stream << "
\n"; stream << "
\n"; if (!(*aiter)->GetDescription().empty()) { stream << (*aiter)->GetDescription() << "
\n"; } else { stream << "no description
\n"; } stream << "Type: " << (*aiter)->GetTypeName() << "   " << "Default: " << (*aiter)->GetDefaultAsString() << "
"; stream << "
\n"; stream << "
\n"; } stream << "
\n"; stream << "
\n"; } _html += stream.str(); _html += childHTML; _html += "
\n"; } ///////////////////////////////////////////////// void Element::PrintDocLeftPane(std::string &_html, int _spacing, int &_index) const { std::ostringstream stream; ElementPtr_V::iterator eiter; int start = _index++; std::string childHTML; for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { (*eiter)->PrintDocLeftPane(childHTML, _spacing + 4, _index); } stream << "dataPtr->name << start << "\"><" << this->dataPtr->name << ">"; stream << "
\n"; _html += stream.str(); _html += childHTML; _html += "
\n"; } void Element::PrintValuesImpl(const std::string &_prefix, std::ostringstream &_out) const { _out << _prefix << "<" << this->dataPtr->name; Param_V::const_iterator aiter; for (aiter = this->dataPtr->attributes.begin(); aiter != this->dataPtr->attributes.end(); ++aiter) { _out << " " << (*aiter)->GetKey() << "='" << (*aiter)->GetAsString() << "'"; } if (this->dataPtr->elements.size() > 0) { _out << ">\n"; ElementPtr_V::const_iterator eiter; for (eiter = this->dataPtr->elements.begin(); eiter != this->dataPtr->elements.end(); ++eiter) { (*eiter)->ToString(_prefix + " ", _out); } _out << _prefix << "dataPtr->name << ">\n"; } else { if (this->dataPtr->value) { _out << ">" << this->dataPtr->value->GetAsString() << "dataPtr->name << ">\n"; } else { _out << "/>\n"; } } } ///////////////////////////////////////////////// void Element::PrintValues(std::string _prefix) const { std::ostringstream ss; PrintValuesImpl(_prefix, ss); std::cout << ss.str(); } ///////////////////////////////////////////////// std::string Element::ToString(const std::string &_prefix) const { std::ostringstream out; this->ToString(_prefix, out); return out.str(); } ///////////////////////////////////////////////// void Element::ToString(const std::string &_prefix, std::ostringstream &_out) const { if (this->dataPtr->includeFilename.empty()) { PrintValuesImpl(_prefix, _out); } else { _out << _prefix << "\n"; } } ///////////////////////////////////////////////// bool Element::HasAttribute(const std::string &_key) const { return this->GetAttribute(_key) != nullptr; } ///////////////////////////////////////////////// bool Element::GetAttributeSet(const std::string &_key) const { bool result = false; ParamPtr p = this->GetAttribute(_key); if (p) { result = p->GetSet(); } return result; } ///////////////////////////////////////////////// ParamPtr Element::GetAttribute(const std::string &_key) const { Param_V::const_iterator iter; for (iter = this->dataPtr->attributes.begin(); iter != this->dataPtr->attributes.end(); ++iter) { if ((*iter)->GetKey() == _key) { return (*iter); } } return ParamPtr(); } ///////////////////////////////////////////////// size_t Element::GetAttributeCount() const { return this->dataPtr->attributes.size(); } ///////////////////////////////////////////////// ParamPtr Element::GetAttribute(unsigned int _index) const { ParamPtr result; if (_index < this->dataPtr->attributes.size()) { result = this->dataPtr->attributes[_index]; } return result; } ///////////////////////////////////////////////// size_t Element::GetElementDescriptionCount() const { return this->dataPtr->elementDescriptions.size(); } ///////////////////////////////////////////////// ElementPtr Element::GetElementDescription(unsigned int _index) const { ElementPtr result; if (_index < this->dataPtr->elementDescriptions.size()) { result = this->dataPtr->elementDescriptions[_index]; } return result; } ///////////////////////////////////////////////// ElementPtr Element::GetElementDescription(const std::string &_key) const { ElementPtr_V::const_iterator iter; for (iter = this->dataPtr->elementDescriptions.begin(); iter != this->dataPtr->elementDescriptions.end(); ++iter) { if ((*iter)->GetName() == _key) { return (*iter); } } return ElementPtr(); } ///////////////////////////////////////////////// ParamPtr Element::GetValue() const { return this->dataPtr->value; } ///////////////////////////////////////////////// bool Element::HasElement(const std::string &_name) const { return this->GetElementImpl(_name) != ElementPtr(); } ///////////////////////////////////////////////// ElementPtr Element::GetElementImpl(const std::string &_name) const { ElementPtr_V::const_iterator iter; for (iter = this->dataPtr->elements.begin(); iter != this->dataPtr->elements.end(); ++iter) { if ((*iter)->GetName() == _name) { return (*iter); } } return ElementPtr(); } ///////////////////////////////////////////////// ElementPtr Element::GetFirstElement() const { if (this->dataPtr->elements.empty()) { return ElementPtr(); } else { return this->dataPtr->elements.front(); } } ///////////////////////////////////////////////// ElementPtr Element::GetNextElement(const std::string &_name) const { auto parent = this->dataPtr->parent.lock(); if (parent) { ElementPtr_V::const_iterator iter; iter = std::find(parent->dataPtr->elements.begin(), parent->dataPtr->elements.end(), shared_from_this()); if (iter == parent->dataPtr->elements.end()) { return ElementPtr(); } ++iter; if (iter == parent->dataPtr->elements.end()) { return ElementPtr(); } else if (_name.empty()) { return *(iter); } else { for (; iter != parent->dataPtr->elements.end(); ++iter) { if ((*iter)->GetName() == _name) { return (*iter); } } } } return ElementPtr(); } ///////////////////////////////////////////////// ElementPtr Element::GetElement(const std::string &_name) { ElementPtr result = this->GetElementImpl(_name); if (result == ElementPtr()) { result = this->AddElement(_name); } return result; } ///////////////////////////////////////////////// void Element::InsertElement(ElementPtr _elem) { this->dataPtr->elements.push_back(_elem); } ///////////////////////////////////////////////// bool Element::HasElementDescription(const std::string &_name) const { return this->GetElementDescription(_name) != ElementPtr(); } ///////////////////////////////////////////////// ElementPtr Element::AddElement(const std::string &_name) { // if this element is a reference sdf and does not have any element // descriptions then get them from its parent auto parent = this->dataPtr->parent.lock(); if (!this->dataPtr->referenceSDF.empty() && this->dataPtr->elementDescriptions.empty() && parent && parent->GetName() == this->dataPtr->name) { for (unsigned int i = 0; i < parent->GetElementDescriptionCount(); ++i) { this->dataPtr->elementDescriptions.push_back( parent->GetElementDescription(i)->Clone()); } } ElementPtr_V::const_iterator iter, iter2; for (iter = this->dataPtr->elementDescriptions.begin(); iter != this->dataPtr->elementDescriptions.end(); ++iter) { if ((*iter)->dataPtr->name == _name) { ElementPtr elem = (*iter)->Clone(); elem->SetParent(shared_from_this()); this->dataPtr->elements.push_back(elem); // Add all child elements. for (iter2 = elem->dataPtr->elementDescriptions.begin(); iter2 != elem->dataPtr->elementDescriptions.end(); ++iter2) { // Add only required child element if ((*iter2)->GetRequired() == "1") { elem->AddElement((*iter2)->dataPtr->name); } } return this->dataPtr->elements.back(); } } sdferr << "Missing element description for [" << _name << "]\n"; return ElementPtr(); } ///////////////////////////////////////////////// void Element::ClearElements() { for (sdf::ElementPtr_V::iterator iter = this->dataPtr->elements.begin(); iter != this->dataPtr->elements.end(); ++iter) { (*iter)->ClearElements(); } this->dataPtr->elements.clear(); } ///////////////////////////////////////////////// void Element::Update() { for (sdf::Param_V::iterator iter = this->dataPtr->attributes.begin(); iter != this->dataPtr->attributes.end(); ++iter) { (*iter)->Update(); } for (sdf::ElementPtr_V::iterator iter = this->dataPtr->elements.begin(); iter != this->dataPtr->elements.end(); ++iter) { (*iter)->Update(); } if (this->dataPtr->value) { this->dataPtr->value->Update(); } } ///////////////////////////////////////////////// void Element::Reset() { for (ElementPtr_V::iterator iter = this->dataPtr->elements.begin(); iter != this->dataPtr->elements.end(); ++iter) { if (*iter) { (*iter)->Reset(); } (*iter).reset(); } for (ElementPtr_V::iterator iter = this->dataPtr->elementDescriptions.begin(); iter != this->dataPtr->elementDescriptions.end(); ++iter) { if (*iter) { (*iter)->Reset(); } (*iter).reset(); } this->dataPtr->elements.clear(); this->dataPtr->elementDescriptions.clear(); this->dataPtr->value.reset(); this->dataPtr->parent.reset(); } ///////////////////////////////////////////////// void Element::AddElementDescription(ElementPtr _elem) { this->dataPtr->elementDescriptions.push_back(_elem); } ///////////////////////////////////////////////// void Element::SetInclude(const std::string &_filename) { this->dataPtr->includeFilename = _filename; } ///////////////////////////////////////////////// std::string Element::GetInclude() const { return this->dataPtr->includeFilename; } ///////////////////////////////////////////////// std::string Element::GetDescription() const { return this->dataPtr->description; } ///////////////////////////////////////////////// void Element::SetDescription(const std::string &_desc) { this->dataPtr->description = _desc; } ///////////////////////////////////////////////// void Element::RemoveFromParent() { auto parent = this->dataPtr->parent.lock(); if (parent) { ElementPtr_V::iterator iter; iter = std::find(parent->dataPtr->elements.begin(), parent->dataPtr->elements.end(), shared_from_this()); if (iter != parent->dataPtr->elements.end()) { parent->dataPtr->elements.erase(iter); parent.reset(); } } } ///////////////////////////////////////////////// void Element::RemoveChild(ElementPtr _child) { SDF_ASSERT(_child, "Cannot remove a nullptr child pointer"); ElementPtr_V::iterator iter; iter = std::find(this->dataPtr->elements.begin(), this->dataPtr->elements.end(), _child); if (iter != this->dataPtr->elements.end()) { _child->SetParent(ElementPtr()); this->dataPtr->elements.erase(iter); } } ///////////////////////////////////////////////// boost::any Element::GetAny(const std::string &_key) const { boost::any result; if (_key.empty() && this->dataPtr->value) { if (!this->dataPtr->value->GetAny(result)) { sdferr << "Couldn't get element [" << this->GetName() << "] as boost::any\n"; } } else if (!_key.empty()) { ParamPtr param = this->GetAttribute(_key); if (param) { if (!this->GetAttribute(_key)->GetAny(result)) { sdferr << "Couldn't get attribute [" << _key << "] as boost::any\n"; } } else { ElementPtr tmp = this->GetElementImpl(_key); if (tmp != ElementPtr()) { result = tmp->GetAny(); } else { tmp = this->GetElementDescription(_key); if (tmp != ElementPtr()) { result = tmp->GetAny(); } else { sdferr << "Unable to find value for key [" << _key << "]\n"; } } } } return result; } sdformat-6.0.0+dfsg/src/Element_TEST.cc000066400000000000000000000362111323606632500176120ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/Element.hh" #include "sdf/Param.hh" ///////////////////////////////////////////////// TEST(Element, New) { sdf::Element elem; ASSERT_FALSE(elem.GetCopyChildren()); ASSERT_EQ(elem.ReferenceSDF(), ""); ASSERT_EQ(elem.GetParent(), nullptr); } ///////////////////////////////////////////////// TEST(Element, Child) { sdf::Element child; sdf::ElementPtr parent = std::make_shared(); ASSERT_EQ(child.GetParent(), nullptr); child.SetParent(parent); ASSERT_NE(child.GetParent(), nullptr); } ///////////////////////////////////////////////// TEST(Element, Name) { sdf::Element elem; ASSERT_EQ(elem.GetName(), ""); elem.SetName("test"); ASSERT_EQ(elem.GetName(), "test"); } ///////////////////////////////////////////////// TEST(Element, Required) { sdf::Element elem; ASSERT_EQ(elem.GetRequired(), ""); elem.SetRequired("1"); ASSERT_EQ(elem.GetRequired(), "1"); } ///////////////////////////////////////////////// TEST(Element, CopyChildren) { sdf::Element elem; ASSERT_FALSE(elem.GetCopyChildren()); elem.SetCopyChildren(true); ASSERT_TRUE(elem.GetCopyChildren()); } ///////////////////////////////////////////////// TEST(Element, ReferenceSDF) { sdf::Element elem; ASSERT_EQ(elem.ReferenceSDF(), ""); elem.SetReferenceSDF("test"); ASSERT_EQ(elem.ReferenceSDF(), "test"); } ///////////////////////////////////////////////// TEST(Element, AddValue) { sdf::Element elem; elem.SetName("test"); elem.AddValue("string", "foo", false, "foo description"); sdf::ParamPtr param = elem.GetValue(); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "test"); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "foo"); ASSERT_EQ(param->GetDescription(), "foo description"); } ///////////////////////////////////////////////// TEST(Element, AddAttribute) { sdf::Element elem; ASSERT_EQ(elem.GetAttributeCount(), 0UL); elem.AddAttribute("test", "string", "foo", false, "foo description"); ASSERT_EQ(elem.GetAttributeCount(), 1UL); elem.AddAttribute("attr", "float", "0.0", false, "float description"); ASSERT_EQ(elem.GetAttributeCount(), 2UL); sdf::ParamPtr param = elem.GetAttribute("test"); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "test"); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "foo"); ASSERT_EQ(param->GetDescription(), "foo description"); param = elem.GetAttribute("attr"); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "attr"); ASSERT_EQ(param->GetTypeName(), "float"); ASSERT_EQ(param->GetDefaultAsString(), "0"); ASSERT_EQ(param->GetDescription(), "float description"); } ///////////////////////////////////////////////// TEST(Element, GetAttributeSet) { sdf::Element elem; ASSERT_EQ(elem.GetAttributeCount(), 0UL); elem.AddAttribute("test", "string", "foo", false, "foo description"); ASSERT_EQ(elem.GetAttributeCount(), 1UL); EXPECT_FALSE(elem.GetAttributeSet("test")); elem.GetAttribute("test")->Set("asdf"); EXPECT_TRUE(elem.GetAttributeSet("test")); } ///////////////////////////////////////////////// TEST(Element, Include) { sdf::Element elem; ASSERT_EQ(elem.GetInclude(), ""); elem.SetInclude("foo.txt"); ASSERT_EQ(elem.GetInclude(), "foo.txt"); } ///////////////////////////////////////////////// TEST(Element, Description) { sdf::Element elem; ASSERT_EQ(elem.GetDescription(), ""); elem.SetDescription("Element description"); ASSERT_EQ(elem.GetDescription(), "Element description"); } ///////////////////////////////////////////////// TEST(Element, AddElementNoDescription) { sdf::Element elem; sdf::ElementPtr ptr = elem.AddElement("foo"); ASSERT_EQ(ptr, sdf::ElementPtr()); } ///////////////////////////////////////////////// TEST(Element, AddElementReferenceSDF) { // TODO(clalancette): The Element class uses shared_from_this(), and one of // the prerequisites of it is that the object must *already* have a // shared_ptr to it before calling shared_from_this(). The fallout from that // is that you cannot instantiate an object using the normal constructor, // and then call the .AddElement() method. You must make a shared_ptr, // and then you can call ->AddElement(), which works. This is kind of a // weird restriction on a class, so we might want to make this better. sdf::ElementPtr child = std::make_shared(); sdf::ElementPtr parent = std::make_shared(); sdf::ElementPtr desc = std::make_shared(); desc->SetName("parent"); parent->SetName("parent"); parent->AddElementDescription(desc); child->SetParent(parent); child->SetReferenceSDF("refsdf"); child->SetName("parent"); ASSERT_EQ(child->GetElementDescriptionCount(), 0UL); sdf::ElementPtr ptr = child->AddElement("parent"); ASSERT_EQ(child->GetElementDescriptionCount(), 1UL); sdf::ElementPtr check = child->GetElementDescription(4); ASSERT_EQ(check, sdf::ElementPtr()); check = child->GetElementDescription(0); ASSERT_NE(check, sdf::ElementPtr()); ASSERT_EQ(check->GetName(), "parent"); check = child->GetElementDescription("bad"); ASSERT_EQ(check, sdf::ElementPtr()); check = child->GetElementDescription("parent"); ASSERT_NE(check, sdf::ElementPtr()); ASSERT_EQ(check->GetName(), "parent"); ASSERT_FALSE(child->HasElement("foo")); ASSERT_TRUE(child->HasElement("parent")); child->Reset(); ASSERT_EQ(child->GetElementDescriptionCount(), 0UL); ASSERT_EQ(child->GetAttributeCount(), 0UL); } ///////////////////////////////////////////////// TEST(Element, GetTemplates) { sdf::ElementPtr elem = std::make_shared(); elem->AddAttribute("test", "string", "foo", false, "foo description"); std::string out = elem->Get("test"); ASSERT_EQ(out, "foo"); std::pair pairout = elem->Get("test", "def"); ASSERT_EQ(pairout.first, "foo"); ASSERT_EQ(pairout.second, true); bool found = elem->Get("test", out, "def"); ASSERT_EQ(out, "foo"); ASSERT_EQ(found, true); } ///////////////////////////////////////////////// TEST(Element, Clone) { sdf::ElementPtr parent = std::make_shared(); sdf::ElementPtr child = std::make_shared(); sdf::ElementPtr desc = std::make_shared(); parent->InsertElement(child); ASSERT_NE(parent->GetFirstElement(), nullptr); parent->AddElementDescription(desc); ASSERT_EQ(parent->GetElementDescriptionCount(), 1UL); parent->AddAttribute("test", "string", "foo", false, "foo description"); ASSERT_EQ(parent->GetAttributeCount(), 1UL); parent->AddValue("string", "foo", false, "foo description"); sdf::ElementPtr newelem = parent->Clone(); ASSERT_NE(newelem->GetFirstElement(), nullptr); ASSERT_EQ(newelem->GetElementDescriptionCount(), 1UL); ASSERT_EQ(newelem->GetAttributeCount(), 1UL); } ///////////////////////////////////////////////// TEST(Element, ClearElements) { sdf::ElementPtr parent = std::make_shared(); sdf::ElementPtr child = std::make_shared(); parent->InsertElement(child); ASSERT_NE(parent->GetFirstElement(), nullptr); parent->ClearElements(); ASSERT_EQ(parent->GetFirstElement(), nullptr); } ///////////////////////////////////////////////// TEST(Element, ToStringElements) { sdf::ElementPtr parent = std::make_shared(); sdf::ElementPtr child = std::make_shared(); parent->InsertElement(child); ASSERT_NE(parent->GetFirstElement(), nullptr); parent->AddAttribute("test", "string", "foo", false, "foo description"); ASSERT_EQ(parent->GetAttributeCount(), 1UL); std::string stringval = parent->ToString("myprefix"); ASSERT_EQ(stringval, "myprefix< test='foo'>\nmyprefix \nmyprefix\n"); } ///////////////////////////////////////////////// TEST(Element, ToStringValue) { sdf::ElementPtr parent = std::make_shared(); parent->AddAttribute("test", "string", "foo", false, "foo description"); ASSERT_EQ(parent->GetAttributeCount(), 1UL); parent->AddValue("string", "val", false, "val description"); std::string stringval = parent->ToString("myprefix"); ASSERT_EQ(stringval, "myprefix< test='foo'>val\n"); } ///////////////////////////////////////////////// TEST(Element, ToStringInclude) { sdf::Element elem; ASSERT_EQ(elem.GetInclude(), ""); elem.SetInclude("foo.txt"); ASSERT_EQ(elem.GetInclude(), "foo.txt"); std::string stringval = elem.ToString("myprefix"); ASSERT_EQ(stringval, "myprefix\n"); } ///////////////////////////////////////////////// TEST(Element, DocLeftPane) { sdf::Element elem; elem.SetDescription("Element description"); elem.AddElementDescription(std::make_shared()); std::string html; int index = 1; elem.PrintDocLeftPane(html, 0, index); ASSERT_EQ(html, "<>" "
\n" "<>" "
\n
\n
\n"); } ///////////////////////////////////////////////// TEST(Element, DocRightPane) { sdf::Element elem; elem.SetDescription("Element description"); elem.AddAttribute("test", "string", "foo", false, "foo description"); elem.AddValue("string", "val", false, "val description"); elem.AddElementDescription(std::make_shared()); std::string html; int index = 1; elem.PrintDocRightPane(html, 0, index); ASSERT_EQ(html, "<>
\n" "
\n" "Description: " "Element description
\n" "Required: " "   \nType: " "string   \n" "Default: val\n" "
" "
\n" "Attributes
" "
\n" "
\n" "test: " "
\n" "
\n" "foo description
\nType: " "string   " "Default: " "foo
" "
\n" "
\n" "
\n" "
\n<>" "
\n" "
\n" "Description: " "none
\nRequired: " "   \n" "Type: n/a\n" "
" "
\n" "
\n"); } ///////////////////////////////////////////////// TEST(Element, SetEmpty) { sdf::Element elem; ASSERT_FALSE(elem.Set("")); } ///////////////////////////////////////////////// TEST(Element, Set) { sdf::Element elem; elem.AddValue("string", "val", false, "val description"); ASSERT_TRUE(elem.Set("hello")); } ///////////////////////////////////////////////// TEST(Element, Copy) { sdf::ElementPtr src = std::make_shared(); sdf::ElementPtr dest = std::make_shared(); src->SetName("test"); src->AddValue("string", "val", false, "val description"); src->AddAttribute("test", "string", "foo", false, "foo description"); src->InsertElement(std::make_shared()); dest->Copy(src); sdf::ParamPtr param = dest->GetValue(); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "test"); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "val"); ASSERT_EQ(param->GetDescription(), "val description"); ASSERT_EQ(dest->GetAttributeCount(), 1UL); param = dest->GetAttribute("test"); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "test"); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "foo"); ASSERT_EQ(param->GetDescription(), "foo description"); ASSERT_NE(dest->GetFirstElement(), nullptr); } ///////////////////////////////////////////////// TEST(Element, CopyDestValue) { sdf::ElementPtr src = std::make_shared(); sdf::ElementPtr dest = std::make_shared(); src->AddValue("string", "val", false, "val description"); src->AddAttribute("test", "string", "foo", false, "foo description"); src->InsertElement(std::make_shared()); dest->AddValue("string", "val", false, "val description"); dest->Copy(src); sdf::ParamPtr param = dest->GetValue(); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), ""); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "val"); ASSERT_EQ(param->GetDescription(), "val description"); ASSERT_EQ(dest->GetAttributeCount(), 1UL); param = dest->GetAttribute("test"); ASSERT_TRUE(param->IsType()); ASSERT_EQ(param->GetKey(), "test"); ASSERT_EQ(param->GetTypeName(), "string"); ASSERT_EQ(param->GetDefaultAsString(), "foo"); ASSERT_EQ(param->GetDescription(), "foo description"); ASSERT_NE(dest->GetFirstElement(), nullptr); } ///////////////////////////////////////////////// TEST(Element, GetNextElement) { sdf::ElementPtr child = std::make_shared(); sdf::ElementPtr parent = std::make_shared(); child->SetParent(parent); ASSERT_EQ(child->GetNextElement("foo"), nullptr); } ///////////////////////////////////////////////// TEST(Element, GetNextElementMultiple) { sdf::ElementPtr child1 = std::make_shared(); sdf::ElementPtr child2 = std::make_shared(); sdf::ElementPtr parent = std::make_shared(); child1->SetParent(parent); child2->SetParent(parent); parent->InsertElement(child1); parent->InsertElement(child2); ASSERT_NE(child1->GetNextElement(""), nullptr); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Error.cc000066400000000000000000000026241323606632500164540ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "sdf/Error.hh" using namespace sdf; ///////////////////////////////////////////////// Error::Error(const ErrorCode _code, const std::string &_message) { this->code = _code; this->message = _message; } ///////////////////////////////////////////////// ErrorCode Error::Code() const { return this->code; } ///////////////////////////////////////////////// std::string Error::Message() const { return this->message; } ///////////////////////////////////////////////// // cppcheck-suppress unusedFunction Error::operator bool() const { return this->code != ErrorCode::NONE; } ///////////////////////////////////////////////// bool Error::operator==(const bool _value) const { return ((this->code != ErrorCode::NONE) && _value) || ((this->code == ErrorCode::NONE) && !_value); } sdformat-6.0.0+dfsg/src/Error_TEST.cc000066400000000000000000000023651323606632500173150ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/sdf_config.h" #include "sdf/Error.hh" ///////////////////////////////////////////////// TEST(Error, DefaultConstruction) { sdf::Error error; EXPECT_EQ(error, false); EXPECT_EQ(error.Code(), sdf::ErrorCode::NONE); EXPECT_TRUE(error.Message().empty()); if (error) FAIL(); } ///////////////////////////////////////////////// TEST(Error, ValueConstruction) { sdf::Error error(sdf::ErrorCode::FILE_READ, "Unable to read a file"); EXPECT_EQ(error, true); EXPECT_EQ(error.Code(), sdf::ErrorCode::FILE_READ); EXPECT_EQ(error.Message(), "Unable to read a file"); if (!error) FAIL(); } sdformat-6.0.0+dfsg/src/Exception.cc000066400000000000000000000055701323606632500173240ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/ExceptionPrivate.hh" #include "sdf/Console.hh" #include "sdf/Exception.hh" using namespace sdf; ////////////////////////////////////////////////// Exception::Exception() : dataPtr(new ExceptionPrivate) { } ////////////////////////////////////////////////// Exception::Exception(const char *_file, std::int64_t _line, std::string _msg) : dataPtr(new ExceptionPrivate) { this->dataPtr->file = _file; this->dataPtr->line = _line; this->dataPtr->str = _msg; this->Print(); } ////////////////////////////////////////////////// Exception::Exception(const Exception &_e) : dataPtr(new ExceptionPrivate) { this->dataPtr->file = _e.dataPtr->file; this->dataPtr->line = _e.dataPtr->line; this->dataPtr->str = _e.dataPtr->str; } ////////////////////////////////////////////////// Exception::~Exception() { } ////////////////////////////////////////////////// void Exception::Print() const { sdf::Console::Instance()->ColorMsg("Exception", this->dataPtr->file, static_cast(this->dataPtr->line), 31) << *this; } ////////////////////////////////////////////////// std::string Exception::GetErrorFile() const { return this->dataPtr->file; } ////////////////////////////////////////////////// std::string Exception::GetErrorStr() const { return this->dataPtr->str; } ////////////////////////////////////////////////// InternalError::InternalError() { } ////////////////////////////////////////////////// InternalError::InternalError(const char *_file, std::int64_t _line, const std::string _msg) : Exception(_file, _line, _msg) { } ////////////////////////////////////////////////// InternalError::~InternalError() { } ////////////////////////////////////////////////// AssertionInternalError::AssertionInternalError( const char * _file, std::int64_t _line, const std::string _expr, const std::string _function, const std::string _msg) : InternalError(_file, _line, "SDF ASSERTION \n" + _msg + "\n" + "In function : " + _function + "\n" + "Assert expression : " + _expr + "\n") { } ////////////////////////////////////////////////// AssertionInternalError::~AssertionInternalError() { } sdformat-6.0.0+dfsg/src/Exception_TEST.cc000066400000000000000000000025461323606632500201630ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/Exception.hh" //////////////////////////////////////////////////// /// Test exception throwing TEST(Exception, Throwing) { EXPECT_ANY_THROW(sdfthrow("throw message")); EXPECT_THROW(sdfthrow("throw message"), sdf::Exception); EXPECT_ANY_THROW(throw sdf::Exception()); EXPECT_THROW(throw sdf::Exception(), sdf::Exception); sdf::Exception ex = sdf::Exception(__FILE__, __LINE__, "testmsg\n"); EXPECT_EQ(ex.GetErrorFile(), __FILE__); EXPECT_ANY_THROW(throw sdf::InternalError()); EXPECT_THROW(throw sdf::InternalError(), sdf::InternalError); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Filesystem.cc000066400000000000000000000355521323606632500175150ustar00rootroot00000000000000/* * Copyright 2002-2009, 2014 Beman Dawes * Copyright 2001 Dietmar Kuehl * * Distributed under the Boost Software License, Version 1.0. * * Boost Software License - Version 1.0 - August 17th, 2003 * * Permission is hereby granted, free of charge, to any person or organization * obtaining a copy of the software and accompanying documentation covered by * this license (the "Software") to use, reproduce, display, distribute, * execute, and transmit the Software, and to prepare derivative works of the * Software, and to permit third-parties to whom the Software is furnished to * do so, all subject to the following: * * The copyright notices in the Software and this entire statement, including * the above license grant, this restriction and the following disclaimer, * must be included in all copies of the Software, in whole or in part, and * all derivative works of the Software, unless such copies or derivative * works are solely in the form of machine-executable object code generated by * a source language processor. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * Most of this code was borrowed from Boost in * libs/filesystem/src/operations.cpp and * libs/filesystem/include/boost/filesystem/operations.hpp. */ #include #include #include #ifndef _WIN32 #include #include #include #include #include #include #include #include #else #include #include #endif #include "sdf/Filesystem.hh" namespace sdf { namespace filesystem { /// \internal /// \brief Private data for the DirIter class. class DirIterPrivate { /// \def current /// \brief The current directory item. public: std::string current; /// \def dirname /// \brief The original path to the directory. public: std::string dirname; /// \def handle /// \brief Opaque handle for holding the directory iterator. public: void *handle; /// \def end /// \brief Private variable to indicate whether the iterator has reached /// the end. public: bool end; }; #ifndef _WIN32 static const char preferred_separator = '/'; ////////////////////////////////////////////////// bool exists(const std::string &_path) { struct stat path_stat; return ::stat(_path.c_str(), &path_stat) == 0; } ////////////////////////////////////////////////// bool is_directory(const std::string &_path) { struct stat path_stat; if (::stat(_path.c_str(), &path_stat) != 0) { return false; } return S_ISDIR(path_stat.st_mode); } ////////////////////////////////////////////////// bool create_directory(const std::string &_path) { return ::mkdir(_path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == 0; } ////////////////////////////////////////////////// std::string current_path() { std::string cur; for (int32_t path_max = 128;; path_max *= 2) // loop 'til buffer large enough { std::vector buf(path_max); if (::getcwd(buf.data(), buf.size()) == 0) { if (errno != ERANGE) { break; } } else { char resolved[PATH_MAX]; if (realpath(buf.data(), resolved) != nullptr) { cur = std::string(resolved); } break; } } return cur; } ////////////////////////////////////////////////// DirIter::DirIter(const std::string &_in) : dataPtr(new DirIterPrivate) { this->dataPtr->dirname = _in; this->dataPtr->current = ""; this->dataPtr->handle = opendir(_in.c_str()); this->dataPtr->end = false; if (this->dataPtr->handle == nullptr) { this->dataPtr->end = true; } else { next(); } } ////////////////////////////////////////////////// void DirIter::next() { while (true) { // It is OK to use readdir() instead of readdir_r() for a couple of reasons: // 1. This iterator class is not thread-safe for other reasons. // 2. As of glibc 2.24, readdir_r is deprecated. // // The NOLINT annotation is there to prevent cpplint from complaining about // this use of readdir. DIR *dirp = reinterpret_cast(this->dataPtr->handle); struct dirent *entry = readdir(dirp); // NOLINT(runtime/threadsafe_fn) if (entry == nullptr) { this->dataPtr->end = true; this->dataPtr->current = ""; break; } // The construct below is much faster than strcmp(). int len = strlen(entry->d_name); bool dot_or_dotdot = (len == 1 && entry->d_name[0] == '.') || (len == 2 && entry->d_name[0] == '.' && entry->d_name[1] == '.'); if (!dot_or_dotdot) { this->dataPtr->current = std::string(entry->d_name); break; } } } ////////////////////////////////////////////////// void DirIter::close_handle() { closedir(reinterpret_cast(this->dataPtr->handle)); } #else // Windows static const char preferred_separator = '\\'; ////////////////////////////////////////////////// static bool not_found_error(int _errval) { return _errval == ERROR_FILE_NOT_FOUND || _errval == ERROR_PATH_NOT_FOUND || _errval == ERROR_INVALID_NAME // "tools/jam/src/:sys:stat.h", "//foo" || _errval == ERROR_INVALID_DRIVE // USB card reader with no card inserted || _errval == ERROR_NOT_READY // CD/DVD drive with no disc inserted || _errval == ERROR_INVALID_PARAMETER // ":sys:stat.h" || _errval == ERROR_BAD_PATHNAME // "//nosuch" on Win64 || _errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32 } ////////////////////////////////////////////////// static bool process_status_failure() { int errval(::GetLastError()); if (not_found_error(errval)) { return false; } else if ((errval == ERROR_SHARING_VIOLATION)) { return true; // odd, but this is what boost does } return false; } struct handle_wrapper { HANDLE handle; explicit handle_wrapper(HANDLE h) : handle(h) {} ~handle_wrapper() { if (handle != INVALID_HANDLE_VALUE) { ::CloseHandle(handle); } } }; // REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part // of the Windows Device Driver Kit. Since that's inconvenient, the definitions // are provided here. See http://msdn.microsoft.com/en-us/library/ms791514.aspx typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; USHORT Reserved; union { struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; ULONG Flags; WCHAR PathBuffer[1]; /* Example of distinction between substitute and print names: mklink /d ldrive c:\ SubstituteName: c:\\??\ PrintName: c:\ */ } SymbolicLinkReparseBuffer; struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; WCHAR PathBuffer[1]; } MountPointReparseBuffer; struct { UCHAR DataBuffer[1]; } GenericReparseBuffer; }; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; ////////////////////////////////////////////////// HANDLE create_file_handle(const std::string &_path, DWORD _dwDesiredAccess, DWORD _dwShareMode, LPSECURITY_ATTRIBUTES _lpSecurityAttributes, DWORD _dwCreationDisposition, DWORD _dwFlagsAndAttributes, HANDLE _hTemplateFile) { return ::CreateFileA(_path.c_str(), _dwDesiredAccess, _dwShareMode, _lpSecurityAttributes, _dwCreationDisposition, _dwFlagsAndAttributes, _hTemplateFile); } #ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) #endif ////////////////////////////////////////////////// bool is_reparse_point_a_symlink(const std::string &_path) { handle_wrapper h(create_file_handle(_path, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr)); if (h.handle == INVALID_HANDLE_VALUE) { return false; } std::vector buf(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); // Query the reparse data DWORD dwRetLen; BOOL result = ::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf.data(), (DWORD)buf.size(), &dwRetLen, nullptr); if (!result) { return false; } return reinterpret_cast(&buf[0])->ReparseTag == IO_REPARSE_TAG_SYMLINK // Issue 9016 asked that NTFS directory junctions be recognized as // directories. That is equivalent to recognizing them as symlinks, and // then the normal symlink mechanism will take care of recognizing them as // directories. // // Directory junctions are very similar to symlinks, but have some // performance and other advantages over symlinks. They can be created from // the command line with "mklink /j junction-name target-path". || reinterpret_cast(&buf[0])->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT; // aka "directory junction" or "junction" } ////////////////////////////////////////////////// bool internal_check_path(const std::string &_path, DWORD &attr) { attr = ::GetFileAttributesA(_path.c_str()); if (attr == 0xFFFFFFFF) { return process_status_failure(); } // reparse point handling; // since GetFileAttributesW does not resolve symlinks, try to open a file // handle to discover if the file exists if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { handle_wrapper h( create_file_handle( _path, 0, // dwDesiredAccess; attributes only FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, // lpSecurityAttributes OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); // hTemplateFile if (h.handle == INVALID_HANDLE_VALUE) { return process_status_failure(); } if (!is_reparse_point_a_symlink(_path)) { return true; } } return true; } ////////////////////////////////////////////////// bool exists(const std::string &_path) { DWORD attr; return internal_check_path(_path, attr); } ////////////////////////////////////////////////// bool is_directory(const std::string &_path) { DWORD attr; if (internal_check_path(_path, attr)) { return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; } return false; } ////////////////////////////////////////////////// bool create_directory(const std::string &_path) { return ::CreateDirectoryA(_path.c_str(), 0) != 0; } ////////////////////////////////////////////////// std::string current_path() { DWORD sz; if ((sz = ::GetCurrentDirectoryA(0, nullptr)) == 0) { sz = 1; } std::vector buf(sz); if (::GetCurrentDirectoryA(sz, buf.data()) == 0) { // error return std::string(""); } else { return buf.data(); } } ////////////////////////////////////////////////// DirIter::DirIter(const std::string &_in) : dataPtr(new DirIterPrivate) { // use a form of search Sebastian Martel reports will work with Win98 this->dataPtr->dirname = _in; this->dataPtr->current = ""; this->dataPtr->end = false; if (_in.empty()) { // To be compatible with Unix, if we are given an empty string, assume this // is the end. this->dataPtr->end = true; return; } std::string dirpath(_in); dirpath += (dirpath.empty() || (dirpath[dirpath.size()-1] != '\\' && dirpath[dirpath.size()-1] != '/' && dirpath[dirpath.size()-1] != ':'))? "\\*" : "*"; WIN32_FIND_DATAA data; if ((this->dataPtr->handle = ::FindFirstFileA(dirpath.c_str(), &data)) == INVALID_HANDLE_VALUE) { this->dataPtr->handle = nullptr; // signal eof this->dataPtr->end = true; } else { this->dataPtr->current = std::string(data.cFileName); } } ////////////////////////////////////////////////// void DirIter::next() { WIN32_FIND_DATAA data; if (::FindNextFileA(this->dataPtr->handle, &data) == 0) // fails { this->dataPtr->end = true; this->dataPtr->current = ""; } else { this->dataPtr->current = std::string(data.cFileName); } } ////////////////////////////////////////////////// void DirIter::close_handle() { ::FindClose(this->dataPtr->handle); } #endif // _WIN32 ////////////////////////////////////////////////// const std::string separator(const std::string &_p) { return _p + preferred_separator; } ////////////////////////////////////////////////// std::string basename(const std::string &_path) { bool last_was_slash = false; std::string basename; basename.reserve(_path.length()); for (size_t i = 0; i < _path.length(); ++i) { if (_path[i] == preferred_separator) { if (i == (_path.length() - 1)) { // if this is the last character, then according to basename we // should return the portion of the path *before* the slash, i.e. // the one we were just building. However, as a special case, if // basename is empty, we return just a "/". if (basename.size() == 0) { basename.push_back(preferred_separator); } break; } last_was_slash = true; } else { if (last_was_slash) { last_was_slash = false; basename.clear(); } basename.push_back(_path[i]); } } return basename; } ////////////////////////////////////////////////// DirIter::DirIter() : dataPtr(new DirIterPrivate) { this->dataPtr->current = ""; this->dataPtr->dirname = ""; this->dataPtr->handle = nullptr; this->dataPtr->end = true; } ////////////////////////////////////////////////// std::string DirIter::operator*() const { return this->dataPtr->dirname + preferred_separator + this->dataPtr->current; } ////////////////////////////////////////////////// // prefix operator; note that we don't support the postfix operator // because it is complicated to do so const DirIter& DirIter::operator++() { next(); return *this; } ////////////////////////////////////////////////// bool DirIter::operator!=(const DirIter &_other) const { return this->dataPtr->end != _other.dataPtr->end; } ////////////////////////////////////////////////// DirIter::~DirIter() { if (this->dataPtr->handle != nullptr) { close_handle(); this->dataPtr->handle = nullptr; } } } // namespace filesystem } // namespace sdf sdformat-6.0.0+dfsg/src/Filesystem_TEST.cc000066400000000000000000000262271323606632500203530ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #ifndef _WIN32 #include #include #include #include #include #include ///////////////////////////////////////////////// bool create_and_switch_to_temp_dir(std::string &_new_temp_path) { std::string tmppath; const char *tmp = getenv("TMPDIR"); if (tmp) { tmppath = std::string(tmp); } else { tmppath = std::string("/tmp"); } tmppath += "/XXXXXX"; char *dtemp = mkdtemp(const_cast(tmppath.c_str())); if (dtemp == nullptr) { return false; } if (chdir(dtemp) < 0) { return false; } char resolved[PATH_MAX]; if (realpath(dtemp, resolved) == nullptr) { return false; } _new_temp_path = std::string(resolved); return true; } ///////////////////////////////////////////////// bool create_new_empty_file(const std::string &_filename) { int fd = open(_filename.c_str(), O_RDWR | O_CREAT, 0644); if (fd < 0) { return false; } close(fd); return true; } ///////////////////////////////////////////////// bool create_new_file_symlink(const std::string &_symlink, const std::string &_target) { return symlink(_target.c_str(), _symlink.c_str()) == 0; } ///////////////////////////////////////////////// bool create_new_dir_symlink(const std::string &_symlink, const std::string &_target) { return symlink(_target.c_str(), _symlink.c_str()) == 0; } ///////////////////////////////////////////////// bool create_new_file_hardlink(const std::string &_hardlink, const std::string &_target) { return link(_target.c_str(), _hardlink.c_str()) == 0; } #else #include #include #include ///////////////////////////////////////////////// bool create_and_switch_to_temp_dir(std::string &_new_temp_path) { char temp_path[MAX_PATH + 1]; DWORD path_len = ::GetTempPathA(MAX_PATH, temp_path); if (path_len >= MAX_PATH || path_len <= 0) { return false; } std::string path_to_create(temp_path); srand(static_cast(time(nullptr))); for (int count = 0; count < 50; ++count) { // Try creating a new temporary directory with a randomly generated name. // If the one we chose exists, keep trying another path name until we reach // some limit. std::string new_dir_name; new_dir_name.append(std::to_string(::GetCurrentProcessId())); new_dir_name.push_back('_'); // On Windows, rand_r() doesn't exist as an alternative to rand(), so the // cpplint warning is spurious. This program is not multi-threaded, so // it is safe to suppress the threadsafe_fn warning here. new_dir_name.append( std::to_string(rand() // NOLINT(runtime/threadsafe_fn) % ((int16_t)0x7fff))); path_to_create += new_dir_name; if (::CreateDirectoryA(path_to_create.c_str(), nullptr)) { _new_temp_path = path_to_create; return ::SetCurrentDirectoryA(_new_temp_path.c_str()) != 0; } } return false; } ///////////////////////////////////////////////// bool create_new_empty_file(const std::string &_filename) { return ::CreateFileA(_filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, 0, nullptr) != INVALID_HANDLE_VALUE; } ///////////////////////////////////////////////// bool create_new_file_symlink(const std::string &_symlink, const std::string &_target) { return ::CreateSymbolicLinkA(_symlink.c_str(), _target.c_str(), 0) == TRUE; } ///////////////////////////////////////////////// bool create_new_dir_symlink(const std::string &_symlink, const std::string &_target) { return ::CreateSymbolicLinkA(_symlink.c_str(), _target.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY) == TRUE; } ///////////////////////////////////////////////// bool create_new_file_hardlink(const std::string &_hardlink, const std::string &_target) { return ::CreateHardLinkA(_hardlink.c_str(), _target.c_str(), nullptr) == TRUE; } #endif #include "sdf/Filesystem.hh" ///////////////////////////////////////////////// TEST(Filesystem, exists) { std::string new_temp_dir; ASSERT_TRUE(create_and_switch_to_temp_dir(new_temp_dir)); ASSERT_TRUE(create_new_empty_file("newfile")); ASSERT_TRUE(sdf::filesystem::create_directory("fstestexists")); EXPECT_TRUE(sdf::filesystem::exists("fstestexists")); EXPECT_TRUE(sdf::filesystem::is_directory("fstestexists")); EXPECT_FALSE(sdf::filesystem::exists("notcreated")); EXPECT_FALSE(sdf::filesystem::is_directory("notcreated")); EXPECT_TRUE(sdf::filesystem::exists("newfile")); EXPECT_FALSE(sdf::filesystem::is_directory("newfile")); } ///////////////////////////////////////////////// TEST(Filesystem, symlink_exists) { // There are 5 cases we want to test for links (Unix doesn't allow hard links // to directories or to non-existent files): // 1. symbolic link to existing file // 2. symbolic link to non-existent file // 3. symbolic link to existing directory // 4. symbolic link to non-existent directory // 5. hard link to existing file std::string new_temp_dir; ASSERT_TRUE(create_and_switch_to_temp_dir(new_temp_dir)); ASSERT_TRUE(create_new_empty_file("newfile")); ASSERT_TRUE(sdf::filesystem::create_directory("newdir")); // Case 1 ASSERT_TRUE(create_new_file_symlink("symlink-file", "newfile")); EXPECT_TRUE(sdf::filesystem::exists("symlink-file")); // Case 2 ASSERT_TRUE(create_new_file_symlink("symlink-file-broken", "nonexistent")); EXPECT_FALSE(sdf::filesystem::exists("symlink-file-broken")); // Case 3 ASSERT_TRUE(create_new_dir_symlink("symlink-dir", "newdir")); EXPECT_TRUE(sdf::filesystem::exists("symlink-dir")); // Case 4 ASSERT_TRUE(create_new_dir_symlink("symlink-dir-broken", "nonexistent-dir")); EXPECT_FALSE(sdf::filesystem::exists("symlink-dir-broken")); // Case 5 ASSERT_TRUE(create_new_file_hardlink("hardlink-file", "newfile")); EXPECT_TRUE(sdf::filesystem::exists("hardlink-file")); } ///////////////////////////////////////////////// TEST(Filesystem, current_path) { std::string new_temp_dir; ASSERT_TRUE(create_and_switch_to_temp_dir(new_temp_dir)); std::string path = sdf::filesystem::current_path(); EXPECT_EQ(path, new_temp_dir); } ///////////////////////////////////////////////// TEST(Filesystem, append) { std::string path = "tmp"; path = sdf::filesystem::append(path, "hello"); ASSERT_EQ(path, sdf::filesystem::separator("tmp") + "hello"); path = sdf::filesystem::append(path, "there", "again"); EXPECT_EQ(path, sdf::filesystem::separator("tmp") + sdf::filesystem::separator("hello") + sdf::filesystem::separator("there") + "again"); } ///////////////////////////////////////////////// TEST(Filesystem, current_path_error) { // This test intentionally creates a directory, switches to it, removes // the directory, and then tries to call current_path() on it to cause // current_path() to fail. Windows does not allow you to remove an // in-use directory, so this test is restricted to Unix. #ifndef _WIN32 std::string new_temp_dir; ASSERT_TRUE(create_and_switch_to_temp_dir(new_temp_dir)); ASSERT_EQ(rmdir(new_temp_dir.c_str()), 0); EXPECT_EQ(sdf::filesystem::current_path(), ""); #endif } ///////////////////////////////////////////////// TEST(Filesystem, basename) { std::string absolute = sdf::filesystem::append("", "home", "bob", "foo"); EXPECT_EQ(sdf::filesystem::basename(absolute), "foo"); std::string relative = sdf::filesystem::append("baz", "foobar"); EXPECT_EQ(sdf::filesystem::basename(relative), "foobar"); std::string basename = "bzzz"; EXPECT_EQ(sdf::filesystem::basename(basename), "bzzz"); std::string nobase = sdf::filesystem::append("baz", ""); EXPECT_EQ(sdf::filesystem::basename(nobase), "baz"); std::string multiple_slash = sdf::filesystem::append("baz", "", "", ""); EXPECT_EQ(sdf::filesystem::basename(multiple_slash), "baz"); std::string multiple_slash_middle = sdf::filesystem::append("", "home", "", "", "bob", "foo"); EXPECT_EQ(sdf::filesystem::basename(multiple_slash_middle), "foo"); std::string multiple_slash_start = sdf::filesystem::append("", "", "", "home", "bob", "foo"); EXPECT_EQ(sdf::filesystem::basename(multiple_slash_start), "foo"); std::string slash_only = sdf::filesystem::append("", ""); EXPECT_EQ(sdf::filesystem::basename(slash_only), sdf::filesystem::append("", "")); std::string multiple_slash_only = sdf::filesystem::append("", "", "", ""); EXPECT_EQ(sdf::filesystem::basename(multiple_slash_only), sdf::filesystem::append("", "")); } ///////////////////////////////////////////////// TEST(Filesystem, directory_iterator) { std::string new_temp_dir; ASSERT_TRUE(create_and_switch_to_temp_dir(new_temp_dir)); ASSERT_TRUE(create_new_empty_file("newfile")); ASSERT_TRUE(sdf::filesystem::create_directory("newdir")); ASSERT_TRUE(create_new_file_symlink("symlink-file", "newfile")); ASSERT_TRUE(create_new_file_symlink("symlink-file-broken", "nonexistent")); ASSERT_TRUE(create_new_dir_symlink("symlink-dir", "newdir")); ASSERT_TRUE(create_new_dir_symlink("symlink-dir-broken", "nonexistent-dir")); ASSERT_TRUE(create_new_file_hardlink("hardlink-file", "newfile")); std::set found_items; sdf::filesystem::DirIter endIter; for (sdf::filesystem::DirIter dirIter("."); dirIter != endIter; ++dirIter) { found_items.insert(sdf::filesystem::basename(*dirIter)); } EXPECT_FALSE(found_items.find("newfile") == found_items.end()); EXPECT_FALSE(found_items.find("newdir") == found_items.end()); EXPECT_FALSE(found_items.find("symlink-file") == found_items.end()); EXPECT_FALSE(found_items.find("symlink-file-broken") == found_items.end()); EXPECT_FALSE(found_items.find("symlink-dir") == found_items.end()); EXPECT_FALSE(found_items.find("symlink-dir-broken") == found_items.end()); EXPECT_FALSE(found_items.find("hardlink-file") == found_items.end()); found_items.clear(); for (sdf::filesystem::DirIter dirIter(""); dirIter != endIter; ++dirIter) { found_items.insert(sdf::filesystem::basename(*dirIter)); } EXPECT_EQ(found_items.size(), 0UL); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Param.cc000066400000000000000000000273471323606632500164340ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include "sdf/Assert.hh" #include "sdf/Param.hh" #include "sdf/Types.hh" using namespace sdf; class any_set : public boost::static_visitor<> { public: explicit any_set(const boost::any &_value) {this->value = _value;} public: template void operator()(T & _operand) const { _operand = boost::any_cast(this->value); } public: boost::any value; }; ////////////////////////////////////////////////// Param::Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_description) : dataPtr(new ParamPrivate) { this->dataPtr->key = _key; this->dataPtr->required = _required; this->dataPtr->typeName = _typeName; this->dataPtr->description = _description; this->dataPtr->set = false; SDF_ASSERT(this->ValueFromString(_default), "Invalid parameter"); this->dataPtr->defaultValue = this->dataPtr->value; } ////////////////////////////////////////////////// Param::~Param() { } ////////////////////////////////////////////////// bool Param::GetAny(boost::any &_anyVal) const { if (this->IsType()) { int ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { uint64_t ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { double ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { float ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { bool ret = false; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { std::string ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { unsigned int ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { char ret = 0; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { sdf::Time ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Color ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Vector3d ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Vector2i ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Vector2d ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Pose3d ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else if (this->IsType()) { ignition::math::Quaterniond ret; if (!this->Get(ret)) { return false; } _anyVal = ret; } else { sdferr << "Type of parameter not known: [" << this->GetTypeName() << "]\n"; return false; } return true; } ////////////////////////////////////////////////// void Param::Update() { if (this->dataPtr->updateFunc) { try { boost::apply_visitor(any_set(this->dataPtr->updateFunc()), this->dataPtr->value); } catch(...) { sdferr << "Unable to set value using Update for key[" << this->dataPtr->key << "]\n"; } } } ////////////////////////////////////////////////// std::string Param::GetAsString() const { std::stringstream ss; ss << this->dataPtr->value; return ss.str(); } ////////////////////////////////////////////////// std::string Param::GetDefaultAsString() const { std::stringstream ss; ss << this->dataPtr->defaultValue; return ss.str(); } ////////////////////////////////////////////////// bool Param::ValueFromString(const std::string &_value) { std::string tmp(_value); std::string lowerTmp(_value); std::transform(lowerTmp.begin(), lowerTmp.end(), lowerTmp.begin(), ::tolower); // "true" and "false" doesn't work properly if (lowerTmp == "true") { tmp = "1"; } else if (lowerTmp == "false") { tmp = "0"; } bool isHex = lowerTmp.compare(0, 2, "0x") == 0; try { // Try to use stoi and stoul for integers, and // stof and stod for floating point values. int numericBase = 10; if (isHex) { numericBase = 16; } if (this->dataPtr->typeName == "bool") { if (lowerTmp == "true" || lowerTmp == "1") { this->dataPtr->value = true; } else if (lowerTmp == "false" || lowerTmp == "0") { this->dataPtr->value = false; } else { sdferr << "Invalid boolean value\n"; return false; } } else if (this->dataPtr->typeName == "char") { this->dataPtr->value = tmp[0]; } else if (this->dataPtr->typeName == "std::string" || this->dataPtr->typeName == "string") { this->dataPtr->value = tmp; } else if (this->dataPtr->typeName == "int") { this->dataPtr->value = std::stoi(tmp, nullptr, numericBase); } else if (this->dataPtr->typeName == "uint64_t") { std::stringstream ss(tmp); std::uint64_t u64tmp; ss >> u64tmp; this->dataPtr->value = u64tmp; } else if (this->dataPtr->typeName == "unsigned int") { this->dataPtr->value = static_cast( std::stoul(tmp, nullptr, numericBase)); } else if (this->dataPtr->typeName == "double") { this->dataPtr->value = std::stod(tmp); } else if (this->dataPtr->typeName == "float") { this->dataPtr->value = std::stof(tmp); } else if (this->dataPtr->typeName == "sdf::Time" || this->dataPtr->typeName == "time") { std::stringstream ss(tmp); sdf::Time timetmp; ss >> timetmp; this->dataPtr->value = timetmp; } else if (this->dataPtr->typeName == "ignition::math::Color" || this->dataPtr->typeName == "color") { std::stringstream ss(tmp); ignition::math::Color colortmp; ss >> colortmp; this->dataPtr->value = colortmp; } else if (this->dataPtr->typeName == "ignition::math::Vector2i" || this->dataPtr->typeName == "vector2i") { std::stringstream ss(tmp); ignition::math::Vector2i vectmp; ss >> vectmp; this->dataPtr->value = vectmp; } else if (this->dataPtr->typeName == "ignition::math::Vector2d" || this->dataPtr->typeName == "vector2d") { std::stringstream ss(tmp); ignition::math::Vector2d vectmp; ss >> vectmp; this->dataPtr->value = vectmp; } else if (this->dataPtr->typeName == "ignition::math::Vector3d" || this->dataPtr->typeName == "vector3") { std::stringstream ss(tmp); ignition::math::Vector3d vectmp; ss >> vectmp; this->dataPtr->value = vectmp; } else if (this->dataPtr->typeName == "ignition::math::Pose3d" || this->dataPtr->typeName == "pose" || this->dataPtr->typeName == "Pose") { std::stringstream ss(tmp); ignition::math::Pose3d posetmp; ss >> posetmp; this->dataPtr->value = posetmp; } else if (this->dataPtr->typeName == "ignition::math::Quaterniond" || this->dataPtr->typeName == "quaternion") { std::stringstream ss(tmp); ignition::math::Quaterniond quattmp; ss >> quattmp; this->dataPtr->value = quattmp; } else { sdferr << "Unknown parameter type[" << this->dataPtr->typeName << "]\n"; return false; } } // Catch invalid argument exception from std::stoi/stoul/stod/stof catch(std::invalid_argument &) { sdferr << "Invalid argument. Unable to set value [" << _value << " ] for key[" << this->dataPtr->key << "].\n"; return false; } // Catch out of range exception from std::stoi/stoul/stod/stof catch(std::out_of_range &) { sdferr << "Out of range. Unable to set value [" << _value << " ] for key[" << this->dataPtr->key << "].\n"; return false; } return true; } ////////////////////////////////////////////////// bool Param::SetFromString(const std::string &_value) { // Under some circumstances, latin locales (es_ES or pt_BR) will return a // comma for decimal position instead of a dot, making the conversion // to fail. See bug #60 for more information. Force to use always C setlocale(LC_NUMERIC, "C"); std::string str = sdf::trim(_value.c_str()); if (str.empty() && this->dataPtr->required) { sdferr << "Empty string used when setting a required parameter. Key[" << this->GetKey() << "]\n"; return false; } else if (str.empty()) { this->dataPtr->value = this->dataPtr->defaultValue; return true; } if (!this->ValueFromString(str)) { return false; } this->dataPtr->set = true; return this->dataPtr->set; } ////////////////////////////////////////////////// void Param::Reset() { this->dataPtr->value = this->dataPtr->defaultValue; this->dataPtr->set = false; } ////////////////////////////////////////////////// ParamPtr Param::Clone() const { return ParamPtr(new Param(this->dataPtr->key, this->dataPtr->typeName, this->GetAsString(), this->dataPtr->required, this->dataPtr->description)); } ////////////////////////////////////////////////// const std::string &Param::GetTypeName() const { return this->dataPtr->typeName; } ///////////////////////////////////////////////// void Param::SetDescription(const std::string &_desc) { this->dataPtr->description = _desc; } ///////////////////////////////////////////////// std::string Param::GetDescription() const { return this->dataPtr->description; } ///////////////////////////////////////////////// const std::string &Param::GetKey() const { return this->dataPtr->key; } ///////////////////////////////////////////////// bool Param::GetRequired() const { return this->dataPtr->required; } ///////////////////////////////////////////////// Param &Param::operator=(const Param &_param) { this->dataPtr->value = _param.dataPtr->value; this->dataPtr->defaultValue = _param.dataPtr->defaultValue; return *this; } ///////////////////////////////////////////////// bool Param::GetSet() const { return this->dataPtr->set; } sdformat-6.0.0+dfsg/src/Param_TEST.cc000066400000000000000000000261311323606632500172610ustar00rootroot00000000000000/* * Copyright 2014 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include "sdf/Exception.hh" #include "sdf/Param.hh" bool check_double(std::string num) { const std::string name = "number"; const std::string type = "double"; const std::string def = "0.0"; sdf::Param param(name, type, def, true); return param.SetFromString(num); } //////////////////////////////////////////////////// /// Test getting a bool using true/false and 1/0. TEST(Param, Bool) { sdf::Param boolParam("key", "bool", "true", false, "description"); bool value = true; boolParam.Get(value); EXPECT_TRUE(value); boolParam.Set(false); boolParam.Get(value); EXPECT_FALSE(value); // String parameter that represents a boolean. sdf::Param strParam("key", "string", "true", false, "description"); strParam.Get(value); EXPECT_TRUE(value); strParam.Set("false"); strParam.Get(value); EXPECT_FALSE(value); strParam.Set("1"); strParam.Get(value); EXPECT_TRUE(value); strParam.Set("0"); strParam.Get(value); EXPECT_FALSE(value); strParam.Set("True"); strParam.Get(value); EXPECT_TRUE(value); strParam.Set("TRUE"); strParam.Get(value); EXPECT_TRUE(value); // Anything other than 1 or true is treated as a false value strParam.Set("%"); strParam.Get(value); EXPECT_FALSE(value); boolParam.Set(true); boost::any anyValue; EXPECT_TRUE(boolParam.GetAny(anyValue)); try { value = boost::any_cast(anyValue); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } EXPECT_TRUE(value); } //////////////////////////////////////////////////// /// Test decimal number TEST(SetFromString, Decimals) { ASSERT_TRUE(check_double("0.2345")); } //////////////////////////////////////////////////// /// Test setting and reading hex int values. TEST(Param, HexInt) { sdf::Param intParam("key", "int", "0", false, "description"); int value; EXPECT_TRUE(intParam.Get(value)); EXPECT_EQ(value, 0); EXPECT_TRUE(intParam.SetFromString("0x01")); EXPECT_TRUE(intParam.Get(value)); EXPECT_EQ(value, 1); EXPECT_TRUE(intParam.SetFromString("0xff")); EXPECT_TRUE(intParam.Get(value)); EXPECT_EQ(value, 255); EXPECT_TRUE(intParam.SetFromString("0x00002")); EXPECT_TRUE(intParam.Get(value)); EXPECT_EQ(value, 2); EXPECT_FALSE(intParam.SetFromString("0xffffffffffffffffffffffffffffffffff")); EXPECT_TRUE(intParam.Get(value)); EXPECT_EQ(value, 2); } //////////////////////////////////////////////////// /// Test setting and reading hex unsigned int values. TEST(Param, HexUInt) { sdf::Param uintParam("key", "unsigned int", "0", false, "description"); unsigned int value; EXPECT_TRUE(uintParam.Get(value)); EXPECT_EQ(value, 0u); EXPECT_TRUE(uintParam.SetFromString("0x01")); EXPECT_TRUE(uintParam.Get(value)); EXPECT_EQ(value, 1u); EXPECT_TRUE(uintParam.SetFromString("0xff")); EXPECT_TRUE(uintParam.Get(value)); EXPECT_EQ(value, 255u); EXPECT_TRUE(uintParam.SetFromString("0x00002")); EXPECT_TRUE(uintParam.Get(value)); EXPECT_EQ(value, 2u); EXPECT_FALSE(uintParam.SetFromString("0xffffffffffffffffffffffffffffffffff")); EXPECT_TRUE(uintParam.Get(value)); EXPECT_EQ(value, 2u); } //////////////////////////////////////////////////// /// Test setting and reading hex and non-hex float values. TEST(Param, HexFloat) { // Microsoft does not parse hex values properly. // https://bitbucket.org/osrf/sdformat/issues/114 #ifndef _MSC_VER sdf::Param floatParam("key", "float", "0", false, "description"); float value; EXPECT_TRUE(floatParam.Get(value)); EXPECT_FLOAT_EQ(value, 0.0f); EXPECT_TRUE(floatParam.SetFromString("0x01")); EXPECT_TRUE(floatParam.Get(value)); EXPECT_FLOAT_EQ(value, 1.0f); EXPECT_TRUE(floatParam.SetFromString("0X2A")); EXPECT_TRUE(floatParam.Get(value)); EXPECT_FLOAT_EQ(value, 42.0f); EXPECT_TRUE(floatParam.SetFromString("0.123")); EXPECT_TRUE(floatParam.Get(value)); EXPECT_FLOAT_EQ(value, 0.123f); EXPECT_FALSE(floatParam.SetFromString("1.0e100")); EXPECT_TRUE(floatParam.Get(value)); EXPECT_FLOAT_EQ(value, 0.123f); #endif } //////////////////////////////////////////////////// /// Test setting and reading hex and non-hex double values. TEST(Param, HexDouble) { sdf::Param doubleParam("key", "double", "0", false, "description"); double value; EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 0.0); // Microsoft does not parse hex values properly. // https://bitbucket.org/osrf/sdformat/issues/114 #ifndef _MSC_VER EXPECT_TRUE(doubleParam.SetFromString("0x01")); EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 1.0); EXPECT_TRUE(doubleParam.SetFromString("0X2A")); EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 42.0); #endif EXPECT_TRUE(doubleParam.SetFromString("0.123456789")); EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 0.123456789); EXPECT_FALSE(doubleParam.SetFromString("1.0e1000")); EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 0.123456789); } //////////////////////////////////////////////////// /// Test setting and reading uint64_t values. TEST(Param, uint64t) { sdf::Param uint64tParam("key", "uint64_t", "1", false, "description"); std::uint64_t value; EXPECT_TRUE(uint64tParam.Get(value)); EXPECT_EQ(value, 1u); // Max uint64_t EXPECT_TRUE(uint64tParam.SetFromString("18446744073709551615")); EXPECT_TRUE(uint64tParam.Get(value)); EXPECT_EQ(value, UINT64_MAX); } //////////////////////////////////////////////////// /// Unknown type, should fall back to stream operators TEST(Param, UnknownType) { sdf::Param doubleParam("key", "double", "1.0", false, "description"); ignition::math::Angle value; EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value.Radian(), 1.0); } //////////////////////////////////////////////////// TEST(Param, Vector2i) { sdf::Param vect2iParam("key", "vector2i", "0 0", false, "description"); ignition::math::Vector2i value; EXPECT_TRUE(vect2iParam.Get(value)); EXPECT_EQ(value, ignition::math::Vector2i(0, 0)); } //////////////////////////////////////////////////// TEST(Param, InvalidConstructor) { ASSERT_THROW(sdf::Param badParam("key", "badtype", "0", false, "description"), sdf::AssertionInternalError); } //////////////////////////////////////////////////// TEST(Param, SetDescription) { sdf::Param uint64Param("key", "uint64_t", "1", false, "description"); uint64Param.SetDescription("new desc"); ASSERT_EQ("new desc", uint64Param.GetDescription()); } //////////////////////////////////////////////////// TEST(Param, Reset) { sdf::Param uint64Param("key", "uint64_t", "1", false, "description"); uint64_t val; uint64Param.SetFromString("89"); uint64Param.Get(val); ASSERT_EQ(89UL, val); uint64Param.Reset(); uint64Param.Get(val); ASSERT_EQ(1UL, val); } //////////////////////////////////////////////////// TEST(Param, EmptyRequiredSetFromString) { sdf::Param uint64Param("key", "uint64_t", "1", true, "description"); uint64_t val; ASSERT_FALSE(uint64Param.SetFromString("")); uint64Param.Get(val); ASSERT_EQ(1UL, val); } //////////////////////////////////////////////////// TEST(Param, EmptySetFromString) { sdf::Param uint64Param("key", "uint64_t", "1", false, "description"); uint64_t val; uint64Param.SetFromString("89"); ASSERT_TRUE(uint64Param.SetFromString("")); uint64Param.Get(val); ASSERT_EQ(1UL, val); } //////////////////////////////////////////////////// TEST(Param, InvalidBool) { sdf::Param boolParam("key", "bool", "true", false, "description"); ASSERT_FALSE(boolParam.SetFromString("false1")); } //////////////////////////////////////////////////// TEST(Param, InvalidInt) { sdf::Param intParam("key", "int", "1", false, "description"); ASSERT_FALSE(intParam.SetFromString("abc")); } //////////////////////////////////////////////////// TEST(Param, GetAny) { boost::any anyValue; sdf::Param intParam("key", "int", "true", false, "description"); EXPECT_TRUE(intParam.GetAny(anyValue)); sdf::Param uint64Param("key", "uint64_t", "1", false, "description"); EXPECT_TRUE(uint64Param.GetAny(anyValue)); sdf::Param doubleParam("key", "double", "1.0", false, "description"); EXPECT_TRUE(doubleParam.GetAny(anyValue)); sdf::Param floatParam("key", "float", "1.0", false, "description"); EXPECT_TRUE(floatParam.GetAny(anyValue)); sdf::Param boolParam("key", "bool", "true", false, "description"); EXPECT_TRUE(boolParam.GetAny(anyValue)); sdf::Param stringParam("key", "string", "hello", false, "description"); EXPECT_TRUE(stringParam.GetAny(anyValue)); sdf::Param unsignedParam("key", "unsigned int", "1", false, "description"); EXPECT_TRUE(unsignedParam.GetAny(anyValue)); sdf::Param charParam("key", "char", "a", false, "description"); EXPECT_TRUE(charParam.GetAny(anyValue)); sdf::Param timeParam("key", "time", "8 20", false, "description"); EXPECT_TRUE(timeParam.GetAny(anyValue)); sdf::Param colorParam("key", "color", "8 20 67 23", false, "description"); EXPECT_TRUE(colorParam.GetAny(anyValue)); sdf::Param vector3Param("key", "vector3", "8.1 20.24 67.7", false, "description"); EXPECT_TRUE(vector3Param.GetAny(anyValue)); sdf::Param vector2iParam("key", "vector2i", "8 20", false, "description"); EXPECT_TRUE(vector2iParam.GetAny(anyValue)); sdf::Param vector2dParam("key", "vector2d", "8.1 20.24", false, "description"); EXPECT_TRUE(vector2dParam.GetAny(anyValue)); sdf::Param poseParam("key", "pose", "1 2 3 4 5 6", false, "description"); EXPECT_TRUE(poseParam.GetAny(anyValue)); sdf::Param quatParam("key", "quaternion", "1 2 3 4", false, "description"); EXPECT_TRUE(quatParam.GetAny(anyValue)); } //////////////////////////////////////////////////// TEST(Param, SetTemplate) { sdf::Param doubleParam("key", "double", "1.0", false, "description"); double value; EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 1.0); doubleParam.Set(25.456); EXPECT_TRUE(doubleParam.Get(value)); EXPECT_DOUBLE_EQ(value, 25.456); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Root.cc000066400000000000000000000077341323606632500163150ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/Root.hh" #include "sdf/World.hh" #include "sdf/sdf_config.h" #include "sdf/parser.hh" using namespace sdf; /// \brief Private data for sdf::Root class sdf::RootPrivate { /// \brief Version string public: std::string version = ""; /// \brief The worlds specified under the root SDF element public: std::vector worlds; }; ///////////////////////////////////////////////// Root::Root() : dataPtr(new RootPrivate) { } ///////////////////////////////////////////////// Root::~Root() { delete this->dataPtr; this->dataPtr = nullptr; } ///////////////////////////////////////////////// Errors Root::Load(const std::string &_filename) { Errors errors; // Read an SDF file, and store the result in sdfParsed. sdf::SDFPtr sdfParsed = sdf::readFile(_filename, errors); // Return if we were not able to read the file. if (!sdfParsed) { errors.push_back( {ErrorCode::FILE_READ, "Unable to read file:" + _filename}); return errors; } sdf::ElementPtr sdf = sdfParsed->Root(); // Get the SDF version. std::pair versionPair = sdf->Get("version", SDF_VERSION); // Check that the version exists. Exit if the version is missing. // sdf::readFile will fail if the version is missing, so this // check should never be triggered. if (!versionPair.second) { errors.push_back( {ErrorCode::ATTRIBUTE_MISSING, "SDF does not have a version."}); return errors; } this->dataPtr->version = versionPair.first; // Read all the worlds if (sdf->HasElement("world")) { sdf::ElementPtr elem = sdf->GetElement("world"); while (elem) { World world; Errors worldErrors = world.Load(elem); // Attempt to load the world if (worldErrors.empty()) { // Check that the world's name does not exist. if (this->WorldNameExists(world.Name())) { errors.push_back({ErrorCode::DUPLICATE_NAME, "World with name[" + world.Name() + "] already exists." " Each world must have a unique name. Skipping this world."}); } else { this->dataPtr->worlds.push_back(std::move(world)); } } else { std::move(worldErrors.begin(), worldErrors.end(), std::back_inserter(errors)); errors.push_back({ErrorCode::ELEMENT_INVALID, "Failed to load a world."}); } elem = elem->GetNextElement("world"); } } return errors; } ///////////////////////////////////////////////// std::string Root::Version() const { return this->dataPtr->version; } ///////////////////////////////////////////////// void Root::SetVersion(const std::string &_version) { this->dataPtr->version = _version; } ///////////////////////////////////////////////// uint64_t Root::WorldCount() const { return this->dataPtr->worlds.size(); } ///////////////////////////////////////////////// const World *Root::WorldByIndex(const uint64_t _index) const { if (_index < this->dataPtr->worlds.size()) return &this->dataPtr->worlds[_index]; return nullptr; } ///////////////////////////////////////////////// bool Root::WorldNameExists(const std::string &_name) const { for (auto const &w : this->dataPtr->worlds) { if (w.Name() == _name) { return true; } } return false; } sdformat-6.0.0+dfsg/src/Root_TEST.cc000066400000000000000000000024161323606632500171440ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/sdf_config.h" #include "sdf/Root.hh" ///////////////////////////////////////////////// TEST(DOMRoot, Construction) { sdf::Root root; EXPECT_EQ(root.Version(), ""); EXPECT_FALSE(root.WorldNameExists("default")); EXPECT_FALSE(root.WorldNameExists("")); EXPECT_EQ(root.WorldCount(), 0u); EXPECT_TRUE(root.WorldByIndex(0) == nullptr); EXPECT_TRUE(root.WorldByIndex(1) == nullptr); } ///////////////////////////////////////////////// TEST(DOMRoot, Set) { sdf::Root root; EXPECT_STREQ(root.Version().c_str(), ""); root.SetVersion(SDF_PROTOCOL_VERSION); EXPECT_STREQ(root.Version().c_str(), SDF_PROTOCOL_VERSION); } sdformat-6.0.0+dfsg/src/SDF.cc000066400000000000000000000247121323606632500160010ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #include #include "sdf/parser.hh" #include "sdf/Assert.hh" #include "sdf/Console.hh" #include "sdf/Filesystem.hh" #include "sdf/SDFImpl.hh" #include "sdf/SDFImplPrivate.hh" #include "sdf/sdf_config.h" using namespace sdf; typedef std::list PathList; typedef std::map URIPathMap; static URIPathMap g_uriPathMap; static std::function g_findFileCB; std::string SDF::version = SDF_VERSION; ///////////////////////////////////////////////// void sdf::setFindCallback(std::function _cb) { g_findFileCB = _cb; } ///////////////////////////////////////////////// std::string sdf::findFile(const std::string &_filename, bool _searchLocalPath, bool _useCallback) { std::string path = _filename; // Check to see if _filename is URI. If so, resolve the URI path. for (URIPathMap::iterator iter = g_uriPathMap.begin(); iter != g_uriPathMap.end(); ++iter) { // Check to see if the URI in the global map is the first part of the // given filename if (_filename.find(iter->first) == 0) { std::string suffix = _filename; size_t index = suffix.find(iter->first); if (index != std::string::npos) { suffix.replace(index, iter->first.length(), ""); } // Check each path in the list. for (PathList::iterator pathIter = iter->second.begin(); pathIter != iter->second.end(); ++pathIter) { // Return the path string if the path + suffix exists. std::string pathSuffix = sdf::filesystem::append(*pathIter, suffix); if (sdf::filesystem::exists(pathSuffix)) { return pathSuffix; } } } } // Next check the install path. path = sdf::filesystem::append(SDF_SHARE_PATH, _filename); if (sdf::filesystem::exists(path)) { return path; } // Next check the versioned install path. path = sdf::filesystem::append(SDF_SHARE_PATH, "sdformat", sdf::SDF::Version(), _filename); if (sdf::filesystem::exists(path)) { return path; } // Next check SDF_PATH environment variable const char *pathCStr = std::getenv("SDF_PATH"); if (pathCStr) { std::vector paths = sdf::split(pathCStr, ":"); for (std::vector::iterator iter = paths.begin(); iter != paths.end(); ++iter) { path = sdf::filesystem::append(*iter, _filename); if (sdf::filesystem::exists(path)) { return path; } } } // Next check to see if the given file exists. path = _filename; if (sdf::filesystem::exists(path)) { return path; } // Finally check the local path, if the flag is set. if (_searchLocalPath) { path = sdf::filesystem::append(sdf::filesystem::current_path(), _filename); if (sdf::filesystem::exists(path)) { return path; } } // If we still haven't found the file, use the registered callback if the // flag has been set if (_useCallback) { if (!g_findFileCB) { sdferr << "Tried to use callback in sdf::findFile(), but the callback " "is empty. Did you call sdf::setFindCallback()?"; return std::string(); } else { return g_findFileCB(_filename); } } return std::string(); } ///////////////////////////////////////////////// void sdf::addURIPath(const std::string &_uri, const std::string &_path) { // Split _path on colons. std::vector parts = sdf::split(_path, ":"); // Add each part of the colon separated path to the global URI map. for (std::vector::iterator iter = parts.begin(); iter != parts.end(); ++iter) { // Only add valid paths if (!(*iter).empty() && sdf::filesystem::is_directory(*iter)) { g_uriPathMap[_uri].push_back(*iter); } } } ///////////////////////////////////////////////// SDF::SDF() : dataPtr(new SDFPrivate) { } ///////////////////////////////////////////////// SDF::~SDF() { } ///////////////////////////////////////////////// void SDF::PrintDescription() { this->Root()->PrintDescription(""); } ///////////////////////////////////////////////// void SDF::PrintValues() { this->Root()->PrintValues(""); } ///////////////////////////////////////////////// void SDF::PrintDoc() { std::string html, html2; int index = 0; this->Root()->PrintDocLeftPane(html, 10, index); index = 0; this->Root()->PrintDocRightPane(html2, 10, index); std::cout << "\n" << "\n" << "\n" << " \n" << " \n" << " \n" << " \n" << " \n" << "\n\n"; std::cout << "
\n" << "

SDF " << SDF::Version() << "

\n"; std::cout << "

The Robot Modeling Language (SDF) is an XML file " << "format used to describe all the elements in a simulation " << "environment.\n

"; std::cout << "

Usage

\n"; std::cout << "
"; std::cout << "
  • Left Panel: List of all the SDF elements.
  • "; std::cout << "
  • Right Panel: Descriptions of all the SDF " << "elements.
  • "; std::cout << "
  • Selection: Clicking an element in the Left Panel " << "moves the corresponding description to the top of the Right " << "Panel.
  • "; std::cout << "
  • Search: Use your web-browser's built in 'Find' " << "function to locate a specific element." << "
"; std::cout << "
"; std::cout << "
\n"; std::cout << "

Meta-Tags

\n"; std::cout << "
"; std::cout << "Meta-tags are processed by the parser before the final " << "SDF file is generated."; std::cout << "
    "; std::cout << "
  • <include>: Include an SDF model file " << "within the current SDF file." << "
      " << "
    • <uri>: URI of SDF model file to include.
    • " << "
    • <name>: Name of the included SDF model.
    • " << "
    • <pose>: Pose of the included SDF model, " << "specified as <pose>x y z roll pitch yaw</pose>, " << "with x, y, and z representing a position in meters, and roll, " << "pitch, and yaw representing Euler angles in radians.
    • " << "
    " << "
  • "; std::cout << "
"; std::cout << "
"; std::cout << "
\n"; std::cout << "
\n"; std::cout << "
\n"; std::cout << html; std::cout << "
\n"; std::cout << "
\n"; std::cout << html2; std::cout << "
\n"; std::cout << "
\n"; std::cout << "\ \ \n"; } ///////////////////////////////////////////////// void SDF::Write(const std::string &_filename) { std::string string = this->Root()->ToString(""); std::ofstream out(_filename.c_str(), std::ios::out); if (!out) { sdferr << "Unable to open file[" << _filename << "] for writing\n"; return; } out << string; out.close(); } ///////////////////////////////////////////////// std::string SDF::ToString() const { std::ostringstream stream; stream << "\n"; if (this->Root()->GetName() != "sdf") { stream << "\n"; } stream << this->Root()->ToString(""); if (this->Root()->GetName() != "sdf") { stream << ""; } return stream.str(); } ///////////////////////////////////////////////// void SDF::SetFromString(const std::string &_sdfData) { sdf::initFile("root.sdf", this->Root()); if (!sdf::readString(_sdfData, this->Root())) { sdferr << "Unable to parse sdf string[" << _sdfData << "]\n"; } } ///////////////////////////////////////////////// ElementPtr SDF::Root() const { return this->dataPtr->root; } ///////////////////////////////////////////////// void SDF::Root(const ElementPtr _root) { this->dataPtr->root = _root; } ///////////////////////////////////////////////// std::string SDF::Version() { return version; } ///////////////////////////////////////////////// void SDF::Version(const std::string &_version) { version = _version; } ///////////////////////////////////////////////// ElementPtr SDF::WrapInRoot(const ElementPtr &_sdf) { ElementPtr root(new Element); root->SetName("sdf"); std::stringstream v; v << Version(); root->AddAttribute("version", "string", v.str(), true, "version"); root->InsertElement(_sdf->Clone()); return root; } sdformat-6.0.0+dfsg/src/SDFExtension.cc000066400000000000000000000067431323606632500177020ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "sdf/SDFExtension.hh" using namespace sdf; ///////////////////////////////////////////////// SDFExtension::SDFExtension() { this->material.clear(); this->visual_blobs.clear(); this->collision_blobs.clear(); this->setStaticFlag = false; this->gravity = true; this->isDampingFactor = false; this->isMaxContacts = false; this->isMaxVel = false; this->isMinDepth = false; this->fdir1.clear(); this->isMu1 = false; this->isMu2 = false; this->isKp = false; this->isKd = false; this->isSelfCollide = false; this->selfCollide = false; this->isLaserRetro = false; this->isSpringReference = false; this->isSpringStiffness = false; this->isStopCfm = false; this->isStopErp = false; this->isFudgeFactor = false; this->isProvideFeedback = false; this->isImplicitSpringDamper = false; this->blobs.clear(); this->dampingFactor = 0; this->maxContacts = 0; this->maxVel = 0; this->minDepth = 0; this->mu1 = 0; this->mu2 = 0; this->kp = 100000000; this->kd = 1; this->laserRetro = 101; this->springReference = 0; this->springStiffness = 0; this->stopCfm = 0; this->stopErp = 0.1; this->fudgeFactor = 1; this->provideFeedback = false; this->implicitSpringDamper = false; } ///////////////////////////////////////////////// SDFExtension::SDFExtension(const SDFExtension &_ge) { this->material = _ge.material; this->visual_blobs = _ge.visual_blobs; this->collision_blobs = _ge.collision_blobs; this->setStaticFlag = _ge.setStaticFlag; this->gravity = _ge.gravity; this->isDampingFactor = _ge.isDampingFactor; this->isMaxContacts = _ge.isMaxContacts; this->isMaxVel = _ge.isMaxVel; this->isMinDepth = _ge.isMinDepth; this->fdir1 = _ge.fdir1; this->isMu1 = _ge.isMu1; this->isMu2 = _ge.isMu2; this->isKp = _ge.isKp; this->isKd = _ge.isKd; this->selfCollide = _ge.selfCollide; this->isLaserRetro = _ge.isLaserRetro; this->isSpringReference = _ge.isSpringReference; this->isSpringStiffness = _ge.isSpringStiffness; this->isStopCfm = _ge.isStopCfm; this->isStopErp = _ge.isStopErp; this->isFudgeFactor = _ge.isFudgeFactor; this->isProvideFeedback = _ge.isProvideFeedback; this->isImplicitSpringDamper = _ge.isImplicitSpringDamper; this->provideFeedback = _ge.provideFeedback; this->implicitSpringDamper = _ge.implicitSpringDamper; this->oldLinkName = _ge.oldLinkName; this->reductionTransform = _ge.reductionTransform; this->blobs = _ge.blobs; this->dampingFactor = _ge.dampingFactor; this->maxContacts = _ge.maxContacts; this->maxVel = _ge.maxVel; this->minDepth = _ge.minDepth; this->mu1 = _ge.mu1; this->mu2 = _ge.mu2; this->kp = _ge.kp; this->kd = _ge.kd; this->laserRetro = _ge.laserRetro; this->springReference = _ge.springReference; this->springStiffness = _ge.springStiffness; this->stopCfm = _ge.stopCfm; this->stopErp = _ge.stopErp; this->fudgeFactor = _ge.fudgeFactor; } sdformat-6.0.0+dfsg/src/SDF_TEST.cc000066400000000000000000000457141323606632500166450ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/sdf.hh" class SDFUpdateFixture { public: std::string GetName() const {return this->name;} public: bool GetFlag() const {return this->flag;} public: ignition::math::Pose3d GetPose() const {return this->pose;} public: std::string name; public: bool flag; public: ignition::math::Pose3d pose; }; //////////////////////////////////////////////////// /// Ensure that SDF::Update is working for attributes TEST(SDF, UpdateAttribute) { // Set up a simple sdf model file std::ostringstream stream; stream << "" << " " << " 0 1 2 0 0 0" << " false" << " " << ""; sdf::SDF sdfParsed; sdfParsed.SetFromString(stream.str()); // Verify correct parsing ASSERT_TRUE(sdfParsed.Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed.Root()->GetElement("model"); // Read name attribute value ASSERT_TRUE(modelElem->HasAttribute("name")); sdf::ParamPtr nameParam = modelElem->GetAttribute("name"); EXPECT_TRUE(nameParam->IsType()); // Set test class variables based on sdf values // Set parameter update functions to test class accessors SDFUpdateFixture fixture; nameParam->Get(fixture.name); nameParam->SetUpdateFunc(std::bind(&SDFUpdateFixture::GetName, &fixture)); std::string nameCheck; int i; for (i = 0; i < 4; i++) { // Update test class variables fixture.name[0] = 'd' + static_cast(i); // Update root sdf element sdfParsed.Root()->Update(); // Expect sdf values to match test class variables nameParam->Get(nameCheck); EXPECT_STREQ(nameCheck.c_str(), fixture.name.c_str()); } } //////////////////////////////////////////////////// /// Ensure that SDF::Update is working for elements TEST(SDF, UpdateElement) { // Set up a simple sdf model file std::ostringstream stream; stream << "" << " " << " 0 1 2 0 0 0" << " false" << " " << ""; sdf::SDF sdfParsed; sdfParsed.SetFromString(stream.str()); // Verify correct parsing ASSERT_TRUE(sdfParsed.Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed.Root()->GetElement("model"); // Read static element value ASSERT_TRUE(modelElem->HasElement("static")); sdf::ParamPtr staticParam = modelElem->GetElement("static")->GetValue(); EXPECT_TRUE(staticParam->IsType()); // Read pose element value ASSERT_TRUE(modelElem->HasElement("pose")); sdf::ParamPtr poseParam = modelElem->GetElement("pose")->GetValue(); EXPECT_TRUE(poseParam->IsType()); // Set test class variables based on sdf values // Set parameter update functions to test class accessors SDFUpdateFixture fixture; staticParam->Get(fixture.flag); staticParam->SetUpdateFunc(std::bind(&SDFUpdateFixture::GetFlag, &fixture)); poseParam->Get(fixture.pose); poseParam->SetUpdateFunc(std::bind(&SDFUpdateFixture::GetPose, &fixture)); bool flagCheck; ignition::math::Pose3d poseCheck; int i; for (i = 0; i < 4; i++) { // Update test class variables fixture.flag = !fixture.flag; fixture.pose.Pos().X() = i; fixture.pose.Pos().Y() = i+10; fixture.pose.Pos().Z() = -i*i*i; // Update root sdf element sdfParsed.Root()->Update(); // Expect sdf values to match test class variables staticParam->Get(flagCheck); EXPECT_EQ(flagCheck, fixture.flag); poseParam->Get(poseCheck); EXPECT_EQ(poseCheck, fixture.pose); } } //////////////////////////////////////////////////// /// Ensure that SDF::Element::RemoveFromParent is working TEST(SDF, ElementRemoveFromParent) { // Set up a simple sdf model file std::ostringstream stream; stream << "" << " " << " 0 1 2 0 0 0" << " false" << " " << " " << " 0 1 2 0 0 0" << " false" << " " << " " << " 0 1 2 0 0 0" << " false" << " " << ""; sdf::SDF sdfParsed; sdfParsed.SetFromString(stream.str()); sdf::ElementPtr elem; // Verify correct parsing ASSERT_TRUE(sdfParsed.Root()->HasElement("model")); elem = sdfParsed.Root()->GetElement("model"); // Select the second model named 'model2' elem = elem->GetNextElement("model"); ASSERT_TRUE(elem != nullptr); EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model2"); EXPECT_EQ(elem->Get("name", "default_value").first, "model2"); EXPECT_TRUE(elem->Get("name", "default_value").second); // Remove model2 elem->RemoveFromParent(); // Get first model element again elem = sdfParsed.Root()->GetElement("model"); // Check name == model1 EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model1"); EXPECT_EQ(elem->Get("bad_name", "default").first, "default"); EXPECT_FALSE(elem->Get("bad_name", "default").second); std::string value; bool success; std::tie(value, success) = elem->Get("bad_name", "default"); EXPECT_FALSE(success); EXPECT_EQ(value, "default"); // Get next model element elem = elem->GetNextElement("model"); // Check name == model3 EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model3"); // Try to get another model element elem = elem->GetNextElement("model"); EXPECT_FALSE(elem); } //////////////////////////////////////////////////// /// Ensure that SDF::Element::RemoveChild is working TEST(SDF, ElementRemoveChild) { // Set up a simple sdf model file std::ostringstream stream; stream << "" << " " << " 0 1 2 0 0 0" << " false" << " " << " " << " 0 1 2 0 0 0" << " false" << " " << " " << " 0 1 2 0 0 0" << " false" << " " << ""; sdf::SDF sdfParsed; sdfParsed.SetFromString(stream.str()); sdf::ElementPtr elem, elem2; // Verify correct parsing ASSERT_TRUE(sdfParsed.Root()->HasElement("model")); elem = sdfParsed.Root()->GetElement("model"); // Select the static element in model1 elem2 = elem->GetElement("static"); EXPECT_TRUE(elem2 != nullptr); EXPECT_FALSE(elem2->Get()); elem->RemoveChild(elem2); // Get first model element again elem = sdfParsed.Root()->GetElement("model"); // Check name == model1 EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model1"); // Check that we have deleted the static element in model1 EXPECT_FALSE(elem->HasElement("static")); // Get model2 elem2 = elem->GetNextElement("model"); // Remove model2 sdfParsed.Root()->RemoveChild(elem2); // Get first model element again elem = sdfParsed.Root()->GetElement("model"); // Check name == model1 EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model1"); // Get next model element elem = elem->GetNextElement("model"); // Check name == model3 EXPECT_TRUE(elem->HasAttribute("name")); EXPECT_EQ(elem->Get("name"), "model3"); // Try to get another model element elem = elem->GetNextElement("model"); EXPECT_FALSE(elem); } //////////////////////////////////////////////////// /// Ensure that getting empty values with empty keys returns correct values. TEST(SDF, EmptyValues) { std::string emptyString; sdf::ElementPtr elem; elem.reset(new sdf::Element()); EXPECT_FALSE(elem->Get(emptyString)); elem->AddValue("bool", "true", "0", "description"); EXPECT_TRUE(elem->Get(emptyString)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), 0); elem->AddValue("int", "12", "0", "description"); EXPECT_EQ(elem->Get(emptyString), 12); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), static_cast(0)); elem->AddValue("unsigned int", "123", "0", "description"); EXPECT_EQ(elem->Get(emptyString), static_cast(123)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), '\0'); elem->AddValue("char", "a", "0", "description"); EXPECT_EQ(elem->Get(emptyString), 'a'); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ""); elem->AddValue("string", "hello", "0", "description"); EXPECT_EQ(elem->Get(emptyString), "hello"); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ignition::math::Vector2d()); elem->AddValue("vector2d", "1 2", "0", "description"); EXPECT_EQ(elem->Get(emptyString), ignition::math::Vector2d(1, 2)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ignition::math::Vector3d()); elem->AddValue("vector3", "1 2 3", "0", "description"); EXPECT_EQ(elem->Get(emptyString), ignition::math::Vector3d(1, 2, 3)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ignition::math::Quaterniond()); elem->AddValue("quaternion", "1 2 3", "0", "description"); EXPECT_EQ(elem->Get(emptyString), ignition::math::Quaterniond(-2.14159, 1.14159, -0.141593)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ignition::math::Pose3d()); elem->AddValue("pose", "1.0 2.0 3.0 4.0 5.0 6.0", "0", "description"); EXPECT_EQ(elem->Get(emptyString).Pos(), ignition::math::Pose3d(1, 2, 3, 4, 5, 6).Pos()); EXPECT_EQ(elem->Get(emptyString).Rot().Euler(), ignition::math::Pose3d(1, 2, 3, 4, 5, 6).Rot().Euler()); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), ignition::math::Color()); elem->AddValue("color", ".1 .2 .3 1.0", "0", "description"); EXPECT_EQ(elem->Get(emptyString), ignition::math::Color(.1f, .2f, .3f, 1.0f)); elem.reset(new sdf::Element()); EXPECT_EQ(elem->Get(emptyString), sdf::Time()); elem->AddValue("time", "1 2", "0", "description"); EXPECT_EQ(elem->Get(emptyString), sdf::Time(1, 2)); elem.reset(new sdf::Element()); EXPECT_NEAR(elem->Get(emptyString), 0.0, 1e-6); elem->AddValue("float", "12.34", "0", "description"); EXPECT_NEAR(elem->Get(emptyString), 12.34, 1e-6); elem.reset(new sdf::Element()); EXPECT_NEAR(elem->Get(emptyString), 0.0, 1e-6); elem->AddValue("double", "12.34", "0", "description"); EXPECT_NEAR(elem->Get(emptyString), 12.34, 1e-6); } ///////////////////////////////////////////////// TEST(SDF, GetAny) { std::ostringstream stream; // Test types double, bool, string, int, vector3, color, pose stream << "" << " " << " 0 0 -7.1 " << " " << " 8" << " 0.002" << " " << " " << " 0 1 2 0 0 0" << " true" << " " << " " << " " << " 0.1 0.1 0.1 1" << " " << " " << " " << " " << " " << ""; sdf::SDF sdfParsed; sdfParsed.SetFromString(stream.str()); // Verify correct parsing ASSERT_TRUE(sdfParsed.Root()->HasElement("world")); sdf::ElementPtr worldElem = sdfParsed.Root()->GetElement("world"); ASSERT_TRUE(worldElem->HasElement("model")); sdf::ElementPtr modelElem = worldElem->GetElement("model"); ASSERT_TRUE(worldElem->HasElement("physics")); sdf::ElementPtr physicsElem = worldElem->GetElement("physics"); { boost::any anyValue = modelElem->GetAny("name"); try { EXPECT_EQ(boost::any_cast(anyValue), "test_model"); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(modelElem->HasElement("pose")); sdf::ElementPtr poseElem = modelElem->GetElement("pose"); boost::any anyValue = poseElem->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), ignition::math::Pose3d(0, 1, 2, 0, 0, 0)); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(worldElem->HasElement("gravity")); boost::any anyValue = worldElem->GetElement("gravity")->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), ignition::math::Vector3d(0, 0, -7.1)); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(physicsElem->HasElement("max_step_size")); boost::any anyValue = physicsElem->GetElement("max_step_size")->GetAny(); try { EXPECT_NEAR(boost::any_cast(anyValue), 0.002, 1e-6); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(physicsElem->HasElement("max_contacts")); boost::any anyValue = physicsElem->GetElement("max_contacts")->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), 8); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(worldElem->HasElement("gravity")); boost::any anyValue = worldElem->GetElement("gravity")->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), ignition::math::Vector3d(0, 0, -7.1)); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(modelElem->HasElement("static")); boost::any anyValue = modelElem->GetElement("static")->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), true); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } { EXPECT_TRUE(modelElem->HasElement("link")); EXPECT_TRUE(modelElem->GetElement("link")->HasElement("visual")); EXPECT_TRUE(modelElem->GetElement("link")->GetElement("visual")-> HasElement("material")); sdf::ElementPtr materialElem = modelElem->GetElement("link")-> GetElement("visual")->GetElement("material"); EXPECT_TRUE(materialElem->HasElement("ambient")); boost::any anyValue = materialElem->GetElement("ambient")->GetAny(); try { EXPECT_EQ(boost::any_cast(anyValue), ignition::math::Color(0.1f, 0.1f, 0.1f, 1.0f)); } catch(boost::bad_any_cast &/*_e*/) { FAIL(); } } } ///////////////////////////////////////////////// TEST(SDF, Version) { EXPECT_STREQ(SDF_VERSION, sdf::SDF::Version().c_str()); sdf::SDF::Version("0.2.3"); EXPECT_STREQ("0.2.3", sdf::SDF::Version().c_str()); } ///////////////////////////////////////////////// TEST(SDF, PrintDoc) { std::stringstream buffer; auto old = std::cout.rdbuf(buffer.rdbuf()); sdf::SDF sdf; sdf.PrintDoc(); EXPECT_GT(buffer.str().size(), 2000u); EXPECT_NE(buffer.str().find("HTML"), std::string::npos); EXPECT_NE(buffer.str().find("SDF"), std::string::npos); EXPECT_NE(buffer.str().find("Usage"), std::string::npos); EXPECT_NE(buffer.str().find("Meta-Tags"), std::string::npos); std::cout.rdbuf(old); } ///////////////////////////////////////////////// TEST(SDF, PrintDescription) { std::stringstream buffer; auto old = std::cout.rdbuf(buffer.rdbuf()); sdf::SDF sdf; sdf.PrintDescription(); EXPECT_GT(buffer.str().size(), 70u); EXPECT_NE(buffer.str().find(""), std::string::npos); std::cout.rdbuf(old); } ///////////////////////////////////////////////// TEST(SDF, PrintValues) { std::stringstream buffer; auto old = std::cout.rdbuf(buffer.rdbuf()); sdf::SDF sdf; sdf.PrintValues(); EXPECT_GT(buffer.str().size(), 3u); EXPECT_NE(buffer.str().find(""), std::string::npos); std::cout.rdbuf(old); } #ifndef _WIN32 bool create_new_temp_dir(std::string &_new_temp_path) { std::string tmppath; const char *tmp = getenv("TMPDIR"); if (tmp) { tmppath = std::string(tmp); } else { tmppath = std::string("/tmp"); } tmppath += "/XXXXXX"; char *dtemp = mkdtemp(const_cast(tmppath.c_str())); if (dtemp == nullptr) { return false; } _new_temp_path = std::string(dtemp); return true; } ///////////////////////////////////////////////// bool g_findFileCbCalled = false; std::string findFileCb(const std::string &) { g_findFileCbCalled = true; return "coconut"; } ///////////////////////////////////////////////// TEST(SDF, WriteURIPath) { // Create temp dir std::string tempDir; ASSERT_TRUE(create_new_temp_dir(tempDir)); // Write to file auto tempFile = tempDir + "/test.sdf"; sdf::SDF sdf; sdf.Write(tempFile); // Check file was created auto fp = fopen(tempFile.c_str(), "r"); ASSERT_NE(nullptr, fp); // Add temp dir to path sdf::addURIPath("test://", tempDir); // Find file EXPECT_EQ(sdf::findFile("test://test.sdf"), tempFile); // Can't find file, fallback to user callback EXPECT_EQ(sdf::findFile("banana", false, true), ""); sdf::setFindCallback(findFileCb); EXPECT_EQ(sdf::findFile("banana", false, true), "coconut"); // Check callback was called EXPECT_TRUE(g_findFileCbCalled); // Cleanup ASSERT_EQ(std::remove(tempFile.c_str()), 0); ASSERT_EQ(rmdir(tempDir.c_str()), 0); } #endif // _WIN32 ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Types.cc000066400000000000000000000031271323606632500164660ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/Types.hh" namespace sdf { ///////////////////////////////////////////////// std::vector split(const std::string &_str, const std::string &_splitter) { std::vector ret; size_t next = 0; size_t current = next; if (_splitter.empty()) { // If the splitter is blank, just return the original ret.push_back(_str); return ret; } while (next != std::string::npos) { next = _str.find(_splitter, current); ret.push_back(_str.substr(current, next - current)); current = next + _splitter.length(); } return ret; } ////////////////////////////////////////////////// std::string trim(const char *_in) { std::string str(_in); const size_t strBegin = str.find_first_not_of(" \t"); if (strBegin == std::string::npos) { return ""; } const size_t strRange = str.find_last_not_of(" \t") - strBegin + 1; return str.substr(strBegin, strRange); } } sdformat-6.0.0+dfsg/src/Types_TEST.cc000066400000000000000000000051311323606632500173220ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/Types.hh" ///////////////////////////////////////////////// TEST(Types, split_nothing) { std::vector split = sdf::split("hello", "/"); ASSERT_EQ(split.size(), 1UL); EXPECT_EQ(split[0], "hello"); } ///////////////////////////////////////////////// TEST(Types, split_single) { std::vector split = sdf::split("hello/there", "/"); ASSERT_EQ(split.size(), 2UL); EXPECT_EQ(split[0], "hello"); EXPECT_EQ(split[1], "there"); } ///////////////////////////////////////////////// TEST(Types, split_blank) { std::vector split = sdf::split("", "/"); ASSERT_EQ(split.size(), 1UL); EXPECT_EQ(split[0], ""); } ///////////////////////////////////////////////// TEST(Types, split_empty_splitter) { std::vector split = sdf::split("hello", ""); ASSERT_EQ(split.size(), 1UL); EXPECT_EQ(split[0], "hello"); } ///////////////////////////////////////////////// TEST(Types, split_empty_string_and_splitter) { std::vector split = sdf::split("", ""); ASSERT_EQ(split.size(), 1UL); EXPECT_EQ(split[0], ""); } ///////////////////////////////////////////////// TEST(Types, split_no_matches) { std::vector split = sdf::split("hello/there", ":"); ASSERT_EQ(split.size(), 1UL); EXPECT_EQ(split[0], "hello/there"); } ///////////////////////////////////////////////// TEST(Types, trim_nothing) { std::string out = sdf::trim("hello"); EXPECT_EQ(out, "hello"); out = sdf::trim(" hello "); EXPECT_EQ(out, "hello"); out = sdf::trim(""); EXPECT_EQ(out, ""); out = sdf::trim(" hello there "); EXPECT_EQ(out, "hello there"); out = sdf::trim(" "); EXPECT_EQ(out, ""); out = sdf::trim("\t\t"); EXPECT_EQ(out, ""); out = sdf::trim("\txyz\t"); EXPECT_EQ(out, "xyz"); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/Utils.cc000066400000000000000000000016071323606632500164630ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "Utils.hh" ///////////////////////////////////////////////// bool sdf::loadName(sdf::ElementPtr _sdf, std::string &_name) { // Read the name std::pair namePair = _sdf->Get("name", ""); _name = namePair.first; return namePair.second; } sdformat-6.0.0+dfsg/src/Utils.hh000066400000000000000000000020061323606632500164670ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDFORMAT_UTILS_HH #define SDFORMAT_UTILS_HH #include #include "sdf/Element.hh" namespace sdf { /// \brief Read the "name" attribute from an element. /// \param[in] _sdf SDF element pointer which contains the name. /// \param[out] _name String to hold the name value. /// \return True when the "name" attribute exists. bool loadName(sdf::ElementPtr _sdf, std::string &_name); } #endif sdformat-6.0.0+dfsg/src/World.cc000066400000000000000000000110161323606632500164450ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/World.hh" #include "Utils.hh" using namespace sdf; class sdf::WorldPrivate { /// \brief Name of the world. public: std::string name = ""; /// \brief Audio device name public: std::string audioDevice = "default"; /// \brief Linear velocity of wind. public: ignition::math::Vector3d windLinearVelocity = ignition::math::Vector3d::Zero; /// \brief Gravity vector. public: ignition::math::Vector3d gravity = ignition::math::Vector3d(0, 0, -9.80665); /// \brief Magnetic field. public: ignition::math::Vector3d magneticField = ignition::math::Vector3d(5.5645e-6, 22.8758e-6, -42.3884e-6); }; ///////////////////////////////////////////////// World::World() : dataPtr(new WorldPrivate) { } ///////////////////////////////////////////////// World::~World() { delete this->dataPtr; this->dataPtr = nullptr; } ///////////////////////////////////////////////// World::World(World &&_world) { this->dataPtr = _world.dataPtr; _world.dataPtr = nullptr; } ///////////////////////////////////////////////// Errors World::Load(sdf::ElementPtr _sdf) { Errors errors; // Check that the provided SDF element is a // This is an error that cannot be recovered, so return an error. if (_sdf->GetName() != "world") { errors.push_back({ErrorCode::ELEMENT_INCORRECT_TYPE, "Attempting to load a World, but the provided SDF element is not a " "."}); return errors; } // Read the world's name if (!loadName(_sdf, this->dataPtr->name)) { errors.push_back({ErrorCode::ATTRIBUTE_MISSING, "A world name is required, but the name is not set."}); } // Read the audio element if (_sdf->HasElement("audio")) { sdf::ElementPtr elem = _sdf->GetElement("audio"); this->dataPtr->audioDevice = elem->Get("device", this->dataPtr->audioDevice).first; } // Read the wind element if (_sdf->HasElement("wind")) { sdf::ElementPtr elem = _sdf->GetElement("wind"); this->dataPtr->windLinearVelocity = elem->Get("linear_velocity", this->dataPtr->windLinearVelocity).first; } // Read gravity. this->dataPtr->gravity = _sdf->Get("gravity", this->dataPtr->gravity).first; // Read the magnetic field. this->dataPtr->magneticField = _sdf->Get("magnetic_field", this->dataPtr->magneticField).first; return errors; } ///////////////////////////////////////////////// std::string World::Name() const { return this->dataPtr->name; } ///////////////////////////////////////////////// void World::SetName(const std::string &_name) const { this->dataPtr->name = _name; } ///////////////////////////////////////////////// std::string World::AudioDevice() const { return this->dataPtr->audioDevice; } ///////////////////////////////////////////////// void World::SetAudioDevice(const std::string &_device) { this->dataPtr->audioDevice = _device; } ///////////////////////////////////////////////// ignition::math::Vector3d World::WindLinearVelocity() const { return this->dataPtr->windLinearVelocity; } ///////////////////////////////////////////////// void World::SetWindLinearVelocity(const ignition::math::Vector3d &_wind) { this->dataPtr->windLinearVelocity = _wind; } ///////////////////////////////////////////////// ignition::math::Vector3d World::Gravity() const { return this->dataPtr->gravity; } ///////////////////////////////////////////////// void World::SetGravity(const ignition::math::Vector3d &_gravity) { this->dataPtr->gravity = _gravity; } ///////////////////////////////////////////////// ignition::math::Vector3d World::MagneticField() const { return this->dataPtr->magneticField; } ///////////////////////////////////////////////// void World::SetMagneticField(const ignition::math::Vector3d &_mag) { this->dataPtr->magneticField = _mag; } sdformat-6.0.0+dfsg/src/World_TEST.cc000066400000000000000000000033211323606632500173040ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/World.hh" ///////////////////////////////////////////////// TEST(DOMWorld, Construction) { sdf::World world; EXPECT_TRUE(world.Name().empty()); EXPECT_EQ(world.Gravity(), ignition::math::Vector3d(0, 0, -9.80665)); EXPECT_EQ(world.MagneticField(), ignition::math::Vector3d(5.5645e-6, 22.8758e-6, -42.3884e-6)); EXPECT_STREQ(world.AudioDevice().c_str(), "default"); EXPECT_EQ(world.WindLinearVelocity(), ignition::math::Vector3d::Zero); } ///////////////////////////////////////////////// TEST(DOMWorld, Set) { sdf::World world; EXPECT_TRUE(world.Name().empty()); world.SetName("default"); EXPECT_EQ(world.Name(), "default"); world.SetAudioDevice("/dev/audio"); EXPECT_EQ(world.AudioDevice(), "/dev/audio"); world.SetWindLinearVelocity({0, 1 , 2}); EXPECT_EQ(world.WindLinearVelocity(), ignition::math::Vector3d(0, 1, 2)); world.SetGravity({1, -2, 4}); EXPECT_EQ(world.Gravity(), ignition::math::Vector3d(1, -2, 4)); world.SetMagneticField({1.2, -2.3, 4.5}); EXPECT_EQ(world.MagneticField(), ignition::math::Vector3d(1.2, -2.3, 4.5)); } sdformat-6.0.0+dfsg/src/cmd/000077500000000000000000000000001323606632500156135ustar00rootroot00000000000000sdformat-6.0.0+dfsg/src/cmd/CMakeLists.txt000066400000000000000000000011731323606632500203550ustar00rootroot00000000000000include (${project_cmake_dir}/SDFUtils.cmake) # Generate a the ruby script. # Note that the major version of the library is included in the name. # Ex: cmdsdformat0.rb if (APPLE) set(IGN_LIBRARY_NAME lib${PROJECT_NAME_LOWER}${SDF_MAJOR_VERSION}.dylib) else() set(IGN_LIBRARY_NAME lib${PROJECT_NAME_LOWER}.so.${SDF_MAJOR_VERSION}) endif() configure_file( "cmdsdformat.rb.in" "${CMAKE_CURRENT_BINARY_DIR}/cmdsdformat${SDF_MAJOR_VERSION}.rb" @ONLY) # Install the ruby command line library in an unversioned location. install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmdsdformat${SDF_MAJOR_VERSION}.rb DESTINATION lib/ruby/ignition) sdformat-6.0.0+dfsg/src/cmd/cmdsdformat.rb.in000066400000000000000000000075611323606632500210610ustar00rootroot00000000000000#!/usr/bin/ruby # Copyright (C) 2017 Open Source Robotics Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # We use 'dl' for Ruby <= 1.9.x and 'fiddle' for Ruby >= 2.0.x if RUBY_VERSION.split('.')[0] < '2' require 'dl' require 'dl/import' include DL else require 'fiddle' require 'fiddle/import' include Fiddle end require 'optparse' # Constants. LIBRARY_NAME = '@IGN_LIBRARY_NAME@' LIBRARY_VERSION = '@SDF_VERSION_FULL@' COMMON_OPTIONS = " -h [ --help ] Print this help message.\n"\ " --force-version Use a specific library version.\n"\ ' --versions Show the available versions.' COMMANDS = { 'sdf' => "Utilities for SDF files.\n\n"\ " ign sdf [options]\n\n"\ "Options:\n\n"\ " -k [ --check ] arg Validate arg.\n" + COMMON_OPTIONS } # # Class for the SDF command line tools. # class Cmd # # Return a structure describing the options. # def parse(args) options = {} usage = COMMANDS[args[0]] # Read the command line arguments. opt_parser = OptionParser.new do |opts| opts.banner = usage opts.on('-h', '--help", "Print this help message') do puts usage exit(0) end opts.on('-k arg', '--check arg', String, 'Validate arg') do |arg| options['check'] = arg end end begin opt_parser.parse!(args) rescue puts usage exit(-1) end # Check that there is at least one command and there is a plugin that knows # how to handle it. if ARGV.empty? || !COMMANDS.key?(ARGV[0]) || options.empty? puts usage exit(-1) end options['command'] = ARGV[0] options end # # Execute the command # def execute(args) options = parse(args) # Debugging: # puts 'Parsed:' # puts options # Read the plugin that handles the command. plugin = LIBRARY_NAME conf_version = LIBRARY_VERSION begin Importer.dlload plugin rescue => exception puts "Library error: #{exception.message}" exit(-1) end # Read the library version. Importer.extern 'char* ignitionVersion()' begin plugin_version = Importer.ignitionVersion.to_s rescue DLError puts "Library error: Problem running 'ignitionVersion()' from #{plugin}." exit(-1) end # Sanity check: Verify that the version of the yaml file matches the version # of the library that we are using. unless plugin_version.eql? conf_version puts "Error: Version mismatch. Your configuration file version is [#{conf_version}] but #{plugin} version is [#{plugin_version}]." exit(-1) end begin case options['command'] when 'sdf' if options.key?('check') Importer.extern 'int cmdCheck(const char *)' exit(Importer.cmdCheck(options['check'])) else puts 'Command error: I do not have an implementation '\ 'for this command.' end else puts 'Command error: I do not have an implementation for '\ "command [ign #{options['command']}]." end rescue puts "Library error: Problem running [#{options['command']}]() "\ "from #{plugin}." end end end sdformat-6.0.0+dfsg/src/ign.cc000066400000000000000000000030071323606632500161340ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/sdf_config.h" #include "sdf/Filesystem.hh" #include "sdf/ign.hh" #include "sdf/parser.hh" #include "sdf/system_util.hh" ////////////////////////////////////////////////// // cppcheck-suppress unusedFunction extern "C" SDFORMAT_VISIBLE int cmdCheck(const char *_path) { if (!sdf::filesystem::exists(_path)) { std::cerr << "Error: File [" << _path << "] does not exist.\n"; return -1; } sdf::SDFPtr sdf(new sdf::SDF()); if (!sdf::init(sdf)) { std::cerr << "Error: SDF schema initialization failed.\n"; return -1; } if (!sdf::readFile(_path, sdf)) { std::cerr << "Error: SDF parsing the xml failed.\n"; return -1; } std::cout << "Valid.\n"; return 0; } ////////////////////////////////////////////////// // cppcheck-suppress unusedFunction extern "C" SDFORMAT_VISIBLE char *ignitionVersion() { return sdf_strdup(SDF_VERSION_FULL); } sdformat-6.0.0+dfsg/src/ign_TEST.cc000066400000000000000000000055441323606632500170030ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include "sdf/sdf_config.h" #include "test_config.h" static const std::string g_sdfVersion(" --force-version " + std::string(SDF_VERSION_FULL)); static const std::string g_ignCommand(std::string(IGN_PATH) + "/ign"); ///////////////////////////////////////////////// std::string custom_exec_str(std::string _cmd) { _cmd += " 2>&1"; FILE *pipe = popen(_cmd.c_str(), "r"); if (!pipe) return "ERROR"; char buffer[128]; std::string result = ""; while (!feof(pipe)) { if (fgets(buffer, 128, pipe) != NULL) result += buffer; } pclose(pipe); return result; } ///////////////////////////////////////////////// TEST(check, SDF) { std::string pathBase = PROJECT_SOURCE_PATH; pathBase += "/test/sdf"; // Check a good SDF file { std::string path = pathBase +"/box_plane_low_friction_test.world"; // Check box_plane_low_friction_test.world std::string output = custom_exec_str(g_ignCommand + " sdf -k " + path + g_sdfVersion); EXPECT_EQ(output, "Valid.\n"); } // Check a bad SDF file { std::string path = pathBase +"/box_bad_test.world"; // Check box_bad_test.world std::string output = custom_exec_str(g_ignCommand + " sdf -k " + path + g_sdfVersion); EXPECT_TRUE(output.find("Required attribute") != std::string::npos); } } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { // Set IGN_CONFIG_PATH to the directory where the .yaml configuration file // is located. setenv("IGN_CONFIG_PATH", IGN_CONFIG_PATH, 1); // Make sure that we load the library recently built and not the one installed // in your system. This is done by placing the the current build directory // first in the LD_LIBRARY_PATH environment variable. // // We need to keep the existing LD_LIBRARY_PATH so that libsdformat.so can // find its dependency. #ifndef _WIN32 char *currentLibraryPath = std::getenv("LD_LIBRARY_PATH"); std::string testLibraryPath = IGN_TEST_LIBRARY_PATH; testLibraryPath = testLibraryPath + ":" + currentLibraryPath; setenv("LD_LIBRARY_PATH", testLibraryPath.c_str(), 1); #endif ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/parser.cc000066400000000000000000001014571323606632500166630ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include "sdf/Console.hh" #include "sdf/Converter.hh" #include "sdf/Filesystem.hh" #include "sdf/Param.hh" #include "sdf/SDFImpl.hh" #include "sdf/parser.hh" #include "sdf/parser_private.hh" #include "sdf/parser_urdf.hh" #include "sdf/sdf_config.h" namespace sdf { ////////////////////////////////////////////////// template static inline bool _initFile(const std::string &_filename, TPtr _sdf) { TiXmlDocument xmlDoc; if (xmlDoc.LoadFile(_filename)) { return initDoc(&xmlDoc, _sdf); } else { sdferr << "Unable to load file[" << _filename << "]\n"; } return false; } ////////////////////////////////////////////////// bool init(SDFPtr _sdf) { bool result = false; std::string filename; std::string fileToFind = "root.sdf"; if (sdf::SDF::Version() == "1.0" || sdf::SDF::Version() == "1.2") { fileToFind = "gazebo.sdf"; } filename = sdf::findFile(fileToFind); FILE *ftest = fopen(filename.c_str(), "r"); if (ftest) { fclose(ftest); result = _initFile(filename, _sdf); } else { sdferr << "Unable to find or open SDF file[" << fileToFind << "]\n"; } return result; } ////////////////////////////////////////////////// bool initFile(const std::string &_filename, SDFPtr _sdf) { return _initFile(sdf::findFile(_filename), _sdf); } ////////////////////////////////////////////////// bool initFile(const std::string &_filename, ElementPtr _sdf) { return _initFile(sdf::findFile(_filename), _sdf); } ////////////////////////////////////////////////// bool initString(const std::string &_xmlString, SDFPtr _sdf) { TiXmlDocument xmlDoc; xmlDoc.Parse(_xmlString.c_str()); if (xmlDoc.Error()) { sdferr << "Failed to parse string as XML: " << xmlDoc.ErrorDesc() << '\n'; return false; } return initDoc(&xmlDoc, _sdf); } ////////////////////////////////////////////////// inline TiXmlElement *_initDocGetElement(TiXmlDocument *_xmlDoc) { if (!_xmlDoc) { sdferr << "Could not parse the xml\n"; return nullptr; } TiXmlElement *element = _xmlDoc->FirstChildElement("element"); if (!element) { sdferr << "Could not find the 'element' element in the xml file\n"; return nullptr; } return element; } ////////////////////////////////////////////////// bool initDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf) { auto element = _initDocGetElement(_xmlDoc); if (!element) { return false; } return initXml(element, _sdf->Root()); } ////////////////////////////////////////////////// bool initDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf) { auto element = _initDocGetElement(_xmlDoc); if (!element) { return false; } return initXml(element, _sdf); } ////////////////////////////////////////////////// bool initXml(TiXmlElement *_xml, ElementPtr _sdf) { const char *refString = _xml->Attribute("ref"); if (refString) { _sdf->SetReferenceSDF(std::string(refString)); } const char *nameString = _xml->Attribute("name"); if (!nameString) { sdferr << "Element is missing the name attribute\n"; return false; } _sdf->SetName(std::string(nameString)); const char *requiredString = _xml->Attribute("required"); if (!requiredString) { sdferr << "Element is missing the required attributed\n"; return false; } _sdf->SetRequired(requiredString); const char *elemTypeString = _xml->Attribute("type"); if (elemTypeString) { bool required = std::string(requiredString) == "1" ? true : false; const char *elemDefaultValue = _xml->Attribute("default"); std::string description; TiXmlElement *descChild = _xml->FirstChildElement("description"); if (descChild && descChild->GetText()) { description = descChild->GetText(); } _sdf->AddValue(elemTypeString, elemDefaultValue, required, description); } // Get all attributes for (TiXmlElement *child = _xml->FirstChildElement("attribute"); child; child = child->NextSiblingElement("attribute")) { TiXmlElement *descriptionChild = child->FirstChildElement("description"); const char *name = child->Attribute("name"); const char *type = child->Attribute("type"); const char *defaultValue = child->Attribute("default"); requiredString = child->Attribute("required"); if (!name) { sdferr << "Attribute is missing a name\n"; return false; } if (!type) { sdferr << "Attribute is missing a type\n"; return false; } if (!defaultValue) { sdferr << "Attribute[" << name << "] is missing a default\n"; return false; } if (!requiredString) { sdferr << "Attribute is missing a required string\n"; return false; } std::string requiredStr = sdf::trim(requiredString); bool required = requiredStr == "1" ? true : false; std::string description; if (descriptionChild && descriptionChild->GetText()) { description = descriptionChild->GetText(); } _sdf->AddAttribute(name, type, defaultValue, required, description); } // Read the element description TiXmlElement *descChild = _xml->FirstChildElement("description"); if (descChild && descChild->GetText()) { _sdf->SetDescription(descChild->GetText()); } // Get all child elements for (TiXmlElement *child = _xml->FirstChildElement("element"); child; child = child->NextSiblingElement("element")) { const char *copyDataString = child->Attribute("copy_data"); if (copyDataString && (std::string(copyDataString) == "true" || std::string(copyDataString) == "1")) { _sdf->SetCopyChildren(true); } else { ElementPtr element(new Element); initXml(child, element); _sdf->AddElementDescription(element); } } // Get all include elements for (TiXmlElement *child = _xml->FirstChildElement("include"); child; child = child->NextSiblingElement("include")) { std::string filename = child->Attribute("filename"); ElementPtr element(new Element); initFile(filename, element); // override description for include elements TiXmlElement *description = child->FirstChildElement("description"); if (description) { element->SetDescription(description->GetText()); } _sdf->AddElementDescription(element); } return true; } ////////////////////////////////////////////////// SDFPtr readFile(const std::string &_filename, Errors &_errors) { // Create and initialize the data structure that will hold the parsed SDF data sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); // Read an SDF file, and store the result in sdfParsed. if (!sdf::readFile(_filename, sdfParsed, _errors)) { return SDFPtr(); } return sdfParsed; } ////////////////////////////////////////////////// SDFPtr readFile(const std::string &_filename) { Errors errors; SDFPtr result = readFile(_filename, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } ////////////////////////////////////////////////// bool readFile(const std::string &_filename, SDFPtr _sdf) { Errors errors; bool result = readFile(_filename, _sdf, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } ////////////////////////////////////////////////// bool readFile(const std::string &_filename, SDFPtr _sdf, Errors &_errors) { TiXmlDocument xmlDoc; std::string filename = sdf::findFile(_filename); if (filename.empty()) { sdferr << "Error finding file [" << _filename << "].\n"; return false; } if (!xmlDoc.LoadFile(filename)) { sdferr << "Error parsing XML in file [" << filename << "]: " << xmlDoc.ErrorDesc() << '\n'; return false; } if (readDoc(&xmlDoc, _sdf, filename, true, _errors)) { return true; } else if (sdf::URDF2SDF::IsURDF(filename)) { sdf::URDF2SDF u2g; TiXmlDocument doc = u2g.InitModelFile(filename); if (sdf::readDoc(&doc, _sdf, "urdf file", true, _errors)) { sdfdbg << "parse from urdf file [" << _filename << "].\n"; return true; } else { sdferr << "parse as old deprecated model file failed.\n"; return false; } } return false; } ////////////////////////////////////////////////// bool readString(const std::string &_xmlString, SDFPtr _sdf) { Errors errors; bool result = readString(_xmlString, _sdf, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } ////////////////////////////////////////////////// bool readString(const std::string &_xmlString, SDFPtr _sdf, Errors &_errors) { TiXmlDocument xmlDoc; xmlDoc.Parse(_xmlString.c_str()); if (xmlDoc.Error()) { sdferr << "Error parsing XML from string: " << xmlDoc.ErrorDesc() << '\n'; return false; } if (readDoc(&xmlDoc, _sdf, "data-string", true, _errors)) { return true; } else { sdf::URDF2SDF u2g; TiXmlDocument doc = u2g.InitModelString(_xmlString); if (sdf::readDoc(&doc, _sdf, "urdf string", true, _errors)) { sdfdbg << "Parsing from urdf.\n"; return true; } else { sdferr << "parse as old deprecated model file failed.\n"; return false; } } return false; } ////////////////////////////////////////////////// bool readString(const std::string &_xmlString, ElementPtr _sdf) { Errors errors; bool result = readString(_xmlString, _sdf, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } ////////////////////////////////////////////////// bool readString(const std::string &_xmlString, ElementPtr _sdf, Errors &_errors) { TiXmlDocument xmlDoc; xmlDoc.Parse(_xmlString.c_str()); if (xmlDoc.Error()) { sdferr << "Error parsing XML from string: " << xmlDoc.ErrorDesc() << '\n'; return false; } if (readDoc(&xmlDoc, _sdf, "data-string", true, _errors)) { return true; } else { sdferr << "parse as sdf version " << SDF::Version() << " failed, " << "should try to parse as old deprecated format\n"; return false; } } ////////////////////////////////////////////////// bool readDoc(TiXmlDocument *_xmlDoc, SDFPtr _sdf, const std::string &_source, bool _convert, Errors &_errors) { if (!_xmlDoc) { sdfwarn << "Could not parse the xml from source[" << _source << "]\n"; return false; } // check sdf version, use old parser if necessary TiXmlElement *sdfNode = _xmlDoc->FirstChildElement("sdf"); if (!sdfNode) { sdfNode = _xmlDoc->FirstChildElement("gazebo"); } if (sdfNode && sdfNode->Attribute("version")) { if (_convert && strcmp(sdfNode->Attribute("version"), SDF::Version().c_str()) != 0) { sdfdbg << "Converting a deprecated source[" << _source << "].\n"; Converter::Convert(_xmlDoc, SDF::Version()); } // parse new sdf xml TiXmlElement *elemXml = _xmlDoc->FirstChildElement(_sdf->Root()->GetName()); if (!readXml(elemXml, _sdf->Root(), _errors)) { _errors.push_back({ErrorCode::ELEMENT_INVALID, "Error reading element <" + _sdf->Root()->GetName() + ">"}); return false; } } else { // try to use the old deprecated parser if (!sdfNode) { sdfdbg << "No element in file[" << _source << "]\n"; } else if (!sdfNode->Attribute("version")) { sdfdbg << "SDF element has no version in file[" << _source << "]\n"; } else if (strcmp(sdfNode->Attribute("version"), SDF::Version().c_str()) != 0) { sdfdbg << "SDF version [" << sdfNode->Attribute("version") << "] is not " << SDF::Version() << "\n"; } return false; } return true; } ////////////////////////////////////////////////// bool readDoc(TiXmlDocument *_xmlDoc, ElementPtr _sdf, const std::string &_source, bool _convert, Errors &_errors) { if (!_xmlDoc) { sdfwarn << "Could not parse the xml\n"; return false; } // check sdf version, use old parser if necessary TiXmlElement *sdfNode = _xmlDoc->FirstChildElement("sdf"); if (!sdfNode) { sdfNode = _xmlDoc->FirstChildElement("gazebo"); } if (sdfNode && sdfNode->Attribute("version")) { if (_convert && strcmp(sdfNode->Attribute("version"), SDF::Version().c_str()) != 0) { sdfwarn << "Converting a deprecated SDF source[" << _source << "].\n"; Converter::Convert(_xmlDoc, SDF::Version()); } TiXmlElement *elemXml = sdfNode; if (sdfNode->Value() != _sdf->GetName() && sdfNode->FirstChildElement(_sdf->GetName())) { elemXml = sdfNode->FirstChildElement(_sdf->GetName()); } // parse new sdf xml if (!readXml(elemXml, _sdf, _errors)) { _errors.push_back({ErrorCode::ELEMENT_INVALID, "Unable to parse sdf element["+ _sdf->GetName() + "]"}); return false; } } else { // try to use the old deprecated parser if (!sdfNode) { sdfdbg << "SDF has no element\n"; } else if (!sdfNode->Attribute("version")) { sdfdbg << " element has no version\n"; } else if (strcmp(sdfNode->Attribute("version"), SDF::Version().c_str()) != 0) { sdfdbg << "SDF version [" << sdfNode->Attribute("version") << "] is not " << SDF::Version() << "\n"; } return false; } return true; } ////////////////////////////////////////////////// std::string getBestSupportedModelVersion(TiXmlElement *_modelXML, std::string &_modelFileName) { TiXmlElement *sdfXML = _modelXML->FirstChildElement("sdf"); TiXmlElement *nameSearch = _modelXML->FirstChildElement("name"); // If a match is not found, use the latest version of the element // that is not older than the SDF parser. ignition::math::SemanticVersion sdfParserVersion(SDF_VERSION); std::string bestVersionStr = "0.0"; TiXmlElement *sdfSearch = sdfXML; while (sdfSearch) { if (sdfSearch->Attribute("version")) { auto version = std::string(sdfSearch->Attribute("version")); ignition::math::SemanticVersion modelVersion(version); ignition::math::SemanticVersion bestVersion(bestVersionStr); if (modelVersion > bestVersion) { // this model is better than the previous one if (modelVersion <= sdfParserVersion) { // the parser can read it sdfXML = sdfSearch; bestVersionStr = version; } else { sdfwarn << "Ignoring version " << version << " for model " << nameSearch->GetText() << " because is newer than this sdf parser" << " (version " << SDF_VERSION << ")\n"; } } } sdfSearch = sdfSearch->NextSiblingElement("sdf"); } if (!sdfXML || !sdfXML->GetText()) { sdferr << "Failure to detect an sdf tag in the model config file" << " for model: " << nameSearch->GetText() << "\n"; _modelFileName = ""; return ""; } if (!sdfXML->Attribute("version")) { sdfwarn << "Can not find the XML attribute 'version'" << " in sdf XML tag for model: " << nameSearch->GetText() << "." << " Please specify the SDF protocol supported in the model" << " configuration file. The first sdf tag in the config file" << " will be used \n"; } _modelFileName = sdfXML->GetText(); return bestVersionStr; } ////////////////////////////////////////////////// std::string getModelFilePath(const std::string &_modelDirPath) { std::string configFilePath; /// \todo This hardcoded bit is very Gazebo centric. It should /// be abstracted away, possibly through a plugin to SDF. configFilePath = sdf::filesystem::append(_modelDirPath, "model.config"); if (!sdf::filesystem::exists(configFilePath)) { // We didn't find model.config, look for manifest.xml instead configFilePath = sdf::filesystem::append(_modelDirPath, "manifest.xml"); if (!sdf::filesystem::exists(configFilePath)) { // We didn't find manifest.xml either, output an error and get out. sdferr << "Could not find model.config or manifest.xml for the model\n"; return std::string(); } else { // We found manifest.xml, but since it is deprecated print a warning. sdfwarn << "The manifest.xml for a model is deprecated. " << "Please rename manifest.xml to " << "model.config" << ".\n"; } } TiXmlDocument configFileDoc; if (!configFileDoc.LoadFile(configFilePath)) { sdferr << "Error parsing XML in file [" << configFilePath << "]: " << configFileDoc.ErrorDesc() << '\n'; return std::string(); } TiXmlElement *modelXML = configFileDoc.FirstChildElement("model"); if (!modelXML) { sdferr << "No element in configFile[" << configFilePath << "]\n"; return std::string(); } std::string modelFileName; if (getBestSupportedModelVersion(modelXML, modelFileName).empty()) { return std::string(); } return sdf::filesystem::append(_modelDirPath, modelFileName); } ////////////////////////////////////////////////// bool readXml(TiXmlElement *_xml, ElementPtr _sdf, Errors &_errors) { // Check if the element pointer is deprecated. if (_sdf->GetRequired() == "-1") { _errors.push_back({ErrorCode::ELEMENT_DEPRECATED, "SDF Element[" + _sdf->GetName() + "] is deprecated"}); return true; } if (!_xml) { if (_sdf->GetRequired() == "1" || _sdf->GetRequired() =="+") { _errors.push_back({ErrorCode::ELEMENT_MISSING, "SDF Element<" + _sdf->GetName() + "> is missing"}); return false; } else { return true; } } if (_xml->GetText() != nullptr && _sdf->GetValue()) { if (!_sdf->GetValue()->SetFromString(_xml->GetText())) return false; } // check for nested sdf std::string refSDFStr = _sdf->ReferenceSDF(); if (!refSDFStr.empty()) { ElementPtr refSDF; refSDF.reset(new Element); std::string refFilename = refSDFStr + ".sdf"; initFile(refFilename, refSDF); _sdf->RemoveFromParent(); _sdf->Copy(refSDF); } TiXmlAttribute *attribute = _xml->FirstAttribute(); unsigned int i = 0; // Iterate over all the attributes defined in the give XML element while (attribute) { // Find the matching attribute in SDF for (i = 0; i < _sdf->GetAttributeCount(); ++i) { ParamPtr p = _sdf->GetAttribute(i); if (p->GetKey() == attribute->Name()) { // Set the value of the SDF attribute if (!p->SetFromString(attribute->ValueStr())) { _errors.push_back({ErrorCode::ATTRIBUTE_INVALID, "Unable to read attribute[" + p->GetKey() + "]"}); return false; } break; } } if (i == _sdf->GetAttributeCount()) { sdfwarn << "XML Attribute[" << attribute->Name() << "] in element[" << _xml->Value() << "] not defined in SDF, ignoring.\n"; } attribute = attribute->Next(); } // Check that all required attributes have been set for (i = 0; i < _sdf->GetAttributeCount(); ++i) { ParamPtr p = _sdf->GetAttribute(i); if (p->GetRequired() && !p->GetSet()) { _errors.push_back({ErrorCode::ATTRIBUTE_MISSING, "Required attribute[" + p->GetKey() + "] in element[" + _xml->Value() + "] is not specified in SDF."}); return false; } } if (_sdf->GetCopyChildren()) { copyChildren(_sdf, _xml); } else { std::string filename; // Iterate over all the child elements TiXmlElement *elemXml = nullptr; for (elemXml = _xml->FirstChildElement(); elemXml; elemXml = elemXml->NextSiblingElement()) { if (std::string("include") == elemXml->Value()) { std::string modelPath; if (elemXml->FirstChildElement("uri")) { std::string uri = elemXml->FirstChildElement("uri")->GetText(); modelPath = sdf::findFile(uri, true, true); // Test the model path if (modelPath.empty()) { _errors.push_back({ErrorCode::URI_LOOKUP, "Unable to find uri[" + uri + "]"}); size_t modelFound = uri.find("model://"); if (modelFound != 0u) { _errors.push_back({ErrorCode::URI_INVALID, "Invalid uri[" + uri + "]. Should be model://" + uri}); } continue; } else { if (!sdf::filesystem::is_directory(modelPath)) { _errors.push_back({ErrorCode::DIRECTORY_NONEXISTANT, "Directory doesn't exist[" + modelPath + "]"}); continue; } } // Get the config.xml filename filename = getModelFilePath(modelPath); } else { _errors.push_back({ErrorCode::ATTRIBUTE_MISSING, " element missing 'uri' attribute"}); continue; } // NOTE: sdf::init is an expensive call. For performance reason, // a new sdf pointer is created here by cloning a fresh sdf template // pointer instead of calling init every iteration. // SDFPtr includeSDF(new SDF); // init(includeSDF); static SDFPtr includeSDFTemplate; if (!includeSDFTemplate) { includeSDFTemplate.reset(new SDF); init(includeSDFTemplate); } SDFPtr includeSDF(new SDF); includeSDF->Root(includeSDFTemplate->Root()->Clone()); if (!readFile(filename, includeSDF)) { _errors.push_back({ErrorCode::FILE_READ, "Unable to read file[" + filename + "]"}); return false; } if (elemXml->FirstChildElement("name")) { includeSDF->Root()->GetElement("model")->GetAttribute( "name")->SetFromString( elemXml->FirstChildElement("name")->GetText()); } TiXmlElement *poseElemXml = elemXml->FirstChildElement("pose"); if (poseElemXml) { sdf::ElementPtr poseElem = includeSDF->Root()->GetElement("model")->GetElement("pose"); poseElem->GetValue()->SetFromString(poseElemXml->GetText()); const char *frame = poseElemXml->Attribute("frame"); if (frame) { poseElem->GetAttribute("frame")->SetFromString(frame); } } if (elemXml->FirstChildElement("static")) { includeSDF->Root()->GetElement("model")->GetElement( "static")->GetValue()->SetFromString( elemXml->FirstChildElement("static")->GetText()); } for (TiXmlElement *childElemXml = elemXml->FirstChildElement(); childElemXml; childElemXml = childElemXml->NextSiblingElement()) { if (std::string("plugin") == childElemXml->Value()) { sdf::ElementPtr pluginElem; pluginElem = includeSDF->Root()->GetElement( "model")->AddElement("plugin"); if (!readXml(childElemXml, pluginElem, _errors)) { _errors.push_back({ErrorCode::ELEMENT_INVALID, "Error reading plugin element"}); return false; } } } if (_sdf->GetName() == "model") { addNestedModel(_sdf, includeSDF->Root()); } else { includeSDF->Root()->GetFirstElement()->SetParent(_sdf); _sdf->InsertElement(includeSDF->Root()->GetFirstElement()); // TODO: This was used to store the included filename so that when // a world is saved, the included model's SDF is not stored in the // world file. This highlights the need to make model inclusion // a core feature of SDF, and not a hack that that parser handles // includeSDF->Root()->GetFirstElement()->SetInclude( // elemXml->Attribute("filename")); } continue; } // Find the matching element in SDF unsigned int descCounter = 0; for (descCounter = 0; descCounter != _sdf->GetElementDescriptionCount(); ++descCounter) { ElementPtr elemDesc = _sdf->GetElementDescription(descCounter); if (elemDesc->GetName() == elemXml->Value()) { ElementPtr element = elemDesc->Clone(); element->SetParent(_sdf); if (readXml(elemXml, element, _errors)) { _sdf->InsertElement(element); } else { _errors.push_back({ErrorCode::ELEMENT_INVALID, std::string("Error reading element <") + elemXml->Value() + ">"}); return false; } break; } } if (descCounter == _sdf->GetElementDescriptionCount()) { sdfwarn << "XML Element[" << elemXml->Value() << "], child of element[" << _xml->Value() << "] not defined in SDF. Ignoring[" << elemXml->Value() << "]. " << "You may have an incorrect SDF file, or an sdformat version " << "that doesn't support this element.\n"; continue; } } // Check that all required elements have been set for (unsigned int descCounter = 0; descCounter != _sdf->GetElementDescriptionCount(); ++descCounter) { ElementPtr elemDesc = _sdf->GetElementDescription(descCounter); if (elemDesc->GetRequired() == "1" || elemDesc->GetRequired() == "+") { if (!_sdf->HasElement(elemDesc->GetName())) { if (_sdf->GetName() == "joint" && _sdf->Get("type") != "ball") { _errors.push_back({ErrorCode::ELEMENT_MISSING, "XML Missing required element[" + elemDesc->GetName() + "], child of element[" + _sdf->GetName() + "]"}); return false; } else { // Add default element _sdf->AddElement(elemDesc->GetName()); } } } } } return true; } ///////////////////////////////////////////////// static void replace_all(std::string &_str, const std::string &_from, const std::string &_to) { if (_from.empty()) { return; } size_t start_pos = 0; while ((start_pos = _str.find(_from, start_pos)) != std::string::npos) { _str.replace(start_pos, _from.length(), _to); // We need to advance our starting position beyond what we // just replaced to deal with the case where the '_to' string // happens to contain a piece of '_from'. start_pos += _to.length(); } } ///////////////////////////////////////////////// void copyChildren(ElementPtr _sdf, TiXmlElement *_xml) { // Iterate over all the child elements TiXmlElement *elemXml = nullptr; for (elemXml = _xml->FirstChildElement(); elemXml; elemXml = elemXml->NextSiblingElement()) { std::string elem_name = elemXml->ValueStr(); if (_sdf->HasElementDescription(elem_name)) { sdf::ElementPtr element = _sdf->AddElement(elem_name); // FIXME: copy attributes for (TiXmlAttribute *attribute = elemXml->FirstAttribute(); attribute; attribute = attribute->Next()) { element->GetAttribute(attribute->Name())->SetFromString( attribute->ValueStr()); } // copy value std::string value = elemXml->GetText(); if (!value.empty()) { element->GetValue()->SetFromString(value); } copyChildren(element, elemXml); } else { ElementPtr element(new Element); element->SetParent(_sdf); element->SetName(elem_name); if (elemXml->GetText() != nullptr) { element->AddValue("string", elemXml->GetText(), "1"); } for (TiXmlAttribute *attribute = elemXml->FirstAttribute(); attribute; attribute = attribute->Next()) { element->AddAttribute(attribute->Name(), "string", "", 1, ""); element->GetAttribute(attribute->Name())->SetFromString( attribute->ValueStr()); } copyChildren(element, elemXml); _sdf->InsertElement(element); } } } ///////////////////////////////////////////////// void addNestedModel(ElementPtr _sdf, ElementPtr _includeSDF) { ElementPtr modelPtr = _includeSDF->GetElement("model"); ElementPtr elem = modelPtr->GetFirstElement(); std::map replace; ignition::math::Pose3d modelPose = modelPtr->Get("pose"); std::string modelName = modelPtr->Get("name"); while (elem) { if (elem->GetName() == "link") { std::string elemName = elem->Get("name"); std::string newName = modelName + "::" + elemName; replace[elemName] = newName; if (elem->HasElementDescription("pose")) { ignition::math::Pose3d offsetPose = elem->Get("pose"); ignition::math::Pose3d newPose = ignition::math::Pose3d( modelPose.Pos() + modelPose.Rot().RotateVector(offsetPose.Pos()), modelPose.Rot() * offsetPose.Rot()); elem->GetElement("pose")->Set(newPose); } } else if (elem->GetName() == "joint") { // for joints, we need to // prefix name like we did with links, and std::string elemName = elem->Get("name"); std::string newName = modelName + "::" + elemName; replace[elemName] = newName; // rotate the joint axis because they are model-global if (elem->HasElement("axis")) { ElementPtr axisElem = elem->GetElement("axis"); ignition::math::Vector3d newAxis = modelPose.Rot().RotateVector( axisElem->Get("xyz")); axisElem->GetElement("xyz")->Set(newAxis); } } elem = elem->GetNextElement(); } std::string str = _includeSDF->ToString(""); for (std::map::iterator iter = replace.begin(); iter != replace.end(); ++iter) { replace_all(str, std::string("\"") + iter->first + "\"", std::string("\"") + iter->second + "\""); replace_all(str, std::string("'") + iter->first + "'", std::string("'") + iter->second + "'"); replace_all(str, std::string(">") + iter->first + "<", std::string(">") + iter->second + "<"); } _includeSDF->ClearElements(); readString(str, _includeSDF); elem = _includeSDF->GetElement("model")->GetFirstElement(); ElementPtr nextElem; while (elem) { nextElem = elem->GetNextElement(); if (elem->GetName() != "pose") { elem->SetParent(_sdf); _sdf->InsertElement(elem); } elem = nextElem; } } ///////////////////////////////////////////////// bool convertFile(const std::string &_filename, const std::string &_version, SDFPtr _sdf) { std::string filename = sdf::findFile(_filename); if (filename.empty()) { sdferr << "Error finding file [" << _filename << "].\n"; return false; } TiXmlDocument xmlDoc; if (xmlDoc.LoadFile(filename)) { if (sdf::Converter::Convert(&xmlDoc, _version, true)) { Errors errors; bool result = sdf::readDoc(&xmlDoc, _sdf, filename, false, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } } else { sdferr << "Error parsing file[" << filename << "]\n"; } return false; } ///////////////////////////////////////////////// bool convertString(const std::string &_sdfString, const std::string &_version, SDFPtr _sdf) { if (_sdfString.empty()) { sdferr << "SDF string is empty.\n"; return false; } TiXmlDocument xmlDoc; xmlDoc.Parse(_sdfString.c_str()); if (!xmlDoc.Error()) { if (sdf::Converter::Convert(&xmlDoc, _version, true)) { Errors errors; bool result = sdf::readDoc(&xmlDoc, _sdf, "data-string", false, errors); // Output errors for (auto const &e : errors) std::cerr << e << std::endl; return result; } } else { sdferr << "Error parsing XML from string[" << _sdfString << "]\n"; } return false; } } sdformat-6.0.0+dfsg/src/parser_TEST.cc000066400000000000000000000035031323606632500175130ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/parser.hh" #include "sdf/Element.hh" ///////////////////////////////////////////////// TEST(parser, initStringTrim) { sdf::SDFPtr sdf(new sdf::SDF()); std::ostringstream stream; stream << "" << " " << " test" << " " << ""; EXPECT_TRUE(sdf::initString(stream.str(), sdf)); sdf::ElementPtr root = sdf->Root(); EXPECT_TRUE(root != nullptr); EXPECT_EQ("visual", root->GetName()); EXPECT_EQ("*", root->GetRequired()); sdf::ParamPtr value = root->GetValue(); ASSERT_NE(nullptr, value); EXPECT_EQ("string", value->GetTypeName()); EXPECT_EQ("_default_value_", value->GetDefaultAsString()); sdf::ParamPtr attr = root->GetAttribute("name"); EXPECT_TRUE(attr != nullptr); EXPECT_TRUE(attr->GetRequired()); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/src/parser_urdf.cc000066400000000000000000003636231323606632500177100ustar00rootroot00000000000000/* * Copyright 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sdf/SDFExtension.hh" #include "sdf/parser_urdf.hh" #include "sdf/sdf.hh" using namespace sdf; namespace sdf { typedef std::shared_ptr TiXmlElementPtr; typedef std::shared_ptr SDFExtensionPtr; typedef std::map > StringSDFExtensionPtrMap; /// create SDF geometry block based on URDF StringSDFExtensionPtrMap g_extensions; bool g_reduceFixedJoints; bool g_enforceLimits; std::string g_collisionExt = "_collision"; std::string g_visualExt = "_visual"; std::string g_lumpPrefix = "_fixed_joint_lump__"; urdf::Pose g_initialRobotPose; bool g_initialRobotPoseValid = false; std::set g_fixedJointsTransformedInRevoluteJoints; std::set g_fixedJointsTransformedInFixedJoints; /// \brief parser xml string into urdf::Vector3 /// \param[in] _key XML key where vector3 value might be /// \param[in] _scale scalar scale for the vector3 /// \return a urdf::Vector3 urdf::Vector3 ParseVector3(TiXmlNode* _key, double _scale = 1.0); urdf::Vector3 ParseVector3(const std::string &_str, double _scale = 1.0); /// insert extensions into collision geoms void InsertSDFExtensionCollision(TiXmlElement *_elem, const std::string &_linkName); /// insert extensions into model void InsertSDFExtensionRobot(TiXmlElement *_elem); /// insert extensions into visuals void InsertSDFExtensionVisual(TiXmlElement *_elem, const std::string &_linkName); /// insert extensions into joints void InsertSDFExtensionJoint(TiXmlElement *_elem, const std::string &_jointName); /// reduced fixed joints: check if a fixed joint should be lumped /// checking both the joint type and if disabledFixedJointLumping /// option is set bool FixedJointShouldBeReduced(urdf::JointSharedPtr _jnt); /// reduced fixed joints: apply transform reduction for ray sensors /// in extensions when doing fixed joint reduction void ReduceSDFExtensionSensorTransformReduction( std::vector::iterator _blobIt, ignition::math::Pose3d _reductionTransform); /// reduced fixed joints: apply transform reduction for projectors in /// extensions when doing fixed joint reduction void ReduceSDFExtensionProjectorTransformReduction( std::vector::iterator _blobIt, ignition::math::Pose3d _reductionTransform); /// reduced fixed joints: apply transform reduction to extensions /// when doing fixed joint reduction void ReduceSDFExtensionsTransform(SDFExtensionPtr _ge); /// reduce fixed joints: lump joints to parent link void ReduceJointsToParent(urdf::LinkSharedPtr _link); /// reduce fixed joints: lump collisions to parent link void ReduceCollisionsToParent(urdf::LinkSharedPtr _link); /// reduce fixed joints: lump visuals to parent link void ReduceVisualsToParent(urdf::LinkSharedPtr _link); /// reduce fixed joints: lump inertial to parent link void ReduceInertialToParent(urdf::LinkSharedPtr /*_link*/); /// create SDF Collision block based on URDF void CreateCollision(TiXmlElement* _elem, urdf::LinkConstSharedPtr _link, urdf::CollisionSharedPtr _collision, const std::string &_oldLinkName = std::string("")); /// create SDF Visual block based on URDF void CreateVisual(TiXmlElement *_elem, urdf::LinkConstSharedPtr _link, urdf::VisualSharedPtr _visual, const std::string &_oldLinkName = std::string("")); /// create SDF Joint block based on URDF void CreateJoint(TiXmlElement *_root, urdf::LinkConstSharedPtr _link, ignition::math::Pose3d &_currentTransform); /// insert extensions into links void InsertSDFExtensionLink(TiXmlElement *_elem, const std::string &_linkName); /// create visual blocks from urdf visuals void CreateVisuals(TiXmlElement* _elem, urdf::LinkConstSharedPtr _link); /// create collision blocks from urdf collisions void CreateCollisions(TiXmlElement* _elem, urdf::LinkConstSharedPtr _link); /// create SDF Inertial block based on URDF void CreateInertial(TiXmlElement *_elem, urdf::LinkConstSharedPtr _link); /// append transform (pose) to the end of the xml element void AddTransform(TiXmlElement *_elem, const ignition::math::Pose3d &_transform); /// create SDF from URDF link void CreateSDF(TiXmlElement *_root, urdf::LinkConstSharedPtr _link, const ignition::math::Pose3d &_transform); /// create SDF Link block based on URDF void CreateLink(TiXmlElement *_root, urdf::LinkConstSharedPtr _link, ignition::math::Pose3d &_currentTransform); /// reduced fixed joints: apply appropriate frame updates in joint /// inside urdf extensions when doing fixed joint reduction void ReduceSDFExtensionJointFrameReplace( std::vector::iterator _blobIt, urdf::LinkSharedPtr _link); /// reduced fixed joints: apply appropriate frame updates in gripper /// inside urdf extensions when doing fixed joint reduction void ReduceSDFExtensionGripperFrameReplace( std::vector::iterator _blobIt, urdf::LinkSharedPtr _link); /// reduced fixed joints: apply appropriate frame updates in projector /// inside urdf extensions when doing fixed joint reduction void ReduceSDFExtensionProjectorFrameReplace( std::vector::iterator _blobIt, urdf::LinkSharedPtr _link); /// reduced fixed joints: apply appropriate frame updates in plugins /// inside urdf extensions when doing fixed joint reduction void ReduceSDFExtensionPluginFrameReplace( std::vector::iterator _blobIt, urdf::LinkSharedPtr _link, const std::string &_pluginName, const std::string &_elementName, ignition::math::Pose3d _reductionTransform); /// reduced fixed joints: apply appropriate frame updates in urdf /// extensions when doing fixed joint reduction void ReduceSDFExtensionContactSensorFrameReplace( std::vector::iterator _blobIt, urdf::LinkSharedPtr _link); /// \brief reduced fixed joints: apply appropriate updates to urdf /// extensions when doing fixed joint reduction /// /// Take the link's existing list of gazebo extensions, transfer them /// into parent link. Along the way, update local transforms by adding /// the additional transform to parent. Also, look through all /// referenced link names with plugins and update references to current /// link to the parent link. (ReduceSDFExtensionFrameReplace()) /// /// \param[in] _link pointer to urdf link, its extensions will be reduced void ReduceSDFExtensionToParent(urdf::LinkSharedPtr _link); /// reduced fixed joints: apply appropriate frame updates /// in urdf extensions when doing fixed joint reduction void ReduceSDFExtensionFrameReplace(SDFExtensionPtr _ge, urdf::LinkSharedPtr _link); /// get value from pair and return it as string std::string GetKeyValueAsString(TiXmlElement* _elem); /// \brief append key value pair to the end of the xml element /// \param[in] _elem pointer to xml element /// \param[in] _key string containing key to add to xml element /// \param[in] _value string containing value for the key added void AddKeyValue(TiXmlElement *_elem, const std::string &_key, const std::string &_value); /// \brief convert values to string /// \param[in] _count number of values in _values array /// \param[in] _values array of double values /// \return a string std::string Values2str(unsigned int _count, const double *_values); void CreateGeometry(TiXmlElement* _elem, urdf::GeometrySharedPtr _geometry); ignition::math::Pose3d inverseTransformToParentFrame( ignition::math::Pose3d _transformInLinkFrame, urdf::Pose _parentToLinkTransform); /// reduced fixed joints: transform to parent frame urdf::Pose TransformToParentFrame(urdf::Pose _transformInLinkFrame, urdf::Pose _parentToLinkTransform); /// reduced fixed joints: transform to parent frame ignition::math::Pose3d TransformToParentFrame( ignition::math::Pose3d _transformInLinkFrame, urdf::Pose _parentToLinkTransform); /// reduced fixed joints: transform to parent frame ignition::math::Pose3d TransformToParentFrame( ignition::math::Pose3d _transformInLinkFrame, ignition::math::Pose3d _parentToLinkTransform); /// reduced fixed joints: utility to copy between urdf::Pose and /// math::Pose ignition::math::Pose3d CopyPose(urdf::Pose _pose); /// reduced fixed joints: utility to copy between urdf::Pose and /// math::Pose urdf::Pose CopyPose(ignition::math::Pose3d _pose); bool URDF2SDF::IsURDF(const std::string &_filename) { TiXmlDocument xmlDoc; if (xmlDoc.LoadFile(_filename)) { std::ostringstream stream; stream << xmlDoc; std::string urdfStr = stream.str(); urdf::ModelInterfaceSharedPtr robotModel = urdf::parseURDF(urdfStr); return robotModel != nullptr; } return false; } ///////////////////////////////////////////////// urdf::Vector3 ParseVector3(const std::string &_str, double _scale) { std::vector pieces = sdf::split(_str, " "); std::vector vals; for (unsigned int i = 0; i < pieces.size(); ++i) { if (pieces[i] != "") { try { vals.push_back(_scale * std::stod(pieces[i])); } catch(std::invalid_argument &) { sdferr << "xml key [" << _str << "][" << i << "] value [" << pieces[i] << "] is not a valid double from a 3-tuple\n"; return urdf::Vector3(0, 0, 0); } } } if (vals.size() == 3) { return urdf::Vector3(vals[0], vals[1], vals[2]); } else { return urdf::Vector3(0, 0, 0); } } ///////////////////////////////////////////////// urdf::Vector3 ParseVector3(TiXmlNode *_key, double _scale) { if (_key != nullptr) { TiXmlElement *key = _key->ToElement(); if (key != nullptr) { return ParseVector3(GetKeyValueAsString(key), _scale); } sdferr << "key[" << _key->Value() << "] does not contain a Vector3\n"; } else { sdferr << "Pointer to XML node _key is nullptr\n"; } return urdf::Vector3(0, 0, 0); } ///////////////////////////////////////////////// /// \brief convert Vector3 to string /// \param[in] _vector a urdf::Vector3 /// \return a string std::string Vector32Str(const urdf::Vector3 _vector) { std::stringstream ss; ss << _vector.x; ss << " "; ss << _vector.y; ss << " "; ss << _vector.z; return ss.str(); } //////////////////////////////////////////////////////////////////////////////// /// \brief Check and add collision to parent link /// \param[in] _parentLink destination for _collision /// \param[in] _name urdfdom 0.3+: urdf collision group name with lumped /// collision info (see ReduceCollisionsToParent). /// urdfdom 0.2: collision name with lumped /// collision info (see ReduceCollisionsToParent). /// \param[in] _collision move this collision to _parentLink void ReduceCollisionToParent(urdf::LinkSharedPtr _parentLink, const std::string &_name, urdf::CollisionSharedPtr _collision) { // added a check to see if _collision already exist in // _parentLink::collision_array if not, add it. _collision->name = _name; std::vector::iterator collisionIt = find(_parentLink->collision_array.begin(), _parentLink->collision_array.end(), _collision); if (collisionIt != _parentLink->collision_array.end()) { sdfwarn << "attempted to add collision [" << _collision->name << "] to link [" << _parentLink->name << "], but it already exists in collision_array under name [" << (*collisionIt)->name << "]\n"; } else { _parentLink->collision_array.push_back(_collision); } } //////////////////////////////////////////////////////////////////////////////// /// \brief Check and add visual to parent link /// \param[in] _parentLink destination for _visual /// \param[in] _name urdfdom 0.3+: urdf visual group name with lumped /// visual info (see ReduceVisualsToParent). /// urdfdom 0.2: visual name with lumped /// visual info (see ReduceVisualsToParent). /// \param[in] _visual move this visual to _parentLink void ReduceVisualToParent(urdf::LinkSharedPtr _parentLink, const std::string &_name, urdf::VisualSharedPtr _visual) { // added a check to see if _visual already exist in // _parentLink::visual_array if not, add it. _visual->name = _name; std::vector::iterator visualIt = find(_parentLink->visual_array.begin(), _parentLink->visual_array.end(), _visual); if (visualIt != _parentLink->visual_array.end()) { sdfwarn << "attempted to add visual [" << _visual->name << "] to link [" << _parentLink->name << "], but it already exists in visual_array under name [" << (*visualIt)->name << "]\n"; } else { _parentLink->visual_array.push_back(_visual); } } //////////////////////////////////////////////////////////////////////////////// /// reduce fixed joints by lumping inertial, visual and // collision elements of the child link into the parent link void ReduceFixedJoints(TiXmlElement *_root, urdf::LinkSharedPtr _link) { // if child is attached to self by fixed _link first go up the tree, // check it's children recursively for (unsigned int i = 0 ; i < _link->child_links.size() ; ++i) { if (FixedJointShouldBeReduced(_link->child_links[i]->parent_joint)) { ReduceFixedJoints(_root, _link->child_links[i]); } } // reduce this _link's stuff up the tree to parent but skip first joint // if it's the world if (_link->getParent() && _link->getParent()->name != "world" && _link->parent_joint && FixedJointShouldBeReduced(_link->parent_joint) ) { sdfdbg << "Fixed Joint Reduction: extension lumping from [" << _link->name << "] to [" << _link->getParent()->name << "]\n"; // lump sdf extensions to parent, (give them new reference _link names) ReduceSDFExtensionToParent(_link); // reduce _link elements to parent ReduceInertialToParent(_link); ReduceVisualsToParent(_link); ReduceCollisionsToParent(_link); ReduceJointsToParent(_link); } // continue down the tree for non-fixed joints for (unsigned int i = 0 ; i < _link->child_links.size() ; ++i) { if (!FixedJointShouldBeReduced(_link->child_links[i]->parent_joint)) { ReduceFixedJoints(_root, _link->child_links[i]); } } } // ODE dMatrix typedef double dMatrix3[4*3]; typedef double dVector3[4]; #define _R(i,j) R[(i)*4+(j)] #define _I(i,j) I[(i)*4+(j)] #define dRecip(x) ((1.0f/(x))) struct dMass; void dMassSetZero(dMass *m); void dMassSetParameters(dMass *m, double themass, double cgx, double cgy, double cgz, double I11, double I22, double I33, double I12, double I13, double I23); struct dMass { double mass; dVector3 c; dMatrix3 I; dMass() { dMassSetZero(this); } void setZero() { dMassSetZero(this); } void setParameters(double themass, double cgx, double cgy, double cgz, double I11, double I22, double I33, double I12, double I13, double I23) { dMassSetParameters(this, themass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23); } }; void dSetZero(double *a, int n) { // dAASSERT (a && n >= 0); double *acurr = a; int ncurr = n; while (ncurr > 0) { *(acurr++) = 0; --ncurr; } } void dMassSetZero(dMass *m) { // dAASSERT (m); m->mass = 0.0; dSetZero(m->c, sizeof(m->c) / sizeof(double)); dSetZero(m->I, sizeof(m->I) / sizeof(double)); } void dMassSetParameters(dMass *m, double themass, double cgx, double cgy, double cgz, double I11, double I22, double I33, double I12, double I13, double I23) { // dAASSERT (m); dMassSetZero(m); m->mass = themass; m->c[0] = cgx; m->c[1] = cgy; m->c[2] = cgz; m->_I(0,0) = I11; m->_I(1,1) = I22; m->_I(2,2) = I33; m->_I(0,1) = I12; m->_I(0,2) = I13; m->_I(1,2) = I23; m->_I(1,0) = I12; m->_I(2,0) = I13; m->_I(2,1) = I23; // dMassCheck (m); } void dRFromEulerAngles(dMatrix3 R, double phi, double theta, double psi) { double sphi,cphi,stheta,ctheta,spsi,cpsi; // dAASSERT (R); sphi = sin(phi); cphi = cos(phi); stheta = sin(theta); ctheta = cos(theta); spsi = sin(psi); cpsi = cos(psi); _R(0,0) = cpsi*ctheta; _R(0,1) = spsi*ctheta; _R(0,2) =-stheta; _R(0,3) = 0.0; _R(1,0) = cpsi*stheta*sphi - spsi*cphi; _R(1,1) = spsi*stheta*sphi + cpsi*cphi; _R(1,2) = ctheta*sphi; _R(1,3) = 0.0; _R(2,0) = cpsi*stheta*cphi + spsi*sphi; _R(2,1) = spsi*stheta*cphi - cpsi*sphi; _R(2,2) = ctheta*cphi; _R(2,3) = 0.0; } double _dCalcVectorDot3(const double *a, const double *b, unsigned step_a, unsigned step_b) { return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b]; } double dCalcVectorDot3(const double *a, const double *b) { return _dCalcVectorDot3(a, b, 1, 1); } double dCalcVectorDot3_41(const double *a, const double *b) { return _dCalcVectorDot3(a, b, 4, 1); } void dMultiply0_331(double *res, const double *a, const double *b) { double res_0, res_1, res_2; res_0 = dCalcVectorDot3(a, b); res_1 = dCalcVectorDot3(a + 4, b); res_2 = dCalcVectorDot3(a + 8, b); res[0] = res_0; res[1] = res_1; res[2] = res_2; } void dMultiply1_331(double *res, const double *a, const double *b) { double res_0, res_1, res_2; res_0 = dCalcVectorDot3_41(a, b); res_1 = dCalcVectorDot3_41(a + 1, b); res_2 = dCalcVectorDot3_41(a + 2, b); res[0] = res_0; res[1] = res_1; res[2] = res_2; } void dMultiply0_133(double *res, const double *a, const double *b) { dMultiply1_331(res, b, a); } void dMultiply0_333(double *res, const double *a, const double *b) { dMultiply0_133(res + 0, a + 0, b); dMultiply0_133(res + 4, a + 4, b); dMultiply0_133(res + 8, a + 8, b); } void dMultiply2_333(double *res, const double *a, const double *b) { dMultiply0_331(res + 0, b, a + 0); dMultiply0_331(res + 4, b, a + 4); dMultiply0_331(res + 8, b, a + 8); } void dMassRotate(dMass *m, const dMatrix3 R) { // if the body is rotated by `R' relative to its point of reference, // the new inertia about the point of reference is: // // R * I * R' // // where I is the old inertia. dMatrix3 t1; double t2[3]; // dAASSERT (m); // rotate inertia matrix dMultiply2_333(t1, m->I, R); dMultiply0_333(m->I, R, t1); // ensure perfect symmetry m->_I(1,0) = m->_I(0,1); m->_I(2,0) = m->_I(0,2); m->_I(2,1) = m->_I(1,2); // rotate center of mass dMultiply0_331(t2, R, m->c); m->c[0] = t2[0]; m->c[1] = t2[1]; m->c[2] = t2[2]; } void dSetCrossMatrixPlus(double *res, const double *a, unsigned skip) { const double a_0 = a[0], a_1 = a[1], a_2 = a[2]; res[1] = -a_2; res[2] = +a_1; res[skip+0] = +a_2; res[skip+2] = -a_0; res[2*skip+0] = -a_1; res[2*skip+1] = +a_0; } void dMassTranslate(dMass *m, double x, double y, double z) { // if the body is translated by `a' relative to its point of reference, // the new inertia about the point of reference is: // // I + mass*(crossmat(c)^2 - crossmat(c+a)^2) // // where c is the existing center of mass and I is the old inertia. int i,j; dMatrix3 ahat,chat,t1,t2; double a[3]; // dAASSERT (m); // adjust inertia matrix dSetZero(chat, 12); dSetCrossMatrixPlus(chat, m->c, 4); a[0] = x + m->c[0]; a[1] = y + m->c[1]; a[2] = z + m->c[2]; dSetZero(ahat, 12); dSetCrossMatrixPlus(ahat, a, 4); dMultiply0_333(t1, ahat, ahat); dMultiply0_333(t2, chat, chat); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]); } } // ensure perfect symmetry m->_I(1,0) = m->_I(0, 1); m->_I(2,0) = m->_I(0, 2); m->_I(2,1) = m->_I(1, 2); // adjust center of mass m->c[0] += x; m->c[1] += y; m->c[2] += z; } void dMassAdd(dMass *a, const dMass *b) { int i; double denom = dRecip(a->mass + b->mass); for (i = 0; i < 3; i++) { a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom; } a->mass += b->mass; for (i = 0; i < 12; i++) { a->I[i] += b->I[i]; } } ///////////////////////////////////////////////// /// print mass for link for debugging void PrintMass(const std::string &_linkName, const dMass &_mass) { sdfdbg << "LINK NAME: [" << _linkName << "] from dMass\n"; sdfdbg << " MASS: [" << _mass.mass << "]\n"; sdfdbg << " CG: [" << _mass.c[0] << ", " << _mass.c[1] << ", " << _mass.c[2] << "]\n"; sdfdbg << " I: [" << _mass.I[0] << ", " << _mass.I[1] << ", " << _mass.I[2] << "]\n"; sdfdbg << " [" << _mass.I[4] << ", " << _mass.I[5] << ", " << _mass.I[6] << "]\n"; sdfdbg << " [" << _mass.I[8] << ", " << _mass.I[9] << ", " << _mass.I[10] << "]\n"; } ///////////////////////////////////////////////// /// print mass for link for debugging void PrintMass(const urdf::LinkSharedPtr _link) { sdfdbg << "LINK NAME: [" << _link->name << "] from dMass\n"; sdfdbg << " MASS: [" << _link->inertial->mass << "]\n"; sdfdbg << " CG: [" << _link->inertial->origin.position.x << ", " << _link->inertial->origin.position.y << ", " << _link->inertial->origin.position.z << "]\n"; sdfdbg << " I: [" << _link->inertial->ixx << ", " << _link->inertial->ixy << ", " << _link->inertial->ixz << "]\n"; sdfdbg << " [" << _link->inertial->ixy << ", " << _link->inertial->iyy << ", " << _link->inertial->iyz << "]\n"; sdfdbg << " [" << _link->inertial->ixz << ", " << _link->inertial->iyz << ", " << _link->inertial->izz << "]\n"; } ///////////////////////////////////////////////// /// reduce fixed joints: lump inertial to parent link void ReduceInertialToParent(urdf::LinkSharedPtr _link) { // now lump all contents of this _link to parent if (_link->inertial) { dMatrix3 R; double phi, theta, psi; // get parent mass (in parent link cg frame) dMass parentMass; if (!_link->getParent()->inertial) { _link->getParent()->inertial.reset(new urdf::Inertial); } dMassSetParameters(&parentMass, _link->getParent()->inertial->mass, 0, 0, 0, _link->getParent()->inertial->ixx, _link->getParent()->inertial->iyy, _link->getParent()->inertial->izz, _link->getParent()->inertial->ixy, _link->getParent()->inertial->ixz, _link->getParent()->inertial->iyz); // transform parent inertia to parent link origin _link->getParent()->inertial->origin.rotation.getRPY(phi, theta, psi); dRFromEulerAngles(R, -phi, 0, 0); dMassRotate(&parentMass, R); dRFromEulerAngles(R, 0, -theta, 0); dMassRotate(&parentMass, R); dRFromEulerAngles(R, 0, 0, -psi); dMassRotate(&parentMass, R); // un-translate link mass from cg(inertial frame) into link frame dMassTranslate(&parentMass, _link->getParent()->inertial->origin.position.x, _link->getParent()->inertial->origin.position.y, _link->getParent()->inertial->origin.position.z); PrintMass("parent: " + _link->getParent()->name, parentMass); // PrintMass(_link->getParent()); ////////////////////////////////////////////// // // // create a_link mass (in _link's cg frame) // // // ////////////////////////////////////////////// dMass linkMass; dMassSetParameters(&linkMass, _link->inertial->mass, 0, 0, 0, _link->inertial->ixx, _link->inertial->iyy, _link->inertial->izz, _link->inertial->ixy, _link->inertial->ixz, _link->inertial->iyz); PrintMass("link : " + _link->name, linkMass); //////////////////////////////////////////// // // // from cg (inertial frame) to link frame // // // //////////////////////////////////////////// // Un-rotate _link mass from cg(inertial frame) into link frame _link->inertial->origin.rotation.getRPY(phi, theta, psi); dRFromEulerAngles(R, -phi, 0, 0); dMassRotate(&linkMass, R); dRFromEulerAngles(R, 0, -theta, 0); dMassRotate(&linkMass, R); dRFromEulerAngles(R, 0, 0, -psi); dMassRotate(&linkMass, R); // un-translate link mass from cg(inertial frame) into link frame dMassTranslate(&linkMass, _link->inertial->origin.position.x, _link->inertial->origin.position.y, _link->inertial->origin.position.z); //////////////////////////////////////////// // // // from link frame to parent link frame // // // //////////////////////////////////////////// // un-rotate _link mass into parent link frame _link->parent_joint->parent_to_joint_origin_transform.rotation.getRPY( phi, theta, psi); dRFromEulerAngles(R, -phi, 0, 0); dMassRotate(&linkMass, R); dRFromEulerAngles(R, 0, -theta, 0); dMassRotate(&linkMass, R); dRFromEulerAngles(R, 0, 0, -psi); dMassRotate(&linkMass, R); // un-translate _link mass into parent link frame dMassTranslate(&linkMass, _link->parent_joint->parent_to_joint_origin_transform.position.x, _link->parent_joint->parent_to_joint_origin_transform.position.y, _link->parent_joint->parent_to_joint_origin_transform.position.z); PrintMass("link in parent link: " + _link->name, linkMass); // // now linkMass is in the parent frame, add linkMass to parentMass // new parentMass should be combined inertia, // centered at parent link inertial frame. // dMassAdd(&parentMass, &linkMass); PrintMass("combined: " + _link->getParent()->name, parentMass); // // Set new combined inertia in parent link frame into parent link urdf // // save combined mass _link->getParent()->inertial->mass = parentMass.mass; // save CoG location _link->getParent()->inertial->origin.position.x = parentMass.c[0]; _link->getParent()->inertial->origin.position.y = parentMass.c[1]; _link->getParent()->inertial->origin.position.z = parentMass.c[2]; // get MOI at new CoG location dMassTranslate(&parentMass, -_link->getParent()->inertial->origin.position.x, -_link->getParent()->inertial->origin.position.y, -_link->getParent()->inertial->origin.position.z); // rotate MOI at new CoG location _link->getParent()->inertial->origin.rotation.getRPY(phi, theta, psi); dRFromEulerAngles(R, phi, theta, psi); dMassRotate(&parentMass, R); // save new combined MOI _link->getParent()->inertial->ixx = parentMass.I[0+4*0]; _link->getParent()->inertial->iyy = parentMass.I[1+4*1]; _link->getParent()->inertial->izz = parentMass.I[2+4*2]; _link->getParent()->inertial->ixy = parentMass.I[0+4*1]; _link->getParent()->inertial->ixz = parentMass.I[0+4*2]; _link->getParent()->inertial->iyz = parentMass.I[1+4*2]; // final urdf inertia check PrintMass(_link->getParent()); } } ///////////////////////////////////////////////// /// \brief reduce fixed joints: lump visuals to parent link /// \param[in] _link take all visuals from _link and lump/move them /// to the parent link (_link->getParentLink()). void ReduceVisualsToParent(urdf::LinkSharedPtr _link) { // lump all visuals of _link to _link->getParent(). // modify visual name (urdf 0.3.x) or // visual group name (urdf 0.2.x) // to indicate that it was lumped (fixed joint reduced) // from another descendant link connected by a fixed joint. // // Algorithm for generating new name (or group name) is: // original name + g_lumpPrefix+original link name (urdf 0.3.x) // original group name + g_lumpPrefix+original link name (urdf 0.2.x) // The purpose is to track where this visual came from // (original parent link name before lumping/reducing). for (std::vector::iterator visualIt = _link->visual_array.begin(); visualIt != _link->visual_array.end(); ++visualIt) { // 20151116: changelog for pull request #235 std::string newVisualName; std::size_t lumpIndex = (*visualIt)->name.find(g_lumpPrefix); if (lumpIndex != std::string::npos) { newVisualName = (*visualIt)->name; sdfdbg << "re-lumping visual [" << (*visualIt)->name << "] for link [" << _link->name << "] to parent [" << _link->getParent()->name << "] with name [" << newVisualName << "]\n"; } else { if ((*visualIt)->name.empty()) { newVisualName = _link->name; } else { newVisualName = (*visualIt)->name; } sdfdbg << "lumping visual [" << (*visualIt)->name << "] for link [" << _link->name << "] to parent [" << _link->getParent()->name << "] with name [" << newVisualName << "]\n"; } // transform visual origin from _link frame to // parent link frame before adding to parent (*visualIt)->origin = TransformToParentFrame( (*visualIt)->origin, _link->parent_joint->parent_to_joint_origin_transform); // add the modified visual to parent ReduceVisualToParent(_link->getParent(), newVisualName, *visualIt); } } ///////////////////////////////////////////////// /// \brief reduce fixed joints: lump collisions to parent link /// \param[in] _link take all collisions from _link and lump/move them /// to the parent link (_link->getParentLink()). void ReduceCollisionsToParent(urdf::LinkSharedPtr _link) { // lump all collisions of _link to _link->getParent(). // modify collision name (urdf 0.3.x) or // collision group name (urdf 0.2.x) // to indicate that it was lumped (fixed joint reduced) // from another descendant link connected by a fixed joint. // // Algorithm for generating new name (or group name) is: // original name + g_lumpPrefix+original link name (urdf 0.3.x) // original group name + g_lumpPrefix+original link name (urdf 0.2.x) // The purpose is to track where this collision came from // (original parent link name before lumping/reducing). for (std::vector::iterator collisionIt = _link->collision_array.begin(); collisionIt != _link->collision_array.end(); ++collisionIt) { std::string newCollisionName; std::size_t lumpIndex = (*collisionIt)->name.find(g_lumpPrefix); if (lumpIndex != std::string::npos) { newCollisionName = (*collisionIt)->name; sdfdbg << "re-lumping collision [" << (*collisionIt)->name << "] for link [" << _link->name << "] to parent [" << _link->getParent()->name << "] with name [" << newCollisionName << "]\n"; } else { if ((*collisionIt)->name.empty()) { newCollisionName = _link->name; } else { newCollisionName = (*collisionIt)->name; } sdfdbg << "lumping collision [" << (*collisionIt)->name << "] for link [" << _link->name << "] to parent [" << _link->getParent()->name << "] with name [" << newCollisionName << "]\n"; } // transform collision origin from _link frame to // parent link frame before adding to parent (*collisionIt)->origin = TransformToParentFrame( (*collisionIt)->origin, _link->parent_joint->parent_to_joint_origin_transform); // add the modified collision to parent ReduceCollisionToParent(_link->getParent(), newCollisionName, *collisionIt); } } ///////////////////////////////////////////////// /// reduce fixed joints: lump joints to parent link void ReduceJointsToParent(urdf::LinkSharedPtr _link) { // set child link's parentJoint's parent link to // a parent link up stream that does not have a fixed parentJoint for (unsigned int i = 0 ; i < _link->child_links.size() ; ++i) { urdf::JointSharedPtr parentJoint = _link->child_links[i]->parent_joint; if (!FixedJointShouldBeReduced(parentJoint)) { // go down the tree until we hit a parent joint that is not fixed urdf::LinkSharedPtr newParentLink = _link; ignition::math::Pose3d jointAnchorTransform; while (newParentLink->parent_joint && newParentLink->getParent()->name != "world" && FixedJointShouldBeReduced(newParentLink->parent_joint) ) { jointAnchorTransform = jointAnchorTransform * jointAnchorTransform; parentJoint->parent_to_joint_origin_transform = TransformToParentFrame( parentJoint->parent_to_joint_origin_transform, newParentLink->parent_joint->parent_to_joint_origin_transform); newParentLink = newParentLink->getParent(); } // now set the _link->child_links[i]->parent_joint's parent link to // the newParentLink _link->child_links[i]->setParent(newParentLink); parentJoint->parent_link_name = newParentLink->name; // and set the _link->child_links[i]->parent_joint's // parent_to_joint_origin_transform as the aggregated anchor transform? } } } //////////////////////////////////////////////////////////////////////////////// std::string lowerStr(const std::string &_str) { std::string out = _str; std::transform(out.begin(), out.end(), out.begin(), ::tolower); return out; } //////////////////////////////////////////////////////////////////////////////// URDF2SDF::URDF2SDF() { // default options g_enforceLimits = true; g_reduceFixedJoints = true; } //////////////////////////////////////////////////////////////////////////////// URDF2SDF::~URDF2SDF() { } //////////////////////////////////////////////////////////////////////////////// std::string Values2str(unsigned int _count, const double *_values) { std::stringstream ss; for (unsigned int i = 0 ; i < _count ; ++i) { if (i > 0) { ss << " "; } ss << _values[i]; } return ss.str(); } ///////////////////////////////////////////////// std::string Values2str(unsigned int _count, const int *_values) { std::stringstream ss; for (unsigned int i = 0 ; i < _count ; ++i) { if (i > 0) { ss << " "; } ss << _values[i]; } return ss.str(); } //////////////////////////////////////////////////////////////////////////////// void AddKeyValue(TiXmlElement *_elem, const std::string &_key, const std::string &_value) { TiXmlElement* childElem = _elem->FirstChildElement(_key); if (childElem) { std::string oldValue = GetKeyValueAsString(childElem); if (oldValue != _value) { sdfwarn << "multiple inconsistent <" << _key << "> exists due to fixed joint reduction" << " overwriting previous value [" << oldValue << "] with [" << _value << "].\n"; } else { sdfdbg << "multiple consistent <" << _key << "> exists with [" << _value << "] due to fixed joint reduction.\n"; } _elem->RemoveChild(childElem); // remove old _elem } TiXmlElement *ekey = new TiXmlElement(_key); TiXmlText *textEkey = new TiXmlText(_value); ekey->LinkEndChild(textEkey); _elem->LinkEndChild(ekey); } //////////////////////////////////////////////////////////////////////////////// void AddTransform(TiXmlElement *_elem, const ignition::math::Pose3d &_transform) { ignition::math::Vector3d e = _transform.Rot().Euler(); double cpose[6] = { _transform.Pos().X(), _transform.Pos().Y(), _transform.Pos().Z(), e.X(), e.Y(), e.Z() }; // set geometry transform AddKeyValue(_elem, "pose", Values2str(6, cpose)); } //////////////////////////////////////////////////////////////////////////////// std::string GetKeyValueAsString(TiXmlElement* _elem) { std::string valueStr; if (_elem->Attribute("value")) { valueStr = _elem->Attribute("value"); } else if (_elem->FirstChild()) /// @todo: FIXME: comment out check for now, different tinyxml /// versions fails to compile: // && _elem->FirstChild()->Type() == TiXmlNode::TINYXML_TEXT) { valueStr = _elem->FirstChild()->ValueStr(); } return valueStr; } ///////////////////////////////////////////////// void ParseRobotOrigin(TiXmlDocument &_urdfXml) { TiXmlElement *robotXml = _urdfXml.FirstChildElement("robot"); TiXmlElement *originXml = robotXml->FirstChildElement("origin"); if (originXml) { const char *xyzstr = originXml->Attribute("xyz"); if (xyzstr == nullptr) { g_initialRobotPose.position = urdf::Vector3(0, 0, 0); } else { g_initialRobotPose.position = ParseVector3(std::string(xyzstr)); } const char *rpystr = originXml->Attribute("rpy"); urdf::Vector3 rpy; if (rpystr == nullptr) { rpy = urdf::Vector3(0, 0, 0); } else { rpy = ParseVector3(std::string(rpystr)); } g_initialRobotPose.rotation.setFromRPY(rpy.x, rpy.y, rpy.z); g_initialRobotPoseValid = true; } } ///////////////////////////////////////////////// void InsertRobotOrigin(TiXmlElement *_elem) { if (g_initialRobotPoseValid) { // set transform double pose[6]; pose[0] = g_initialRobotPose.position.x; pose[1] = g_initialRobotPose.position.y; pose[2] = g_initialRobotPose.position.z; g_initialRobotPose.rotation.getRPY(pose[3], pose[4], pose[5]); AddKeyValue(_elem, "pose", Values2str(6, pose)); } } //////////////////////////////////////////////////////////////////////////////// void URDF2SDF::ParseSDFExtension(TiXmlDocument &_urdfXml) { TiXmlElement* robotXml = _urdfXml.FirstChildElement("robot"); // Get all SDF extension elements, put everything in // g_extensions map, containing a key string // (link/joint name) and values for (TiXmlElement* sdfXml = robotXml->FirstChildElement("gazebo"); sdfXml; sdfXml = sdfXml->NextSiblingElement("gazebo")) { const char* ref = sdfXml->Attribute("reference"); std::string refStr; if (!ref) { // copy extensions for robot (outside of link/joint) refStr.clear(); } else { // copy extensions for link/joint refStr = std::string(ref); } if (g_extensions.find(refStr) == g_extensions.end()) { // create extension map for reference std::vector ge; g_extensions.insert(std::make_pair(refStr, ge)); } // create and insert a new SDFExtension into the map SDFExtensionPtr sdf(new SDFExtension()); // begin parsing xml node for (TiXmlElement *childElem = sdfXml->FirstChildElement(); childElem; childElem = childElem->NextSiblingElement()) { sdf->oldLinkName = refStr; // go through all elements of the extension, // extract what we know, and save the rest in blobs // @todo: somehow use sdf definitions here instead of hard coded // objects // material if (childElem->ValueStr() == "material") { sdf->material = GetKeyValueAsString(childElem); } else if (childElem->ValueStr() == "collision" || childElem->ValueStr() == "visual") { // anything inside of collision or visual tags: // // // // // // // // // are treated as blobs that gets inserted // into all collisions and visuals for the link // // // // // // // // // a place to store converted doc for (TiXmlElement* e = childElem->FirstChildElement(); e; e = e->NextSiblingElement()) { TiXmlDocument xmlNewDoc; std::ostringstream origStream; origStream << *e; xmlNewDoc.Parse(origStream.str().c_str()); // save all unknown stuff in a vector of blobs TiXmlElementPtr blob( new TiXmlElement(*xmlNewDoc.FirstChildElement())); if (childElem->ValueStr() == "collision") { sdf->collision_blobs.push_back(blob); } else { sdf->visual_blobs.push_back(blob); } } } else if (childElem->ValueStr() == "static") { std::string valueStr = GetKeyValueAsString(childElem); // default of setting static flag is false if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { sdf->setStaticFlag = true; } else { sdf->setStaticFlag = false; } } else if (childElem->ValueStr() == "turnGravityOff") { std::string valueStr = GetKeyValueAsString(childElem); // default of gravity is true if (lowerStr(valueStr) == "false" || lowerStr(valueStr) == "no" || valueStr == "0") { sdf->gravity = true; } else { sdf->gravity = false; } } else if (childElem->ValueStr() == "dampingFactor") { sdf->isDampingFactor = true; sdf->dampingFactor = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "maxVel") { sdf->isMaxVel = true; sdf->maxVel = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "minDepth") { sdf->isMinDepth = true; sdf->minDepth = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "mu1") { sdf->isMu1 = true; sdf->mu1 = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "mu2") { sdf->isMu2 = true; sdf->mu2 = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "fdir1") { sdf->fdir1 = GetKeyValueAsString(childElem); } else if (childElem->ValueStr() == "kp") { sdf->isKp = true; sdf->kp = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "kd") { sdf->isKd = true; sdf->kd = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "selfCollide") { sdf->isSelfCollide = true; std::string valueStr = GetKeyValueAsString(childElem); // default of selfCollide is false if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { sdf->selfCollide = true; } else { sdf->selfCollide = false; } } else if (childElem->ValueStr() == "maxContacts") { sdf->isMaxContacts = true; sdf->maxContacts = std::stoi(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "laserRetro") { sdf->isLaserRetro = true; sdf->laserRetro = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "springReference") { sdf->isSpringReference = true; sdf->springReference = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "springStiffness") { sdf->isSpringStiffness = true; sdf->springStiffness = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "stopCfm") { sdf->isStopCfm = true; sdf->stopCfm = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "stopErp") { sdf->isStopErp = true; sdf->stopErp = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "fudgeFactor") { sdf->isFudgeFactor = true; sdf->fudgeFactor = std::stod(GetKeyValueAsString(childElem)); } else if (childElem->ValueStr() == "provideFeedback") { sdf->isProvideFeedback = true; std::string valueStr = GetKeyValueAsString(childElem); if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { sdf->provideFeedback = true; } else { sdf->provideFeedback = false; } } else if (childElem->ValueStr() == "canonicalBody") { sdfdbg << "do nothing with canonicalBody\n"; } else if (childElem->ValueStr() == "cfmDamping" || childElem->ValueStr() == "implicitSpringDamper") { if (childElem->ValueStr() == "cfmDamping") { sdfwarn << "Note that cfmDamping is being deprecated by " << "implicitSpringDamper, please replace instances " << "of cfmDamping with implicitSpringDamper in your model.\n"; } sdf->isImplicitSpringDamper = true; std::string valueStr = GetKeyValueAsString(childElem); if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { sdf->implicitSpringDamper = true; } else { sdf->implicitSpringDamper = false; } } else if (childElem->ValueStr() == "disableFixedJointLumping") { std::string valueStr = GetKeyValueAsString(childElem); if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { g_fixedJointsTransformedInRevoluteJoints.insert(refStr); } } else if (childElem->ValueStr() == "preserveFixedJoint") { std::string valueStr = GetKeyValueAsString(childElem); if (lowerStr(valueStr) == "true" || lowerStr(valueStr) == "yes" || valueStr == "1") { g_fixedJointsTransformedInFixedJoints.insert(refStr); } } else { // a place to store converted doc TiXmlDocument xmlNewDoc; std::ostringstream stream; stream << *childElem; sdfdbg << "extension [" << stream.str() << "] not converted from URDF, probably already in SDF format.\n"; xmlNewDoc.Parse(stream.str().c_str()); // save all unknown stuff in a vector of blobs TiXmlElementPtr blob(new TiXmlElement(*xmlNewDoc.FirstChildElement())); sdf->blobs.push_back(blob); } } // insert into my map (g_extensions.find(refStr))->second.push_back(sdf); } // Handle fixed joints for which both disableFixedJointLumping // and preserveFixedJoint options are present for (auto& fixedJointConvertedToFixed: g_fixedJointsTransformedInFixedJoints) { // If both options are present, the model creator is aware of the // existence of the preserveFixedJoint option and the // disableFixedJointLumping option is there only for backward compatibility // For this reason, if both options are present then the preserveFixedJoint // option has the precedence g_fixedJointsTransformedInRevoluteJoints.erase(fixedJointConvertedToFixed); } } //////////////////////////////////////////////////////////////////////////////// void InsertSDFExtensionCollision(TiXmlElement *_elem, const std::string &_linkName) { // loop through extensions for the whole model // and see which ones belong to _linkName // This might be complicated since there's: // - urdf collision name -> sdf collision name conversion // - fixed joint reduction / lumping for (StringSDFExtensionPtrMap::iterator sdfIt = g_extensions.begin(); sdfIt != g_extensions.end(); ++sdfIt) { if (sdfIt->first == _linkName) { // std::cerr << "============================\n"; // std::cerr << "working on g_extensions for link [" // << sdfIt->first << "]\n"; // if _elem already has a surface element, use it TiXmlNode *surface = _elem->FirstChild("surface"); TiXmlNode *friction = nullptr; TiXmlNode *frictionOde = nullptr; TiXmlNode *contact = nullptr; TiXmlNode *contactOde = nullptr; // loop through all the gazebo extensions stored in sdfIt->second for (std::vector::iterator ge = sdfIt->second.begin(); ge != sdfIt->second.end(); ++ge) { // Check if this blob belongs to _elem based on // - blob's reference link name (_linkName or sdfIt->first) // - _elem (destination for blob, which is a collision sdf). if (!_elem->Attribute("name")) { sdferr << "ERROR: collision _elem has no name," << " something is wrong" << "\n"; } std::string sdfCollisionName(_elem->Attribute("name")); // std::cerr << "----------------------------\n"; // std::cerr << "blob belongs to [" << _linkName // << "] with old parent LinkName [" << (*ge)->oldLinkName // << "]\n"; // std::cerr << "_elem sdf collision name [" << sdfCollisionName // << "]\n"; // std::cerr << "----------------------------\n"; std::string lumpCollisionName = g_lumpPrefix + (*ge)->oldLinkName + g_collisionExt; bool wasReduced = (_linkName == (*ge)->oldLinkName); bool collisionNameContainsLinkname = sdfCollisionName.find(_linkName) != std::string::npos; bool collisionNameContainsLumpedLinkname = sdfCollisionName.find(lumpCollisionName) != std::string::npos; bool collisionNameContainsLumpedRef = sdfCollisionName.find(g_lumpPrefix) != std::string::npos; if (!collisionNameContainsLinkname) { sdferr << "collision name does not contain link name," << " file an issue.\n"; } // if the collision _elem was not reduced, // its name should not have g_lumpPrefix in it. // otherwise, its name should have // "g_lumpPrefix+[original link name before reduction]". if ((wasReduced && !collisionNameContainsLumpedRef) || (!wasReduced && collisionNameContainsLumpedLinkname)) { // insert any blobs (including visual plugins) // warning, if you insert a sdf here, it might // duplicate what was constructed above. // in the future, we should use blobs (below) in place of // explicitly specified fields (above). if (!(*ge)->collision_blobs.empty()) { std::vector::iterator blob; for (blob = (*ge)->collision_blobs.begin(); blob != (*ge)->collision_blobs.end(); ++blob) { // find elements and assign pointers if they exist // for mu1, mu2, minDepth, maxVel, fdir1, kp, kd // otherwise, they are allocated by 'new' below. // std::cerr << ">>>>> working on extension blob: [" // << (*blob)->Value() << "]\n"; // print for debug std::ostringstream origStream; std::unique_ptr blobClone((*blob)->Clone()); origStream << *blobClone; // std::cerr << "collision extension [" // << origStream.str() << "]\n"; if (strcmp((*blob)->Value(), "surface") == 0) { // blob is a , tread carefully otherwise // we end up with multiple copies of . // Also, get pointers (contact[Ode], friction[Ode]) // below for backwards (non-blob) compatibility. if (surface == nullptr) { // do not exist, it simple, // just add it to the current collision // and it's done. _elem->LinkEndChild((*blob)->Clone()); surface = _elem->LastChild("surface"); // std::cerr << " --- surface created " // << (void*)surface << "\n"; } else { // exist already, remove it and // overwrite with the blob. _elem->RemoveChild(surface); _elem->LinkEndChild((*blob)->Clone()); surface = _elem->FirstChild("surface"); // std::cerr << " --- surface exists, replace with blob.\n"; } // Extra code for backwards compatibility, to // deal with old way of specifying collision attributes // using individual elements listed below: // "mu" // "mu2" // "fdir1" // "kp" // "kd" // "max_vel" // "min_depth" // "laser_retro" // "max_contacts" // Get contact[Ode] and friction[Ode] node pointers // if they exist. contact = surface->FirstChild("contact"); if (contact != nullptr) { contactOde = contact->FirstChild("ode"); } friction = surface->FirstChild("friction"); if (friction != nullptr) { frictionOde = friction->FirstChild("ode"); } } else { // If the blob is not a , we don't have // to worry about backwards compatibility. // Simply add to master element. _elem->LinkEndChild((*blob)->Clone()); } } } // Extra code for backwards compatibility, to // deal with old way of specifying collision attributes // using individual elements listed below: // "mu" // "mu2" // "fdir1" // "kp" // "kd" // "max_vel" // "min_depth" // "laser_retro" // "max_contacts" // The new way to do this is to specify everything // in collision blobs by using the tag. // So there's no need for custom code for each property. // construct new elements if not in blobs if (surface == nullptr) { surface = new TiXmlElement("surface"); if (!surface) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } _elem->LinkEndChild(surface); } // construct new elements if not in blobs if (contact == nullptr) { if (surface->FirstChild("contact") == nullptr) { contact = new TiXmlElement("contact"); if (!contact) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } surface->LinkEndChild(contact); } else { contact = surface->FirstChild("contact"); } } if (contactOde == nullptr) { if (contact->FirstChild("ode") == nullptr) { contactOde = new TiXmlElement("ode"); if (!contactOde) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } contact->LinkEndChild(contactOde); } else { contactOde = contact->FirstChild("ode"); } } if (friction == nullptr) { if (surface->FirstChild("friction") == nullptr) { friction = new TiXmlElement("friction"); if (!friction) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } surface->LinkEndChild(friction); } else { friction = surface->FirstChild("friction"); } } if (frictionOde == nullptr) { if (friction->FirstChild("ode") == nullptr) { frictionOde = new TiXmlElement("ode"); if (!frictionOde) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } friction->LinkEndChild(frictionOde); } else { frictionOde = friction->FirstChild("ode"); } } // insert mu1, mu2, kp, kd for collision if ((*ge)->isMu1) { AddKeyValue(frictionOde->ToElement(), "mu", Values2str(1, &(*ge)->mu1)); } if ((*ge)->isMu2) { AddKeyValue(frictionOde->ToElement(), "mu2", Values2str(1, &(*ge)->mu2)); } if (!(*ge)->fdir1.empty()) { AddKeyValue(frictionOde->ToElement(), "fdir1", (*ge)->fdir1); } if ((*ge)->isKp) { AddKeyValue(contactOde->ToElement(), "kp", Values2str(1, &(*ge)->kp)); } if ((*ge)->isKd) { AddKeyValue(contactOde->ToElement(), "kd", Values2str(1, &(*ge)->kd)); } // max contact interpenetration correction velocity if ((*ge)->isMaxVel) { AddKeyValue(contactOde->ToElement(), "max_vel", Values2str(1, &(*ge)->maxVel)); } // contact interpenetration margin tolerance if ((*ge)->isMinDepth) { AddKeyValue(contactOde->ToElement(), "min_depth", Values2str(1, &(*ge)->minDepth)); } if ((*ge)->isLaserRetro) { AddKeyValue(_elem, "laser_retro", Values2str(1, &(*ge)->laserRetro)); } if ((*ge)->isMaxContacts) { AddKeyValue(_elem, "max_contacts", Values2str(1, &(*ge)->maxContacts)); } } } } } } //////////////////////////////////////////////////////////////////////////////// void InsertSDFExtensionVisual(TiXmlElement *_elem, const std::string &_linkName) { // loop through extensions for the whole model // and see which ones belong to _linkName // This might be complicated since there's: // - urdf visual name -> sdf visual name conversion // - fixed joint reduction / lumping for (StringSDFExtensionPtrMap::iterator sdfIt = g_extensions.begin(); sdfIt != g_extensions.end(); ++sdfIt) { if (sdfIt->first == _linkName) { // std::cerr << "============================\n"; // std::cerr << "working on g_extensions for link [" // << sdfIt->first << "]\n"; // if _elem already has a material element, use it TiXmlNode *material = _elem->FirstChild("material"); TiXmlElement *script = nullptr; // loop through all the gazebo extensions stored in sdfIt->second for (std::vector::iterator ge = sdfIt->second.begin(); ge != sdfIt->second.end(); ++ge) { // Check if this blob belongs to _elem based on // - blob's reference link name (_linkName or sdfIt->first) // - _elem (destination for blob, which is a visual sdf). if (!_elem->Attribute("name")) { sdferr << "ERROR: visual _elem has no name," << " something is wrong" << "\n"; } std::string sdfVisualName(_elem->Attribute("name")); // std::cerr << "----------------------------\n"; // std::cerr << "blob belongs to [" << _linkName // << "] with old parent LinkName [" << (*ge)->oldLinkName // << "]\n"; // std::cerr << "_elem sdf visual name [" << sdfVisualName // << "]\n"; // std::cerr << "----------------------------\n"; std::string lumpVisualName = g_lumpPrefix + (*ge)->oldLinkName + g_visualExt; bool wasReduced = (_linkName == (*ge)->oldLinkName); bool visualNameContainsLinkname = sdfVisualName.find(_linkName) != std::string::npos; bool visualNameContainsLumpedLinkname = sdfVisualName.find(lumpVisualName) != std::string::npos; bool visualNameContainsLumpedRef = sdfVisualName.find(g_lumpPrefix) != std::string::npos; if (!visualNameContainsLinkname) { sdferr << "visual name does not contain link name," << " file an issue.\n"; } // if the visual _elem was not reduced, // its name should not have g_lumpPrefix in it. // otherwise, its name should have // "g_lumpPrefix+[original link name before reduction]". if ((wasReduced && !visualNameContainsLumpedRef) || (!wasReduced && visualNameContainsLumpedLinkname)) { // insert any blobs (including visual plugins) // warning, if you insert a sdf here, it might // duplicate what was constructed above. // in the future, we should use blobs (below) in place of // explicitly specified fields (above). if (!(*ge)->visual_blobs.empty()) { std::vector::iterator blob; for (blob = (*ge)->visual_blobs.begin(); blob != (*ge)->visual_blobs.end(); ++blob) { // find elements and assign pointers if they exist // for mu1, mu2, minDepth, maxVel, fdir1, kp, kd // otherwise, they are allocated by 'new' below. // std::cerr << ">>>>> working on extension blob: [" // << (*blob)->Value() << "]\n"; // print for debug // std::ostringstream origStream; // origStream << *(*blob)->Clone(); // std::cerr << "visual extension [" // << origStream.str() << "]\n"; if (strcmp((*blob)->Value(), "material") == 0) { // blob is a , tread carefully otherwise // we end up with multiple copies of . // Also, get pointers (script) // below for backwards (non-blob) compatibility. if (material == nullptr) { // do not exist, it simple, // just add it to the current visual // and it's done. _elem->LinkEndChild((*blob)->Clone()); material = _elem->LastChild("material"); // std::cerr << " --- material created " // << (void*)material << "\n"; } else { // exist already, remove it and // overwrite with the blob. _elem->RemoveChild(material); _elem->LinkEndChild((*blob)->Clone()); material = _elem->FirstChild("material"); // std::cerr << " --- material exists, replace with blob.\n"; } // Extra code for backwards compatibility, to // deal with old way of specifying visual attributes // using individual element: // "script" // Get script node pointers // if they exist. script = material->FirstChildElement("script"); } else { // std::cerr << "***** working on extension blob: [" // << (*blob)->Value() << "]\n"; // If the blob is not a , we don't have // to worry about backwards compatibility. // Simply add to master element. _elem->LinkEndChild((*blob)->Clone()); } } } // Extra code for backwards compatibility, to // deal with old way of specifying visual attributes // using individual element: // "script" // The new way to do this is to specify everything // in visual blobs by using the tag. // So there's no need for custom code for each property. // construct new elements if not in blobs if (material == nullptr) { material = new TiXmlElement("material"); if (!material) { // Memory allocation error sdferr << "Memory allocation error while" << " processing .\n"; } _elem->LinkEndChild(material); } if (script == nullptr) { if (material->FirstChildElement("script") == nullptr) { script = new TiXmlElement("script"); if (!script) { // Memory allocation error sdferr << "Memory allocation error while" << " processing EXPECT_EQ(urdf_child_link_1_col->Get("max_contacts"), 177); EXPECT_EQ(urdf_child_link_1_col->Get("max_contacts"), sdf_child_link_1_col->Get("max_contacts")); double urdf_mu1 = urdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"); double sdf_mu1 = sdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"); sdfmsg << "urdf mu1: " << urdf_mu1 << "\n"; EXPECT_DOUBLE_EQ(urdf_mu1, 0.7); EXPECT_DOUBLE_EQ(urdf_mu1, sdf_mu1); double urdf_mu2 = urdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"); double sdf_mu2 = sdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"); sdfmsg << "urdf mu2: " << urdf_mu2 << "\n"; EXPECT_DOUBLE_EQ(urdf_mu2, 0.71); EXPECT_DOUBLE_EQ(urdf_mu2, sdf_mu2); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name"), "script_uri_71_name"); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name"), sdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name")); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("uri"), "file://media/materials/scripts/gazebo.material"); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> Get("ambient"), ignition::math::Color(0, 1, 0, 1)); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> Get("ambient"), sdf_child_link_1_vis->GetElement("material")-> Get("ambient")); // child_link_1a // // 166 // 0.6 // 0.61 // // // // EXPECT_EQ(urdf_child_link_1a_col->Get("max_contacts"), 166); EXPECT_EQ(urdf_child_link_1a_col->Get("max_contacts"), sdf_child_link_1a_col->Get("max_contacts")); EXPECT_DOUBLE_EQ(urdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"), 0.6); EXPECT_DOUBLE_EQ(urdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"), sdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu")); EXPECT_DOUBLE_EQ(urdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"), 0.61); EXPECT_DOUBLE_EQ(urdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"), sdf_child_link_1a_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2")); EXPECT_EQ(urdf_child_link_1a_vis->GetElement("material")-> GetElement("script")->Get("name"), "__default__"); EXPECT_EQ(urdf_child_link_1a_vis->GetElement("material")-> GetElement("script")->Get("name"), sdf_child_link_1a_vis->GetElement("material")-> GetElement("script")->Get("name")); EXPECT_EQ(urdf_child_link_1a_vis->GetElement("material")-> GetElement("script")->Get("uri"), "__default__"); // ambient unassigned should be 0, 0, 0, 1 EXPECT_EQ(urdf_child_link_1a_vis->GetElement("material")-> Get("ambient"), ignition::math::Color(0, 0, 0, 1)); EXPECT_EQ(urdf_child_link_1a_vis->GetElement("material")-> Get("ambient"), sdf_child_link_1a_vis->GetElement("material")-> Get("ambient")); // child_link_2 // // 0.5 // 0.51 // // script_uri_51 // script_name_51 // unassigne max_contacts defaut is 10 EXPECT_EQ(urdf_child_link_2_col->Get("max_contacts"), 10); EXPECT_EQ(urdf_child_link_2_col->Get("max_contacts"), sdf_child_link_2_col->Get("max_contacts")); EXPECT_DOUBLE_EQ(urdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"), 0.5); EXPECT_DOUBLE_EQ(urdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"), sdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu")); EXPECT_DOUBLE_EQ(urdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"), 0.51); EXPECT_DOUBLE_EQ(urdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"), sdf_child_link_2_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2")); EXPECT_EQ(urdf_child_link_2_vis->GetElement("material")-> GetElement("script")->Get("name"), "script_name_51"); EXPECT_EQ(urdf_child_link_2_vis->GetElement("material")-> GetElement("script")->Get("name"), sdf_child_link_2_vis->GetElement("material")-> GetElement("script")->Get("name")); EXPECT_EQ(urdf_child_link_2_vis->GetElement("material")-> GetElement("script")->Get("uri"), "script_uri_51"); // ambient unassigned should be 0, 0, 0, 1 EXPECT_EQ(urdf_child_link_2_vis->GetElement("material")-> Get("ambient"), ignition::math::Color(0, 0, 0, 1)); EXPECT_EQ(urdf_child_link_2_vis->GetElement("material")-> Get("ambient"), sdf_child_link_2_vis->GetElement("material")-> Get("ambient")); } ///////////////////////////////////////////////// void FixedJointReductionCollisionVisualExtensionEmptyRoot( const std::string &_urdfFile, const std::string &_sdfFile) { // load urdf file, load sdf file. // check to see that urdf load results are consistent with sdf load. // load urdf sdf::SDFPtr urdfRobot(new sdf::SDF()); sdf::init(urdfRobot); ASSERT_TRUE(sdf::readFile(_urdfFile, urdfRobot)); // load sdf sdf::SDFPtr sdfRobot(new sdf::SDF()); sdf::init(sdfRobot); ASSERT_TRUE(sdf::readFile(_sdfFile, sdfRobot)); // check two loaded files, make sure they are the same sdf::ElementPtr urdfModel = urdfRobot->Root()->GetElement("model"); sdf::ElementPtr urdf_child_link_1_col; sdf::ElementPtr urdf_child_link_1_vis; for (sdf::ElementPtr link = urdfModel->GetElement("link"); link; link = link->GetNextElement("link")) { for (sdf::ElementPtr col = link->GetElement("collision"); col; col = col->GetNextElement("collision")) { std::string colName = col->Get("name"); // note that if there is only one child visual, no _1 is appended // compare this with FixedJointReductionCollisionVisualExtension test if (colName == "base_link_fixed_joint_lump__child_link_1_collision") { urdf_child_link_1_col = col; } sdfmsg << "col: " << colName << "\n"; } for (sdf::ElementPtr vis = link->GetElement("visual"); vis; vis = vis->GetNextElement("visual")) { std::string visName = vis->Get("name"); // note that if there is only one child visual, no _1 is appended // compare this with FixedJointReductionCollisionVisualExtension test if (visName == "base_link_fixed_joint_lump__child_link_1_visual") { urdf_child_link_1_vis = vis; } sdfmsg << "vis: " << visName << "\n"; } } sdf::ElementPtr sdfModel = sdfRobot->Root()->GetElement("model"); sdf::ElementPtr sdf_child_link_1_col; sdf::ElementPtr sdf_child_link_1_vis; for (sdf::ElementPtr link = sdfModel->GetElement("link"); link; link = link->GetNextElement("link")) { for (sdf::ElementPtr col = link->GetElement("collision"); col; col = col->GetNextElement("collision")) { std::string colName = col->Get("name"); // note that if there is only one child visual, no _1 is appended // compare this with FixedJointReductionCollisionVisualExtension test if (colName == "base_link_fixed_joint_lump__child_link_1_collision") { sdf_child_link_1_col = col; } sdfmsg << "col: " << colName << "\n"; } for (sdf::ElementPtr vis = link->GetElement("visual"); vis; vis = vis->GetNextElement("visual")) { std::string visName = vis->Get("name"); // note that if there is only one child visual, no _1 is appended // compare this with FixedJointReductionCollisionVisualExtension test if (visName == "base_link_fixed_joint_lump__child_link_1_visual") { sdf_child_link_1_vis = vis; } sdfmsg << "vis: " << visName << "\n"; } } // child_link_1 // // 0.007 // 0.7 // 0.71 // // 0 1 0 1 // EXPECT_EQ(urdf_child_link_1_col->Get("max_contacts"), 177); EXPECT_EQ(urdf_child_link_1_col->Get("max_contacts"), sdf_child_link_1_col->Get("max_contacts")); double urdf_mu1 = urdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"); double sdf_mu1 = sdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu"); sdfmsg << "urdf mu1: " << urdf_mu1 << "\n"; EXPECT_DOUBLE_EQ(urdf_mu1, 0.7); EXPECT_DOUBLE_EQ(urdf_mu1, sdf_mu1); double urdf_mu2 = urdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"); double sdf_mu2 = sdf_child_link_1_col->GetElement("surface") ->GetElement("friction")->GetElement("ode")->Get("mu2"); sdfmsg << "urdf mu2: " << urdf_mu2 << "\n"; EXPECT_DOUBLE_EQ(urdf_mu2, 0.71); EXPECT_DOUBLE_EQ(urdf_mu2, sdf_mu2); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name"), "script_uri_71_name"); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name"), sdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("name")); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> GetElement("script")->Get("uri"), "file://media/materials/scripts/gazebo.material"); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> Get("ambient"), ignition::math::Color(0, 1, 0, 1)); EXPECT_EQ(urdf_child_link_1_vis->GetElement("material")-> Get("ambient"), sdf_child_link_1_vis->GetElement("material")-> Get("ambient")); } ///////////////////////////////////////////////// void FixedJointReductionEquivalence(const std::string &_file) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(_file, robot)); std::map linkMasses; std::map linkPoses; std::map mapIxxIyyIzz; std::map mapIxyIxzIyz; { std::string linkName = "link0"; linkMasses[linkName] = 1000; linkPoses[linkName] = ignition::math::Pose3d(0, 0, -0.5, 0, -0, 0); mapIxxIyyIzz[linkName] = ignition::math::Vector3d(1, 1, 1); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(0, 0, 0); } { std::string linkName = "link1"; linkMasses[linkName] = 100; linkPoses[linkName] = ignition::math::Pose3d(0, -1.5, 0, -2.14159, 0.141593, 0.858407); mapIxxIyyIzz[linkName] = ignition::math::Vector3d(2, 3, 4); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(0, 0, 0); } { std::string linkName = "link2"; linkMasses[linkName] = 200; linkPoses[linkName] = ignition::math::Pose3d(0.2, 0.4, 1, -1.14159, -0.141593, 1.5708); mapIxxIyyIzz[linkName] = ignition::math::Vector3d(5, 6, 7); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(0, 0, 0); } { std::string linkName = "link3"; linkMasses[linkName] = 400; linkPoses[linkName] = ignition::math::Pose3d(0.1, 0.2, 0.3, -1.14159, 0.141593, 0.858407); mapIxxIyyIzz[linkName] = ignition::math::Vector3d(8, 9, 10); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(0, 0, 0); } { std::string linkName = "link1a"; linkMasses[linkName] = 700; linkPoses[linkName] = ignition::math::Pose3d( 1.6, -2.72857, -0.342857, -2.14159, 0.141593, 0.858407); mapIxxIyyIzz[linkName] = ignition::math::Vector3d(576.477, 527.681, 420.127); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(-65.6808, 134.562, 264.781); } // Count collisions and visuals unsigned int countVisuals = 0; unsigned int countCollisions = 0; sdf::ElementPtr model = robot->Root()->GetElement("model"); for (sdf::ElementPtr link = model->GetElement("link"); link; link = link->GetNextElement("link")) { std::string linkName = link->Get("name"); sdf::ElementPtr inertial = link->GetElement("inertial"); double linkMass = inertial->Get("mass"); ignition::math::Pose3d linkPose = inertial->Get("pose"); sdf::ElementPtr inertia = inertial->GetElement("inertia"); double ixx = inertia->Get("ixx"); double iyy = inertia->Get("iyy"); double izz = inertia->Get("izz"); double ixy = inertia->Get("ixy"); double ixz = inertia->Get("ixz"); double iyz = inertia->Get("iyz"); sdfmsg << "name [" << linkName << "] m[" << linkMass << "] p[" << linkPose << "] ixx[" << ixx << "] iyy[" << iyy << "] izz[" << izz << "] ixy[" << ixy << "] ixz[" << ixz << "] iyz[" << iyz << "]\n"; EXPECT_NEAR(linkMass, linkMasses[linkName], gc_tolerance); EXPECT_EQ(linkPose, linkPoses[linkName]); EXPECT_NEAR(ixx, mapIxxIyyIzz[linkName].X(), gc_tolerance); EXPECT_NEAR(iyy, mapIxxIyyIzz[linkName].Y(), gc_tolerance); EXPECT_NEAR(izz, mapIxxIyyIzz[linkName].Z(), gc_tolerance); EXPECT_NEAR(ixy, mapIxyIxzIyz[linkName].X(), gc_tolerance); EXPECT_NEAR(ixz, mapIxyIxzIyz[linkName].Y(), gc_tolerance); EXPECT_NEAR(iyz, mapIxyIxzIyz[linkName].Z(), gc_tolerance); if (link->HasElement("collision")) { for (sdf::ElementPtr coll = link->GetElement("collision"); coll; coll = coll->GetNextElement("collision")) { ++countCollisions; } } if (link->HasElement("visual")) { for (sdf::ElementPtr vis = link->GetElement("visual"); vis; vis = vis->GetNextElement("visual")) { ++countVisuals; } } } if (_file.compare(SDF_TEST_FILE) == 0) { EXPECT_EQ(countCollisions, 7u); EXPECT_EQ(countVisuals, 7u); } else if (_file.compare(SDF_TEST_FILE_COLLISION) == 0) { EXPECT_EQ(countCollisions, 6u); EXPECT_EQ(countVisuals, 0u); } else if (_file.compare(SDF_TEST_FILE_VISUAL) == 0) { EXPECT_EQ(countCollisions, 0u); EXPECT_EQ(countVisuals, 6u); } } ///////////////////////////////////////////////// TEST(SDFParser, FixedJointReductionSimple) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(SDF_TEST_FILE_SIMPLE, robot)); std::map linkMasses; std::map linkPoses; std::map mapIxxIyyIzz; std::map mapIxyIxzIyz; const ignition::math::Vector3d defaultIxxIyyIzz(7, 9, 11); { std::string linkName = "link1"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz; mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } { std::string linkName = "link1a"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz; mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } { std::string linkName = "link1b"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz; mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } { std::string linkName = "link1c"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(0.2, 0, 0, 0, 0, 0); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz + ignition::math::Vector3d(0, 6, 6); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } { std::string linkName = "link1d"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(0.2, 0, 0, 0, 0, 0); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz + ignition::math::Vector3d(0, 6, 6); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } { std::string linkName = "link1e"; linkMasses[linkName] = 300; linkPoses[linkName] = ignition::math::Pose3d(0.2, 0, 0, 0, 0, 0); mapIxxIyyIzz[linkName] = defaultIxxIyyIzz + ignition::math::Vector3d(0, 6, 6); mapIxyIxzIyz[linkName] = ignition::math::Vector3d(); } sdf::ElementPtr model = robot->Root()->GetElement("model"); for (sdf::ElementPtr link = model->GetElement("link"); link; link = link->GetNextElement("link")) { std::string linkName = link->Get("name"); sdf::ElementPtr inertial = link->GetElement("inertial"); double linkMass = inertial->Get("mass"); ignition::math::Pose3d linkPose = inertial->Get("pose"); sdf::ElementPtr inertia = inertial->GetElement("inertia"); double ixx = inertia->Get("ixx"); double iyy = inertia->Get("iyy"); double izz = inertia->Get("izz"); double ixy = inertia->Get("ixy"); double ixz = inertia->Get("ixz"); double iyz = inertia->Get("iyz"); sdfmsg << "name [" << linkName << "] m[" << linkMass << "] p[" << linkPose << "] ixx[" << ixx << "] iyy[" << iyy << "] izz[" << izz << "] ixy[" << ixy << "] ixz[" << ixz << "] iyz[" << iyz << "]\n"; EXPECT_NEAR(linkMass, linkMasses[linkName], gc_tolerance); EXPECT_EQ(linkPose, linkPoses[linkName]); EXPECT_NEAR(ixx, mapIxxIyyIzz[linkName].X(), gc_tolerance); EXPECT_NEAR(iyy, mapIxxIyyIzz[linkName].Y(), gc_tolerance); EXPECT_NEAR(izz, mapIxxIyyIzz[linkName].Z(), gc_tolerance); EXPECT_NEAR(ixy, mapIxyIxzIyz[linkName].X(), gc_tolerance); EXPECT_NEAR(ixz, mapIxyIxzIyz[linkName].Y(), gc_tolerance); EXPECT_NEAR(iyz, mapIxyIxzIyz[linkName].Z(), gc_tolerance); } } sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction.urdf000066400000000000000000000123731323606632500250310ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_collision.urdf000066400000000000000000000102311323606632500270730ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_collision_visual_empty_root.sdf000066400000000000000000000030111323606632500325510ustar00rootroot00000000000000 0 0 0 0 -0 0 0 0 0 0 -0 0 1 0.001 0 0 0.001 0 0.001 0 0 0 0 -0 0 0.03 177 0.007 0.71 0.7 0 0 0 0 -0 0 0.03 0 1 0 1 1 0 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_collision_visual_empty_root.urdf000066400000000000000000000025511323606632500327450ustar00rootroot00000000000000 0.007 0.7 177 0.71 0 1 0 1 script_uri_71_name sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_collision_visual_extension.sdf000066400000000000000000000072351323606632500324000ustar00rootroot00000000000000 0 0 0 0 -0 0 0 0 0 0 -0 0 4 0.004 0 0 0.004 0 0.004 0 0 0 0 -0 0 0.02 0 0 0 0 -0 0 0.03 177 0.007 0.71 0.7 0 0 0 0 -0 0 0.05 0.51 0.5 0 0 0 0 -0 0 0.03 0.61 0.6 166 0 0 0 0 -0 0 0.02 0 0 0 0 -0 0 0.03 0 1 0 1 0 0 0 0 -0 0 0.05 0 0 0 0 -0 0 0.03 1 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_collision_visual_extension.urdf000066400000000000000000000100731323606632500325560ustar00rootroot00000000000000 0.007 0.7 177 0.71 0 1 0 1 script_uri_71_name 0.6 166 0.61 0.5 0.51 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_disabled.urdf000066400000000000000000000105661323606632500266620ustar00rootroot00000000000000 true sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_simple.urdf000066400000000000000000000143071323606632500264010ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/integration/fixed_joint_reduction_visual.urdf000066400000000000000000000101651323606632500264110ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/integration/force_torque_sensor.cc000066400000000000000000000033731323606632500241660ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" const std::string SDF_TEST_FILE = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "force_torque_sensor.urdf"); ///////////////////////////////////////////////// TEST(SDFParser, ForceTorqueSensorTest) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(SDF_TEST_FILE, robot)); sdf::ElementPtr model = robot->Root()->GetElement("model"); unsigned int jointBitMask = 0; for (sdf::ElementPtr joint = model->GetElement("joint"); joint; joint = joint->GetNextElement("joint")) { std::string jointName = joint->Get("name"); if (jointName == "joint_1") { jointBitMask |= 0x1; // Sensor tag was specified EXPECT_TRUE(joint->HasElement("sensor")); } else if (jointName == "joint_2") { jointBitMask |= 0x2; // No sensor tag was specified EXPECT_FALSE(joint->HasElement("sensor")); } else { FAIL() << "Unexpected joint name[" << jointName << "]"; } } EXPECT_EQ(jointBitMask, 0x3u); } sdformat-6.0.0+dfsg/test/integration/force_torque_sensor.urdf000066400000000000000000000024341323606632500245360ustar00rootroot00000000000000 true 1 100.0 1 child sdformat-6.0.0+dfsg/test/integration/frame.cc000066400000000000000000001305011323606632500211640ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/sdf.hh" #include "test_config.h" //////////////////////////////////////// // Test parsing a model element that has a frame element TEST(Frame, ModelFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " 1 1 0 0 0 0" << " " << " 1 0 0 0 0 0" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // model frame EXPECT_TRUE(modelElem->HasElement("frame")); sdf::ElementPtr frameElem = modelElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "mframe"); // model frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "/world"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(1, 1, 0, 0, 0, 0)); // model pose EXPECT_TRUE(modelElem->HasElement("pose")); sdf::ElementPtr modelPoseElem = modelElem->GetElement("pose"); EXPECT_TRUE(modelPoseElem->HasAttribute("frame")); EXPECT_EQ(modelPoseElem->Get("frame"), "mframe"); EXPECT_EQ(modelPoseElem->Get(), ignition::math::Pose3d(1, 0, 0, 0, 0, 0)); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); } //////////////////////////////////////// // Test parsing a model element with an empty frame element TEST(Frame, FrameDefaultPose) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // model frame EXPECT_TRUE(modelElem->HasElement("frame")); sdf::ElementPtr frameElem = modelElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "mframe"); // model frame pose EXPECT_TRUE(!frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), ""); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(0, 0, 0, 0, 0, 0)); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); } //////////////////////////////////////// // Test parsing a model element with no frames - for backward compatibility TEST(Frame, NoFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); { // model frame EXPECT_TRUE(!modelElem->HasElement("frame")); sdf::ElementPtr frameElem = modelElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), ""); // model frame pose EXPECT_TRUE(!frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), ""); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(0, 0, 0, 0, 0, 0)); } // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); { // link frame EXPECT_TRUE(!linkElem->HasElement("frame")); sdf::ElementPtr frameElem = linkElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), ""); // link frame pose EXPECT_TRUE(!frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), ""); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(0, 0, 0, 0, 0, 0)); } } //////////////////////////////////////// // Test parsing a link element that has a frame element TEST(Frame, LinkFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << " 1 0 2 0 0 0" << " " << " 0 5 0 0 0 0" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); // link frame EXPECT_TRUE(linkElem->HasElement("frame")); sdf::ElementPtr frameElem = linkElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "lframe"); // link frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "model"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(1, 0, 2, 0, 0, 0)); // link pose EXPECT_TRUE(linkElem->HasElement("pose")); sdf::ElementPtr linkPoseElem = linkElem->GetElement("pose"); EXPECT_TRUE(linkPoseElem->HasAttribute("frame")); EXPECT_EQ(linkPoseElem->Get("frame"), "lframe"); EXPECT_EQ(linkPoseElem->Get(), ignition::math::Pose3d(0, 5, 0, 0, 0, 0)); } //////////////////////////////////////// // Test parsing a joint element that has a frame element TEST(Frame, JointFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << " " << " parent" << " child" << " " << " 1 0 0" << " " << " " << " 0 0 1 0 0 0" << " " << " 0 2 1 0 0 0" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "parent"); linkElem = linkElem->GetNextElement("link"); EXPECT_TRUE(linkElem != nullptr); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "child"); // joint EXPECT_TRUE(modelElem->HasElement("joint")); sdf::ElementPtr jointElem = modelElem->GetElement("joint"); EXPECT_TRUE(jointElem->HasAttribute("name")); EXPECT_EQ(jointElem->Get("name"), "revjoint"); EXPECT_TRUE(jointElem->HasAttribute("type")); EXPECT_EQ(jointElem->Get("type"), "revolute"); // joint links EXPECT_TRUE(jointElem->HasElement("parent")); EXPECT_EQ(jointElem->Get("parent"), "parent"); EXPECT_TRUE(jointElem->HasElement("child")); EXPECT_EQ(jointElem->Get("child"), "child"); // joint axis EXPECT_TRUE(jointElem->HasElement("axis")); sdf::ElementPtr axisElem = jointElem->GetElement("axis"); EXPECT_TRUE(axisElem->HasElement("xyz")); EXPECT_EQ(axisElem->Get("xyz"), ignition::math::Vector3d(1, 0, 0)); // joint frame EXPECT_TRUE(jointElem->HasElement("frame")); sdf::ElementPtr frameElem = jointElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "jframe"); // joint frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "child"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(0, 0, 1, 0, 0, 0)); // joint pose EXPECT_TRUE(jointElem->HasElement("pose")); sdf::ElementPtr jointPoseElem = jointElem->GetElement("pose"); EXPECT_TRUE(jointPoseElem->HasAttribute("frame")); EXPECT_EQ(jointPoseElem->Get("frame"), "jframe"); EXPECT_EQ(jointPoseElem->Get(), ignition::math::Pose3d(0, 2, 1, 0, 0, 0)); } //////////////////////////////////////// // Test parsing a collision element that has a frame element TEST(Frame, CollisionFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << " " << " 1 3 1 0 0 0" << " " << " 0 2 0 0 0 0" << " " << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); // collision EXPECT_TRUE(linkElem->HasElement("collision")); sdf::ElementPtr collisionElem = linkElem->GetElement("collision"); EXPECT_TRUE(collisionElem->HasAttribute("name")); EXPECT_EQ(collisionElem->Get("name"), "collision"); // collision frame EXPECT_TRUE(collisionElem->HasElement("frame")); sdf::ElementPtr frameElem = collisionElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "cframe"); // collision frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "link"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(1, 3, 1, 0, 0, 0)); // collision pose EXPECT_TRUE(collisionElem->HasElement("pose")); sdf::ElementPtr collisionPoseElem = collisionElem->GetElement("pose"); EXPECT_TRUE(collisionPoseElem->HasAttribute("frame")); EXPECT_EQ(collisionPoseElem->Get("frame"), "cframe"); EXPECT_EQ(collisionPoseElem->Get(), ignition::math::Pose3d(0, 2, 0, 0, 0, 0)); } //////////////////////////////////////// // Test parsing a visual element that has a frame element TEST(Frame, VisualFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << " " << " 1 1 1 0 0 0" << " " << " 2 2 2 0 0 0" << " " << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); // visual EXPECT_TRUE(linkElem->HasElement("visual")); sdf::ElementPtr visualElem = linkElem->GetElement("visual"); EXPECT_TRUE(visualElem->HasAttribute("name")); EXPECT_EQ(visualElem->Get("name"), "visual"); // visual frame EXPECT_TRUE(visualElem->HasElement("frame")); sdf::ElementPtr frameElem = visualElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "vframe"); // visual frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "link"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(1, 1, 1, 0, 0, 0)); // visual pose EXPECT_TRUE(visualElem->HasElement("pose")); sdf::ElementPtr visualPoseElem = visualElem->GetElement("pose"); EXPECT_TRUE(visualPoseElem->HasAttribute("frame")); EXPECT_EQ(visualPoseElem->Get("frame"), "vframe"); EXPECT_EQ(visualPoseElem->Get(), ignition::math::Pose3d(2, 2, 2, 0, 0, 0)); } //////////////////////////////////////// // Test parsing an inertial element that has a frame element TEST(Frame, InertialFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " " << " " << " 1 2 3 0 0 0" << " " << " 3 2 1 0 0 0" << " " << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "my_model"); // link EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linkElem = modelElem->GetElement("link"); EXPECT_TRUE(linkElem->HasAttribute("name")); EXPECT_EQ(linkElem->Get("name"), "link"); // inertial EXPECT_TRUE(linkElem->HasElement("inertial")); sdf::ElementPtr inertialElem = linkElem->GetElement("inertial"); // inertial frame EXPECT_TRUE(inertialElem->HasElement("frame")); sdf::ElementPtr frameElem = inertialElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "iframe"); // inertial frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "link"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(1, 2, 3, 0, 0, 0)); // inertial pose EXPECT_TRUE(inertialElem->HasElement("pose")); sdf::ElementPtr inertialPoseElem = inertialElem->GetElement("pose"); EXPECT_TRUE(inertialPoseElem->HasAttribute("frame")); EXPECT_EQ(inertialPoseElem->Get("frame"), "iframe"); EXPECT_EQ(inertialPoseElem->Get(), ignition::math::Pose3d(3, 2, 1, 0, 0, 0)); } //////////////////////////////////////// // Test parsing a light element that has a frame element TEST(Frame, LightFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " 0.1 10 0 0 0 0" << " " << " 0.1 0 0 0 0 0" << " 0.2 0.3 0.4 1" << " 0.3 0.4 0.5 1" << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // light EXPECT_TRUE(sdfParsed->Root()->HasElement("light")); sdf::ElementPtr lightElem = sdfParsed->Root()->GetElement("light"); EXPECT_TRUE(lightElem->HasAttribute("name")); EXPECT_EQ(lightElem->Get("name"), "my_light"); EXPECT_TRUE(lightElem->HasAttribute("type")); EXPECT_EQ(lightElem->Get("type"), "directional"); // light frame EXPECT_TRUE(lightElem->HasElement("frame")); sdf::ElementPtr frameElem = lightElem->GetElement("frame"); EXPECT_TRUE(frameElem->HasAttribute("name")); EXPECT_EQ(frameElem->Get("name"), "lframe"); // light frame pose EXPECT_TRUE(frameElem->HasElement("pose")); sdf::ElementPtr poseElem = frameElem->GetElement("pose"); EXPECT_TRUE(poseElem->HasAttribute("frame")); EXPECT_EQ(poseElem->Get("frame"), "/world"); EXPECT_EQ(poseElem->Get(), ignition::math::Pose3d(0.1, 10, 0, 0, 0, 0)); // light pose EXPECT_TRUE(lightElem->HasElement("pose")); sdf::ElementPtr lightPoseElem = lightElem->GetElement("pose"); EXPECT_TRUE(lightPoseElem->HasAttribute("frame")); EXPECT_EQ(lightPoseElem->Get("frame"), "lframe"); EXPECT_EQ(lightPoseElem->Get(), ignition::math::Pose3d(0.1, 0, 0, 0, 0, 0)); // diffuse EXPECT_TRUE(lightElem->HasElement("diffuse")); sdf::ElementPtr diffuseElem = lightElem->GetElement("diffuse"); EXPECT_EQ(diffuseElem->Get(), ignition::math::Color(0.2f, 0.3f, 0.4f, 1.0f)); // specular EXPECT_TRUE(lightElem->HasElement("specular")); sdf::ElementPtr specularElem = lightElem->GetElement("specular"); EXPECT_EQ(specularElem->Get(), ignition::math::Color(0.3f, 0.4f, 0.5f, 1.0f)); } //////////////////////////////////////// // Test parsing an actor element that has a frame element TEST(Frame, ActorFrame) { std::ostringstream stream; std::string version = SDF_VERSION; stream << "" << "" << " " << " 1 5 0 0 0 0" << " " << " 0.1 3 0 0 0 0" << " " << " moonwalk.dae" << " " << " " << " walk.dae" << " " << " sdformat-6.0.0+dfsg/test/integration/model/cococan/model-1_2.sdf000066400000000000000000000010351323606632500244440ustar00rootroot00000000000000 0 0 0.5 0 0 0 1 1 1 1 1 1 sdformat-6.0.0+dfsg/test/integration/model/cococan/model-1_4.sdf000066400000000000000000000010351323606632500244460ustar00rootroot00000000000000 0 0 0.5 0 0 0 1 1 1 1 1 1 sdformat-6.0.0+dfsg/test/integration/model/cococan/model.config000066400000000000000000000005701323606632500245610ustar00rootroot00000000000000 cococan 1.0 model-1_2.sdf model-1_4.sdf model-100.sdf Testo testo@osrfoundation.org A simple box with multiple versions sdformat-6.0.0+dfsg/test/integration/model/cococan_malformed/000077500000000000000000000000001323606632500243165ustar00rootroot00000000000000sdformat-6.0.0+dfsg/test/integration/model/cococan_malformed/model.config000066400000000000000000000003731323606632500266100ustar00rootroot00000000000000 cococan 1.0 Testo testo@osrfoundation.org A simple box with multiple versions sdformat-6.0.0+dfsg/test/integration/model/cococan_noversiontag/000077500000000000000000000000001323606632500250665ustar00rootroot00000000000000sdformat-6.0.0+dfsg/test/integration/model/cococan_noversiontag/model-1_2.sdf000066400000000000000000000010351323606632500272420ustar00rootroot00000000000000 0 0 0.5 0 0 0 1 1 1 1 1 1 sdformat-6.0.0+dfsg/test/integration/model/cococan_noversiontag/model-1_4.sdf000066400000000000000000000010351323606632500272440ustar00rootroot00000000000000 0 0 0.5 0 0 0 1 1 1 1 1 1 sdformat-6.0.0+dfsg/test/integration/model/cococan_noversiontag/model.config000066400000000000000000000004611323606632500273560ustar00rootroot00000000000000 cococan 1.0 model-1_2.sdf model-1_4.sdf Testo testo@osrfoundation.org A simple box with multiple versions sdformat-6.0.0+dfsg/test/integration/model/double_pendulum.sdf000066400000000000000000000131461323606632500245510ustar00rootroot00000000000000 100 0 0 0.01 0 0 0 0.8 0.02 -0.275 0 1.1 0 0 0 0.2 0.2 2.2 0 0 0.01 0 0 0 0.8 0.02 -0.275 0 1.1 0 0 0 0.2 0.2 2.2 0 0 2.1 -1.5708 0 0 0 0 0 0.5 0 0 0 -0.05 0 0 0 1.5708 0 0.1 0.3 0 0 1.0 0 1.5708 0 0.1 0.2 0 0 0.5 0 0 0 0.1 0.9 -0.05 0 0 0 1.5708 0 0.1 0.3 0 0 1.0 0 1.5708 0 0.1 0.2 0 0 0.5 0 0 0 0.1 0.9 0.25 1.0 2.1 -2 0 0 0 0 0 0.5 0 0 0 0 0 0 0 1.5708 0 0.08 0.3 0 0 0.5 0 0 0 0.1 0.9 0 0 0 0 1.5708 0 0.08 0.3 0 0 0.5 0 0 0 0.1 0.9 base upper_link 1.0 0 0 upper_link lower_link 1.0 0 0 sdformat-6.0.0+dfsg/test/integration/model/pr2.sdf000066400000000000000000002762551323606632500221050ustar00rootroot00000000000000 0 0 118.001000 -0.062421 0.000000 0.201365 0.000000 -0.000000 0.000000 8.431730 -0.009720 1.901570 8.533050 -0.007380 3.787470 0.000000 0.000000 0.071000 0.000000 -0.000000 0.000000 0.001000 0.001000 0.001000 0.010000 0.010000 0.010000 -0.290000 0.000000 0.851000 0.000000 -0.000000 0.000000 0.050000 0.370000 0.300000 -0.290000 0.000000 0.851000 0.000000 -0.000000 0.000000 0.050000 0.370000 0.300000 0.000000 0.000000 0.051000 0.000000 -0.000000 0.000000 model://pr2/meshes/base_v0/base_L.stl 0.000000 0.000000 0.051000 0.000000 -0.000000 0.000000 model://pr2/meshes/base_v0/base.dae 100.000000 base_footprint_geom_base_link __default_topic__ 1 1 20.000000 0.275000 0.000000 0.303000 0.000000 -0.000000 0.000000 640 1.000000 -2.268900 2.268900 0.080000 10.000000 0.010000 0 -0.224600 0.224600 0.079200 0.000000 -0.000000 0.000000 3.473080 0.000000 0.000000 0.070000 0.000000 -0.000000 0.000000 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 model://pr2/meshes/base_v0/caster_L.stl model://pr2/meshes/base_v0/caster.stl 0 -0.224600 0.273600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 -0.224600 0.175600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 0.000712 0.000503 0.015218 0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 -0.224600 -0.224600 0.079200 0.000000 -0.000000 0.000000 3.473080 0.000000 0.000000 0.070000 0.000000 -0.000000 0.000000 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 model://pr2/meshes/base_v0/caster_L.stl model://pr2/meshes/base_v0/caster.stl 0 -0.224600 -0.175600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 -0.224600 -0.273600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 0.224600 0.224600 0.079200 0.000000 -0.000000 0.000000 3.473080 0.000000 0.000000 0.070000 0.000000 -0.000000 0.000000 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 model://pr2/meshes/base_v0/caster_L.stl model://pr2/meshes/base_v0/caster.stl 0 0.224600 0.273600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 0.224600 0.175600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 0.224600 -0.224600 0.079200 0.000000 -0.000000 0.000000 3.473080 0.000000 0.000000 0.070000 0.000000 -0.000000 0.000000 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 model://pr2/meshes/base_v0/caster_L.stl model://pr2/meshes/base_v0/caster.stl 0 0.224600 -0.175600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 0.224600 -0.273600 0.079200 0.000000 -0.000000 0.000000 0.440360 0.012412 -0.000712 0.000503 0.015218 -0.000004 0.011764 0.000000 0.000000 0.000000 1.570800 -0.000000 0.000000 0.074792 0.034000 model://pr2/meshes/base_v0/wheel.dae 0 -0.050000 0.000000 0.790675 0.000000 -0.000000 0.000000 36.449000 -0.099499 -0.000004 -0.086764 0.000000 -0.000000 0.000000 2.792330 0.004280 -0.160631 2.521060 0.029689 0.536551 model://pr2/meshes/torso_v0/torso_lift_L.stl model://pr2/meshes/torso_v0/torso_lift.dae 100.000000 torso_lift_link_geom __default_topic__ 0 -0.067070 0.000000 1.172130 0.000000 -0.000000 0.000000 6.339000 0.010907 0.031693 0.090507 0.000000 -0.000000 0.000000 0.032498 0.000636 0.002585 0.046546 -0.002453 0.057653 model://pr2/meshes/head_v0/head_pan_L.stl model://pr2/meshes/head_v0/head_pan.dae stereo_projection_pattern_high_res_red.png 0.959931 0.100000 10.000000 0.023200 0.110000 0.119100 0 -1.570793 0 0 0.000930 0.000000 1.172130 0.000000 -0.000000 0.000000 5.319000 -0.005151 -0.014635 0.072819 0.000000 -0.000000 0.000000 0.126134 0.000237 0.011881 0.165102 0.001606 0.166947 model://pr2/meshes/head_v0/head_tilt_L.stl model://pr2/meshes/head_v0/head_tilt.dae -0.147067 0.012500 0.291953 0.000000 -0.000000 0.000000 0.000500 -0.147067 0.012500 0.291953 0.000000 -0.000000 0.000000 0.000250 -0.147067 0.017500 0.291953 0.000000 -0.000000 0.000000 0.000500 -0.147067 0.017500 0.291953 0.000000 -0.000000 0.000000 0.000250 -0.114800 0.000000 0.155500 0.000000 -0.000000 0.000000 0.000500 -0.114800 0.000000 0.155500 0.000000 -0.000000 0.000000 model://pr2/meshes/sensors/kinect_prosilica_v0/115x100_swept_back--coarse.STL 0.001000 0.001000 0.001000 -0.161257 0.012500 0.244421 0.000000 -0.000000 0.000000 0.000500 -0.161257 0.012500 0.244421 0.000000 -0.000000 0.000000 0.000250 0.023200 0.000000 0.064500 0.000000 -0.000000 0.000000 0.010000 0.010000 0.010000 0.023200 0.000000 0.064500 0.000000 -0.000000 0.000000 0.010000 0.010000 0.010000 0 0 1.000000 -0.147067 0.012500 0.291953 0.000000 -0.000000 0.000000 0.994838 640 480 L8 0.010000 5.000000 1.000000 -0.161257 0.012500 0.244421 0.000000 -0.000000 0.000000 1.120501 320 240 R8G8B8 0.100000 100.000000 1.000000 -0.161257 0.012500 0.244421 0.000000 -0.000000 0.000000 1.120501 320 240 R8G8B8 0.100000 100.000000 1 1 25.000000 0.068200 0.060000 0.114600 0.000000 -0.000000 0.000000 0.785398 640 480 L8 0.100000 100.000000 1 25.000000 0.068200 -0.030000 0.114600 0.000000 -0.000000 0.000000 0.785398 640 480 L8 0.100000 100.000000 25.000000 0.068200 0.030000 0.114600 0.000000 -0.000000 0.000000 1.570796 640 480 BAYER_BGGR8 0.100000 100.000000 25.000000 0.068200 -0.060000 0.114600 0.000000 -0.000000 0.000000 1.570796 640 480 BAYER_BGGR8 0.100000 100.000000 20.000000 0.069657 -0.110000 0.119100 0.000000 -0.000000 0.000000 0.785398 2448 2050 R8G8B8 0.100000 100.000000 0 0 -0.050000 0.188000 0.790675 0.000000 -0.000000 0.000000 25.799300 -0.001201 0.024513 -0.098231 0.000000 -0.000000 0.000000 0.866179 -0.060865 -0.121181 0.874217 -0.058866 0.273538 model://pr2/meshes/shoulder_v0/shoulder_pan.stl model://pr2/meshes/shoulder_v0/shoulder_pan.dae 0 0 0.050000 0.188000 0.790675 0.000000 -0.000000 0.000000 2.749880 0.021950 -0.026640 -0.031270 0.000000 -0.000000 0.000000 0.021056 0.004967 -0.001948 0.021272 0.001104 0.019758 model://pr2/meshes/shoulder_v0/shoulder_lift.stl model://pr2/meshes/shoulder_v0/shoulder_lift.dae 0 0 0.050000 0.188000 0.790675 0.000000 -0.000000 0.000000 6.117690 0.210551 0.016309 -0.000561 0.000000 -0.000000 0.000000 0.025306 -0.003393 0.000608 0.084737 -0.000200 0.086016 model://pr2/meshes/shoulder_v0/upper_arm_roll_L.stl model://pr2/meshes/shoulder_v0/upper_arm_roll.stl model://pr2/meshes/upper_arm_v0/upper_arm.stl model://pr2/meshes/upper_arm_v0/upper_arm.dae 0 0 0.450000 0.188000 0.790675 0.000000 -0.000000 0.000000 1.903270 0.010140 0.000320 -0.012110 0.000000 -0.000000 0.000000 0.003465 0.000041 0.000432 0.004416 -0.000040 0.003592 model://pr2/meshes/upper_arm_v0/elbow_flex.stl model://pr2/meshes/upper_arm_v0/elbow_flex.dae 0 0 0.450000 0.188000 0.790675 0.000000 -0.000000 0.000000 2.689680 0.180727 -0.000163 -0.008583 0.000000 -0.000000 0.000000 0.014668 0.000052 0.000656 0.026279 -0.000013 0.027775 model://pr2/meshes/upper_arm_v0/forearm_roll_L.stl model://pr2/meshes/upper_arm_v0/forearm_roll.stl model://pr2/meshes/forearm_v0/forearm.stl model://pr2/meshes/forearm_v0/forearm.dae 25.000000 0.135000 0.000000 0.044000 -1.570800 -0.562869 0.000000 1.570796 640 480 R8G8B8 0.100000 100.000000 0 0 0.771000 0.188000 0.790675 0.000000 -0.000000 0.000000 0.614020 -0.001570 0.000000 -0.000750 0.000000 -0.000000 0.000000 0.000652 0.000000 0.000003 0.000198 0.000000 0.000645 model://pr2/meshes/forearm_v0/wrist_flex.stl model://pr2/meshes/forearm_v0/wrist_flex.dae 0 0 0.771000 0.188000 0.790675 0.000000 -0.000000 0.000000 0.681070 0.056408 0.000451 -0.001014 0.000000 -0.000000 0.000000 0.011352 -0.000016 -0.000001 0.011677 -0.000001 0.011866 model://pr2/meshes/forearm_v0/wrist_roll_L.stl model://pr2/meshes/forearm_v0/wrist_roll.stl 0.001000 0.001000 0.001000 0.001000 0.001000 0.001000 model://pr2/meshes/gripper_v0/gripper_palm.stl model://pr2/meshes/gripper_v0/gripper_palm.dae 0 0 0.847910 0.198000 0.790675 0.000000 -0.000000 0.000000 0.171260 0.035980 0.017300 -0.001640 0.000000 -0.000000 0.000000 0.000078 0.000001 -0.000010 0.000197 -0.000003 0.000181 model://pr2/meshes/gripper_v0/l_finger.stl 500.000000 500.000000 0.000000 0.000000 1000000.000000 1.000000 100.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.dae 0 0 0.939280 0.202950 0.790675 0.000000 -0.000000 0.000000 0.044190 0.004230 0.002840 0.000000 0.000000 -0.000000 0.000000 0.000008 0.000006 0.000000 0.000010 0.000000 0.000015 model://pr2/meshes/gripper_v0/l_finger_tip.stl 500.000000 500.000000 0.000000 0.000000 10000000.000000 1.000000 100.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.dae 100.000000 l_gripper_l_finger_tip_link_geom __default_topic__ 0 0 0.939280 0.188000 0.790675 0.000000 -0.000000 0.000000 0.010000 0.001000 0.000000 0.000000 0.001000 0.000000 0.001000 0 0 0.939280 0.188000 0.790675 0.000000 -0.000000 0.000000 0.010000 0.000100 0.000000 0.000000 0.000100 0.000000 0.000100 0 0 0.847910 0.178000 0.790675 0.000000 -0.000000 0.000000 0.173890 0.035760 -0.017360 -0.000950 0.000000 -0.000000 0.000000 0.000077 -0.000002 -0.000008 0.000198 0.000002 0.000181 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.stl 500.000000 500.000000 0.000000 0.000000 1000000.000000 1.000000 100.000000 0.000000 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.dae 0 0 0.939280 0.173050 0.790675 0.000000 -0.000000 0.000000 0.044190 0.004230 -0.002840 0.000000 0.000000 -0.000000 0.000000 0.000008 -0.000006 0.000000 0.000010 0.000000 0.000015 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.stl 500.000000 500.000000 0.000000 0.000000 10000000.000000 1.000000 100.000000 0.000000 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.dae 100.000000 l_gripper_r_finger_tip_link_geom __default_topic__ 0 0.048930 0.000000 1.017680 0.000000 -0.000000 0.000000 0.592000 -0.001134 0.001667 -0.007067 0.000000 -0.000000 0.000000 0.001296 0.000023 0.000037 0.001086 0.000035 0.000895 model://pr2/meshes/tilting_laser_v0/tilting_hokuyo_L.stl 0.000000 0.000000 0.000000 0.000000 1000000000000.000000 10000.000000 100.000000 0.000000 model://pr2/meshes/tilting_laser_v0/tilting_hokuyo.dae 40.000000 0.000000 0.000000 0.030000 0.000000 -0.000000 0.000000 640 1.000000 -1.396263 1.396263 0.080000 10.000000 0.010000 0 0 -0.050000 -0.188000 0.790675 0.000000 -0.000000 0.000000 25.799300 -0.001201 0.024513 -0.098231 0.000000 -0.000000 0.000000 0.866179 -0.060865 -0.121181 0.874217 -0.058866 0.273538 model://pr2/meshes/shoulder_v0/shoulder_pan.stl 0.000000 0.000000 0.000000 0.000000 1000000000000.000000 10000.000000 100.000000 0.000000 model://pr2/meshes/shoulder_v0/shoulder_pan.dae 0 0 0.050000 -0.188000 0.790675 0.000000 -0.000000 0.000000 2.749880 0.021950 -0.026640 -0.031270 0.000000 -0.000000 0.000000 0.021056 0.004967 -0.001948 0.021272 0.001104 0.019758 model://pr2/meshes/shoulder_v0/shoulder_lift.stl 0.000000 0.000000 0.000000 0.000000 1000000000000.000000 10000.000000 100.000000 0.000000 model://pr2/meshes/shoulder_v0/shoulder_lift.dae 0 0 0.050000 -0.188000 0.790675 0.000000 -0.000000 0.000000 6.117690 0.210482 -0.015945 -0.000197 0.000000 -0.000000 0.000000 0.025378 0.003757 -0.000709 0.084737 -0.000179 0.086088 model://pr2/meshes/shoulder_v0/upper_arm_roll_L.stl model://pr2/meshes/shoulder_v0/upper_arm_roll.stl model://pr2/meshes/upper_arm_v0/upper_arm.stl model://pr2/meshes/upper_arm_v0/upper_arm.dae 0 0 0.450000 -0.188000 0.790675 0.000000 -0.000000 0.000000 1.903270 0.010140 0.000320 -0.012110 0.000000 -0.000000 0.000000 0.003465 0.000041 0.000432 0.004416 -0.000040 0.003592 model://pr2/meshes/upper_arm_v0/elbow_flex.stl model://pr2/meshes/upper_arm_v0/elbow_flex.dae 0 0 0.450000 -0.188000 0.790675 0.000000 -0.000000 0.000000 2.689680 0.180727 -0.000163 -0.008583 0.000000 -0.000000 0.000000 0.014668 0.000052 0.000656 0.026279 -0.000013 0.027775 model://pr2/meshes/upper_arm_v0/forearm_roll_L.stl model://pr2/meshes/upper_arm_v0/forearm_roll.stl model://pr2/meshes/forearm_v0/forearm.stl model://pr2/meshes/forearm_v0/forearm.dae 25.000000 0.135000 0.000000 0.044000 1.570800 -0.562869 -0.000000 1.570796 640 480 R8G8B8 0.100000 100.000000 0 0 0.771000 -0.188000 0.790675 0.000000 -0.000000 0.000000 0.614020 -0.001570 0.000000 -0.000750 0.000000 -0.000000 0.000000 0.000652 0.000000 0.000003 0.000198 0.000000 0.000645 model://pr2/meshes/forearm_v0/wrist_flex.stl model://pr2/meshes/forearm_v0/wrist_flex.dae 0 0 0.771000 -0.188000 0.790675 0.000000 -0.000000 0.000000 0.681070 0.056408 0.000451 -0.001014 0.000000 -0.000000 0.000000 0.011352 -0.000016 -0.000001 0.011677 -0.000001 0.011866 model://pr2/meshes/forearm_v0/wrist_roll_L.stl model://pr2/meshes/forearm_v0/wrist_roll.stl 0.001000 0.001000 0.001000 0.001000 0.001000 0.001000 model://pr2/meshes/gripper_v0/gripper_palm.stl model://pr2/meshes/gripper_v0/gripper_palm.dae 0 0 0.847910 -0.178000 0.790675 0.000000 -0.000000 0.000000 0.171260 0.035980 0.017300 -0.001640 0.000000 -0.000000 0.000000 0.000078 0.000001 0.000010 0.000197 -0.000003 0.000181 model://pr2/meshes/gripper_v0/l_finger.stl 500.000000 500.000000 0.000000 0.000000 1000000.000000 1.000000 100.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.dae 0 0 0.939280 -0.173050 0.790675 0.000000 -0.000000 0.000000 0.044190 0.004230 0.002840 0.000000 0.000000 -0.000000 0.000000 0.000008 0.000006 0.000000 0.000010 0.000000 0.000015 model://pr2/meshes/gripper_v0/l_finger_tip.stl 500.000000 500.000000 0.000000 0.000000 10000000.000000 1.000000 100.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.dae 100.000000 r_gripper_l_finger_tip_link_geom __default_topic__ 0 0 0.939280 -0.188000 0.790675 0.000000 -0.000000 0.000000 0.010000 0.001000 0.000000 0.000000 0.001000 0.000000 0.001000 0 0 0.939280 -0.188000 0.790675 0.000000 -0.000000 0.000000 0.010000 0.000100 0.000000 0.000000 0.000100 0.000000 0.000100 0 0 0.847910 -0.198000 0.790675 0.000000 -0.000000 0.000000 0.173890 0.035760 -0.017360 -0.000950 0.000000 -0.000000 0.000000 0.000077 -0.000002 -0.000008 0.000198 0.000002 0.000181 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.stl 500.000000 500.000000 0.000000 0.000000 1000000.000000 1.000000 100.000000 0.000000 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger.dae 0 0 0.939280 -0.202950 0.790675 0.000000 -0.000000 0.000000 0.044190 0.004230 -0.002840 0.000000 0.000000 -0.000000 0.000000 0.000008 -0.000006 0.000000 0.000010 0.000000 0.000015 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.stl 500.000000 500.000000 0.000000 0.000000 10000000.000000 1.000000 100.000000 0.000000 0.000000 0.000000 0.000000 -3.141590 0.000000 0.000000 model://pr2/meshes/gripper_v0/l_finger_tip.dae 100.000000 r_gripper_r_finger_tip_link_geom __default_topic__ 0 -0.150000 0.000000 0.751000 0.000000 -0.000000 0.000000 1.000000 0.001000 0.000000 0.000000 0.001000 0.000000 0.001000 0 0 0.829910 -0.157000 0.790675 0.000000 -0.000000 0.000000 0.171260 0.035980 0.017300 -0.001640 0.000000 -0.000000 0.000000 0.000078 0.000001 -0.000010 0.000197 -0.000003 0.000181 0 0 0.829910 -0.219000 0.790675 0.000000 -0.000000 0.000000 0.173890 0.035760 -0.017360 -0.000950 0.000000 -0.000000 0.000000 0.000077 -0.000002 -0.000008 0.000198 0.000002 0.000181 0 0 0.829910 0.219000 0.790675 0.000000 -0.000000 0.000000 0.171260 0.035980 0.017300 -0.001640 0.000000 -0.000000 0.000000 0.000078 0.000001 0.000010 0.000197 -0.000003 0.000181 0 0 0.829910 0.157000 0.790675 0.000000 -0.000000 0.000000 0.173890 0.035760 -0.017360 -0.000950 0.000000 -0.000000 0.000000 0.000077 -0.000002 0.000008 0.000198 0.000002 0.000181 base_footprint bl_caster_rotation_link 0.000000 0.000000 1.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 bl_caster_rotation_link bl_caster_l_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 bl_caster_rotation_link bl_caster_r_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 base_footprint br_caster_rotation_link 0.000000 0.000000 1.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 br_caster_rotation_link br_caster_l_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 br_caster_rotation_link br_caster_r_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 base_footprint fl_caster_rotation_link 0.000000 0.000000 1.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 fl_caster_rotation_link fl_caster_l_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 fl_caster_rotation_link fl_caster_r_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 base_footprint fr_caster_rotation_link 0.000000 0.000000 1.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 fr_caster_rotation_link fr_caster_l_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 fr_caster_rotation_link fr_caster_r_wheel_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 base_footprint torso_lift_link 0.000000 0.000000 1.000000 0.000000 0.330000 0.000000 4.000000 torso_lift_link head_pan_link 0.000000 0.000000 1.000000 2.000000 0.000000 -3.006993 3.006993 0.000000 4.000000 head_pan_link head_tilt_link 0.000000 1.000000 0.000000 10.000000 0.000000 -0.471237 1.396260 0.000000 4.000000 torso_lift_link l_shoulder_pan_link 0.000000 0.000000 1.000000 10.000000 0.000000 -0.714602 2.285404 0.000000 4.000000 l_shoulder_pan_link l_shoulder_lift_link 0.000000 1.000000 0.000000 10.000000 0.000000 -0.523601 1.396300 0.000000 4.000000 l_shoulder_lift_link l_upper_arm_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -0.800000 3.900008 0.000000 4.000000 l_upper_arm_roll_link l_elbow_flex_link 0.000000 1.000000 0.000000 1.000000 0.000000 -2.321305 0.000000 0.000000 4.000000 l_elbow_flex_link l_forearm_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_forearm_roll_link l_wrist_flex_link 0.000000 1.000000 0.000000 0.100000 0.000000 -2.180004 0.000000 0.000000 4.000000 l_wrist_flex_link l_wrist_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_wrist_roll_link l_gripper_l_finger_link 0.000000 0.000000 1.000000 0.020000 0.000000 0.000000 0.548000 0.000000 4.000000 l_gripper_l_finger_link l_gripper_l_finger_tip_link 0.000000 0.000000 -1.000000 0.001000 0.000000 0.000000 0.548000 0.000000 4.000000 l_wrist_roll_link l_gripper_motor_slider_link 1.000000 0.000000 0.000000 -0.100000 0.100000 0.000000 4.000000 l_gripper_motor_slider_link l_gripper_motor_screw_link 0.000000 1.000000 0.000000 0.000100 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_wrist_roll_link l_gripper_r_finger_link 0.000000 0.000000 -1.000000 0.020000 0.000000 0.000000 0.548000 0.000000 4.000000 l_gripper_r_finger_link l_gripper_r_finger_tip_link 0.000000 0.000000 1.000000 0.001000 0.000000 0.000000 0.548000 0.000000 4.000000 torso_lift_link laser_tilt_mount_link 0.000000 1.000000 0.000000 0.008000 0.000000 -0.785400 1.483530 0.000000 4.000000 torso_lift_link r_shoulder_pan_link 0.000000 0.000000 1.000000 10.000000 0.000000 -2.285404 0.714602 0.000000 4.000000 r_shoulder_pan_link r_shoulder_lift_link 0.000000 1.000000 0.000000 10.000000 0.000000 -0.523601 1.396300 0.000000 4.000000 r_shoulder_lift_link r_upper_arm_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -3.900008 0.800000 0.000000 4.000000 r_upper_arm_roll_link r_elbow_flex_link 0.000000 1.000000 0.000000 1.000000 0.000000 -2.321305 0.000000 0.000000 4.000000 r_elbow_flex_link r_forearm_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_forearm_roll_link r_wrist_flex_link 0.000000 1.000000 0.000000 0.100000 0.000000 -2.180004 0.000000 0.000000 4.000000 r_wrist_flex_link r_wrist_roll_link 1.000000 0.000000 0.000000 0.100000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_wrist_roll_link r_gripper_l_finger_link 0.000000 0.000000 1.000000 0.020000 0.000000 0.000000 0.548000 0.000000 4.000000 r_gripper_l_finger_link r_gripper_l_finger_tip_link 0.000000 0.000000 -1.000000 0.001000 0.000000 0.000000 0.548000 0.000000 4.000000 r_wrist_roll_link r_gripper_motor_slider_link 1.000000 0.000000 0.000000 0.000000 0.000000 -0.100000 0.100000 0.000000 4.000000 r_gripper_motor_slider_link r_gripper_motor_screw_link 0.000000 1.000000 0.000000 0.000100 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_wrist_roll_link r_gripper_r_finger_link 0.000000 0.000000 -1.000000 0.020000 0.000000 0.000000 0.548000 0.000000 4.000000 r_gripper_r_finger_link r_gripper_r_finger_tip_link 0.000000 0.000000 1.000000 0.001000 0.000000 0.000000 0.548000 0.000000 4.000000 base_footprint torso_lift_motor_screw_link 0.000000 0.000000 1.000000 0.000100 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 torso_lift_link torso_lift_motor_screw_link 3141.600000 0.000000 0.000000 1.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_gripper_r_finger_tip_link r_gripper_motor_screw_link -3141.600000 0.000000 1.000000 0.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_gripper_l_finger_tip_link r_gripper_motor_screw_link 3141.600000 0.000000 1.000000 0.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 0.058910 -0.031000 0.000000 0.000000 -0.000000 0.000000 r_gripper_r_parallel_link r_wrist_roll_link 0.000000 0.000000 -1.000000 0.200000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 0.058910 0.031000 0.000000 0.000000 -0.000000 0.000000 r_gripper_l_parallel_link r_wrist_roll_link 0.000000 0.000000 1.000000 0.200000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 -0.018000 -0.021000 0.000000 0.000000 -0.000000 0.000000 r_gripper_r_parallel_link r_gripper_r_finger_tip_link 0.000000 0.000000 1.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 -0.018000 0.021000 0.000000 0.000000 -0.000000 0.000000 r_gripper_l_parallel_link r_gripper_l_finger_tip_link 0.000000 0.000000 1.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 r_gripper_r_finger_tip_link r_gripper_l_finger_tip_link 0.000000 1.000000 0.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_gripper_r_finger_tip_link l_gripper_motor_screw_link -3141.600000 0.000000 1.000000 0.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_gripper_l_finger_tip_link l_gripper_motor_screw_link 3141.600000 0.000000 1.000000 0.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 0.058910 -0.031000 0.000000 0.000000 -0.000000 0.000000 l_gripper_r_parallel_link l_wrist_roll_link 0.000000 0.000000 -1.000000 0.200000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 0.058910 0.031000 0.000000 0.000000 -0.000000 0.000000 l_gripper_l_parallel_link l_wrist_roll_link 0.000000 0.000000 1.000000 0.200000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 -0.018000 -0.021000 0.000000 0.000000 -0.000000 0.000000 l_gripper_r_parallel_link l_gripper_r_finger_tip_link 0.000000 0.000000 1.000000 0.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 -0.018000 0.021000 0.000000 0.000000 -0.000000 0.000000 l_gripper_l_parallel_link l_gripper_l_finger_tip_link 0.000000 0.000000 1.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 l_gripper_r_finger_tip_link l_gripper_l_finger_tip_link 0.000000 1.000000 0.000000 -10000000000000000.000000 10000000000000000.000000 0.000000 4.000000 sdformat-6.0.0+dfsg/test/integration/model/turtlebot.sdf000066400000000000000000000332141323606632500234100ustar00rootroot00000000000000 0.001453 -0.000453 0.029787 0 0 0 0.058640 0.000124 0.000615 0.058786 0.000014 1.532440 2.234000 -0.043340 0 0.084757 0 0 0 0.233502 0.314845 0.006401 -0.043340 0 0.084757 0 0 0 model://turtlebot/meshes/plate_0_logo.dae -0.002660 0 0.141907 0 0 0 0.314856 0.314856 0.006401 -0.002660 0 0.141907 0 0 0 model://turtlebot/meshes/plate_1_logo.dae -0.002660 0 0.199108 0 0 0 0.314856 0.314856 0.006401 -0.002660 0 0.199108 0 0 0 model://turtlebot/meshes/plate_1_logo.dae -0.015820 0 0.405457 0 0 0 0.288000 0.315000 0.006401 -0.015820 0 0.405457 0 0 0 model://turtlebot/meshes/plate_2_logo.dae -0.002540 0.111468 0.079992 0 0 0 0.012700 0.003175 -0.002540 0.111468 0.079992 0 0 0 model://turtlebot/meshes/68-02403-125_Spacer.dae -0.002540 -0.111468 0.079992 0 0 0 0.012700 0.003175 -0.002540 -0.111468 0.079992 0 0 0 model://turtlebot/meshes/68-02403-125_Spacer.dae -0.072390 -0.111468 0.079992 0 0 0 0.012700 0.003175 -0.072390 -0.111468 0.079992 0 0 0 model://turtlebot/meshes/68-02403-125_Spacer.dae -0.072390 0.111468 0.079992 0 0 0 0.012700 0.003175 -0.072390 0.111468 0.079992 0 0 0 model://turtlebot/meshes/68-02403-125_Spacer.dae 0.067640 0.131420 0.087980 0 0 0 0.038100 0.063500 0.067640 0.131420 0.087980 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae 0.067640 -0.131420 0.087980 0 0 0 0.038100 0.063500 0.067640 -0.131420 0.087980 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae -0.052832 -0.131420 0.087980 0 0 0 0.038100 0.063500 -0.052832 -0.131420 0.087980 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae -0.052832 0.131420 0.087980 0 0 0 0.038100 0.063500 -0.052832 0.131420 0.087980 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae 0.067640 0.131420 0.145130 0 0 0 0.038100 0.063500 0.067640 0.131420 0.145130 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae 0.067640 -0.131420 0.145130 0 0 0 0.038100 0.063500 0.067640 -0.131420 0.145130 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae -0.052832 -0.131420 0.145130 0 0 0 0.038100 0.063500 -0.052832 -0.131420 0.145130 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae -0.052832 0.131420 0.145130 0 0 0 0.038100 0.063500 -0.052832 0.131420 0.145130 0 0 0 model://turtlebot/meshes/68-04552-2000-RA_Turtlebot_M-F_Standoff.dae 0.067640 0.131420 0.202280 0 0 0 0.011113 0.203200 0.067640 0.131420 0.202280 0 0 0 model://turtlebot/meshes/68-02421-8000-RA_Turtlebot_F-F_Standoff.dae 0.067640 -0.131420 0.202280 0 0 0 0.011113 0.203200 0.067640 -0.131420 0.202280 0 0 0 model://turtlebot/meshes/68-02421-8000-RA_Turtlebot_F-F_Standoff.dae -0.052832 -0.131420 0.202280 0 0 0 0.011113 0.203200 -0.052832 -0.131420 0.202280 0 0 0 model://turtlebot/meshes/68-02421-8000-RA_Turtlebot_F-F_Standoff.dae -0.052832 0.131420 0.202280 0 0 0 0.011113 0.203200 -0.052832 0.131420 0.202280 0 0 0 model://turtlebot/meshes/68-02421-8000-RA_Turtlebot_F-F_Standoff.dae -0.105098 0.098000 0.202308 0 0 0 0.001111 0.008585 -0.105098 0.098000 0.202308 0 0 0 model://turtlebot/meshes/68-04556-RA_Kinect_Standoff_Assy.dae -0.105098 -0.098000 0.202308 0 0 0 0.001111 0.008585 -0.105098 -0.098000 0.202308 0 0 0 model://turtlebot/meshes/68-04556-RA_Kinect_Standoff_Assy.dae -0.065000 0 0.092000 0 0 0 180 1.000000 -2.268928 2.268928 0.080000 10 0.010000 20 model://create model://kinect -0.087098 0 0.303857 0 0 0 create::base rack 0 0 1 0 0 kinect::link rack 0 0 1 0 0 sdformat-6.0.0+dfsg/test/integration/model_versions.cc000066400000000000000000000042461323606632500231300ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" TEST(ModelVersionsTest, Empty_ModelFilePath) { std::string modelPath = sdf::getModelFilePath(""); EXPECT_EQ(modelPath, ""); } TEST(ModelVersionsTest, NonExistent_ModelFilePath) { const std::string MODEL_PATH = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "non-existent"); std::string modelPath = sdf::getModelFilePath(MODEL_PATH); EXPECT_EQ(modelPath, ""); } TEST(ModelVersionsTest, MalFormed_ModelFilePath) { const std::string MODEL_PATH = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "cococan_malformed"); std::string modelPath = sdf::getModelFilePath(MODEL_PATH); EXPECT_EQ(modelPath, ""); } TEST(ModelVersionsTest, NoVersionTag_ModelFilePath) { const std::string MODEL_PATH = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "cococan_noversiontag"); std::string modelPath = sdf::getModelFilePath(MODEL_PATH); EXPECT_EQ(modelPath, sdf::filesystem::append(MODEL_PATH, "model-1_2.sdf")); } TEST(ModelVersionsTest, Correct_ModelFilePath) { const std::string MODEL_PATH = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "cococan"); std::string modelPath = sdf::getModelFilePath(MODEL_PATH); EXPECT_EQ(modelPath, sdf::filesystem::append(MODEL_PATH, "model-1_4.sdf")); } ///////////////////////////////////////////////// int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/test/integration/nested_model.cc000066400000000000000000000233021323606632500225340ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include "sdf/sdf.hh" //////////////////////////////////////// // Test parsing nested model with joint TEST(NestedModel, NestedModel) { std::ostringstream stream; std::string version = "1.5"; stream << "" << "" << " " << " " << " " << " " << " " << " " << " parent" << " child" << " " << " 1 0 0" << " " << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Verify correct parsing // top level model EXPECT_TRUE(sdfParsed->Root()->HasElement("model")); sdf::ElementPtr modelElem = sdfParsed->Root()->GetElement("model"); EXPECT_TRUE(modelElem->HasAttribute("name")); EXPECT_EQ(modelElem->Get("name"), "top_level_model"); // top level links EXPECT_TRUE(modelElem->HasElement("link")); sdf::ElementPtr linklElem = modelElem->GetElement("link"); EXPECT_TRUE(linklElem->HasAttribute("name")); EXPECT_EQ(linklElem->Get("name"), "parent"); linklElem = linklElem->GetNextElement("link"); EXPECT_TRUE(linklElem != nullptr); EXPECT_TRUE(linklElem->HasAttribute("name")); EXPECT_EQ(linklElem->Get("name"), "child"); // nested model EXPECT_TRUE(modelElem->HasElement("model")); sdf::ElementPtr nestedModelElem = modelElem->GetElement("model"); // nested model link EXPECT_TRUE(nestedModelElem->HasElement("link")); sdf::ElementPtr nestedLinkElem = nestedModelElem->GetElement("link"); EXPECT_TRUE(nestedLinkElem->HasAttribute("name")); EXPECT_EQ(nestedLinkElem->Get("name"), "nested_link01"); // top level model joint EXPECT_TRUE(modelElem->HasElement("joint")); sdf::ElementPtr jointElem = modelElem->GetElement("joint"); EXPECT_TRUE(jointElem->HasAttribute("name")); EXPECT_EQ(jointElem->Get("name"), "top_level_joint"); EXPECT_TRUE(jointElem->HasAttribute("type")); EXPECT_EQ(jointElem->Get("type"), "revolute"); // joint links EXPECT_TRUE(jointElem->HasElement("parent")); EXPECT_EQ(jointElem->Get("parent"), "parent"); EXPECT_TRUE(jointElem->HasElement("child")); EXPECT_EQ(jointElem->Get("child"), "child"); // joint axis EXPECT_TRUE(jointElem->HasElement("axis")); sdf::ElementPtr axisElem = jointElem->GetElement("axis"); EXPECT_TRUE(axisElem->HasElement("xyz")); EXPECT_EQ(axisElem->Get("xyz"), ignition::math::Vector3d(1, 0, 0)); } //////////////////////////////////////// // Test parsing nested model states TEST(NestedModel, State) { std::ostringstream sdfStr; sdfStr << "" << "" << "" << "" << " 0 0 0.5 0 0 0" << " " << " 0 0 0.5 0 0 0" << " 0.001 0 0 0 0 0" << " 0 0.006121 0 0.012288 0 0.001751" << " 0 0.006121 0 0 0 0" << " " << " " << " 1 0 0.5 0 0 0" << " " << " 1.25 0 0.5 0 0 0" << " 0 -0.001 0 0 0 0" << " 0 0.000674 0 -0.001268 0 0" << " 0 0.000674 0 0 0 0" << " " << " " << " 1 1 0.5 0 0 0" << " " << " 1.25 1 0.5 0 0 0" << " 0 0 0.001 0 0 0" << " 0 0 0 0 0 0" << " 0 0 0 0 0 0" << " " << " " << " " << "" << "" << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(sdfStr.str(), sdfParsed)); // load the state sdf EXPECT_TRUE(sdfParsed->Root()->HasElement("world")); sdf::ElementPtr worldElem = sdfParsed->Root()->GetElement("world"); EXPECT_TRUE(worldElem->HasElement("state")); sdf::ElementPtr stateElem = worldElem->GetElement("state"); EXPECT_TRUE(stateElem->HasElement("model")); sdf::ElementPtr modelStateElem = stateElem->GetElement("model"); // model sdf EXPECT_TRUE(modelStateElem->HasAttribute("name")); EXPECT_EQ(modelStateElem->Get("name"), "model_00"); EXPECT_TRUE(modelStateElem->HasElement("pose")); EXPECT_EQ(modelStateElem->Get("pose"), ignition::math::Pose3d(0, 0, 0.5, 0, 0, 0)); EXPECT_TRUE(!modelStateElem->HasElement("joint")); // link sdf EXPECT_TRUE(modelStateElem->HasElement("link")); sdf::ElementPtr linkStateElem = modelStateElem->GetElement("link"); EXPECT_TRUE(linkStateElem->HasAttribute("name")); EXPECT_EQ(linkStateElem->Get("name"), "link_00"); EXPECT_TRUE(linkStateElem->HasElement("pose")); EXPECT_EQ(linkStateElem->Get("pose"), ignition::math::Pose3d(0, 0, 0.5, 0, 0, 0)); EXPECT_TRUE(linkStateElem->HasElement("velocity")); EXPECT_EQ(linkStateElem->Get("velocity"), ignition::math::Pose3d(0.001, 0, 0, 0, 0, 0)); EXPECT_TRUE(linkStateElem->HasElement("acceleration")); EXPECT_EQ(linkStateElem->Get("acceleration"), ignition::math::Pose3d(0, 0.006121, 0, 0.012288, 0, 0.001751)); EXPECT_TRUE(linkStateElem->HasElement("wrench")); EXPECT_EQ(linkStateElem->Get("wrench"), ignition::math::Pose3d(0, 0.006121, 0, 0, 0, 0)); // nested model sdf EXPECT_TRUE(modelStateElem->HasElement("model")); sdf::ElementPtr nestedModelStateElem = modelStateElem->GetElement("model"); EXPECT_TRUE(nestedModelStateElem->HasAttribute("name")); EXPECT_EQ(nestedModelStateElem->Get("name"), "model_01"); EXPECT_TRUE(nestedModelStateElem->HasElement("pose")); EXPECT_EQ(nestedModelStateElem->Get("pose"), ignition::math::Pose3d(1, 0, 0.5, 0, 0, 0)); EXPECT_TRUE(!nestedModelStateElem->HasElement("joint")); // nested model's link sdf EXPECT_TRUE(nestedModelStateElem->HasElement("link")); sdf::ElementPtr nestedLinkStateElem = nestedModelStateElem->GetElement("link"); EXPECT_TRUE(nestedLinkStateElem->HasAttribute("name")); EXPECT_EQ(nestedLinkStateElem->Get("name"), "link_01"); EXPECT_TRUE(nestedLinkStateElem->HasElement("pose")); EXPECT_EQ(nestedLinkStateElem->Get("pose"), ignition::math::Pose3d(1.25, 0, 0.5, 0, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("velocity")); EXPECT_EQ(nestedLinkStateElem->Get("velocity"), ignition::math::Pose3d(0, -0.001, 0, 0, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("acceleration")); EXPECT_EQ(nestedLinkStateElem->Get("acceleration"), ignition::math::Pose3d(0, 0.000674, 0, -0.001268, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("wrench")); EXPECT_EQ(nestedLinkStateElem->Get("wrench"), ignition::math::Pose3d(0, 0.000674, 0, 0, 0, 0)); // double nested model sdf EXPECT_TRUE(nestedModelStateElem->HasElement("model")); nestedModelStateElem = nestedModelStateElem->GetElement("model"); EXPECT_TRUE(nestedModelStateElem->HasAttribute("name")); EXPECT_EQ(nestedModelStateElem->Get("name"), "model_02"); EXPECT_TRUE(nestedModelStateElem->HasElement("pose")); EXPECT_EQ(nestedModelStateElem->Get("pose"), ignition::math::Pose3d(1, 1, 0.5, 0, 0, 0)); EXPECT_TRUE(!nestedModelStateElem->HasElement("joint")); // double nested model's link sdf EXPECT_TRUE(nestedModelStateElem->HasElement("link")); nestedLinkStateElem = nestedModelStateElem->GetElement("link"); EXPECT_TRUE(nestedLinkStateElem->HasAttribute("name")); EXPECT_EQ(nestedLinkStateElem->Get("name"), "link_02"); EXPECT_TRUE(nestedLinkStateElem->HasElement("pose")); EXPECT_EQ(nestedLinkStateElem->Get("pose"), ignition::math::Pose3d(1.25, 1, 0.5, 0, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("velocity")); EXPECT_EQ(nestedLinkStateElem->Get("velocity"), ignition::math::Pose3d(0, 0, 0.001, 0, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("acceleration")); EXPECT_EQ(nestedLinkStateElem->Get("acceleration"), ignition::math::Pose3d(0, 0, 0, 0, 0, 0)); EXPECT_TRUE(nestedLinkStateElem->HasElement("wrench")); EXPECT_EQ(nestedLinkStateElem->Get("wrench"), ignition::math::Pose3d(0, 0, 0, 0, 0, 0)); } sdformat-6.0.0+dfsg/test/integration/numeric.sdf000066400000000000000000000013551323606632500217270ustar00rootroot00000000000000 10 0 3 0 0 3.141592 0.0 0.0 -10.00 quick 100 0.823 0.0 0.2 0.1 0.0 0 0.001 sdformat-6.0.0+dfsg/test/integration/parser_error_detection.cc000066400000000000000000000027671323606632500246510ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/sdf.hh" std::string get_sdf_string() { std::ostringstream stream; stream << "" << "" << " " << " " << " " << " 1 1 1" << " " << " " << " " << " " << " 1 1 1" << " " << " " << " " << "" << ""; return stream.str(); } //////////////////////////////////////// // make sure that XML errors get caught TEST(ParserErrorDetection, BadXML) { sdf::SDFPtr model(new sdf::SDF()); sdf::init(model); ASSERT_FALSE(sdf::readString(get_sdf_string(), model)); } sdformat-6.0.0+dfsg/test/integration/plugin_attribute.cc000066400000000000000000000037431323606632500234620ustar00rootroot00000000000000/* * Copyright 2014 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/sdf.hh" std::string get_sdf_string() { std::ostringstream stream; stream << "" << "" << " " << " " << " " << " value" << " " << "" << ""; return stream.str(); } //////////////////////////////////////// // make sure that plugin attributes get parsed TEST(PluginAttribute, ParseAttributes) { sdf::SDFPtr model(new sdf::SDF()); sdf::init(model); ASSERT_TRUE(sdf::readString(get_sdf_string(), model)); sdf::ElementPtr plugin = model->Root()->GetElement("model")->GetElement("plugin"); ASSERT_TRUE(plugin->HasElement("user")); { sdf::ElementPtr user = plugin->GetElement("user"); EXPECT_TRUE(user->HasAttribute("attribute")); EXPECT_EQ(user->GetAttribute("attribute")->GetAsString(), std::string("attribute")); } { sdf::ElementPtr value = plugin->GetElement("value"); EXPECT_TRUE(value->HasAttribute("attribute")); EXPECT_EQ(value->GetAttribute("attribute")->GetAsString(), std::string("attribute")); EXPECT_EQ(value->Get(""), std::string("value")); } } sdformat-6.0.0+dfsg/test/integration/plugin_bool.cc000066400000000000000000000040511323606632500224030ustar00rootroot00000000000000/* * Copyright 2014 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/sdf.hh" std::string get_sdf_string() { std::ostringstream stream; stream << "" << "" << " " << " true" << " 1" << " false" << " 0" << " True" << " TRUE" << " " << "" << ""; return stream.str(); } //////////////////////////////////////// // make sure that we can read boolean values from inside a plugin TEST(PluginBool, ParseBoolValue) { sdf::SDFPtr model(new sdf::SDF()); sdf::init(model); ASSERT_TRUE(sdf::readString(get_sdf_string(), model)); sdf::ElementPtr plugin = model->Root()->GetElement("model")->GetElement("plugin"); ASSERT_TRUE(plugin->HasElement("value1")); EXPECT_TRUE(plugin->Get("value1")); ASSERT_TRUE(plugin->HasElement("value2")); EXPECT_TRUE(plugin->Get("value2")); ASSERT_TRUE(plugin->HasElement("value3")); EXPECT_FALSE(plugin->Get("value3")); ASSERT_TRUE(plugin->HasElement("value4")); EXPECT_FALSE(plugin->Get("value4")); ASSERT_TRUE(plugin->HasElement("value5")); EXPECT_TRUE(plugin->Get("value5")); ASSERT_TRUE(plugin->HasElement("value6")); EXPECT_TRUE(plugin->Get("value6")); } sdformat-6.0.0+dfsg/test/integration/plugin_include.cc000066400000000000000000000061531323606632500231000ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" //////////////////////////////////////// // Test that plugin child elements are available even when nested in an include TEST(PluginInclude, PluginChildElements) { const std::string MODEL_PATH = std::string(PROJECT_SOURCE_PATH) + "/test/integration/model/box"; std::ostringstream stream; stream << "" << "" << " " + MODEL_PATH + "" << " " << " " << " true" << " some_uri" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_TRUE(sdf::readString(stream.str(), sdfParsed)); // Plugin attributes sdf::ElementPtr plugin = sdfParsed->Root()->GetElement("model")->GetElement("plugin"); EXPECT_TRUE(plugin->HasAttribute("name")); EXPECT_EQ(plugin->GetAttribute("name")->GetAsString(), "example"); EXPECT_TRUE(plugin->HasAttribute("filename")); EXPECT_EQ(plugin->GetAttribute("filename")->GetAsString(), "libexample.so"); // 1st child element ASSERT_TRUE(plugin->HasElement("user")); { sdf::ElementPtr user = plugin->GetElement("user"); EXPECT_TRUE(user->HasAttribute("attribute")); EXPECT_EQ(user->GetAttribute("attribute")->GetAsString(), "attribute"); } // 2nd child element ASSERT_TRUE(plugin->HasElement("value")); { sdf::ElementPtr value = plugin->GetElement("value"); EXPECT_TRUE(value->HasAttribute("attribute")); EXPECT_EQ(value->GetAttribute("attribute")->GetAsString(), "boolean"); EXPECT_TRUE(value->Get("")); } EXPECT_TRUE(plugin->Get("value")); // 3rd child element ASSERT_TRUE(plugin->HasElement("uri")); EXPECT_EQ(plugin->Get("uri"), "some_uri"); } //////////////////////////////////////// // Test that missing required plugin attributes are detected TEST(PluginInclude, PluginMissingFilename) { const std::string MODEL_PATH = std::string(PROJECT_SOURCE_PATH) + "/test/integration/model/box"; std::ostringstream stream; stream << "" << "" << " " + MODEL_PATH + "" << " " << "" << ""; sdf::SDFPtr sdfParsed(new sdf::SDF()); sdf::init(sdfParsed); ASSERT_FALSE(sdf::readString(stream.str(), sdfParsed)); } sdformat-6.0.0+dfsg/test/integration/provide_feedback.cc000066400000000000000000000050111323606632500233430ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" const std::string SDF_TEST_FILE = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "provide_feedback.urdf"); ///////////////////////////////////////////////// TEST(SDFParser, ProvideFeedbackTest) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(SDF_TEST_FILE, robot)); sdf::ElementPtr root = robot->Root(); ASSERT_TRUE(root != nullptr); sdf::ElementPtr model = root->GetElement("model"); ASSERT_TRUE(model != nullptr); unsigned int jointBitMask = 0; for (sdf::ElementPtr joint = model->GetElement("joint"); joint; joint = joint->GetNextElement("joint")) { std::string jointName = joint->Get("name"); if (jointName == "jointw0") { jointBitMask |= 0x1; // No provide_feedback tag was specified EXPECT_FALSE(joint->HasElement("physics")); } else if (jointName == "joint01") { jointBitMask |= 0x2; // provide_feedback = 0 ASSERT_TRUE(joint->HasElement("physics")); sdf::ElementPtr physics = joint->GetElement("physics"); ASSERT_TRUE(physics->HasElement("provide_feedback")); EXPECT_FALSE(physics->Get("provide_feedback")); } else if (jointName == "joint12") { jointBitMask |= 0x4; // provide_feedback = 1 ASSERT_TRUE(joint->HasElement("physics")); sdf::ElementPtr physics = joint->GetElement("physics"); ASSERT_TRUE(physics->HasElement("provide_feedback")); EXPECT_TRUE(physics->Get("provide_feedback")); } else { FAIL() << "Unexpected joint name[" << jointName << "]"; } } EXPECT_EQ(jointBitMask, 0x7u); } ///////////////////////////////////////////////// /// Main int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/test/integration/provide_feedback.urdf000066400000000000000000000023551323606632500237260ustar00rootroot00000000000000 0 1 sdformat-6.0.0+dfsg/test/integration/root_dom.cc000066400000000000000000000037761323606632500217310ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/Root.hh" #include "sdf/World.hh" #include "sdf/Filesystem.hh" #include "test_config.h" ///////////////////////////////////////////////// TEST(DOMRoot, InvalidSDF) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "empty_invalid.sdf"); sdf::Root root; sdf::Errors errors = root.Load(testFile); EXPECT_FALSE(errors.empty()); EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::FILE_READ); } ///////////////////////////////////////////////// TEST(DOMRoot, NoVersion) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "empty_noversion.sdf"); sdf::Root root; sdf::Errors errors = root.Load(testFile); EXPECT_FALSE(errors.empty()); std::cout << errors[0].Message() << std::endl; EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::FILE_READ); } ///////////////////////////////////////////////// TEST(DOMRoot, Load) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "empty.sdf"); sdf::Root root; EXPECT_EQ(root.WorldCount(), 0u); EXPECT_TRUE(root.Load(testFile).empty()); EXPECT_EQ(root.Version(), "1.6"); EXPECT_EQ(root.WorldCount(), 1u); EXPECT_TRUE(root.WorldByIndex(0) != nullptr); EXPECT_TRUE(root.WorldByIndex(1) == nullptr); EXPECT_EQ(root.WorldByIndex(0)->Name(), "default"); } sdformat-6.0.0+dfsg/test/integration/schema_test.cc000066400000000000000000000042661323606632500224010ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include "sdf/sdf.hh" #include "test_config.h" const std::string SDF_ROOT_SCHEMA = sdf::filesystem::append(PROJECT_BINARY_DIR, "sdf", SDF_PROTOCOL_VERSION, "root.xsd"); const std::string SDF_TEST_PR2 = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "pr2.sdf"); const std::string SDF_TEST_TURTLEBOT = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "turtlebot.sdf"); const std::string SDF_TEST_PENDULUM = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "model", "double_pendulum.sdf"); class SDFSchemaGenerator : public testing::Test { public: void runXMLlint(const std::string & model) { std::string xmllintCmd = "xmllint --noout --schema " + SDF_ROOT_SCHEMA + " " + model; std::cout << "CMD[" << xmllintCmd << "]\n"; if (system(xmllintCmd.c_str()) != 0) { FAIL() << "Fail in parsing the model"; } else { SUCCEED(); } } }; ///////////////////////////////////////////////// TEST_F(SDFSchemaGenerator, TestDoublePendulum) { runXMLlint(SDF_TEST_PENDULUM); } ///////////////////////////////////////////////// TEST_F(SDFSchemaGenerator, TestPR2Model) { runXMLlint(SDF_TEST_PR2); } ///////////////////////////////////////////////// TEST_F(SDFSchemaGenerator, TestTurtleBotModel) { runXMLlint(SDF_TEST_TURTLEBOT); } sdformat-6.0.0+dfsg/test/integration/sdf_basic.cc000066400000000000000000000033531323606632500220130ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include "sdf/sdf.hh" #include "test_config.h" // testing the wrapper around an sdf element WrapInRoot(const ElementPtr &_sdf) TEST(BasicTest, RootWrapper) { // create a test element std::string testName = "sdf-test"; sdf::ElementPtr testElem(new sdf::Element()); testElem->SetName(testName); // wrap it in the sdf root sdf::ElementPtr wrappedElem = sdf::SDF::WrapInRoot(testElem); ASSERT_NE(wrappedElem, nullptr); // only one top-level element expected, which is "sdf" EXPECT_FALSE(wrappedElem->GetNextElement()); EXPECT_EQ(wrappedElem->GetName(), "sdf"); // needs to have the version attribute EXPECT_TRUE(wrappedElem->HasAttribute("version")); EXPECT_EQ(wrappedElem->GetAttribute("version")->GetAsString(), sdf::SDF::Version()); // check if the child element is the same test element sdf::ElementPtr checkElem = wrappedElem->GetFirstElement(); ASSERT_NE(checkElem, nullptr); EXPECT_EQ(checkElem->GetName(), testName); } ///////////////////////////////////////////////// int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } sdformat-6.0.0+dfsg/test/integration/urdf_gazebo_extensions.cc000066400000000000000000000076321323606632500246500ustar00rootroot00000000000000/* * Copyright 2015 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" const std::string URDF_TEST_FILE = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "urdf_gazebo_extensions.urdf"); ///////////////////////////////////////////////// TEST(SDFParser, UrdfGazeboExtensionURDFTest) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(URDF_TEST_FILE, robot)); sdf::ElementPtr model = robot->Root()->GetElement("model"); for (sdf::ElementPtr joint = model->GetElement("joint"); joint; joint = joint->GetNextElement("joint")) { std::string jointName = joint->Get("name"); if (jointName == "jointw0") { // No cfm_damping tag was specified EXPECT_FALSE(joint->HasElement("physics")); } else if (jointName == "joint01") { // cfmDamping = true ASSERT_TRUE(joint->HasElement("physics")); sdf::ElementPtr physics = joint->GetElement("physics"); ASSERT_TRUE(physics->HasElement("ode")); ASSERT_TRUE(physics->HasElement("provide_feedback")); EXPECT_TRUE(physics->Get("provide_feedback")); ASSERT_TRUE(physics->HasElement("ode")); sdf::ElementPtr ode = physics->GetElement("ode"); ASSERT_TRUE(ode->HasElement("provide_feedback")); EXPECT_TRUE(ode->Get("provide_feedback")); ASSERT_TRUE(ode->HasElement("implicit_spring_damper")); EXPECT_TRUE(!ode->Get("implicit_spring_damper")); ASSERT_TRUE(ode->HasElement("cfm_damping")); EXPECT_TRUE(!ode->Get("cfm_damping")); ASSERT_TRUE(ode->HasElement("fudge_factor")); EXPECT_DOUBLE_EQ(ode->Get("fudge_factor"), 0.56789); ASSERT_TRUE(ode->HasElement("limit")); sdf::ElementPtr limit = ode->GetElement("limit"); ASSERT_TRUE(limit->HasElement("cfm")); EXPECT_DOUBLE_EQ(limit->Get("cfm"), 123); ASSERT_TRUE(limit->HasElement("erp")); EXPECT_DOUBLE_EQ(limit->Get("erp"), 0.987); ASSERT_TRUE(joint->HasElement("axis")); sdf::ElementPtr axis = joint->GetElement("axis"); ASSERT_TRUE(axis->HasElement("dynamics")); sdf::ElementPtr dynamics = axis->GetElement("dynamics"); ASSERT_TRUE(dynamics->HasElement("damping")); EXPECT_DOUBLE_EQ(dynamics->Get("damping"), 1.1111); ASSERT_TRUE(dynamics->HasElement("friction")); EXPECT_DOUBLE_EQ(dynamics->Get("friction"), 2.2222); ASSERT_TRUE(dynamics->HasElement("spring_reference")); EXPECT_DOUBLE_EQ(dynamics->Get("spring_reference"), 0.234); ASSERT_TRUE(dynamics->HasElement("spring_stiffness")); EXPECT_DOUBLE_EQ(dynamics->Get("spring_stiffness"), 0.567); } else if (jointName == "joint12") { // cfmDamping not provided ASSERT_TRUE(joint->HasElement("physics")); sdf::ElementPtr physics = joint->GetElement("physics"); EXPECT_FALSE(physics->HasElement("implicit_spring_damper")); } else if (jointName == "joint13") { // implicitSpringDamper = 1 ASSERT_TRUE(joint->HasElement("physics")); sdf::ElementPtr physics = joint->GetElement("physics"); ASSERT_TRUE(physics->HasElement("implicit_spring_damper")); EXPECT_TRUE(physics->Get("implicit_spring_damper")); } } } sdformat-6.0.0+dfsg/test/integration/urdf_gazebo_extensions.urdf000066400000000000000000000076361323606632500252270ustar00rootroot00000000000000 true 123 0.987 0.234 0.567 1 false 0.56789 0 true sdformat-6.0.0+dfsg/test/integration/urdf_joint_parameters.cc000066400000000000000000000040541323606632500244630ustar00rootroot00000000000000/* * Copyright 2014 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "test_config.h" const std::string SDF_TEST_FILE = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "integration", "urdf_joint_parameters.urdf"); ///////////////////////////////////////////////// TEST(SDFParser, JointAxisParameters) { sdf::SDFPtr robot(new sdf::SDF()); sdf::init(robot); ASSERT_TRUE(sdf::readFile(SDF_TEST_FILE, robot)); sdf::ElementPtr model = robot->Root()->GetElement("model"); ASSERT_TRUE(model->HasElement("joint")); unsigned int bitmask = 0; for (sdf::ElementPtr joint = model->GetElement("joint"); joint; joint = joint->GetNextElement("joint")) { std::string jointName = joint->Get("name"); double value = -1.0; if (jointName == "jointw0") { bitmask |= 0x1; value = 0.0; } else if (jointName == "joint01") { bitmask |= 0x2; value = 1.0; } else { continue; } ASSERT_TRUE(joint->HasElement("axis")); sdf::ElementPtr axis = joint->GetElement("axis"); ASSERT_TRUE(axis->HasElement("dynamics")); sdf::ElementPtr dynamics = axis->GetElement("dynamics"); ASSERT_TRUE(dynamics->HasElement("damping")); ASSERT_TRUE(dynamics->HasElement("friction")); EXPECT_DOUBLE_EQ(value, dynamics->Get("damping")); EXPECT_DOUBLE_EQ(value, dynamics->Get("friction")); } EXPECT_EQ(bitmask, 0x3u); } sdformat-6.0.0+dfsg/test/integration/urdf_joint_parameters.urdf000066400000000000000000000061051323606632500250350ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/integration/world_dom.cc000066400000000000000000000056731323606632500220730ustar00rootroot00000000000000/* * Copyright 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include "sdf/SDFImpl.hh" #include "sdf/parser.hh" #include "sdf/Root.hh" #include "sdf/World.hh" #include "sdf/Filesystem.hh" #include "test_config.h" ////////////////////////////////////////////////// TEST(DOMWorld, NoName) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "world_noname.sdf"); sdf::Root root; sdf::Errors errors = root.Load(testFile); EXPECT_FALSE(errors.empty()); EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::ATTRIBUTE_MISSING); } ////////////////////////////////////////////////// TEST(DOMWorld, Duplicate) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "world_duplicate.sdf"); sdf::Root root; sdf::Errors errors = root.Load(testFile); EXPECT_FALSE(errors.empty()); EXPECT_TRUE(errors[0].Code() == sdf::ErrorCode::DUPLICATE_NAME); } ////////////////////////////////////////////////// TEST(DOMWorld, LoadIncorrectElement) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "world_complete.sdf"); sdf::Errors errors; // Read an SDF file, and store the result in sdfParsed. sdf::SDFPtr sdfParsed = sdf::readFile(testFile, errors); ASSERT_TRUE(errors.empty()); sdf::World world; errors = world.Load(sdfParsed->Root()); EXPECT_FALSE(errors.empty()); EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::ELEMENT_INCORRECT_TYPE); EXPECT_TRUE(errors[0].Message().find("Attempting to load a World") != std::string::npos); } ////////////////////////////////////////////////// TEST(DOMWorld, Load) { const std::string testFile = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf", "world_complete.sdf"); sdf::Root root; EXPECT_TRUE(root.Load(testFile).empty()); EXPECT_EQ(root.Version(), "1.6"); EXPECT_EQ(root.WorldCount(), 1u); EXPECT_TRUE(root.WorldNameExists("default")); const sdf::World *world = root.WorldByIndex(0); ASSERT_TRUE(world != nullptr); EXPECT_EQ(world->Name(), "default"); EXPECT_EQ(world->AudioDevice(), "/dev/audio"); EXPECT_EQ(world->WindLinearVelocity(), ignition::math::Vector3d(4, 5, 6)); EXPECT_EQ(world->Gravity(), ignition::math::Vector3d(1, 2, 3)); EXPECT_EQ(world->MagneticField(), ignition::math::Vector3d(-1, 0.5, 10)); } sdformat-6.0.0+dfsg/test/performance/000077500000000000000000000000001323606632500175415ustar00rootroot00000000000000sdformat-6.0.0+dfsg/test/performance/CMakeLists.txt000066400000000000000000000002041323606632500222750ustar00rootroot00000000000000set(TEST_TYPE "PERFORMANCE") set(tests parser_urdf.cc ) link_directories(${PROJECT_BINARY_DIR}/test) sdf_build_tests(${tests}) sdformat-6.0.0+dfsg/test/performance/parser_urdf.cc000066400000000000000000000021761323606632500223720ustar00rootroot00000000000000/* * Copyright 2013 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include "sdf/sdf.hh" #include "sdf/parser_urdf.hh" #include "test_config.h" TEST(URDFParser, AtlasURDF_5runs_performance) { const std::string URDF_TEST_FILE = sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "performance", "parser_urdf_atlas.urdf"); sdf::URDF2SDF parser; for (int i = 0; i < 5; i++) { TiXmlDocument sdf_result = parser.InitModelFile(URDF_TEST_FILE); } } sdformat-6.0.0+dfsg/test/performance/parser_urdf_atlas.urdf000066400000000000000000001763451323606632500241430ustar00rootroot00000000000000 0 0 0.93 0 0 0 joint_trajectory 1000.0 1 1000.0 gaussian 0.0 2e-4 0.0000075 0.0000008 0.0 1.7e-2 0.1 0.001 1 1 1 1 1 1 1000000.0 100.0 1.5 1.5 1 0 0 1.0 0.00 1000000.0 100.0 1.5 1.5 1 0 0 1.0 0.00 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 0.9 pelvis /ground_truth_odom true 100.0 1000.0 1 r_foot_collision /r_foot_contact 1000.0 1 l_foot_collision /l_foot_contact pelvis /atlas/apply_pelvis_force 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 false 40 720 1 -1.570796 1.570796 0.10 30.0 0.01 gaussian 0.0 0.01 /multisense_sl/laser/scan head_hokuyo_frame 30.0 1.3962634 800 800 R8G8B8 0.02 300 gaussian 0.0 0.007 0 -0.07 0 0 0 0 1.3962634 800 800 R8G8B8 0.02 300 gaussian 0.0 0.007 true 0.0 multisense_sl/camera image_raw camera_info left_camera_optical_frame 0.07 0.0 0.0 0.0 0.0 0.0 1 1000.0 gaussian 0.0 2e-4 0.0000075 0.0000008 0.0 1.7e-2 0.1 0.001 sdformat-6.0.0+dfsg/test/sdf/000077500000000000000000000000001323606632500160145ustar00rootroot00000000000000sdformat-6.0.0+dfsg/test/sdf/box_bad_test.world000066400000000000000000000014211323606632500215200ustar00rootroot00000000000000 0 0.5 0.0 0.0 0.0 0.05 1.0 1.0 1.0 1.0 1.0 1.0 .1 .1 sdformat-6.0.0+dfsg/test/sdf/box_plane_low_friction_test.world000066400000000000000000000033451323606632500246560ustar00rootroot00000000000000 0.0 0.0 0.5 0.0 0.0 0.0 0.05 1.0 1.0 1.0 1.0 1.0 1.0 .1 .1 true 0 0 1 100 100 0 0 false 0 0 1 100 100 sdformat-6.0.0+dfsg/test/sdf/empty.sdf000066400000000000000000000030751323606632500176550ustar00rootroot00000000000000 true 0 0 1 100 100 0xffff 100 50 false 0 0 1 100 100 true 0 0 10 0 0 0 0.8 0.8 0.8 1 0.2 0.2 0.2 1 1000 0.9 0.01 0.001 -0.5 0.1 -0.9 sdformat-6.0.0+dfsg/test/sdf/empty_invalid.sdf000066400000000000000000000000621323606632500213540ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/sdf/empty_noversion.sdf000066400000000000000000000000441323606632500217500ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/sdf/world_complete.sdf000066400000000000000000000004431323606632500215320ustar00rootroot00000000000000 4 5 6 1 2 3 -1 0.5 10 sdformat-6.0.0+dfsg/test/sdf/world_duplicate.sdf000066400000000000000000000001721323606632500216730ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/sdf/world_noname.sdf000066400000000000000000000001071323606632500211740ustar00rootroot00000000000000 sdformat-6.0.0+dfsg/test/test_config.h.in000066400000000000000000000027401323606632500203250ustar00rootroot00000000000000/* * Copyright (C) 2017 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef SDF_TEST_CONFIG_HH_ #define SDF_TEST_CONFIG_HH_ #define IGN_CONFIG_PATH "@CMAKE_BINARY_DIR@/test/conf" #define IGN_PATH "@IGNITION-TOOLS_BINARY_DIRS@" #define IGN_TEST_LIBRARY_PATH "${PROJECT_BINARY_DIR}/src:"\ "@IGNITION-MSGS_LIBRARY_DIRS@:" #define PROJECT_SOURCE_PATH "${PROJECT_SOURCE_DIR}" #define PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}" #define SDF_PROTOCOL_VERSION "${SDF_PROTOCOL_VERSION}" /* * setenv/unstenv are not present in Windows. Define them to make the code * portable */ #if (_MSC_VER >= 1400) // Visual Studio 2005 #include int setenv(const char * name, const char * value, int /*rewrite*/) { std::stringstream sstr; sstr << *name << '=' << value; return _putenv(sstr.str().c_str()); } void unsetenv(const char * name) { std::stringstream sstr; sstr << *name << '='; _putenv(sstr.str().c_str()); return; } #endif #endif sdformat-6.0.0+dfsg/tools/000077500000000000000000000000001323606632500154215ustar00rootroot00000000000000sdformat-6.0.0+dfsg/tools/check_test_ran.py000077500000000000000000000056371323606632500207650ustar00rootroot00000000000000#!/usr/bin/env python # Software License Agreement (BSD License) # # Copyright (c) 2008, Willow Garage, Inc. # All rights reserved. # # 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. # * Neither the name of Willow Garage, Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # 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 OWNER 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. # # Revision $Id: check_test_ran.py 16671 2012-04-27 16:15:28Z dthomas $ """ Writes a test failure out to test file if it doesn't exist. """ # Adapted from rosunit/check_test_ran.py from __future__ import print_function NAME="check_test_ran.py" import os import sys def usage(): print("""Usage: \t%s test-file.xml """%(NAME), file=sys.stderr) print(sys.argv) sys.exit(getattr(os, 'EX_USAGE', 1)) def check_main(): if len(sys.argv) < 2: usage() test_file = sys.argv[1] print("Checking for test results in %s"%test_file) if not os.path.exists(test_file): if not os.path.exists(os.path.dirname(test_file)): os.makedirs(os.path.dirname(test_file)) print("Cannot find results, writing failure results to", test_file) with open(test_file, 'w') as f: test_name = os.path.basename(test_file) d = {'test': test_name, 'test_file': test_file } f.write(""" """%d) if __name__ == '__main__': check_main() sdformat-6.0.0+dfsg/tools/code_check.sh000077500000000000000000000050421323606632500200300ustar00rootroot00000000000000#!/bin/sh # Jenkins will pass -xml, in which case we want to generate XML output xmlout=0 if test "$1" = "-xmldir" -a -n "$2"; then xmlout=1 xmldir=$2 mkdir -p $xmldir rm -rf $xmldir/*.xml # Assuming that Jenkins called, the `build` directory is a sibling to the src dir builddir=../build else # This is a heuristic guess; not every developer puts the `build` dir in the src dir builddir=./build fi # Use a suppression file for spurious errors SUPPRESS=/tmp/sdf_cpp_check.suppress echo "*:test/integration/locale_fix.cc:40" > $SUPPRESS # Use another suppression file for unused function checking SUPPRESS2=/tmp/sdf_cpp_check2.suppress echo "*:src/parser_urdf.cc" >> $SUPPRESS2 CHECK_FILE_DIRS="./src ./include ./examples ./test/performance ./test/integration" #cppcheck CPPCHECK_BASE="cppcheck -q --suppressions-list=$SUPPRESS" CPPCHECK_BASE2="cppcheck -q --suppressions-list=$SUPPRESS2 --inline-suppr" CPPCHECK_FILES=`find $CHECK_FILE_DIRS -name "*.cc"` CPPCHECK_INCLUDES="-I include -I . -I $builddir -I $builddir/include" CPPCHECK_COMMAND1="-j 4 --enable=style,performance,portability,information $CPPCHECK_FILES" # Unused function checking must happen in one job CPPCHECK_COMMAND2="--enable=unusedFunction $CPPCHECK_FILES" # -j 4 was used previously in CPPCHECK_COMMAND3 but it will generate a false # warning as described in bug: # http://sourceforge.net/apps/trac/cppcheck/ticket/4946 CPPCHECK_COMMAND3="-j 1 --enable=missingInclude --suppress=missingIncludeSystem $CPPCHECK_FILES $CPPCHECK_INCLUDES --check-config" if [ $xmlout -eq 1 ]; then # Performance, style, portability, and information ($CPPCHECK_BASE --xml --xml-version=2 $CPPCHECK_COMMAND1) 2> $xmldir/cppcheck.xml # Unused function checking ($CPPCHECK_BASE2 --xml --xml-version=2 $CPPCHECK_COMMAND2) 2> $xmldir/cppcheck-unused-functions.xml # Check the configuration ($CPPCHECK_BASE --xml --xml-version=2 $CPPCHECK_COMMAND3) 2> $xmldir/cppcheck-configuration.xml else # Performance, style, portability, and information $CPPCHECK_BASE $CPPCHECK_COMMAND1 2>&1 # Unused function checking $CPPCHECK_BASE2 $CPPCHECK_COMMAND2 2>&1 # Check the configuration $CPPCHECK_BASE $CPPCHECK_COMMAND3 2>&1 fi # cpplint # exclude urdf files for now, since they generate lots of errors CPPLINT_FILES=`find $CHECK_FILE_DIRS -name "*.cc" -o -name "*.hh" | grep -iv urdf` if [ $xmlout -eq 1 ]; then (echo $CPPLINT_FILES | xargs python tools/cpplint.py 2>&1) \ | python tools/cpplint_to_cppcheckxml.py 2> $xmldir/cpplint.xml else echo $CPPLINT_FILES | xargs python tools/cpplint.py 2>&1 fi sdformat-6.0.0+dfsg/tools/cpplint.py000066400000000000000000004051421323606632500174520ustar00rootroot00000000000000#!/usr/bin/python2.4 # # Copyright (c) 2009 Google Inc. All rights reserved. # # 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. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # 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 # OWNER 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. # Here are some issues that I've had people identify in my code during reviews, # that I think are possible to flag automatically in a lint tool. If these were # caught by lint, it would save time both for myself and that of my reviewers. # Most likely, some of these are beyond the scope of the current lint framework, # but I think it is valuable to retain these wish-list items even if they cannot # be immediately implemented. # # Suggestions # ----------- # - Check for no 'explicit' for multi-arg ctor # - Check for boolean assign RHS in parens # - Check for ctor initializer-list colon position and spacing # - Check that if there's a ctor, there should be a dtor # - Check accessors that return non-pointer member variables are # declared const # - Check accessors that return non-const pointer member vars are # *not* declared const # - Check for using public includes for testing # - Check for spaces between brackets in one-line inline method # - Check for no assert() # - Check for spaces surrounding operators # - Check for 0 in pointer context (should be NULL) # - Check for 0 in char context (should be '\0') # - Check for camel-case method name conventions for methods # that are not simple inline getters and setters # - Check that base classes have virtual destructors # put " // namespace" after } that closes a namespace, with # namespace's name after 'namespace' if it is named. # - Do not indent namespace contents # - Avoid inlining non-trivial constructors in header files # include base/basictypes.h if DISALLOW_EVIL_CONSTRUCTORS is used # - Check for old-school (void) cast for call-sites of functions # ignored return value # - Check gUnit usage of anonymous namespace # - Check for class declaration order (typedefs, consts, enums, # ctor(s?), dtor, friend declarations, methods, member vars) # """Does google-lint on c++ files. The goal of this script is to identify places in the code that *may* be in non-compliance with google style. It does not attempt to fix up these problems -- the point is to educate. It does also not attempt to find all problems, or to ensure that everything it does find is legitimately a problem. In particular, we can get very confused by /* and // inside strings! We do a small hack, which is to ignore //'s with "'s after them on the same line, but it is far from perfect (in either direction). """ import codecs import getopt import math # for log import os import re import sre_compile import string import sys import unicodedata _USAGE = """ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] [--counting=total|toplevel|detailed] [file] ... The style guidelines this tries to follow are those in http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml Every problem is given a confidence score from 1-5, with 5 meaning we are certain of the problem, and 1 meaning it could be a legitimate construct. This will miss some errors, and is not a substitute for a code review. To suppress false-positive errors of a certain category, add a 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) suppresses errors of all categories on that line. The files passed in will be linted; at least one file must be provided. Linted extensions are .cc, .cpp, and .h. Other file types will be ignored. Flags: output=vs7 By default, the output is formatted to ease emacs parsing. Visual Studio compatible output (vs7) may also be used. Other formats are unsupported. verbose=# Specify a number 0-5 to restrict errors to certain verbosity levels. filter=-x,+y,... Specify a comma-separated list of category-filters to apply: only error messages whose category names pass the filters will be printed. (Category names are printed with the message and look like "[whitespace/indent]".) Filters are evaluated left to right. "-FOO" and "FOO" means "do not print categories that start with FOO". "+FOO" means "do print categories that start with FOO". Examples: --filter=-whitespace,+whitespace/braces --filter=whitespace,runtime/printf,+runtime/printf_format --filter=-,+build/include_what_you_use To see a list of all the categories used in cpplint, pass no arg: --filter= counting=total|toplevel|detailed The total number of errors found is always printed. If 'toplevel' is provided, then the count of errors in each of the top-level categories like 'build' and 'whitespace' will also be printed. If 'detailed' is provided, then a count is provided for each category like 'build/class'. """ # We categorize each error message we print. Here are the categories. # We want an explicit list so we can list them all in cpplint --filter=. # If you add a new error message with a new category, add it to the list # here! cpplint_unittest.py should tell you if you forget to do this. # \ used for clearer layout -- pylint: disable-msg=C6013 _ERROR_CATEGORIES = [ 'build/class', 'build/deprecated', 'build/endif_comment', 'build/explicit_make_pair', 'build/forward_decl', 'build/header_guard', 'build/include', 'build/include_alpha', 'build/include_order', 'build/include_what_you_use', 'build/namespaces', 'build/printf_format', 'build/storage_class', 'legal/copyright', 'readability/braces', 'readability/casting', 'readability/check', 'readability/constructors', 'readability/fn_size', 'readability/function', 'readability/multiline_comment', 'readability/multiline_string', 'readability/nolint', 'readability/streams', 'readability/todo', 'readability/utf8', 'runtime/arrays', 'runtime/casting', 'runtime/explicit', 'runtime/int', 'runtime/init', 'runtime/invalid_increment', 'runtime/member_string_references', 'runtime/memset', 'runtime/operator', 'runtime/printf', 'runtime/printf_format', 'runtime/references', 'runtime/rtti', 'runtime/sizeof', 'runtime/string', 'runtime/threadsafe_fn', 'runtime/virtual', 'whitespace/blank_line', 'whitespace/braces', 'whitespace/comma', 'whitespace/comments', 'whitespace/end_of_line', 'whitespace/ending_newline', 'whitespace/indent', 'whitespace/labels', 'whitespace/line_length', 'whitespace/newline', 'whitespace/operators', 'whitespace/parens', 'whitespace/semicolon', 'whitespace/tab', 'whitespace/todo' ] # These constants define types of headers for use with # _IncludeState.CheckNextIncludeOrder(). _C_SYS_HEADER = 1 _CPP_SYS_HEADER = 2 _OTHER_HEADER = 3 _LIKELY_MY_HEADER = 4 _POSSIBLE_MY_HEADER = 5 # The default state of the category filter. This is overrided by the --filter= # flag. By default all errors are on, so only add here categories that should be # off by default (i.e., categories that must be enabled by the --filter= flags). # All entries here should start with a '-' or '+', as in the --filter= flag. _DEFAULT_FILTERS = ['-build/include_alpha'] # We used to check for high-bit characters, but after much discussion we # decided those were OK, as long as they were in UTF-8 and didn't represent # hard-coded international strings, which belong in a separate i18n file. # Headers that we consider STL headers. _STL_HEADERS = frozenset([ 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new', 'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', 'utility', 'vector', 'vector.h', ]) # Non-STL C++ system headers. _CPP_HEADERS = frozenset([ 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype', 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath', 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef', 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype', 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream', 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip', 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream', 'istream.h', 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h', 'numeric', 'ostream', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h', 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h', 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept', 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string', 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray', ]) # Assertion macros. These are defined in base/logging.h and # testing/base/gunit.h. Note that the _M versions need to come first # for substring matching to work. _CHECK_MACROS = [ 'DCHECK', 'CHECK', 'EXPECT_TRUE_M', 'EXPECT_TRUE', 'ASSERT_TRUE_M', 'ASSERT_TRUE', 'EXPECT_FALSE_M', 'EXPECT_FALSE', 'ASSERT_FALSE_M', 'ASSERT_FALSE', ] # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) for op, replacement in [('==', 'EQ'), ('!=', 'NE'), ('>=', 'GE'), ('>', 'GT'), ('<=', 'LE'), ('<', 'LT')]: _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), ('>=', 'LT'), ('>', 'LE'), ('<=', 'GT'), ('<', 'GE')]: _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement _regexp_compile_cache = {} # Finds occurrences of NOLINT or NOLINT(...). _RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') # {str, set(int)}: a map from error categories to sets of linenumbers # on which those errors are expected and should be suppressed. _error_suppressions = {} def ParseNolintSuppressions(filename, raw_line, linenum, error): """Updates the global list of error-suppressions. Parses any NOLINT comments on the current line, updating the global error_suppressions store. Reports an error if the NOLINT comment was malformed. Args: filename: str, the name of the input file. raw_line: str, the line of input text, with comments. linenum: int, the number of the current line. error: function, an error handler. """ # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*). matched = _RE_SUPPRESSION.search(raw_line) if matched: category = matched.group(1) if category in (None, '(*)'): # => "suppress all" _error_suppressions.setdefault(None, set()).add(linenum) else: if category.startswith('(') and category.endswith(')'): category = category[1:-1] if category in _ERROR_CATEGORIES: _error_suppressions.setdefault(category, set()).add(linenum) else: error(filename, linenum, 'readability/nolint', 5, 'Unknown NOLINT error category: %s' % category) def ResetNolintSuppressions(): "Resets the set of NOLINT suppressions to empty." _error_suppressions.clear() def IsErrorSuppressedByNolint(category, linenum): """Returns true if the specified error category is suppressed on this line. Consults the global error_suppressions map populated by ParseNolintSuppressions/ResetNolintSuppressions. Args: category: str, the category of the error. linenum: int, the current line number. Returns: bool, True iff the error should be suppressed due to a NOLINT comment. """ return (linenum in _error_suppressions.get(category, set()) or linenum in _error_suppressions.get(None, set())) def Match(pattern, s): """Matches the string with the pattern, caching the compiled regexp.""" # The regexp compilation caching is inlined in both Match and Search for # performance reasons; factoring it out into a separate function turns out # to be noticeably expensive. if not pattern in _regexp_compile_cache: _regexp_compile_cache[pattern] = sre_compile.compile(pattern) return _regexp_compile_cache[pattern].match(s) def Search(pattern, s): """Searches the string for the pattern, caching the compiled regexp.""" if not pattern in _regexp_compile_cache: _regexp_compile_cache[pattern] = sre_compile.compile(pattern) return _regexp_compile_cache[pattern].search(s) class _IncludeState(dict): """Tracks line numbers for includes, and the order in which includes appear. As a dict, an _IncludeState object serves as a mapping between include filename and line number on which that file was included. Call CheckNextIncludeOrder() once for each header in the file, passing in the type constants defined above. Calls in an illegal order will raise an _IncludeError with an appropriate error message. """ # self._section will move monotonically through this set. If it ever # needs to move backwards, CheckNextIncludeOrder will raise an error. _INITIAL_SECTION = 0 _C_SECTION = 1 _CPP_SECTION = 2 _OTHER_H_SECTION = 3 _MY_H_SECTION = 4 _TYPE_NAMES = { _C_SYS_HEADER: 'C system header', _CPP_SYS_HEADER: 'C++ system header', _LIKELY_MY_HEADER: 'header this file implements', _POSSIBLE_MY_HEADER: 'header this file may implement', _OTHER_HEADER: 'other header', } _SECTION_NAMES = { _INITIAL_SECTION: "... nothing. (This can't be an error.)", _C_SECTION: 'C system header', _CPP_SECTION: 'C++ system header', _OTHER_H_SECTION: 'other header', _MY_H_SECTION: 'a header this file implements', } def __init__(self): dict.__init__(self) # The name of the current section. self._section = self._INITIAL_SECTION # The path of last found header. self._last_header = '' def CanonicalizeAlphabeticalOrder(self, header_path): """Returns a path canonicalized for alphabetical comparison. - replaces "-" with "_" so they both cmp the same. - removes '-inl' since we don't require them to be after the main header. - lowercase everything, just in case. Args: header_path: Path to be canonicalized. Returns: Canonicalized path. """ return header_path.replace('-inl.h', '.h').replace('-', '_').lower() def IsInAlphabeticalOrder(self, header_path): """Check if a header is in alphabetical order with the previous header. Args: header_path: Header to be checked. Returns: Returns true if the header is in alphabetical order. """ canonical_header = self.CanonicalizeAlphabeticalOrder(header_path) if self._last_header > canonical_header: return False self._last_header = canonical_header return True def CheckNextIncludeOrder(self, header_type): """Returns a non-empty error message if the next header is out of order. This function also updates the internal state to be ready to check the next include. Args: header_type: One of the _XXX_HEADER constants defined above. Returns: The empty string if the header is in the right order, or an error message describing what's wrong. """ error_message = ('Found %s after %s' % (self._TYPE_NAMES[header_type], self._SECTION_NAMES[self._section])) last_section = self._section if header_type == _C_SYS_HEADER: if self._section <= self._C_SECTION: self._section = self._C_SECTION else: self._last_header = '' return error_message elif header_type == _CPP_SYS_HEADER: if self._section <= self._CPP_SECTION: self._section = self._CPP_SECTION else: self._last_header = '' return error_message elif header_type == _LIKELY_MY_HEADER: if self._section <= self._MY_H_SECTION: self._section = self._MY_H_SECTION else: self._section = self._OTHER_H_SECTION elif header_type == _POSSIBLE_MY_HEADER: if self._section <= self._MY_H_SECTION: self._section = self._MY_H_SECTION else: # This will always be the fallback because we're not sure # enough that the header is associated with this file. self._section = self._OTHER_H_SECTION else: assert header_type == _OTHER_HEADER self._section = self._OTHER_H_SECTION if last_section != self._section: self._last_header = '' return '' class _CppLintState(object): """Maintains module-wide state..""" def __init__(self): self.verbose_level = 1 # global setting. self.error_count = 0 # global count of reported errors # filters to apply when emitting error messages self.filters = _DEFAULT_FILTERS[:] self.counting = 'total' # In what way are we counting errors? self.errors_by_category = {} # string to int dict storing error counts # output format: # "emacs" - format that emacs can parse (default) # "vs7" - format that Microsoft Visual Studio 7 can parse self.output_format = 'emacs' def SetOutputFormat(self, output_format): """Sets the output format for errors.""" self.output_format = output_format def SetVerboseLevel(self, level): """Sets the module's verbosity, and returns the previous setting.""" last_verbose_level = self.verbose_level self.verbose_level = level return last_verbose_level def SetCountingStyle(self, counting_style): """Sets the module's counting options.""" self.counting = counting_style def SetFilters(self, filters): """Sets the error-message filters. These filters are applied when deciding whether to emit a given error message. Args: filters: A string of comma-separated filters (eg "+whitespace/indent"). Each filter should start with + or -; else we die. Raises: ValueError: The comma-separated filters did not all start with '+' or '-'. E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" """ # Default filters always have less priority than the flag ones. self.filters = _DEFAULT_FILTERS[:] for filt in filters.split(','): clean_filt = filt.strip() if clean_filt: self.filters.append(clean_filt) for filt in self.filters: if not (filt.startswith('+') or filt.startswith('-')): raise ValueError('Every filter in --filters must start with + or -' ' (%s does not)' % filt) def ResetErrorCounts(self): """Sets the module's error statistic back to zero.""" self.error_count = 0 self.errors_by_category = {} def IncrementErrorCount(self, category): """Bumps the module's error statistic.""" self.error_count += 1 if self.counting in ('toplevel', 'detailed'): if self.counting != 'detailed': category = category.split('/')[0] if category not in self.errors_by_category: self.errors_by_category[category] = 0 self.errors_by_category[category] += 1 def PrintErrorCounts(self): """Print a summary of errors by category, and the total.""" for category, count in self.errors_by_category.iteritems(): sys.stderr.write('Category \'%s\' errors found: %d\n' % (category, count)) sys.stderr.write('Total errors found: %d\n' % self.error_count) _cpplint_state = _CppLintState() def _OutputFormat(): """Gets the module's output format.""" return _cpplint_state.output_format def _SetOutputFormat(output_format): """Sets the module's output format.""" _cpplint_state.SetOutputFormat(output_format) def _VerboseLevel(): """Returns the module's verbosity setting.""" return _cpplint_state.verbose_level def _SetVerboseLevel(level): """Sets the module's verbosity, and returns the previous setting.""" return _cpplint_state.SetVerboseLevel(level) def _SetCountingStyle(level): """Sets the module's counting options.""" _cpplint_state.SetCountingStyle(level) def _Filters(): """Returns the module's list of output filters, as a list.""" return _cpplint_state.filters def _SetFilters(filters): """Sets the module's error-message filters. These filters are applied when deciding whether to emit a given error message. Args: filters: A string of comma-separated filters (eg "whitespace/indent"). Each filter should start with + or -; else we die. """ _cpplint_state.SetFilters(filters) class _FunctionState(object): """Tracks current function name and the number of lines in its body.""" _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. def __init__(self): self.in_a_function = False self.lines_in_function = 0 self.current_function = '' def Begin(self, function_name): """Start analyzing function body. Args: function_name: The name of the function being tracked. """ self.in_a_function = True self.lines_in_function = 0 self.current_function = function_name def Count(self): """Count line in current function body.""" if self.in_a_function: self.lines_in_function += 1 def Check(self, error, filename, linenum): """Report if too many lines in function body. Args: error: The function to call with any errors found. filename: The name of the current file. linenum: The number of the line to check. """ if Match(r'T(EST|est)', self.current_function): base_trigger = self._TEST_TRIGGER else: base_trigger = self._NORMAL_TRIGGER trigger = base_trigger * 2**_VerboseLevel() if self.lines_in_function > trigger: error_level = int(math.log(self.lines_in_function / base_trigger, 2)) # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... if error_level > 5: error_level = 5 error(filename, linenum, 'readability/fn_size', error_level, 'Small and focused functions are preferred:' ' %s has %d non-comment lines' ' (error triggered by exceeding %d lines).' % ( self.current_function, self.lines_in_function, trigger)) def End(self): """Stop analyzing function body.""" self.in_a_function = False class _IncludeError(Exception): """Indicates a problem with the include order in a file.""" pass class FileInfo: """Provides utility functions for filenames. FileInfo provides easy access to the components of a file's path relative to the project root. """ def __init__(self, filename): self._filename = filename def FullName(self): """Make Windows paths like Unix.""" return os.path.abspath(self._filename).replace('\\', '/') def RepositoryName(self): """FullName after removing the local path to the repository. If we have a real absolute path name here we can try to do something smart: detecting the root of the checkout and truncating /path/to/checkout from the name so that we get header guards that don't include things like "C:\Documents and Settings\..." or "/home/username/..." in them and thus people on different computers who have checked the source out to different locations won't see bogus errors. """ fullname = self.FullName() if os.path.exists(fullname): project_dir = os.path.dirname(fullname) if os.path.exists(os.path.join(project_dir, ".svn")): # If there's a .svn file in the current directory, we recursively look # up the directory tree for the top of the SVN checkout root_dir = project_dir one_up_dir = os.path.dirname(root_dir) while os.path.exists(os.path.join(one_up_dir, ".svn")): root_dir = os.path.dirname(root_dir) one_up_dir = os.path.dirname(one_up_dir) prefix = os.path.commonprefix([root_dir, project_dir]) return fullname[len(prefix) + 1:] # Not SVN? Try to find a git or hg top level directory by searching up # from the current path. root_dir = os.path.dirname(fullname) while (root_dir != os.path.dirname(root_dir) and not os.path.exists(os.path.join(root_dir, ".git")) and not os.path.exists(os.path.join(root_dir, ".hg"))): root_dir = os.path.dirname(root_dir) if (os.path.exists(os.path.join(root_dir, ".git")) or os.path.exists(os.path.join(root_dir, ".hg"))): prefix = os.path.commonprefix([root_dir, project_dir]) return fullname[len(prefix) + 1:] # Don't know what to do; header guard warnings may be wrong... return fullname def Split(self): """Splits the file into the directory, basename, and extension. For 'chrome/browser/browser.cc', Split() would return ('chrome/browser', 'browser', '.cc') Returns: A tuple of (directory, basename, extension). """ googlename = self.RepositoryName() project, rest = os.path.split(googlename) return (project,) + os.path.splitext(rest) def BaseName(self): """File base name - text after the final slash, before the final period.""" return self.Split()[1] def Extension(self): """File extension - text following the final period.""" return self.Split()[2] def NoExtension(self): """File has no source file extension.""" return '/'.join(self.Split()[0:2]) def IsSource(self): """File has a source file extension.""" return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') def _ShouldPrintError(category, confidence, linenum): """If confidence >= verbose, category passes filter and is not suppressed.""" # There are three ways we might decide not to print an error message: # a "NOLINT(category)" comment appears in the source, # the verbosity level isn't high enough, or the filters filter it out. if IsErrorSuppressedByNolint(category, linenum): return False if confidence < _cpplint_state.verbose_level: return False is_filtered = False for one_filter in _Filters(): if one_filter.startswith('-'): if category.startswith(one_filter[1:]): is_filtered = True elif one_filter.startswith('+'): if category.startswith(one_filter[1:]): is_filtered = False else: assert False # should have been checked for in SetFilter. if is_filtered: return False return True def Error(filename, linenum, category, confidence, message): """Logs the fact we've found a lint error. We log where the error was found, and also our confidence in the error, that is, how certain we are this is a legitimate style regression, and not a misidentification or a use that's sometimes justified. False positives can be suppressed by the use of "cpplint(category)" comments on the offending line. These are parsed into _error_suppressions. Args: filename: The name of the file containing the error. linenum: The number of the line containing the error. category: A string used to describe the "category" this bug falls under: "whitespace", say, or "runtime". Categories may have a hierarchy separated by slashes: "whitespace/indent". confidence: A number from 1-5 representing a confidence score for the error, with 5 meaning that we are certain of the problem, and 1 meaning that it could be a legitimate construct. message: The error message. """ if _ShouldPrintError(category, confidence, linenum): _cpplint_state.IncrementErrorCount(category) if _cpplint_state.output_format == 'vs7': sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( filename, linenum, message, category, confidence)) else: sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( filename, linenum, message, category, confidence)) # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') # Matches strings. Escape codes should already be removed by ESCAPES. _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"') # Matches characters. Escape codes should already be removed by ESCAPES. _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'") # Matches multi-line C++ comments. # This RE is a little bit more complicated than one might expect, because we # have to take care of space removals tools so we can handle comments inside # statements better. # The current rule is: We only clear spaces from both sides when we're at the # end of the line. Otherwise, we try to remove spaces from the right side, # if this doesn't work we try on left side but only if there's a non-character # on the right. _RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( r"""(\s*/\*.*\*/\s*$| /\*.*\*/\s+| \s+/\*.*\*/(?=\W)| /\*.*\*/)""", re.VERBOSE) def IsCppString(line): """Does line terminate so, that the next symbol is in string constant. This function does not consider single-line nor multi-line comments. Args: line: is a partial line of code starting from the 0..n. Returns: True, if next character appended to 'line' is inside a string constant. """ line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 def FindNextMultiLineCommentStart(lines, lineix): """Find the beginning marker for a multiline comment.""" while lineix < len(lines): if lines[lineix].strip().startswith('/*'): # Only return this marker if the comment goes beyond this line if lines[lineix].strip().find('*/', 2) < 0: return lineix lineix += 1 return len(lines) def FindNextMultiLineCommentEnd(lines, lineix): """We are inside a comment, find the end marker.""" while lineix < len(lines): if lines[lineix].strip().endswith('*/'): return lineix lineix += 1 return len(lines) def RemoveMultiLineCommentsFromRange(lines, begin, end): """Clears a range of lines for multi-line comments.""" # Having // dummy comments makes the lines non-empty, so we will not get # unnecessary blank line warnings later in the code. for i in range(begin, end): lines[i] = '// dummy' def RemoveMultiLineComments(filename, lines, error): """Removes multiline (c-style) comments from lines.""" lineix = 0 while lineix < len(lines): lineix_begin = FindNextMultiLineCommentStart(lines, lineix) if lineix_begin >= len(lines): return lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) if lineix_end >= len(lines): error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, 'Could not find end of multi-line comment') return RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) lineix = lineix_end + 1 def CleanseComments(line): """Removes //-comments and single-line C-style /* */ comments. Args: line: A line of C++ source. Returns: The line with single-line comments removed. """ commentpos = line.find('//') if commentpos != -1 and not IsCppString(line[:commentpos]): line = line[:commentpos].rstrip() # get rid of /* ... */ return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) class CleansedLines(object): """Holds 3 copies of all lines with different preprocessing applied to them. 1) elided member contains lines without strings and comments, 2) lines member contains lines without comments, and 3) raw member contains all the lines without processing. All these three members are of , and of the same length. """ def __init__(self, lines): self.elided = [] self.lines = [] self.raw_lines = lines self.num_lines = len(lines) for linenum in range(len(lines)): self.lines.append(CleanseComments(lines[linenum])) elided = self._CollapseStrings(lines[linenum]) self.elided.append(CleanseComments(elided)) def NumLines(self): """Returns the number of lines represented.""" return self.num_lines @staticmethod def _CollapseStrings(elided): """Collapses strings and chars on a line to simple "" or '' blocks. We nix strings first so we're not fooled by text like '"http://"' Args: elided: The line being processed. Returns: The line with collapsed strings. """ if not _RE_PATTERN_INCLUDE.match(elided): # Remove escaped characters first to make quote/single quote collapsing # basic. Things that look like escaped characters shouldn't occur # outside of strings and chars. elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided) elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided) return elided def CloseExpression(clean_lines, linenum, pos): """If input points to ( or { or [, finds the position that closes it. If lines[linenum][pos] points to a '(' or '{' or '[', finds the linenum/pos that correspond to the closing of the expression. Args: clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. pos: A position on the line. Returns: A tuple (line, linenum, pos) pointer *past* the closing brace, or (line, len(lines), -1) if we never find a close. Note we ignore strings and comments when matching; and the line we return is the 'cleansed' line at linenum. """ line = clean_lines.elided[linenum] startchar = line[pos] if startchar not in '({[': return (line, clean_lines.NumLines(), -1) if startchar == '(': endchar = ')' if startchar == '[': endchar = ']' if startchar == '{': endchar = '}' num_open = line.count(startchar) - line.count(endchar) while linenum < clean_lines.NumLines() and num_open > 0: linenum += 1 line = clean_lines.elided[linenum] num_open += line.count(startchar) - line.count(endchar) # OK, now find the endchar that actually got us back to even endpos = len(line) while num_open >= 0: endpos = line.rfind(')', 0, endpos) num_open -= 1 # chopped off another ) return (line, linenum, endpos + 1) def CheckForCopyright(filename, lines, error): """Logs an error if no Copyright message appears at the top of the file.""" # We'll say it should occur by line 10. Don't forget there's a # dummy line at the front. for line in xrange(1, min(len(lines), 11)): if re.search(r'Copyright', lines[line], re.I): break else: # means no copyright line was found error(filename, 0, 'legal/copyright', 5, 'No copyright message found. ' 'You should have a line: "Copyright [year] "') def GetHeaderGuardCPPVariable(filename): """Returns the CPP variable that should be used as a header guard. Args: filename: The name of a C++ header file. Returns: The CPP variable that should be used as a header guard in the named file. """ # Restores original filename in case that cpplint is invoked from Emacs's # flymake. filename = re.sub(r'_flymake\.h$', '.h', filename) fileinfo = FileInfo(filename) return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' def CheckForHeaderGuard(filename, lines, error): """Checks that the file contains a header guard. Logs an error if no #ifndef header guard is present. For other headers, checks that the full pathname is used. Args: filename: The name of the C++ header file. lines: An array of strings, each representing a line of the file. error: The function to call with any errors found. """ cppvar = GetHeaderGuardCPPVariable(filename) ifndef = None ifndef_linenum = 0 define = None endif = None endif_linenum = 0 for linenum, line in enumerate(lines): linesplit = line.split() if len(linesplit) >= 2: # find the first occurrence of #ifndef and #define, save arg if not ifndef and linesplit[0] == '#ifndef': # set ifndef to the header guard presented on the #ifndef line. ifndef = linesplit[1] ifndef_linenum = linenum if not define and linesplit[0] == '#define': define = linesplit[1] # find the last occurrence of #endif, save entire line if line.startswith('#endif'): endif = line endif_linenum = linenum if not ifndef or not define or ifndef != define: error(filename, 0, 'build/header_guard', 5, 'No #ifndef header guard found, suggested CPP variable is: %s' % cppvar) return # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ # for backward compatibility. #if ifndef != cppvar: # error_level = 0 # if ifndef != cppvar + '_': # error_level = 5 # ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, # error) # error(filename, ifndef_linenum, 'build/header_guard', error_level, # '#ifndef header guard has wrong style, please use: %s' % cppvar) #if endif != ('#endif // %s' % cppvar): # error_level = 0 # if endif != ('#endif // %s' % (cppvar + '_')): # error_level = 5 # ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, # error) # error(filename, endif_linenum, 'build/header_guard', error_level, # '#endif line should be "#endif // %s"' % cppvar) def CheckForUnicodeReplacementCharacters(filename, lines, error): """Logs an error for each line containing Unicode replacement characters. These indicate that either the file contained invalid UTF-8 (likely) or Unicode replacement characters (which it shouldn't). Note that it's possible for this to throw off line numbering if the invalid UTF-8 occurred adjacent to a newline. Args: filename: The name of the current file. lines: An array of strings, each representing a line of the file. error: The function to call with any errors found. """ for linenum, line in enumerate(lines): if u'\ufffd' in line: error(filename, linenum, 'readability/utf8', 5, 'Line contains invalid UTF-8 (or Unicode replacement character).') def CheckForNewlineAtEOF(filename, lines, error): """Logs an error if there is no newline char at the end of the file. Args: filename: The name of the current file. lines: An array of strings, each representing a line of the file. error: The function to call with any errors found. """ # The array lines() was created by adding two newlines to the # original file (go figure), then splitting on \n. # To verify that the file ends in \n, we just have to make sure the # last-but-two element of lines() exists and is empty. if len(lines) < 3 or lines[-2]: error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, 'Could not find a newline character at the end of the file.') def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): """Logs an error if we see /* ... */ or "..." that extend past one line. /* ... */ comments are legit inside macros, for one line. Otherwise, we prefer // comments, so it's ok to warn about the other. Likewise, it's ok for strings to extend across multiple lines, as long as a line continuation character (backslash) terminates each line. Although not currently prohibited by the C++ style guide, it's ugly and unnecessary. We don't do well with either in this lint program, so we warn about both. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ line = clean_lines.elided[linenum] # Remove all \\ (escaped backslashes) from the line. They are OK, and the # second (escaped) slash may trigger later \" detection erroneously. line = line.replace('\\\\', '') if line.count('/*') > line.count('*/'): error(filename, linenum, 'readability/multiline_comment', 5, 'Complex multi-line /*...*/-style comment found. ' 'Lint may give bogus warnings. ' 'Consider replacing these with //-style comments, ' 'with #if 0...#endif, ' 'or with more clearly structured multi-line comments.') #if (line.count('"') - line.count('\\"')) % 2: # error(filename, linenum, 'readability/multiline_string', 5, # 'Multi-line string ("...") found. This lint script doesn\'t ' # 'do well with such strings, and may give bogus warnings. They\'re ' # 'ugly and unnecessary, and you should use concatenation instead".') threading_list = ( ('asctime(', 'asctime_r('), ('ctime(', 'ctime_r('), ('getgrgid(', 'getgrgid_r('), ('getgrnam(', 'getgrnam_r('), ('getlogin(', 'getlogin_r('), ('getpwnam(', 'getpwnam_r('), ('getpwuid(', 'getpwuid_r('), ('gmtime(', 'gmtime_r('), ('localtime(', 'localtime_r('), ('rand(', 'rand_r('), ('readdir(', 'readdir_r('), ('strtok(', 'strtok_r('), ('ttyname(', 'ttyname_r('), ) def CheckPosixThreading(filename, clean_lines, linenum, error): """Checks for calls to thread-unsafe functions. Much code has been originally written without consideration of multi-threading. Also, engineers are relying on their old experience; they have learned posix before threading extensions were added. These tests guide the engineers to use thread-safe functions (when using posix directly). Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ line = clean_lines.elided[linenum] for single_thread_function, multithread_safe_function in threading_list: ix = line.find(single_thread_function) # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and line[ix - 1] not in ('_', '.', '>'))): error(filename, linenum, 'runtime/threadsafe_fn', 2, 'Consider using ' + multithread_safe_function + '...) instead of ' + single_thread_function + '...) for improved thread safety.') # Matches invalid increment: *count++, which moves pointer instead of # incrementing a value. _RE_PATTERN_INVALID_INCREMENT = re.compile( r'^\s*\*\w+(\+\+|--);') def CheckInvalidIncrement(filename, clean_lines, linenum, error): """Checks for invalid increment *count++. For example following function: void increment_counter(int* count) { *count++; } is invalid, because it effectively does count++, moving pointer, and should be replaced with ++*count, (*count)++ or *count += 1. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ line = clean_lines.elided[linenum] if _RE_PATTERN_INVALID_INCREMENT.match(line): error(filename, linenum, 'runtime/invalid_increment', 5, 'Changing pointer instead of value (or unused value of operator*).') class _ClassInfo(object): """Stores information about a class.""" def __init__(self, name, clean_lines, linenum): self.name = name self.linenum = linenum self.seen_open_brace = False self.is_derived = False self.virtual_method_linenumber = None self.has_virtual_destructor = False self.brace_depth = 0 # Try to find the end of the class. This will be confused by things like: # class A { # } *x = { ... # # But it's still good enough for CheckSectionSpacing. self.last_line = 0 depth = 0 for i in range(linenum, clean_lines.NumLines()): line = clean_lines.lines[i] depth += line.count('{') - line.count('}') if not depth: self.last_line = i break class _ClassState(object): """Holds the current state of the parse relating to class declarations. It maintains a stack of _ClassInfos representing the parser's guess as to the current nesting of class declarations. The innermost class is at the top (back) of the stack. Typically, the stack will either be empty or have exactly one entry. """ def __init__(self): self.classinfo_stack = [] def CheckFinished(self, filename, error): """Checks that all classes have been completely parsed. Call this when all lines in a file have been processed. Args: filename: The name of the current file. error: The function to call with any errors found. """ if self.classinfo_stack: # Note: This test can result in false positives if #ifdef constructs # get in the way of brace matching. See the testBuildClass test in # cpplint_unittest.py for an example of this. error(filename, self.classinfo_stack[0].linenum, 'build/class', 5, 'Failed to find complete declaration of class %s' % self.classinfo_stack[0].name) def CheckForNonStandardConstructs(filename, clean_lines, linenum, class_state, error): """Logs an error if we see certain non-ANSI constructs ignored by gcc-2. Complain about several constructs which gcc-2 accepts, but which are not standard C++. Warning about these in lint is one way to ease the transition to new compilers. - put storage class first (e.g. "static const" instead of "const static"). - "%lld" instead of %qd" in printf-type functions. - "%1$d" is non-standard in printf-type functions. - "\%" is an undefined character escape sequence. - text after #endif is not allowed. - invalid inner-style forward declaration. - >? and ?= and )\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', line): error(filename, linenum, 'build/deprecated', 3, '>? and ))?' # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' error(filename, linenum, 'runtime/member_string_references', 2, 'const string& members are dangerous. It is much better to use ' 'alternatives, such as pointers or simple constants.') # Track class entry and exit, and attempt to find cases within the # class declaration that don't meet the C++ style # guidelines. Tracking is very dependent on the code matching Google # style guidelines, but it seems to perform well enough in testing # to be a worthwhile addition to the checks. classinfo_stack = class_state.classinfo_stack # Look for a class declaration. The regexp accounts for decorated classes # such as in: # class LOCKABLE API Object { # }; class_decl_match = Match( r'\s*(template\s*<[\w\s<>,:]*>\s*)?' '(class|struct)\s+([A-Z_]+\s+)*(\w+(::\w+)*)', line) if class_decl_match: classinfo_stack.append(_ClassInfo( class_decl_match.group(4), clean_lines, linenum)) # Everything else in this function uses the top of the stack if it's # not empty. if not classinfo_stack: return classinfo = classinfo_stack[-1] # If the opening brace hasn't been seen look for it and also # parent class declarations. if not classinfo.seen_open_brace: # If the line has a ';' in it, assume it's a forward declaration or # a single-line class declaration, which we won't process. if line.find(';') != -1: classinfo_stack.pop() return classinfo.seen_open_brace = (line.find('{') != -1) # Look for a bare ':' if Search('(^|[^:]):($|[^:])', line): classinfo.is_derived = True if not classinfo.seen_open_brace: return # Everything else in this function is for after open brace # The class may have been declared with namespace or classname qualifiers. # The constructor and destructor will not have those qualifiers. base_classname = classinfo.name.split('::')[-1] # Look for single-argument constructors that aren't marked explicit. # Technically a valid construct, but against style. args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' % re.escape(base_classname), line) if (args and args.group(1) != 'void' and not Match(r'(const\s+)?%s\s*(?:<\w+>\s*)?&' % re.escape(base_classname), args.group(1).strip())): error(filename, linenum, 'runtime/explicit', 5, 'Single-argument constructors should be marked explicit.') # Look for methods declared virtual. if Search(r'\bvirtual\b', line): classinfo.virtual_method_linenumber = linenum # Only look for a destructor declaration on the same line. It would # be extremely unlikely for the destructor declaration to occupy # more than one line. if Search(r'~%s\s*\(' % base_classname, line): classinfo.has_virtual_destructor = True # Look for class end. brace_depth = classinfo.brace_depth brace_depth = brace_depth + line.count('{') - line.count('}') if brace_depth <= 0: classinfo = classinfo_stack.pop() # Try to detect missing virtual destructor declarations. # For now, only warn if a non-derived class with virtual methods lacks # a virtual destructor. This is to make it less likely that people will # declare derived virtual destructors without declaring the base # destructor virtual. if ((classinfo.virtual_method_linenumber is not None) and (not classinfo.has_virtual_destructor) and (not classinfo.is_derived)): # Only warn for base classes error(filename, classinfo.linenum, 'runtime/virtual', 4, 'The class %s probably needs a virtual destructor due to ' 'having virtual method(s), one declared at line %d.' % (classinfo.name, classinfo.virtual_method_linenumber)) else: classinfo.brace_depth = brace_depth def CheckSpacingForFunctionCall(filename, line, linenum, error): """Checks for the correctness of various spacing around function calls. Args: filename: The name of the current file. line: The text of the line to check. linenum: The number of the line to check. error: The function to call with any errors found. """ # Since function calls often occur inside if/for/while/switch # expressions - which have their own, more liberal conventions - we # first see if we should be looking inside such an expression for a # function call, to which we can apply more strict standards. fncall = line # if there's no control flow construct, look at whole line for pattern in (r'\bif\s*\((.*)\)\s*{', r'\bfor\s*\((.*)\)\s*{', r'\bwhile\s*\((.*)\)\s*[{;]', r'\bswitch\s*\((.*)\)\s*{'): match = Search(pattern, line) if match: fncall = match.group(1) # look inside the parens for function calls break # Except in if/for/while/switch, there should never be space # immediately inside parens (eg "f( 3, 4 )"). We make an exception # for nested parens ( (a+b) + c ). Likewise, there should never be # a space before a ( when it's a function argument. I assume it's a # function argument when the char before the whitespace is legal in # a function name (alnum + _) and we're not starting a macro. Also ignore # pointers and references to arrays and functions coz they're too tricky: # we use a very simple way to recognize these: # " (something)(maybe-something)" or # " (something)(maybe-something," or # " (something)[something]" # Note that we assume the contents of [] to be short enough that # they'll never need to wrap. if ( # Ignore control structures. not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and # Ignore pointers/references to functions. not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and # Ignore pointers/references to arrays. not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call error(filename, linenum, 'whitespace/parens', 4, 'Extra space after ( in function call') elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): error(filename, linenum, 'whitespace/parens', 2, 'Extra space after (') if (Search(r'\w\s+\(', fncall) and not Search(r'#\s*define|typedef', fncall) and not Search(r'<.*',fncall)): error(filename, linenum, 'whitespace/parens', 4, 'Extra space before ( in function call') # If the ) is followed only by a newline or a { + newline, assume it's # part of a control statement (if/while/etc), and don't complain if Search(r'[^)]\s+\)\s*[^{\s]', fncall): # If the closing parenthesis is preceded by only whitespaces, # try to give a more descriptive error message. if Search(r'^\s+\)', fncall): error(filename, linenum, 'whitespace/parens', 2, 'Closing ) should be moved to the previous line') else: error(filename, linenum, 'whitespace/parens', 2, 'Extra space before )') def IsBlankLine(line): """Returns true if the given line is blank. We consider a line to be blank if the line is empty or consists of only white spaces. Args: line: A line of a string. Returns: True, if the given line is blank. """ return not line or line.isspace() def CheckForFunctionLengths(filename, clean_lines, linenum, function_state, error): """Reports for long function bodies. For an overview why this is done, see: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions Uses a simplistic algorithm assuming other style guidelines (especially spacing) are followed. Only checks unindented functions, so class members are unchecked. Trivial bodies are unchecked, so constructors with huge initializer lists may be missed. Blank/comment lines are not counted so as to avoid encouraging the removal of vertical space and comments just to get through a lint check. NOLINT *on the last line of a function* disables this check. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. function_state: Current function name and lines in body so far. error: The function to call with any errors found. """ lines = clean_lines.lines line = lines[linenum] raw = clean_lines.raw_lines raw_line = raw[linenum] joined_line = '' starting_func = False regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... match_result = Match(regexp, line) if match_result: # If the name is all caps and underscores, figure it's a macro and # ignore it, unless it's TEST or TEST_F. function_name = match_result.group(1).split()[-1] if function_name == 'TEST' or function_name == 'TEST_F' or ( not Match(r'[A-Z_]+$', function_name)): starting_func = True if starting_func: body_found = False for start_linenum in xrange(linenum, clean_lines.NumLines()): start_line = lines[start_linenum] joined_line += ' ' + start_line.lstrip() if Search(r'(;|})', start_line): # Declarations and trivial functions body_found = True break # ... ignore elif Search(r'{', start_line): body_found = True function = Search(r'((\w|:)*)\(', line).group(1) if Match(r'TEST', function): # Handle TEST... macros parameter_regexp = Search(r'(\(.*\))', joined_line) if parameter_regexp: # Ignore bad syntax function += parameter_regexp.group(1) else: function += '()' function_state.Begin(function) break if not body_found: # No body for the function (or evidence of a non-function) was found. error(filename, linenum, 'readability/fn_size', 5, 'Lint failed to find start of function body.') elif Match(r'^\}\s*$', line): # function end function_state.Check(error, filename, linenum) function_state.End() elif not Match(r'^\s*$', line): function_state.Count() # Count non-blank/non-comment lines. _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') def CheckComment(comment, filename, linenum, error): """Checks for common mistakes in TODO comments. Args: comment: The text of the comment from the line in question. filename: The name of the current file. linenum: The number of the line to check. error: The function to call with any errors found. """ match = _RE_PATTERN_TODO.match(comment) if match: # One whitespace is correct; zero whitespace is handled elsewhere. leading_whitespace = match.group(1) if len(leading_whitespace) > 1: error(filename, linenum, 'whitespace/todo', 2, 'Too many spaces before TODO') #username = match.group(2) #if not username: # error(filename, linenum, 'readability/todo', 2, # 'Missing username in TODO; it should look like ' # '"// TODO(my_username): Stuff."') middle_whitespace = match.group(3) # Comparisons made explicit for correctness -- pylint: disable-msg=C6403 if middle_whitespace != ' ' and middle_whitespace != '': error(filename, linenum, 'whitespace/todo', 2, 'TODO(my_username) should be followed by a space') def CheckSpacing(filename, clean_lines, linenum, error): """Checks for the correctness of various spacing issues in the code. Things we check for: spaces around operators, spaces after if/for/while/switch, no spaces around parens in function calls, two spaces between code and comment, don't start a block with a blank line, don't end a function with a blank line, don't add a blank line after public/protected/private, don't have too many blank lines in a row. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ raw = clean_lines.raw_lines line = raw[linenum] # Before nixing comments, check if the line is blank for no good # reason. This includes the first line after a block is opened, and # blank lines at the end of a function (ie, right before a line like '}' if IsBlankLine(line): elided = clean_lines.elided prev_line = elided[linenum - 1] prevbrace = prev_line.rfind('{') # TODO(unknown): Don't complain if line before blank line, and line after, # both start with alnums and are indented the same amount. # This ignores whitespace at the start of a namespace block # because those are not usually indented. if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1 and prev_line[:prevbrace].find('namespace') == -1): # OK, we have a blank line at the start of a code block. Before we # complain, we check if it is an exception to the rule: The previous # non-empty line has the parameters of a function header that are indented # 4 spaces (because they did not fit in a 80 column line when placed on # the same line as the function name). We also check for the case where # the previous line is indented 6 spaces, which may happen when the # initializers of a constructor do not fit into a 80 column line. exception = False if Match(r' {6}\w', prev_line): # Initializer list? # We are looking for the opening column of initializer list, which # should be indented 4 spaces to cause 6 space indentation afterwards. search_position = linenum-2 while (search_position >= 0 and Match(r' {6}\w', elided[search_position])): search_position -= 1 exception = (search_position >= 0 and elided[search_position][:5] == ' :') else: # Search for the function arguments or an initializer list. We use a # simple heuristic here: If the line is indented 4 spaces; and we have a # closing paren, without the opening paren, followed by an opening brace # or colon (for initializer lists) we assume that it is the last line of # a function header. If we have a colon indented 4 spaces, it is an # initializer list. exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', prev_line) or Match(r' {4}:', prev_line)) if not exception: error(filename, linenum, 'whitespace/blank_line', 2, 'Blank line at the start of a code block. Is this needed?') # This doesn't ignore whitespace at the end of a namespace block # because that is too hard without pairing open/close braces; # however, a special exception is made for namespace closing # brackets which have a comment containing "namespace". # # Also, ignore blank lines at the end of a block in a long if-else # chain, like this: # if (condition1) { # // Something followed by a blank line # # } else if (condition2) { # // Something else # } if linenum + 1 < clean_lines.NumLines(): next_line = raw[linenum + 1] if (next_line and Match(r'\s*}', next_line) and next_line.find('namespace') == -1 and next_line.find('} else ') == -1): error(filename, linenum, 'whitespace/blank_line', 3, 'Blank line at the end of a code block. Is this needed?') #matched = Match(r'\s*(public|protected|private):', prev_line) #if matched: # error(filename, linenum, 'whitespace/blank_line', 3, # 'Do not leave a blank line after "%s:"' % matched.group(1)) # Next, we complain if there's a comment too near the text commentpos = line.find('//') if commentpos != -1: # Check if the // may be in quotes. If so, ignore it # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 if (line.count('"', 0, commentpos) - line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes # Allow one space for new scopes, two spaces otherwise: if (not Match(r'^\s*{ //', line) and ((commentpos >= 1 and line[commentpos-1] not in string.whitespace) or (commentpos >= 2 and line[commentpos-2] not in string.whitespace))): error(filename, linenum, 'whitespace/comments', 2, 'At least two spaces is best between code and comments') # There should always be a space between the // and the comment commentend = commentpos + 2 if commentend < len(line) and not line[commentend] == ' ': # but some lines are exceptions -- e.g. if they're big # comment delimiters like: # //---------------------------------------------------------- # or are an empty C++ style Doxygen comment, like: # /// # or they begin with multiple slashes followed by a space: # //////// Header comment match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or Search(r'^/$', line[commentend:]) or Search(r'^/+ ', line[commentend:])) if not match: error(filename, linenum, 'whitespace/comments', 4, 'Should have a space between // and comment') CheckComment(line[commentpos:], filename, linenum, error) line = clean_lines.elided[linenum] # get rid of comments and strings # Don't try to do spacing checks for operator methods line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". # Otherwise not. Note we only check for non-spaces on *both* sides; # sometimes people put non-spaces on one side when aligning ='s among # many lines (not that this is behavior that I approve of...) if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): error(filename, linenum, 'whitespace/operators', 4, 'Missing spaces around =') # It's ok not to have spaces around binary operators like + - * /, but if # there's too little whitespace, we get concerned. It's hard to tell, # though, so we punt on this one for now. TODO. # You should always have whitespace around binary operators. # Alas, we can't test < or > because they're legitimately used sans spaces # (a->b, vector a). The only time we can tell is a < with no >, and # only if it's not template params list spilling into the next line. match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) if not match: # Note that while it seems that the '<[^<]*' term in the following # regexp could be simplified to '<.*', which would indeed match # the same class of strings, the [^<] means that searching for the # regexp takes linear rather than quadratic time. if not Search(r'<[^<]*,\s*$', line): # template params spill match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line) if match: error(filename, linenum, 'whitespace/operators', 3, 'Missing spaces around %s' % match.group(1)) # We allow no-spaces around << and >> when used like this: 10<<20, but # not otherwise (particularly, not when used as streams) match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line) if match: error(filename, linenum, 'whitespace/operators', 3, 'Missing spaces around %s' % match.group(1)) # There shouldn't be space around unary operators match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) if match: error(filename, linenum, 'whitespace/operators', 4, 'Extra space for operator %s' % match.group(1)) # A pet peeve of mine: no spaces after an if, while, switch, or for match = Search(r' (if\(|for\(|while\(|switch\()', line) if match: error(filename, linenum, 'whitespace/parens', 5, 'Missing space before ( in %s' % match.group(1)) # For if/for/while/switch, the left and right parens should be # consistent about how many spaces are inside the parens, and # there should either be zero or one spaces inside the parens. # We don't want: "if ( foo)" or "if ( foo )". # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. match = Search(r'\b(if|for|while|switch)\s*' r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', line) if match: if len(match.group(2)) != len(match.group(4)): if not (match.group(3) == ';' and len(match.group(2)) == 1 + len(match.group(4)) or not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): error(filename, linenum, 'whitespace/parens', 5, 'Mismatching spaces inside () in %s' % match.group(1)) if not len(match.group(2)) in [0, 1]: error(filename, linenum, 'whitespace/parens', 5, 'Should have zero or one spaces inside ( and ) in %s' % match.group(1)) # You should always have a space after a comma (either as fn arg or operator) if Search(r',[^\s]', line): error(filename, linenum, 'whitespace/comma', 3, 'Missing space after ,') # You should always have a space after a semicolon # except for few corner cases # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more # space after ; if Search(r';[^\s};\\)/]', line): error(filename, linenum, 'whitespace/semicolon', 3, 'Missing space after ;') # Next we will look for issues with function calls. CheckSpacingForFunctionCall(filename, line, linenum, error) # Except after an opening paren, or after another opening brace (in case of # an initializer list, for instance), you should have spaces before your # braces. And since you should never have braces at the beginning of a line, # this is an easy test. if Search(r'[^ ({]{', line): error(filename, linenum, 'whitespace/braces', 5, 'Missing space before {') # Make sure '} else {' has spaces. if Search(r'}else', line): error(filename, linenum, 'whitespace/braces', 5, 'Missing space before else') # You shouldn't have spaces before your brackets, except maybe after # 'delete []' or 'new char * []'. if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line): error(filename, linenum, 'whitespace/braces', 5, 'Extra space before [') # You shouldn't have a space before a semicolon at the end of the line. # There's a special case for "for" since the style guide allows space before # the semicolon there. if Search(r':\s*;\s*$', line): error(filename, linenum, 'whitespace/semicolon', 5, 'Semicolon defining empty statement. Use { } instead.') elif Search(r'^\s*;\s*$', line): error(filename, linenum, 'whitespace/semicolon', 5, 'Line contains only semicolon. If this should be an empty statement, ' 'use { } instead.') elif (Search(r'\s+;\s*$', line) and not Search(r'\bfor\b', line)): error(filename, linenum, 'whitespace/semicolon', 5, 'Extra space before last semicolon. If this should be an empty ' 'statement, use { } instead.') def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): """Checks for additional blank line issues related to sections. Currently the only thing checked here is blank line before protected/private. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. class_info: A _ClassInfo objects. linenum: The number of the line to check. error: The function to call with any errors found. """ # Skip checks if the class is small, where small means 25 lines or less. # 25 lines seems like a good cutoff since that's the usual height of # terminals, and any class that can't fit in one screen can't really # be considered "small". # # Also skip checks if we are on the first line. This accounts for # classes that look like # class Foo { public: ... }; # # If we didn't find the end of the class, last_line would be zero, # and the check will be skipped by the first condition. if (class_info.last_line - class_info.linenum <= 24 or linenum <= class_info.linenum): return matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum]) if matched: # Issue warning if the line before public/protected/private was # not a blank line, but don't do this if the previous line contains # "class" or "struct". This can happen two ways: # - We are at the beginning of the class. # - We are forward-declaring an inner class that is semantically # private, but needed to be public for implementation reasons. prev_line = clean_lines.lines[linenum - 1] if (not IsBlankLine(prev_line) and not Search(r'\b(class|struct)\b', prev_line)): # Try a bit harder to find the beginning of the class. This is to # account for multi-line base-specifier lists, e.g.: # class Derived # : public Base { end_class_head = class_info.linenum for i in range(class_info.linenum, linenum): if Search(r'\{\s*$', clean_lines.lines[i]): end_class_head = i break if end_class_head < linenum - 1: error(filename, linenum, 'whitespace/blank_line', 3, '"%s:" should be preceded by a blank line' % matched.group(1)) def GetPreviousNonBlankLine(clean_lines, linenum): """Return the most recent non-blank line and its line number. Args: clean_lines: A CleansedLines instance containing the file contents. linenum: The number of the line to check. Returns: A tuple with two elements. The first element is the contents of the last non-blank line before the current line, or the empty string if this is the first non-blank line. The second is the line number of that line, or -1 if this is the first non-blank line. """ prevlinenum = linenum - 1 while prevlinenum >= 0: prevline = clean_lines.elided[prevlinenum] if not IsBlankLine(prevline): # if not a blank line... return (prevline, prevlinenum) prevlinenum -= 1 return ('', -1) def CheckBraces(filename, clean_lines, linenum, error): """Looks for misplaced braces (e.g. at the end of line). Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ line = clean_lines.elided[linenum] # get rid of comments and strings if Search(r'[\);:}]\s*{\s*$', line): error(filename, linenum, 'whitespace/braces', 4, '{ should never be at the end of the previous line') # An else clause should be on the same line as the preceding closing brace. if Match(r'\s*}\s*else\s*', line): error(filename, linenum, 'whitespace/newline', 4, 'An else should not appear on the same line as the previous }') if Match(r'\s*else\s*{', line): error(filename, linenum, 'whitespace/newline', 4, 'An else should not appear on the same line as the next {') # If braces come on one side of an else, they should be on both. # However, we have to worry about "else if" that spans multiple lines! if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if # find the ( after the if pos = line.find('else if') pos = line.find('(', pos) if pos > 0: (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) if endline[endpos:].find('{') == -1: # must be brace after if error(filename, linenum, 'readability/braces', 5, 'If an else has a brace on one side, it should have it on both') else: # common case: else not followed by a multi-line if error(filename, linenum, 'readability/braces', 5, 'If an else has a brace on one side, it should have it on both') # Likewise, an else should never have the else clause on the same line if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): error(filename, linenum, 'whitespace/newline', 4, 'Else clause should never be on same line as else (use 2 lines)') # In the same way, a do/while should never be on one line if Match(r'\s*do [^\s{]', line): error(filename, linenum, 'whitespace/newline', 4, 'do/while clauses should not be on a single line') # Braces shouldn't be followed by a ; unless they're defining a struct # or initializing an array. # We can't tell in general, but we can for some common cases. prevlinenum = linenum while True: (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum) if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'): line = prevline + line else: break if (Search(r'{.*}\s*;', line) and line.count('{') == line.count('}') and not Search(r'struct|class|enum|\s*=\s*{', line)): error(filename, linenum, 'readability/braces', 4, "You don't need a ; after a }") def ReplaceableCheck(operator, macro, line): """Determine whether a basic CHECK can be replaced with a more specific one. For example suggest using CHECK_EQ instead of CHECK(a == b) and similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE. Args: operator: The C++ operator used in the CHECK. macro: The CHECK or EXPECT macro being called. line: The current source line. Returns: True if the CHECK can be replaced with a more specific one. """ # This matches decimal and hex integers, strings, and chars (in that order). match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')' # Expression to match two sides of the operator with something that # looks like a literal, since CHECK(x == iterator) won't compile. # This means we can't catch all the cases where a more specific # CHECK is possible, but it's less annoying than dealing with # extraneous warnings. match_this = (r'\s*' + macro + r'\((\s*' + match_constant + r'\s*' + operator + r'[^<>].*|' r'.*[^<>]' + operator + r'\s*' + match_constant + r'\s*\))') # Don't complain about CHECK(x == NULL) or similar because # CHECK_EQ(x, NULL) won't compile (requires a cast). # Also, don't complain about more complex boolean expressions # involving && or || such as CHECK(a == b || c == d). return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line) def CheckCheck(filename, clean_lines, linenum, error): """Checks the use of CHECK and EXPECT macros. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ # Decide the set of replacement macros that should be suggested raw_lines = clean_lines.raw_lines current_macro = '' for macro in _CHECK_MACROS: if raw_lines[linenum].find(macro) >= 0: current_macro = macro break if not current_macro: # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT' return line = clean_lines.elided[linenum] # get rid of comments and strings # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc. for operator in ['==', '!=', '>=', '>', '<=', '<']: if ReplaceableCheck(operator, current_macro, line): error(filename, linenum, 'readability/check', 2, 'Consider using %s instead of %s(a %s b)' % ( _CHECK_REPLACEMENT[current_macro][operator], current_macro, operator)) break def GetLineWidth(line): """Determines the width of the line in column positions. Args: line: A string, which may be a Unicode string. Returns: The width of the line in column positions, accounting for Unicode combining characters and wide characters. """ if isinstance(line, unicode): width = 0 for uc in unicodedata.normalize('NFC', line): if unicodedata.east_asian_width(uc) in ('W', 'F'): width += 2 elif not unicodedata.combining(uc): width += 1 return width else: return len(line) def CheckStyle(filename, clean_lines, linenum, file_extension, class_state, error): """Checks rules from the 'C++ style rules' section of cppguide.html. Most of these rules are hard to test (naming, comment style), but we do what we can. In particular we check for 2-space indents, line lengths, tab usage, spaces inside code, etc. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. file_extension: The extension (without the dot) of the filename. error: The function to call with any errors found. """ raw_lines = clean_lines.raw_lines line = raw_lines[linenum] if line.find('\t') != -1: error(filename, linenum, 'whitespace/tab', 1, 'Tab found; better to use spaces') # One or three blank spaces at the beginning of the line is weird; it's # hard to reconcile that with 2-space indents. # NOTE: here are the conditions rob pike used for his tests. Mine aren't # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces # if(RLENGTH > 20) complain = 0; # if(match($0, " +(error|private|public|protected):")) complain = 0; # if(match(prev, "&& *$")) complain = 0; # if(match(prev, "\\|\\| *$")) complain = 0; # if(match(prev, "[\",=><] *$")) complain = 0; # if(match($0, " <<")) complain = 0; # if(match(prev, " +for \\(")) complain = 0; # if(prevodd && match(prevprev, " +for \\(")) complain = 0; initial_spaces = 0 cleansed_line = clean_lines.elided[linenum] while initial_spaces < len(line) and line[initial_spaces] == ' ': initial_spaces += 1 if line and line[-1].isspace(): error(filename, linenum, 'whitespace/end_of_line', 4, 'Line ends in whitespace. Consider deleting these extra spaces.') # There are certain situations we allow one space, notably for labels elif ((initial_spaces == 1 or initial_spaces == 3) and not Match(r'\s*\w+\s*:\s*$', cleansed_line)): error(filename, linenum, 'whitespace/indent', 3, 'Weird number of spaces at line-start. ' 'Are you using a 2-space indent?') # Labels should always be indented at least one space. elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$', line): error(filename, linenum, 'whitespace/labels', 4, 'Labels should always be indented at least one space. ' 'If this is a member-initializer list in a constructor or ' 'the base class list in a class definition, the colon should ' 'be on the following line.') # Check if the line is a header guard. is_header_guard = False if file_extension == 'h': cppvar = GetHeaderGuardCPPVariable(filename) if (line.startswith('#ifndef %s' % cppvar) or line.startswith('#define %s' % cppvar) or line.startswith('#endif // %s' % cppvar)): is_header_guard = True # #include lines and header guards can be long, since there's no clean way to # split them. # # URLs can be long too. It's possible to split these, but it makes them # harder to cut&paste. # # The "$Id:...$" comment may also get very long without it being the # developers fault. if (not line.startswith('#include') and not is_header_guard and not Match(r'^\s*//.*http(s?)://\S*$', line) and not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): line_width = GetLineWidth(line) if line_width > 100: error(filename, linenum, 'whitespace/line_length', 4, 'Lines should very rarely be longer than 100 characters') elif line_width > 80: error(filename, linenum, 'whitespace/line_length', 2, 'Lines should be <= 80 characters long') if (cleansed_line.count(';') > 1 and # for loops are allowed two ;'s (and may run over two lines). cleansed_line.find('for') == -1 and (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and # It's ok to have many commands in a switch case that fits in 1 line not ((cleansed_line.find('case ') != -1 or cleansed_line.find('default:') != -1) and cleansed_line.find('break;') != -1)): error(filename, linenum, 'whitespace/newline', 4, 'More than one command on the same line') # Some more style checks CheckBraces(filename, clean_lines, linenum, error) CheckSpacing(filename, clean_lines, linenum, error) CheckCheck(filename, clean_lines, linenum, error) if class_state and class_state.classinfo_stack: CheckSectionSpacing(filename, clean_lines, class_state.classinfo_stack[-1], linenum, error) _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') # Matches the first component of a filename delimited by -s and _s. That is: # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' # _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' # _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' # _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' _RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') def _DropCommonSuffixes(filename): """Drops common suffixes like _test.cc or -inl.h from filename. For example: >>> _DropCommonSuffixes('foo/foo-inl.h') 'foo/foo' >>> _DropCommonSuffixes('foo/bar/foo.cc') 'foo/bar/foo' >>> _DropCommonSuffixes('foo/foo_internal.h') 'foo/foo' >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') 'foo/foo_unusualinternal' Args: filename: The input filename. Returns: The filename with the common suffix removed. """ for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', 'inl.h', 'impl.h', 'internal.h'): if (filename.endswith(suffix) and len(filename) > len(suffix) and filename[-len(suffix) - 1] in ('-', '_')): return filename[:-len(suffix) - 1] return os.path.splitext(filename)[0] def _IsTestFilename(filename): """Determines if the given filename has a suffix that identifies it as a test. Args: filename: The input filename. Returns: True if 'filename' looks like a test, False otherwise. """ if (filename.endswith('_test.cc') or filename.endswith('_unittest.cc') or filename.endswith('_regtest.cc')): return True else: return False def _ClassifyInclude(fileinfo, include, is_system): """Figures out what kind of header 'include' is. Args: fileinfo: The current file cpplint is running over. A FileInfo instance. include: The path to a #included file. is_system: True if the #include used <> rather than "". Returns: One of the _XXX_HEADER constants. For example: >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) _C_SYS_HEADER >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) _CPP_SYS_HEADER >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) _LIKELY_MY_HEADER >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), ... 'bar/foo_other_ext.h', False) _POSSIBLE_MY_HEADER >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) _OTHER_HEADER """ # This is a list of all standard c++ header files, except # those already checked for above. is_stl_h = include in _STL_HEADERS is_cpp_h = is_stl_h or include in _CPP_HEADERS or include.find(".hpp") or include.find(".hh") > 0 if is_system: if is_cpp_h: return _CPP_SYS_HEADER else: return _C_SYS_HEADER # If the target file and the include we're checking share a # basename when we drop common extensions, and the include # lives in . , then it's likely to be owned by the target file. target_dir, target_base = ( os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) if target_base == include_base and ( include_dir == target_dir or include_dir == os.path.normpath(target_dir + '/../public')): return _LIKELY_MY_HEADER # If the target and include share some initial basename # component, it's possible the target is implementing the # include, so it's allowed to be first, but we'll never # complain if it's not there. target_first_component = _RE_FIRST_COMPONENT.match(target_base) include_first_component = _RE_FIRST_COMPONENT.match(include_base) if (target_first_component and include_first_component and target_first_component.group(0) == include_first_component.group(0)): return _POSSIBLE_MY_HEADER return _OTHER_HEADER def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): """Check rules that are applicable to #include lines. Strings on #include lines are NOT removed from elided line, to make certain tasks easier. However, to prevent false positives, checks applicable to #include lines in CheckLanguage must be put here. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. include_state: An _IncludeState instance in which the headers are inserted. error: The function to call with any errors found. """ fileinfo = FileInfo(filename) line = clean_lines.lines[linenum] # "include" should use the new style "foo/bar.h" instead of just "bar.h" #if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): # error(filename, linenum, 'build/include', 4, # 'Include the directory when naming .h files') # we shouldn't include a file more than once. actually, there are a # handful of instances where doing so is okay, but in general it's # not. match = _RE_PATTERN_INCLUDE.search(line) if match: include = match.group(2) is_system = (match.group(1) == '<') if include in include_state: error(filename, linenum, 'build/include', 4, '"%s" already included at %s:%s' % (include, filename, include_state[include])) else: include_state[include] = linenum # We want to ensure that headers appear in the right order: # 1) for foo.cc, foo.h (preferred location) # 2) c system files # 3) cpp system files # 4) for foo.cc, foo.h (deprecated location) # 5) other google headers # # We classify each include statement as one of those 5 types # using a number of techniques. The include_state object keeps # track of the highest type seen, and complains if we see a # lower type after that. error_message = include_state.CheckNextIncludeOrder( _ClassifyInclude(fileinfo, include, is_system)) if error_message: error(filename, linenum, 'build/include_order', 4, '%s. Should be: c system, c++ system, other, %s.h .' % (error_message, fileinfo.BaseName())) if not include_state.IsInAlphabeticalOrder(include): error(filename, linenum, 'build/include_alpha', 4, 'Include "%s" not in alphabetical order' % include) # Look for any of the stream classes that are part of standard C++. #match = _RE_PATTERN_INCLUDE.match(line) #if match: # include = match.group(2) # if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): # # Many unit tests use cout, so we exempt them. # if not _IsTestFilename(filename): # error(filename, linenum, 'readability/streams', 3, # 'Streams are highly discouraged.') def _GetTextInside(text, start_pattern): """Retrieves all the text between matching open and close parentheses. Given a string of lines and a regular expression string, retrieve all the text following the expression and between opening punctuation symbols like (, [, or {, and the matching close-punctuation symbol. This properly nested occurrences of the punctuations, so for the text like printf(a(), b(c())); a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. start_pattern must match string having an open punctuation symbol at the end. Args: text: The lines to extract text. Its comments and strings must be elided. It can be single line and can span multiple lines. start_pattern: The regexp string indicating where to start extracting the text. Returns: The extracted text. None if either the opening string or ending punctuation could not be found. """ # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably # rewritten to use _GetTextInside (and use inferior regexp matching today). # Give opening punctuations to get the matching close-punctuations. matching_punctuation = {'(': ')', '{': '}', '[': ']'} closing_punctuation = set(matching_punctuation.itervalues()) # Find the position to start extracting text. match = re.search(start_pattern, text, re.M) if not match: # start_pattern not found in text. return None start_position = match.end(0) assert start_position > 0, ( 'start_pattern must ends with an opening punctuation.') assert text[start_position - 1] in matching_punctuation, ( 'start_pattern must ends with an opening punctuation.') # Stack of closing punctuations we expect to have in text after position. punctuation_stack = [matching_punctuation[text[start_position - 1]]] position = start_position while punctuation_stack and position < len(text): if text[position] == punctuation_stack[-1]: punctuation_stack.pop() elif text[position] in closing_punctuation: # A closing punctuation without matching opening punctuations. return None elif text[position] in matching_punctuation: punctuation_stack.append(matching_punctuation[text[position]]) position += 1 if punctuation_stack: # Opening punctuations left without matching close-punctuations. return None # punctuations match. return text[start_position:position - 1] def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state, error): """Checks rules from the 'C++ language rules' section of cppguide.html. Some of these rules are hard to test (function overloading, using uint32 inappropriately), but we do the best we can. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. file_extension: The extension (without the dot) of the filename. include_state: An _IncludeState instance in which the headers are inserted. error: The function to call with any errors found. """ # If the line is empty or consists of entirely a comment, no need to # check it. line = clean_lines.elided[linenum] if not line: return match = _RE_PATTERN_INCLUDE.search(line) if match: CheckIncludeLine(filename, clean_lines, linenum, include_state, error) return # Create an extended_line, which is the concatenation of the current and # next lines, for more effective checking of code that may span more than one # line. if linenum + 1 < clean_lines.NumLines(): extended_line = line + clean_lines.elided[linenum + 1] else: extended_line = line # Make Windows paths like Unix. fullname = os.path.abspath(filename).replace('\\', '/') # TODO(unknown): figure out if they're using default arguments in fn proto. # Check for non-const references in functions. This is tricky because & # is also used to take the address of something. We allow <> for templates, # (ignoring whatever is between the braces) and : for classes. # These are complicated re's. They try to capture the following: # paren (for fn-prototype start), typename, &, varname. For the const # version, we're willing for const to be before typename or after # Don't check the implementation on same line. #fnline = line.split('{', 1)[0] #if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) > # len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?' # r'(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) + # len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+\s+const(\s?&|&\s?)[\w]+', # fnline))): # # We allow non-const references in a few standard places, like functions # # called "swap()" or iostream operators like "<<" or ">>". # if not Search( # r'(swap|Swap|operator[<>][<>])\s*\(\s*(?:[\w:]|<.*>)+\s*&', # fnline): # error(filename, linenum, 'runtime/references', 2, # 'Is this a non-const reference? ' # 'If so, make const or use a pointer.') # Check to see if they're using an conversion function cast. # I just try to capture the most common basic types, though there are more. # Parameterless conversion functions, such as bool(), are allowed as they are # probably a member operator declaration or default constructor. match = Search( r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there r'(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line) if match: # gMock methods are defined using some variant of MOCK_METHODx(name, type) # where type may be float(), int(string), etc. Without context they are # virtually indistinguishable from int(x) casts. Likewise, gMock's # MockCallback takes a template parameter of the form return_type(arg_type), # which looks much like the cast we're trying to detect. if (match.group(1) is None and # If new operator, then this isn't a cast not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or Match(r'^\s*MockCallback<.*>', line))): error(filename, linenum, 'readability/casting', 4, 'Using deprecated casting style. ' 'Use static_cast<%s>(...) instead' % match.group(2)) CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 'static_cast', r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) # This doesn't catch all cases. Consider (const char * const)"hello". # # (char *) "foo" should always be a const_cast (reinterpret_cast won't # compile). if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error): pass else: # Check pointer casts for other than string constants CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) # In addition, we look for people taking the address of a cast. This # is dangerous -- casts can assign to temporaries, so the pointer doesn't # point where you think. if Search( r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): error(filename, linenum, 'runtime/casting', 4, ('Are you taking an address of a cast? ' 'This is dangerous: could be a temp var. ' 'Take the address before doing the cast, rather than after')) # Check for people declaring static/global STL strings at the top level. # This is dangerous because the C++ language does not guarantee that # globals with constructors are initialized before the first access. match = Match( r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', line) # Make sure it's not a function. # Function template specialization looks like: "string foo(...". # Class template definitions look like: "string Foo::Method(...". if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3)): error(filename, linenum, 'runtime/string', 4, 'For a static/global string constant, use a C style string instead: ' '"%schar %s[]".' % (match.group(1), match.group(2))) # Check that we're not using RTTI outside of testing code. #if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename): # error(filename, linenum, 'runtime/rtti', 5, # 'Do not use dynamic_cast<>. If you need to cast within a class ' # "hierarchy, use static_cast<> to upcast. Google doesn't support " # 'RTTI.') if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): error(filename, linenum, 'runtime/init', 4, 'You seem to be initializing a member variable with itself.') if file_extension == 'h': # TODO(unknown): check that 1-arg constructors are explicit. # How to tell it's a constructor? # (handled in CheckForNonStandardConstructs for now) # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS # (level 1 error) pass # Check if people are using the verboten C basic types. The only exception # we regularly allow is "unsigned short port" for port. if Search(r'\bshort port\b', line): if not Search(r'\bunsigned short port\b', line): error(filename, linenum, 'runtime/int', 4, 'Use "unsigned short" for ports, not "short"') else: match = Search(r'\b(short|long(?! +double)|long long)\b', line) if match: error(filename, linenum, 'runtime/int', 4, 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) # When snprintf is used, the second argument shouldn't be a literal. match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) if match and match.group(2) != '0': # If 2nd arg is zero, snprintf is used to calculate size. error(filename, linenum, 'runtime/printf', 3, 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' 'to snprintf.' % (match.group(1), match.group(2))) # Check if some verboten C functions are being used. if Search(r'\bsprintf\b', line): error(filename, linenum, 'runtime/printf', 5, 'Never use sprintf. Use snprintf instead.') match = Search(r'\b(strcpy|strcat)\b', line) if match: error(filename, linenum, 'runtime/printf', 4, 'Almost always, snprintf is better than %s' % match.group(1)) #if Search(r'\bsscanf\b', line): # error(filename, linenum, 'runtime/printf', 1, # 'sscanf can be ok, but is slow and can overflow buffers.') # Check if some verboten operator overloading is going on # TODO(unknown): catch out-of-line unary operator&: # class X {}; # int operator&(const X& x) { return 42; } // unary operator& # The trick is it's hard to tell apart from binary operator&: # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& if Search(r'\boperator\s*&\s*\(\s*\)', line): error(filename, linenum, 'runtime/operator', 4, 'Unary operator& is dangerous. Do not use it.') # Check for suspicious usage of "if" like # } if (a == b) { if Search(r'\}\s*if\s*\(', line): error(filename, linenum, 'readability/braces', 4, 'Did you mean "else if"? If not, start a new line for "if".') # Check for potential format string bugs like printf(foo). # We constrain the pattern not to pick things like DocidForPrintf(foo). # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) # TODO(sugawarayu): Catch the following case. Need to change the calling # convention of the whole function to process multiple line to handle it. # printf( # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') if printf_args: match = Match(r'([\w.\->()]+)$', printf_args) if match: function_name = re.search(r'\b((?:string)?printf)\s*\(', line, re.I).group(1) error(filename, linenum, 'runtime/printf', 4, 'Potential format string bug. Do %s("%%s", %s) instead.' % (function_name, match.group(1))) # Check for potential memset bugs like memset(buf, sizeof(buf), 0). match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): error(filename, linenum, 'runtime/memset', 4, 'Did you mean "memset(%s, 0, %s)"?' % (match.group(1), match.group(2))) #if Search(r'\busing namespace\b', line): # error(filename, linenum, 'build/namespaces', 5, # 'Do not use namespace using-directives. ' # 'Use using-declarations instead.') # Detect variable-length arrays. match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) if (match and match.group(2) != 'return' and match.group(2) != 'delete' and match.group(3).find(']') == -1): # Split the size using space and arithmetic operators as delimiters. # If any of the resulting tokens are not compile time constants then # report the error. tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) is_const = True skip_next = False for tok in tokens: if skip_next: skip_next = False continue if Search(r'sizeof\(.+\)', tok): continue if Search(r'arraysize\(\w+\)', tok): continue tok = tok.lstrip('(') tok = tok.rstrip(')') if not tok: continue if Match(r'\d+', tok): continue if Match(r'0[xX][0-9a-fA-F]+', tok): continue if Match(r'k[A-Z0-9]\w*', tok): continue if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue # A catch all for tricky sizeof cases, including 'sizeof expression', # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' # requires skipping the next token because we split on ' ' and '*'. if tok.startswith('sizeof'): skip_next = True continue is_const = False break if not is_const: error(filename, linenum, 'runtime/arrays', 1, 'Do not use variable-length arrays. Use an appropriately named ' "('k' followed by CamelCase) compile-time constant for the size.") # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing # in the class declaration. match = Match( (r'\s*' r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' r'\(.*\);$'), line) if match and linenum + 1 < clean_lines.NumLines(): next_line = clean_lines.elided[linenum + 1] # We allow some, but not all, declarations of variables to be present # in the statement that defines the class. The [\w\*,\s]* fragment of # the regular expression below allows users to declare instances of # the class or pointers to instances, but not less common types such # as function pointers or arrays. It's a tradeoff between allowing # reasonable code and avoiding trying to parse more C++ using regexps. if not Search(r'^\s*}[\w\*,\s]*;', next_line): error(filename, linenum, 'readability/constructors', 3, match.group(1) + ' should be the last thing in the class') # Check for use of unnamed namespaces in header files. Registration # macros are typically OK, so we allow use of "namespace {" on lines # that end with backslashes. if (file_extension == 'h' and Search(r'\bnamespace\s*{', line) and line[-1] != '\\'): error(filename, linenum, 'build/namespaces', 4, 'Do not use unnamed namespaces in header files. See ' 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' ' for more information.') def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, error): """Checks for a C-style cast by looking for the pattern. This also handles sizeof(type) warnings, due to similarity of content. Args: filename: The name of the current file. linenum: The number of the line to check. line: The line of code to check. raw_line: The raw line of code to check, with comments. cast_type: The string for the C++ cast to recommend. This is either reinterpret_cast, static_cast, or const_cast, depending. pattern: The regular expression used to find C-style casts. error: The function to call with any errors found. Returns: True if an error was emitted. False otherwise. """ match = Search(pattern, line) if not match: return False # e.g., sizeof(int) sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1]) if sizeof_match: error(filename, linenum, 'runtime/sizeof', 1, 'Using sizeof(type). Use sizeof(varname) instead if possible') return True typeid_match = Match(r'.*typeid\s*$',line[0:match.start(1) - 1]) if typeid_match: return True remainder = line[match.end(0):] # The close paren is for function pointers as arguments to a function. # eg, void foo(void (*bar)(int)); # The semicolon check is a more basic function check; also possibly a # function pointer typedef. # eg, void foo(int); or void foo(int) const; # The equals check is for function pointer assignment. # eg, void *(*foo)(int) = ... # The > is for MockCallback<...> ... # # Right now, this will only catch cases where there's a single argument, and # it's unnamed. It should probably be expanded to check for multiple # arguments with some unnamed. function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)|>))', remainder) #print "Remainder[%s]" % remainder if function_match: if ('SIGNAL' not in raw_line and 'SLOT' not in raw_line and (not function_match.group(3) or function_match.group(3) == ';' or ('<' not in raw_line and '/*' not in raw_line))): error(filename, linenum, 'readability/function', 3, 'All parameters should be named in a function') return True # At this point, all that should be left is actual casts. if len(remainder) > 0 and 'public: ' not in raw_line and 'private:' not in raw_line and 'protected: ' not in raw_line and remainder != ' const' and '::' not in raw_line: error(filename, linenum, 'readability/casting', 4, 'Using C-style cast. Use %s<%s>(...) instead' % (cast_type, match.group(1))) return True _HEADERS_CONTAINING_TEMPLATES = ( ('', ('deque',)), ('', ('unary_function', 'binary_function', 'plus', 'minus', 'multiplies', 'divides', 'modulus', 'negate', 'equal_to', 'not_equal_to', 'greater', 'less', 'greater_equal', 'less_equal', 'logical_and', 'logical_or', 'logical_not', 'unary_negate', 'not1', 'binary_negate', 'not2', 'bind1st', 'bind2nd', 'pointer_to_unary_function', 'pointer_to_binary_function', 'ptr_fun', 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', 'mem_fun_ref_t', 'const_mem_fun_t', 'const_mem_fun1_t', 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', 'mem_fun_ref', )), ('', ('numeric_limits',)), ('', ('list',)), ('', ('map', 'multimap',)), ('', ('allocator',)), ('', ('queue', 'priority_queue',)), ('', ('set', 'multiset',)), ('', ('stack',)), ('', ('char_traits', 'basic_string',)), ('', ('pair',)), ('', ('vector',)), # gcc extensions. # Note: std::hash is their hash, ::hash is our hash ('', ('hash_map', 'hash_multimap',)), ('', ('hash_set', 'hash_multiset',)), ('', ('slist',)), ) _RE_PATTERN_STRING = re.compile(r'\bstring\b') _re_pattern_algorithm_header = [] for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap', 'transform'): # Match max(..., ...), max(..., ...), but not foo->max, foo.max or # type::max(). _re_pattern_algorithm_header.append( (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), _template, '')) _re_pattern_templates = [] for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: for _template in _templates: _re_pattern_templates.append( (re.compile(r'(\<|\b)' + _template + r'\s*\<'), _template + '<>', _header)) def FilesBelongToSameModule(filename_cc, filename_h): """Check if these two filenames belong to the same module. The concept of a 'module' here is a as follows: foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the same 'module' if they are in the same directory. some/path/public/xyzzy and some/path/internal/xyzzy are also considered to belong to the same module here. If the filename_cc contains a longer path than the filename_h, for example, '/absolute/path/to/base/sysinfo.cc', and this file would include 'base/sysinfo.h', this function also produces the prefix needed to open the header. This is used by the caller of this function to more robustly open the header file. We don't have access to the real include paths in this context, so we need this guesswork here. Known bugs: tools/base/bar.cc and base/bar.h belong to the same module according to this implementation. Because of this, this function gives some false positives. This should be sufficiently rare in practice. Args: filename_cc: is the path for the .cc file filename_h: is the path for the header path Returns: Tuple with a bool and a string: bool: True if filename_cc and filename_h belong to the same module. string: the additional prefix needed to open the header file. """ if not filename_cc.endswith('.cc'): return (False, '') filename_cc = filename_cc[:-len('.cc')] if filename_cc.endswith('_unittest'): filename_cc = filename_cc[:-len('_unittest')] elif filename_cc.endswith('_test'): filename_cc = filename_cc[:-len('_test')] filename_cc = filename_cc.replace('/public/', '/') filename_cc = filename_cc.replace('/internal/', '/') if not filename_h.endswith('.h'): return (False, '') filename_h = filename_h[:-len('.h')] if filename_h.endswith('-inl'): filename_h = filename_h[:-len('-inl')] filename_h = filename_h.replace('/public/', '/') filename_h = filename_h.replace('/internal/', '/') files_belong_to_same_module = filename_cc.endswith(filename_h) common_path = '' if files_belong_to_same_module: common_path = filename_cc[:-len(filename_h)] return files_belong_to_same_module, common_path def UpdateIncludeState(filename, include_state, io=codecs): """Fill up the include_state with new includes found from the file. Args: filename: the name of the header to read. include_state: an _IncludeState instance in which the headers are inserted. io: The io factory to use to read the file. Provided for testability. Returns: True if a header was succesfully added. False otherwise. """ headerfile = None try: headerfile = io.open(filename, 'r', 'utf8', 'replace') except IOError: return False linenum = 0 for line in headerfile: linenum += 1 clean_line = CleanseComments(line) match = _RE_PATTERN_INCLUDE.search(clean_line) if match: include = match.group(2) # The value formatting is cute, but not really used right now. # What matters here is that the key is in include_state. include_state.setdefault(include, '%s:%d' % (filename, linenum)) return True def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, io=codecs): """Reports for missing stl includes. This function will output warnings to make sure you are including the headers necessary for the stl containers and functions that you use. We only give one reason to include a header. For example, if you use both equal_to<> and less<> in a .h file, only one (the latter in the file) of these will be reported as a reason to include the . Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. include_state: An _IncludeState instance. error: The function to call with any errors found. io: The IO factory to use to read the header file. Provided for unittest injection. """ required = {} # A map of header name to linenumber and the template entity. # Example of required: { '': (1219, 'less<>') } for linenum in xrange(clean_lines.NumLines()): line = clean_lines.elided[linenum] if not line or line[0] == '#': continue # String is special -- it is a non-templatized type in STL. matched = _RE_PATTERN_STRING.search(line) if matched: # Don't warn about strings in non-STL namespaces: # (We check only the first match per line; good enough.) prefix = line[:matched.start()] if prefix.endswith('std::') or not prefix.endswith('::'): required[''] = (linenum, 'string') for pattern, template, header in _re_pattern_algorithm_header: if pattern.search(line): required[header] = (linenum, template) # The following function is just a speed up, no semantics are changed. if not '<' in line: # Reduces the cpu time usage by skipping lines. continue for pattern, template, header in _re_pattern_templates: if pattern.search(line): required[header] = (linenum, template) # The policy is that if you #include something in foo.h you don't need to # include it again in foo.cc. Here, we will look at possible includes. # Let's copy the include_state so it is only messed up within this function. include_state = include_state.copy() # Did we find the header for this file (if any) and succesfully load it? header_found = False # Use the absolute path so that matching works properly. abs_filename = os.path.abspath(filename) # For Emacs's flymake. # If cpplint is invoked from Emacs's flymake, a temporary file is generated # by flymake and that file name might end with '_flymake.cc'. In that case, # restore original file name here so that the corresponding header file can be # found. # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' # instead of 'foo_flymake.h' abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) # include_state is modified during iteration, so we iterate over a copy of # the keys. header_keys = include_state.keys() for header in header_keys: (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) fullpath = common_path + header if same_module and UpdateIncludeState(fullpath, include_state, io): header_found = True # If we can't find the header file for a .cc, assume it's because we don't # know where to look. In that case we'll give up as we're not sure they # didn't include it in the .h file. # TODO(unknown): Do a better job of finding .h files so we are confident that # not having the .h file means there isn't one. if filename.endswith('.cc') and not header_found: return # All the lines have been processed, report the errors found. for required_header_unstripped in required: template = required[required_header_unstripped][1] if required_header_unstripped.strip('<>"') not in include_state: error(filename, required[required_header_unstripped][0], 'build/include_what_you_use', 4, 'Add #include ' + required_header_unstripped + ' for ' + template) _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): """Check that make_pair's template arguments are deduced. G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are specified explicitly, and such use isn't intended in any case. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found. """ raw = clean_lines.raw_lines line = raw[linenum] match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) if match: error(filename, linenum, 'build/explicit_make_pair', 4, # 4 = high confidence 'Omit template arguments from make_pair OR use pair directly OR' ' if appropriate, construct a pair directly') def ProcessLine(filename, file_extension, clean_lines, line, include_state, function_state, class_state, error, extra_check_functions=[]): """Processes a single line in the file. Args: filename: Filename of the file that is being processed. file_extension: The extension (dot not included) of the file. clean_lines: An array of strings, each representing a line of the file, with comments stripped. line: Number of line being processed. include_state: An _IncludeState instance in which the headers are inserted. function_state: A _FunctionState instance which counts function lines, etc. class_state: A _ClassState instance which maintains information about the current stack of nested class declarations being parsed. error: A callable to which errors are reported, which takes 4 arguments: filename, line number, error level, and message extra_check_functions: An array of additional check functions that will be run on each source line. Each function takes 4 arguments: filename, clean_lines, line, error """ raw_lines = clean_lines.raw_lines ParseNolintSuppressions(filename, raw_lines[line], line, error) CheckForFunctionLengths(filename, clean_lines, line, function_state, error) CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) CheckStyle(filename, clean_lines, line, file_extension, class_state, error) CheckLanguage(filename, clean_lines, line, file_extension, include_state, error) CheckForNonStandardConstructs(filename, clean_lines, line, class_state, error) CheckPosixThreading(filename, clean_lines, line, error) CheckInvalidIncrement(filename, clean_lines, line, error) CheckMakePairUsesDeduction(filename, clean_lines, line, error) for check_fn in extra_check_functions: check_fn(filename, clean_lines, line, error) def ProcessFileData(filename, file_extension, lines, error, extra_check_functions=[]): """Performs lint checks and reports any errors to the given error function. Args: filename: Filename of the file that is being processed. file_extension: The extension (dot not included) of the file. lines: An array of strings, each representing a line of the file, with the last element being empty if the file is terminated with a newline. error: A callable to which errors are reported, which takes 4 arguments: filename, line number, error level, and message extra_check_functions: An array of additional check functions that will be run on each source line. Each function takes 4 arguments: filename, clean_lines, line, error """ lines = (['// marker so line numbers and indices both start at 1'] + lines + ['// marker so line numbers end in a known way']) include_state = _IncludeState() function_state = _FunctionState() class_state = _ClassState() ResetNolintSuppressions() CheckForCopyright(filename, lines, error) if file_extension == 'h': CheckForHeaderGuard(filename, lines, error) RemoveMultiLineComments(filename, lines, error) clean_lines = CleansedLines(lines) for line in xrange(clean_lines.NumLines()): ProcessLine(filename, file_extension, clean_lines, line, include_state, function_state, class_state, error, extra_check_functions) class_state.CheckFinished(filename, error) CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) # We check here rather than inside ProcessLine so that we see raw # lines rather than "cleaned" lines. CheckForUnicodeReplacementCharacters(filename, lines, error) CheckForNewlineAtEOF(filename, lines, error) def ProcessFile(filename, vlevel, extra_check_functions=[]): """Does google-lint on a single file. Args: filename: The name of the file to parse. vlevel: The level of errors to report. Every error of confidence >= verbose_level will be reported. 0 is a good default. extra_check_functions: An array of additional check functions that will be run on each source line. Each function takes 4 arguments: filename, clean_lines, line, error """ _SetVerboseLevel(vlevel) try: # Support the UNIX convention of using "-" for stdin. Note that # we are not opening the file with universal newline support # (which codecs doesn't support anyway), so the resulting lines do # contain trailing '\r' characters if we are reading a file that # has CRLF endings. # If after the split a trailing '\r' is present, it is removed # below. If it is not expected to be present (i.e. os.linesep != # '\r\n' as in Windows), a warning is issued below if this file # is processed. if filename == '-': lines = codecs.StreamReaderWriter(sys.stdin, codecs.getreader('utf8'), codecs.getwriter('utf8'), 'replace').read().split('\n') else: lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') carriage_return_found = False # Remove trailing '\r'. for linenum in range(len(lines)): if lines[linenum].endswith('\r'): lines[linenum] = lines[linenum].rstrip('\r') carriage_return_found = True except IOError: #sys.stderr.write( # "Skipping input '%s': Can't open for reading\n" % filename) return # Note, if no dot is found, this will give the entire filename as the ext. file_extension = filename[filename.rfind('.') + 1:] # When reading from stdin, the extension is unknown, so no cpplint tests # should rely on the extension. if (filename != '-' and file_extension != 'cc' and file_extension != 'h' and file_extension != 'cpp' and file_extension != 'hh'): if (filename != "CMakeLists.txt" and file_extension != "in" and file_extension != "proto" and file_extension != "sdf"): pass #sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename) else: ProcessFileData(filename, file_extension, lines, Error, extra_check_functions) if carriage_return_found and os.linesep != '\r\n': # Use 0 for linenum since outputting only one error for potentially # several lines. Error(filename, 0, 'whitespace/newline', 1, 'One or more unexpected \\r (^M) found;' 'better to use only a \\n') #sys.stderr.write('Done processing %s\n' % filename) def PrintUsage(message): """Prints a brief usage string and exits, optionally with an error message. Args: message: The optional error message. """ sys.stderr.write(_USAGE) if message: sys.exit('\nFATAL ERROR: ' + message) else: sys.exit(1) def PrintCategories(): """Prints a list of all the error-categories used by error messages. These are the categories used to filter messages via --filter. """ sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) sys.exit(0) def ParseArguments(args): """Parses the command line arguments. This may set the output format and verbosity level as side-effects. Args: args: The command line arguments: Returns: The list of filenames to lint. """ try: (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', 'counting=', 'filter=']) except getopt.GetoptError: PrintUsage('Invalid arguments.') verbosity = _VerboseLevel() output_format = _OutputFormat() filters = '' counting_style = '' for (opt, val) in opts: if opt == '--help': PrintUsage(None) elif opt == '--output': if not val in ('emacs', 'vs7'): PrintUsage('The only allowed output formats are emacs and vs7.') output_format = val elif opt == '--verbose': verbosity = int(val) elif opt == '--filter': filters = val if not filters: PrintCategories() elif opt == '--counting': if val not in ('total', 'toplevel', 'detailed'): PrintUsage('Valid counting options are total, toplevel, and detailed') counting_style = val if not filenames: PrintUsage('No files were specified.') _SetOutputFormat(output_format) _SetVerboseLevel(verbosity) _SetFilters(filters) _SetCountingStyle(counting_style) return filenames def main(): filenames = ParseArguments(sys.argv[1:]) # Change stderr to write with replacement characters so we don't die # if we try to print something containing non-ASCII characters. sys.stderr = codecs.StreamReaderWriter(sys.stderr, codecs.getreader('utf8'), codecs.getwriter('utf8'), 'replace') _cpplint_state.ResetErrorCounts() for filename in filenames: if filename != "./gazebo/rendering/cegui.h": ProcessFile(filename, _cpplint_state.verbose_level) _cpplint_state.PrintErrorCounts() sys.exit(_cpplint_state.error_count > 0) if __name__ == '__main__': main() sdformat-6.0.0+dfsg/tools/cpplint_to_cppcheckxml.py000066400000000000000000000027071323606632500225350ustar00rootroot00000000000000#!/usr/bin/env python # Convert output from Google's cpplint.py to the cppcheck XML format for # consumption by the Jenkins cppcheck plugin. # Reads from stdin and writes to stderr (to mimic cppcheck) import sys import re import xml.sax.saxutils def cpplint_score_to_cppcheck_severity(score): # I'm making this up if score == 1: return 'style' elif score == 2: return 'style' elif score == 3: return 'warning' elif score == 4: return 'warning' elif score == 5: return 'error' def parse(): # TODO: do this properly, using the xml module. # Write header sys.stderr.write('''\n''') sys.stderr.write('''\n''') # Do line-by-line conversion r = re.compile('([^:]*):([0-9]*): ([^\[]*)\[([^\]]*)\] \[([0-9]*)\].*') for l in sys.stdin.readlines(): m = r.match(l.strip()) if not m: continue g = m.groups() if len(g) != 5: continue fname, lineno, rawmsg, label, score = g # Protect Jenkins from bad XML, which makes it barf msg = xml.sax.saxutils.escape(rawmsg) severity = cpplint_score_to_cppcheck_severity(int(score)) sys.stderr.write('''\n'''%(fname, lineno, label, severity, msg)) # Write footer sys.stderr.write('''\n''') if __name__ == '__main__': parse() sdformat-6.0.0+dfsg/tools/get_mem_info.py000066400000000000000000000006251323606632500204260ustar00rootroot00000000000000#!/usr/bin/env python import os; import psutil; # get pid of parent process pid = os.getppid(); # get and print memory usage of parent process p = psutil.Process(pid); # note that different versions of psutil have different API # some versions have memory_info(), others have get_memory_info() memory_info = (p.memory_info() if hasattr(p, 'memory_info') else p.get_memory_info()); print (memory_info[0]) sdformat-6.0.0+dfsg/tools/xmlschema.rb000077500000000000000000000211551323606632500177360ustar00rootroot00000000000000#!/usr/bin/env ruby require "rexml/document" require "optparse" $path = nil ################################################# # \brief A not very elegant way to convert to schema types def xsdType(_type) if _type == "unsigned int" return "unsignedInt" elsif _type == "unsigned long" return "unsignedLog" elsif _type == "bool" return "boolean" else return _type end end ################################################# def isStdType(_type) return _type == "string" || _type == "int" || _type == "double" || _type == "float" || _type == "bool" || _type == "char" || _type == "unsigned int" end ################################################# def printElem(_file, _spaces, _elem) # this currently short-circuits the plugin.sdf copy_data element. if _elem.attributes["name"].nil? _file.printf("%*s\n", _spaces-2, "") _file.printf("%*s\n", _spaces, "") _file.printf("%*s\n", _spaces-2, "") return end type = _elem.attributes["type"] if isStdType(type) type = "xsd:" + xsdType(type) end minOccurs = '0' maxOccurs = 'unbounded' if _elem.attributes["required"] == '0' minOccurs='0' maxOccurs='1' elsif _elem.attributes["required"] == '1' minOccurs='1' maxOccurs='1' elsif _elem.attributes["required"] == '+' minOccurs='1' maxOccurs='unbounded' elsif _elem.attributes["required"] == '*' minOccurs='0' maxOccurs='unbounded' end _file.printf("%*s\n", _spaces, "", minOccurs, maxOccurs) # Print the complex type with a name if type.nil? || type == "" _file.printf("%*s\n", _spaces, "", _elem.attributes["name"]) if !_elem.elements["description"].nil? && !_elem.elements["description"].text.nil? printDocumentation(_file, _spaces+2, _elem.elements["description"].text) end _file.printf("%*s\n", _spaces+2, "") _file.printf("%*s\n", _spaces+4, "") _elem.get_elements("element").each do |elem| printElem(_file, _spaces+6, elem) end _file.printf("%*s\n", _spaces+4, "") # Print the attributes for the complex type # Attributes must go at the end of the complex type. _elem.get_elements("attribute").each do |attr| printAttribute(_file, _spaces+4, attr); end _file.printf("%*s\n", _spaces+2, "") else _file.printf("%*s\n", _spaces, "", _elem.attributes["name"], type) if !_elem.elements["description"].nil? && !_elem.elements["description"].text.nil? printDocumentation(_file, _spaces+2, _elem.elements["description"].text) end end _file.printf("%*s\n", _spaces, "") _file.printf("%*s\n", _spaces, "") end ################################################# def printDocumentation(_file, _spaces, _doc) _file.printf("%*s\n", _spaces, "") _spaces += 2 _file.printf("%*s\n", _spaces, "") _spaces += 2 _file.printf("%*s\n",_spaces, "", _doc); _spaces -= 2 _file.printf("%*s\n", _spaces, "") _spaces -= 2 _file.printf("%*s\n", _spaces, "") end ################################################# def printIncludeRef(_file, _spaces, _inc) path = File.join($path, _inc.attributes["filename"]) doc = REXML::Document.new File.new(path) incElemName = doc.root.attributes['name'] _file.printf("%*s\n", _spaces, "", incElemName) end ################################################# def printInclude(_file, _spaces, _attr) loc = "http://sdformat.org/schemas/" loc += _attr.attributes['filename'].sub("\.sdf","\.xsd") _file.printf("%*s\n", _spaces, "", loc) end ################################################# def printAttribute(_file, _spaces, _attr) name = _attr.attributes["name"] type = _attr.attributes["type"] use = "" default = "" if !_attr.attributes["required"].nil? if _attr.attributes["required"] == "1" use = "use='required'" elsif _attr.attributes["required"] == "0" use = "use='optional'" # Default is only valid if use is optional if !_attr.attributes["default"].nil? default="default='#{_attr.attributes["default"]}'" end end end if isStdType(type) type = "xsd:" + xsdType(type) end _file.printf("%*s\n", _spaces, "", name, type, use, default) if !_attr.elements["description"].nil? && !_attr.elements["description"].text.nil? printDocumentation(_file, _spaces+2, _attr.elements["description"].text) end _file.printf("%*s\n", _spaces, "") end ################################################# # \brief Print the complete schema for an element into a file. # \param[in] _file File pointer in which to print the schema. # \param[in] _spaces Number of spaces to prepend to each line. # \param[in] _elem The SDF element to convert to an xml schema. def printXSD(_file, _spaces, _elem) if !_elem.elements["description"].nil? && !_elem.elements["description"].text.nil? printDocumentation(_file, _spaces, _elem.elements["description"].text) end _file.printf("%*s\n", _spaces, "") # Print the inclues for the complex type # The includes must appear first _elem.get_elements("include").each do |inc| printInclude(_file, _spaces, inc); end if _elem.get_elements("element").size > 0 || _elem.get_elements("attribute").size > 0 || _elem.get_elements("include").size > 0 # Print the complex type with a name _file.printf("%*s\n", _spaces, "", _elem.attributes["name"]) _file.printf("%*s\n", _spaces+2, "") if _elem.attributes['name'] != "plugin" && (_elem.get_elements("element").size > 0 || _elem.get_elements("include").size > 0) _file.printf("%*s\n", _spaces+4, "") end # Print all the child elements _elem.get_elements("element").each do |elem| printElem(_file, _spaces+6, elem); end # Print all the included sdf's root elements _elem.get_elements("include").each do |inc| printIncludeRef(_file, _spaces+6, inc); end if _elem.attributes['name'] != "plugin" && (_elem.get_elements("element").size > 0 || _elem.get_elements("include").size > 0) _file.printf("%*s\n", _spaces+4, "") end # Print the attributes for the complex type # Attributes must go at the end of the complex type. _elem.get_elements("attribute").each do |attr| printAttribute(_file, _spaces+4, attr); end # Close the complex type _file.printf("%*s\n", _spaces+2, "") _file.printf("%*s\n", _spaces, "") else type = _elem.attributes["type"] if isStdType(type) type = "xsd:" + type end if !type.nil? type = "type='" + type + "'" end _file.printf("%*s\n", _spaces, "", _elem.attributes["name"], type) end end infile = nil outdir = nil opt_parser = OptionParser.new do |o| o.on("-i", "--in [path]", String, "SDF file to compile") {|path| infile = path} o.on("-o", "--out [path]", String, "Output directory for source and header files") {|path| outdir = path} o.on("-s", "--sdf [path]", String, "Directory containing all the SDF files") {|path| $path = path} o.on("-h", "--help", "Display this help message") do puts opt_parser exit end end opt_parser.parse! if infile.nil? puts "Missing option -i." exit elsif !File.exists?(infile) puts "Input file[#{infile}] does not exist\n" exit end if $path.nil? puts "Missing option -s." exit elsif !Dir.exists?($path) puts "SDF source dir[#{$path}] does not exist\n" exit end if outdir.nil? puts "Missing output directory, option -o." exit elsif !Dir.exists?(outdir) Dir.mkdir(outdir) end doc = REXML::Document.new File.new(infile) spaces = 2 doc.elements.each_with_index("element") do |elem, i| out_xsd = infile.split("/").last.sub("\.sdf","\.xsd") file = File.open(File.join(outdir, out_xsd), "w") file.print("\n") file.print("\n") printXSD(file, spaces, elem) file.print("\n") file.close() end