diff --git a/CMakeLists.txt b/CMakeLists.txt index 41e3da5dd4..96235b3e49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ ign_find_package (Qt5 #-------------------------------------- # Find ignition-physics -ign_find_package(ignition-physics3 +ign_find_package(ignition-physics3 VERSION 3.1 COMPONENTS mesh sdf @@ -171,3 +171,7 @@ ign_create_docs( "${IGNITION-SENSORS_DOXYGEN_TAGFILE} = ${IGNITION-SENSORS_API_URL}" "${IGNITION-COMMON_DOXYGEN_TAGFILE} = ${IGNITION-COMMON_API_URL}" ) + +if(TARGET doc) + file(COPY ${CMAKE_SOURCE_DIR}/tutorials/files/ DESTINATION ${CMAKE_BINARY_DIR}/doxygen/html/files/) +endif() diff --git a/Changelog.md b/Changelog.md index 6c8ba1f7e9..fb6e6c1037 100644 --- a/Changelog.md +++ b/Changelog.md @@ -97,6 +97,104 @@ ## Ignition Gazebo 3.x +### Ignition Gazebo 3.X.X (20XX-XX-XX) + +### Ignition Gazebo 3.4.0 (2020-10-14) + +1. Fix gui sendEvent memory leaks + * [Pull Request 365](https://github.com/ignitionrobotics/ign-gazebo/pull/365) + +1. Support nested models + * [Pull Request 258](https://github.com/ignitionrobotics/ign-gazebo/pull/258) + +1. Generalize actor count and pose in actor population erb SDF + * [Pull Request 336](https://github.com/ignitionrobotics/ign-gazebo/pull/336) + +1. Add more link APIs, with tutorial + * [Pull Request 375](https://github.com/ignitionrobotics/ign-gazebo/pull/375) + +1. Add screenshots to GUI config tutorial + * [Pull Request 406](https://github.com/ignitionrobotics/ign-gazebo/pull/406) + +1. Fix adding performers to entity tree + * [Pull Request 374](https://github.com/ignitionrobotics/ign-gazebo/pull/374) + +1. Remove sidebar and put world control in bottom left for joint controller examples + * [Pull Request 384](https://github.com/ignitionrobotics/ign-gazebo/pull/384) + +1. Allow executing a blocking single Server run in both paused and unpaused states + * [Pull Request 297](https://github.com/ignitionrobotics/ign-gazebo/pull/297) + +1. Add camera video recorder system + * [Pull Request 316](https://github.com/ignitionrobotics/ign-gazebo/pull/316) + +1. Decrease time step for quadcopter world + * [Pull Request 372](https://github.com/ignitionrobotics/ign-gazebo/pull/372) + +1. Add support for moving the GUI camera to a pose + * [Pull Request 352](https://github.com/ignitionrobotics/ign-gazebo/pull/352) + +1. Remove `lib`+`.so` from plugin's name + * [Pull Request 279](https://github.com/ignitionrobotics/ign-gazebo/pull/279) + * [Pull Request 335](https://github.com/ignitionrobotics/ign-gazebo/pull/335) + +1. EntityComponentManager::EachRemoved documentation fix. + * [Pull Request 348](https://github.com/ignitionrobotics/ign-gazebo/pull/348) + +1. Add more model APIs. + * [Pull Request 349](https://github.com/ignitionrobotics/ign-gazebo/pull/349) + +1. Update dimensions of the grid config. + * [Pull Request 383](https://github.com/ignitionrobotics/ign-gazebo/pull/383) + +1. Fix top-left toolbar layout so magnet shows. + * [Pull Request 381](https://github.com/ignitionrobotics/ign-gazebo/pull/381) + +1. Add instructions to bitmask world. + * [Pull Request 377](https://github.com/ignitionrobotics/ign-gazebo/pull/377) + +1. Add search and sort for resource spawner. + * [Pull Request 359](https://github.com/ignitionrobotics/ign-gazebo/pull/359) + +1. Fix source build instructions for ign-gazebo3. + * [Pull Request 395](https://github.com/ignitionrobotics/ign-gazebo/pull/395) + +1. Added playback scrubber GUI + * [Pull Request 299](https://github.com/ignitionrobotics/ign-gazebo/pull/299) + * [Pull Request 362](https://github.com/ignitionrobotics/ign-gazebo/pull/362) + +1. Added wheel slip system plugin. + * [Pull Request 134](https://github.com/ignitionrobotics/ign-gazebo/pull/134) + * [Pull Request 357](https://github.com/ignitionrobotics/ign-gazebo/pull/357) + * [Pull Request 362](https://github.com/ignitionrobotics/ign-gazebo/pull/362) + +1. Enhanced log playback performance. + * [Pull Request 351](https://github.com/ignitionrobotics/ign-gazebo/pull/351) + * [Pull Request 362](https://github.com/ignitionrobotics/ign-gazebo/pull/362) + +1. Tests & Warnings: Qt 5.14, breadcrumbs, Gui, ign_TEST + * [Pull Request 327](https://github.com/ignitionrobotics/ign-gazebo/pull/327) + +1. Added support for specifying topics to record. + * [Pull Request 315](https://github.com/ignitionrobotics/ign-gazebo/pull/315) + +1. Make sure OpenGL core profile context is used by GzScene3D. + * [Pull Request 339](https://github.com/ignitionrobotics/ign-gazebo/pull/339) + +1. Support relative paths for PBR materials + * [Pull Request 328](https://github.com/ignitionrobotics/ign-gazebo/pull/328) + * [Pull Request 362](https://github.com/ignitionrobotics/ign-gazebo/pull/362) + +1. Add file extension automatically for record plugin. + * [Pull Request 303](https://github.com/ignitionrobotics/ign-gazebo/pull/303) + * [Pull Request 362](https://github.com/ignitionrobotics/ign-gazebo/pull/362) + +1. Support spawning during log playback. + * [Pull Request 346](https://github.com/ignitionrobotics/ign-gazebo/pull/346) + +1. Add Render Engine Cmd Line option + * [Pull Request 331](https://github.com/ignitionrobotics/ign-gazebo/pull/331) + ### Ignition Gazebo 3.3.0 (2020-08-31) 1. Added marker array service. @@ -206,6 +304,33 @@ ## Ignition Gazebo 2.x +### Ignition Gazebo 2.25.0 (2020-09-17) + +1. Added wheel slip system plugin. + * [Pull Request 134](https://github.com/ignitionrobotics/ign-gazebo/pull/134) + * [Pull Request 357](https://github.com/ignitionrobotics/ign-gazebo/pull/357) + +1. Enhanced log playback performance. + * [Pull Request 351](https://github.com/ignitionrobotics/ign-gazebo/pull/351) + +1. Tests & Warnings: Qt 5.14, breadcrumbs, Gui, ign_TEST + * [Pull Request 327](https://github.com/ignitionrobotics/ign-gazebo/pull/327) + +1. Added support for specifying topics to record. + * [Pull Request 315](https://github.com/ignitionrobotics/ign-gazebo/pull/315) + +1. Make sure OpenGL core profile context is used by GzScene3D. + * [Pull Request 339](https://github.com/ignitionrobotics/ign-gazebo/pull/339) + +1. Support relative paths for PBR materials + * [Pull Request 328](https://github.com/ignitionrobotics/ign-gazebo/pull/328) + +1. Add file extension automatically for record plugin. + * [Pull Request 303](https://github.com/ignitionrobotics/ign-gazebo/pull/303) + +1. Support spawning during log playback. + * [Pull Request 346](https://github.com/ignitionrobotics/ign-gazebo/pull/346) + ### Ignition Gazebo 2.24.0 (2020-09-03) 1. Resource env var, with transport interface. diff --git a/examples/worlds/shapes_population.sdf b/examples/worlds/3k_shapes.sdf similarity index 100% rename from examples/worlds/shapes_population.sdf rename to examples/worlds/3k_shapes.sdf diff --git a/examples/worlds/actors_population.sdf b/examples/worlds/actors_population.sdf index 5759357bfc..e69de29bb2 100644 --- a/examples/worlds/actors_population.sdf +++ b/examples/worlds/actors_population.sdf @@ -1,2841 +0,0 @@ - - - - - - - - - - - - - - - - 3D View - false - docked - - - ogre2 - scene - 0.4 0.4 0.4 - 0.8 0.8 0.8 - -6 0 6 0 0.5 0 - - - - - - World control - false - false - 72 - 121 - 1 - - floating - - - - - - - true - true - true - /world/actors/control - /world/actors/stats - - - - - - - World stats - false - false - 110 - 290 - 1 - - floating - - - - - - - true - true - true - true - /world/actors/stats - - - - - - - false - docked - - - - - - - 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 - - - - true - - - - - 0.0 0.0 1 - - - - - - - 0.0 0.0 1 - 100 100 - - - - 0.8 0.8 0.8 1 - 0.8 0.8 0.8 1 - 0.8 0.8 0.8 1 - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 1.0 - - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae - 0.055 - true - - - - - - diff --git a/examples/worlds/actors_population.sdf.erb b/examples/worlds/actors_population.sdf.erb index ebc5490cba..0d62684efe 100644 --- a/examples/worlds/actors_population.sdf.erb +++ b/examples/worlds/actors_population.sdf.erb @@ -1,6 +1,10 @@ @@ -133,18 +137,27 @@ - - https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor - - <% - # number of population - total = 10 - for i in (0..total-1) - for j in (1..total) + vars = ARGV.take_while {|arg| arg[/^\w+=/]} + ARGV.slice!(0, vars.size) + vars.each do |var| + k, v = var.split('=', 2) + TOPLEVEL_BINDING.eval %Q(#{k} = "#{v}") + end + # population = column * row, default to 100 actors + column = 10 + row = 10 + if (defined? c) + column = c.to_i + end + for j in (0..column-1) + if (defined? r) + row = r.to_i + end + for i in (0..row-1) %> - + https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/talk_b.dae 1.0 @@ -157,14 +170,14 @@ diff --git a/examples/worlds/diff_drive_skid.sdf b/examples/worlds/diff_drive_skid.sdf index d42f8bbb60..dad1d68639 100644 --- a/examples/worlds/diff_drive_skid.sdf +++ b/examples/worlds/diff_drive_skid.sdf @@ -149,7 +149,9 @@ - 0.01 + 0.5 + 1.0 + 0 0 1 @@ -190,7 +192,9 @@ - 5 + 0.5 + 1.0 + 0 0 1 @@ -231,7 +235,9 @@ - 0.01 + 0.5 + 1.0 + 0 0 1 @@ -272,7 +278,9 @@ - 5 + 0.5 + 1.0 + 0 0 1 diff --git a/examples/worlds/joint_controller.sdf b/examples/worlds/joint_controller.sdf index 29a35e5d80..b4db4b5cfe 100644 --- a/examples/worlds/joint_controller.sdf +++ b/examples/worlds/joint_controller.sdf @@ -26,18 +26,12 @@ - 3D View false - false - 0 - - - - + docked ogre @@ -56,16 +50,19 @@ 72 121 1 - - - + floating + + + + + true true true - + true 0 0 10 0 0 0 diff --git a/examples/worlds/joint_position_controller.sdf b/examples/worlds/joint_position_controller.sdf index 4d1d65a7ac..6d2ad62e83 100644 --- a/examples/worlds/joint_position_controller.sdf +++ b/examples/worlds/joint_position_controller.sdf @@ -26,12 +26,7 @@ 3D View false - false - 0 - - - - + docked ogre @@ -50,8 +45,12 @@ 72 121 1 - - + + floating + + + + true diff --git a/examples/worlds/nested_model.sdf b/examples/worlds/nested_model.sdf new file mode 100644 index 0000000000..ca705c7825 --- /dev/null +++ b/examples/worlds/nested_model.sdf @@ -0,0 +1,110 @@ + + + + + 0.001 + 1.0 + + + libignition-physics-tpe-plugin.so + + + + + + + + 1.0 1.0 1.0 + 0.8 0.8 0.8 + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + + 0 0 0.5 0 0 0 + + 0 0 0 0 0 0 + + + + 0.5 + + + + + + + 0.5 + + + + + + + 1 0 0.0 0 0 0 + + 0.25 0 0.0 0 0 0.785398 + + + + 1 1 1 + + + + + + + 1 1 1 + + + + + + + + + diff --git a/examples/worlds/quadcopter.sdf b/examples/worlds/quadcopter.sdf index 3499711fdc..7126135016 100644 --- a/examples/worlds/quadcopter.sdf +++ b/examples/worlds/quadcopter.sdf @@ -13,8 +13,8 @@ --> - - 0.004 + + 0.001 1.0 + @@ -23,87 +34,6 @@ 0.8 0.8 0.8 - - - - - - 3D View - false - docked - - - ogre2 - scene - 1.0 1.0 1.0 - 0.8 0.8 0.8 - -6 0 6 0 0.5 0 - - - - - - World control - false - false - 72 - 121 - 1 - - floating - - - - - - - true - true - true - /world/shapes_bitmask/control - /world/shapes_bitmask/stats - - - - - - - World stats - false - false - 110 - 290 - 1 - - floating - - - - - - - true - true - true - true - /world/shapes_bitmask/stats - - - - - - - false - docked - - - - - - - - - true 0 0 10 0 0 0 @@ -144,7 +74,7 @@ - + 0 0 1.0 0 0 0 @@ -185,7 +115,7 @@ - + 0 0 3.0 0 0 0 @@ -226,7 +156,7 @@ - + 0 0 6.0 0 0 0 diff --git a/examples/worlds/trisphere_cycle_wheel_slip.sdf b/examples/worlds/trisphere_cycle_wheel_slip.sdf new file mode 100644 index 0000000000..bd7a23b219 --- /dev/null +++ b/examples/worlds/trisphere_cycle_wheel_slip.sdf @@ -0,0 +1,936 @@ + + + + + + -2 0 -9.8 + + + + + + + + + + + + + + 3D View + false + docked + + + ogre2 + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + -6 0 6 0 0.5 0 + + + + + + World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + true + /world/wheel_slip/control + /world/wheel_slip/stats + + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + /world/wheel_slip/stats + + + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + true + 0 0 10 0 0 0 + 1 1 1 1 + 0.5 0.5 0.5 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + -0.40855911616047164 0 0.38502293110800634 0 -0.522020852957719 0 + + 0.0 0 0 0 0 0 + 10 + + 0.22799999999999998 + 0.7435210984814149 + 0.9655210984814149 + 0 + 0 + 0 + + + + -0.4713346258704366 0 0 1.5707963267948966 0 0 + + + 1.0392304845413263 + 0.03 + + + + + -0.4713346258704366 0 0 1.5707963267948966 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 1.0392304845413263 + 0.03 + + + + + 0 0.17155177419583564 0 0 1.5707963267948966 -0.3490658503988659 + + + 1.0031676644991372 + 0.03 + + + + + 0 0.17155177419583564 0 0 1.5707963267948966 -0.3490658503988659 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 1.0031676644991372 + 0.03 + + + + + 0 -0.17155177419583564 0 0 1.5707963267948966 0.3490658503988659 + + + 1.0031676644991372 + 0.03 + + + + + 0 -0.17155177419583564 0 0 1.5707963267948966 0.3490658503988659 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 1.0031676644991372 + 0.03 + + + + + + 0.04144088383952833 0 0.38502293110800634 0 -0.17453292519943295 0 + + 3 + + 0.15820312499999997 + 0.058359374999999984 + 0.10265624999999999 + 0 + 0 + 0 + + + + 0 0 0.397747564417433 1.5707963267948966 0 0 + + + 0.6363961030678927 + 0.0375 + + + + + 0 0 0.397747564417433 1.5707963267948966 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.6363961030678927 + 0.0375 + + + + + 0 0 0.2386485386504598 0 0 0 + + + 0.31819805153394637 + 0.0375 + + + + + 0 0 0.2386485386504598 0 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.31819805153394637 + 0.0375 + + + + + 0 0 -0.23864853865045976 1.5707963267948966 0 0 + + + 0.6363961030678927 + 0.015 + + + + + 0 0 -0.23864853865045976 1.5707963267948966 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.6363961030678927 + 0.015 + + + + + 0 0.15909902576697318 -0.07954951288348658 0.7853981633974483 0 0 + + + 0.45 + 0.0375 + + + + + 0 0.15909902576697318 -0.07954951288348658 0.7853981633974483 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.45 + 0.0375 + + + + + 0 -0.15909902576697318 -0.07954951288348658 -0.7853981633974483 0 0 + + + 0.45 + 0.0375 + + + + + 0 -0.15909902576697318 -0.07954951288348658 -0.7853981633974483 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.45 + 0.0375 + + + + + + 0.08288176767905665 0 0.15 0 0 0 + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.15 + + + + + + frame + fork + + 0 0 1 + + -0.9599310885968813 + 0.9599310885968813 + + + + + fork + wheel_front + + 0 1 0 + + + + -0.8171182323209433 0.5196152422706631 0.15 0 0 0 + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.15 + + + + + + frame + wheel_rear_left + + 0 1 0 + + + + -0.8171182323209433 -0.5196152422706631 0.15 0 0 0 + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + 0.8 0.3 0.3 1 + + + + 0.15 + + + + + + frame + wheel_rear_right + + 0 1 0 + + + + + + 0.15 + 0 + 0 + 77 + + + 0.15 + 0 + 0 + 32 + + + 0.15 + 0 + 0 + 32 + + + + + 0 2 0 0 0 0 + + -0.40855911616047164 0 0.38502293110800634 0 -0.522020852957719 0 + + 0.0 0 0 0 0 0 + 10 + + 0.22799999999999998 + 0.7435210984814149 + 0.9655210984814149 + 0 + 0 + 0 + + + + -0.4713346258704366 0 0 1.5707963267948966 0 0 + + + 1.0392304845413263 + 0.03 + + + + + -0.4713346258704366 0 0 1.5707963267948966 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 1.0392304845413263 + 0.03 + + + + + 0 0.17155177419583564 0 0 1.5707963267948966 -0.3490658503988659 + + + 1.0031676644991372 + 0.03 + + + + + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + 0 0.17155177419583564 0 0 1.5707963267948966 -0.3490658503988659 + + + 1.0031676644991372 + 0.03 + + + + + 0 -0.17155177419583564 0 0 1.5707963267948966 0.3490658503988659 + + + 1.0031676644991372 + 0.03 + + + + + 0 -0.17155177419583564 0 0 1.5707963267948966 0.3490658503988659 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 1.0031676644991372 + 0.03 + + + + + + 0.04144088383952833 0 0.38502293110800634 0 -0.17453292519943295 0 + + 3 + + 0.15820312499999997 + 0.058359374999999984 + 0.10265624999999999 + 0 + 0 + 0 + + + + 0 0 0.397747564417433 1.5707963267948966 0 0 + + + 0.6363961030678927 + 0.0375 + + + + + 0 0 0.397747564417433 1.5707963267948966 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.6363961030678927 + 0.0375 + + + + + 0 0 0.2386485386504598 0 0 0 + + + 0.31819805153394637 + 0.0375 + + + + + 0 0 0.2386485386504598 0 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.31819805153394637 + 0.0375 + + + + + 0 0 -0.23864853865045976 1.5707963267948966 0 0 + + + 0.6363961030678927 + 0.015 + + + + + 0 0 -0.23864853865045976 1.5707963267948966 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.6363961030678927 + 0.015 + + + + + 0 0.15909902576697318 -0.07954951288348658 0.7853981633974483 0 0 + + + 0.45 + 0.0375 + + + + + 0 0.15909902576697318 -0.07954951288348658 0.7853981633974483 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.45 + 0.0375 + + + + + 0 -0.15909902576697318 -0.07954951288348658 -0.7853981633974483 0 0 + + + 0.45 + 0.0375 + + + + + 0 -0.15909902576697318 -0.07954951288348658 -0.7853981633974483 0 0 + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.45 + 0.0375 + + + + + + 0.08288176767905665 0 0.15 0 0 0 + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.15 + + + + + + frame + fork + + 0 0 1 + + -0.9599310885968813 + 0.9599310885968813 + + + + + fork + wheel_front + + 0 1 0 + + + + -0.8171182323209433 0.5196152422706631 0.15 0 0 0 + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.15 + + + + + + frame + wheel_rear_left + + 0 1 0 + + + + -0.8171182323209433 -0.5196152422706631 0.15 0 0 0 + + 0.5 + + 0.0045 + 0.0045 + 0.0045 + 0 + 0 + 0 + + + + + + 0.15 + + + + + + 100000000.0 + 1 + 0.0005 + + + + + + + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + 0.3 0.3 0.8 1 + + + + 0.15 + + + + + + frame + wheel_rear_right + + 0 1 0 + + + + + + 1 + 1 + 77 + 0.15 + + + 1 + 1 + 32 + 0.15 + + + 1 + 1 + 32 + 0.15 + + + + + + diff --git a/include/ignition/gazebo/EntityComponentManager.hh b/include/ignition/gazebo/EntityComponentManager.hh index ddbb03e3a8..2aefa6c54c 100644 --- a/include/ignition/gazebo/EntityComponentManager.hh +++ b/include/ignition/gazebo/EntityComponentManager.hh @@ -214,6 +214,18 @@ namespace ignition public: template ComponentTypeT *Component(const ComponentKey &_key); + /// \brief Get the data from a component. + /// * If the component type doesn't hold any data, this won't compile. + /// * If the entity doesn't have that component, it will return nullopt. + /// * If the entity has the component, return its data. + /// \param[in] _entity The entity. + /// \tparam ComponentTypeT Component type + /// \return The data of the component of the specified type assigned to + /// specified Entity, or nullptr if the component could not be found. + public: template + std::optional ComponentData( + const Entity _entity) const; + /// \brief Get the type IDs of all components attached to an entity. /// \param[in] _entity Entity to check. /// \return All the component type IDs. diff --git a/include/ignition/gazebo/Link.hh b/include/ignition/gazebo/Link.hh index 25d9cbec59..1f6ad18cd6 100644 --- a/include/ignition/gazebo/Link.hh +++ b/include/ignition/gazebo/Link.hh @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,56 @@ namespace ignition public: std::optional ParentModel( const EntityComponentManager &_ecm) const; + /// \brief Check if this is the canonical link. + /// \param[in] _ecm Entity-component manager. + /// \return True if it is the canonical link. + public: bool IsCanonical(const EntityComponentManager &_ecm) const; + + /// \brief Get whether this link has wind enabled. + /// \param[in] _ecm Entity-component manager. + /// \return True if wind mode is on. + public: bool WindMode(const EntityComponentManager &_ecm) const; + + /// \brief Get the ID of a collision entity which is an immediate child of + /// this link. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _name Collision name. + /// \return Collision entity. + public: gazebo::Entity CollisionByName(const EntityComponentManager &_ecm, + const std::string &_name) const; + + /// \brief Get the ID of a visual entity which is an immediate child of + /// this link. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _name Visual name. + /// \return Visual entity. + public: gazebo::Entity VisualByName(const EntityComponentManager &_ecm, + const std::string &_name) const; + + /// \brief Get all collisions which are immediate children of this link. + /// \param[in] _ecm Entity-component manager. + /// \return All collisions in this link. + public: std::vector Collisions( + const EntityComponentManager &_ecm) const; + + /// \brief Get all visuals which are immediate children of this link. + /// \param[in] _ecm Entity-component manager. + /// \return All visuals in this link. + public: std::vector Visuals( + const EntityComponentManager &_ecm) const; + + /// \brief Get the number of collisions which are immediate children of + /// this link. + /// \param[in] _ecm Entity-component manager. + /// \return Number of collisions in this link. + public: uint64_t CollisionCount(const EntityComponentManager &_ecm) const; + + /// \brief Get the number of visuals which are immediate children of this + /// link. + /// \param[in] _ecm Entity-component manager. + /// \return Number of visuals in this link. + public: uint64_t VisualCount(const EntityComponentManager &_ecm) const; + /// \brief Get the pose of the link frame in the world coordinate frame. /// \param[in] _ecm Entity-component manager. /// \return Absolute Pose of the link or nullopt if the entity does not diff --git a/include/ignition/gazebo/Model.hh b/include/ignition/gazebo/Model.hh index 0e3fcdf0b0..89450cb45c 100644 --- a/include/ignition/gazebo/Model.hh +++ b/include/ignition/gazebo/Model.hh @@ -19,6 +19,9 @@ #include #include +#include + +#include #include #include @@ -95,11 +98,35 @@ namespace ignition /// \return Model's name. public: std::string Name(const EntityComponentManager &_ecm) const; + /// \brief Get whether this model is static. + /// \param[in] _ecm Entity-component manager. + /// \return True if static. + public: bool Static(const EntityComponentManager &_ecm) const; + + /// \brief Get whether this model has self-collide enabled. + /// \param[in] _ecm Entity-component manager. + /// \return True if self-colliding. + public: bool SelfCollide(const EntityComponentManager &_ecm) const; + + /// \brief Get whether this model has wind enabled. + /// \param[in] _ecm Entity-component manager. + /// \return True if wind mode is on. + public: bool WindMode(const EntityComponentManager &_ecm) const; + + /// \brief Get the source file where this model came from. If empty, + /// the model wasn't loaded directly from a file, probably from an SDF + /// string. + /// \param[in] _ecm Entity-component manager. + /// \return Path to the source SDF file. + public: std::string SourceFilePath(const EntityComponentManager &_ecm) + const; + /// \brief Get the ID of a joint entity which is an immediate child of /// this model. /// \param[in] _ecm Entity-component manager. /// \param[in] _name Joint name. /// \return Joint entity. + /// \todo(anyone) Make const public: gazebo::Entity JointByName(const EntityComponentManager &_ecm, const std::string &_name); @@ -108,9 +135,40 @@ namespace ignition /// \param[in] _ecm Entity-component manager. /// \param[in] _name Link name. /// \return Link entity. + /// \todo(anyone) Make const public: gazebo::Entity LinkByName(const EntityComponentManager &_ecm, const std::string &_name); + /// \brief Get all joints which are immediate children of this model. + /// \param[in] _ecm Entity-component manager. + /// \return All joints in this model. + public: std::vector Joints( + const EntityComponentManager &_ecm) const; + + /// \brief Get all links which are immediate children of this model. + /// \param[in] _ecm Entity-component manager. + /// \return All links in this model. + public: std::vector Links( + const EntityComponentManager &_ecm) const; + + /// \brief Get the number of joints which are immediate children of this + /// model. + /// \param[in] _ecm Entity-component manager. + /// \return Number of joints in this model. + public: uint64_t JointCount(const EntityComponentManager &_ecm) const; + + /// \brief Get the number of links which are immediate children of this + /// model. + /// \param[in] _ecm Entity-component manager. + /// \return Number of links in this model. + public: uint64_t LinkCount(const EntityComponentManager &_ecm) const; + + /// \brief Set a command to change the model's pose. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _pose New model pose. + public: void SetWorldPoseCmd(EntityComponentManager &_ecm, + const math::Pose3d &_pose); + /// \brief Pointer to private data. private: std::unique_ptr dataPtr; }; diff --git a/include/ignition/gazebo/SdfEntityCreator.hh b/include/ignition/gazebo/SdfEntityCreator.hh index 0a94094609..8ad31f32bb 100644 --- a/include/ignition/gazebo/SdfEntityCreator.hh +++ b/include/ignition/gazebo/SdfEntityCreator.hh @@ -155,6 +155,18 @@ namespace ignition /// \param[in] _parent Entity which should be _child's parent. public: void SetParent(Entity _child, Entity _parent); + /// \brief Overloaded function to recursively create model entities + /// and make sure a) only one canonical link is created per model tree, + /// and b) we override the nested model's static property to true if + /// its parent is static + /// \param[in] _model SDF model object. + /// \param[in] _createCanonicalLink True to create a canonical link + /// component and attach to its child link entity + /// \param[in] _staticParent True if parent is static, false otherwise. + /// \return Model entity. + private: Entity CreateEntities(const sdf::Model *_model, + bool _createCanonicalLink, bool _staticParent); + /// \brief Pointer to private data. private: std::unique_ptr dataPtr; }; diff --git a/include/ignition/gazebo/ServerConfig.hh b/include/ignition/gazebo/ServerConfig.hh index 5d529b8062..50b5d25270 100644 --- a/include/ignition/gazebo/ServerConfig.hh +++ b/include/ignition/gazebo/ServerConfig.hh @@ -327,6 +327,23 @@ namespace ignition /// \param[in] _physicsEngine File containing physics engine library. public: void SetPhysicsEngine(const std::string &_physicsEngine); + /// \brief Render engine plugin library to load. + /// \return File containing render engine library. + public: const std::string &RenderEngineServer() const; + + /// \brief Render engine plugin library to load. + /// \return File containing render engine library. + public: const std::string &RenderEngineGui() const; + + /// \brief Set the render engine server plugin library. + /// \param[in] _renderEngine File containing render engine library. + public: void SetRenderEngineServer( + const std::string &_renderEngineServer); + + /// \brief Set the render engine gui plugin library. + /// \param[in] _renderEngine File containing render engine library. + public: void SetRenderEngineGui(const std::string &_renderEngineGui); + /// \brief Instruct simulation to attach a plugin to a specific /// entity when simulation starts. /// \param[in] _info Information about the plugin to load. diff --git a/include/ignition/gazebo/Util.hh b/include/ignition/gazebo/Util.hh index 87cc852779..436cdf4334 100644 --- a/include/ignition/gazebo/Util.hh +++ b/include/ignition/gazebo/Util.hh @@ -51,6 +51,56 @@ namespace ignition const EntityComponentManager &_ecm, const std::string &_delim = "/", bool _includePrefix = true); + /// \brief Generally, each entity will be of some specific high-level type, + /// such as World, Sensor, Collision, etc, and one type only. + /// The entity type is usually marked by having some component that + /// represents that type, such as `ignition::gazebo::components::Visual`. + /// + /// This function returns the type ID of the given entity's type, which + /// can be checked against different types. For example, if the + /// entity is a model, this will be true: + /// + /// `gazebo::components::Model::typeId == entityTypeId(entity, ecm)` + /// + /// In case the entity isn't of any known type, this will return + /// `ignition::gazebo::kComponentTypeIdInvalid`. + /// + /// In case the entity has more than one type, only one of them will be + /// returned. This is not standard usage. + /// + /// \param[in] _entity Entity to get the type for. + /// \param[in] _ecm Immutable reference to ECM. + /// \return ID of entity's type-defining components. + ComponentTypeId IGNITION_GAZEBO_VISIBLE entityTypeId(const Entity &_entity, + const EntityComponentManager &_ecm); + + /// \brief Generally, each entity will be of some specific high-level type, + /// such as "world", "sensor", "collision", etc, and one type only. + /// + /// This function returns a lowercase string for each type. For example, + /// "light", "actor", etc. + /// + /// In case the entity isn't of any known type, this will return an empty + /// string. + /// + /// In case the entity has more than one type, only one of them will be + /// returned. This is not standard usage. + /// + /// Note that this is different from component type names. + /// + /// \param[in] _entity Entity to get the type for. + /// \param[in] _ecm Immutable reference to ECM. + /// \return ID of entity's type-defining components. + std::string IGNITION_GAZEBO_VISIBLE entityTypeStr(const Entity &_entity, + const EntityComponentManager &_ecm); + + /// \brief Get the world to which the given entity belongs. + /// \param[in] _entity Entity to get the world for. + /// \param[in] _ecm Immutable reference to ECM. + /// \return World entity ID. + Entity IGNITION_GAZEBO_VISIBLE worldEntity(const Entity &_entity, + const EntityComponentManager &_ecm); + /// \brief Helper function to remove a parent scope from a given name. /// This removes the first name found before the delimiter. /// \param[in] _name Input name possibly generated by scopedName. @@ -81,6 +131,14 @@ namespace ignition void IGNITION_GAZEBO_VISIBLE addResourcePaths( const std::vector &_paths = {}); + /// \brief Get the top level model of an entity + /// \param[in] _entity Input entity + /// \param[in] _ecm Constant reference to ECM. + /// \return Entity of top level model + ignition::gazebo::Entity IGNITION_GAZEBO_VISIBLE topLevelModel( + const Entity &_entity, + const EntityComponentManager &_ecm); + /// \brief Environment variable holding resource paths. const std::string kResourcePathEnv{"IGN_GAZEBO_RESOURCE_PATH"}; diff --git a/include/ignition/gazebo/World.hh b/include/ignition/gazebo/World.hh new file mode 100644 index 0000000000..1e902ef169 --- /dev/null +++ b/include/ignition/gazebo/World.hh @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2020 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 IGNITION_GAZEBO_WORLD_HH_ +#define IGNITION_GAZEBO_WORLD_HH_ + +#include +#include +#include + +#include +#include + +#include "ignition/gazebo/config.hh" +#include "ignition/gazebo/EntityComponentManager.hh" +#include "ignition/gazebo/Export.hh" +#include "ignition/gazebo/Types.hh" + +namespace ignition +{ + namespace gazebo + { + // Inline bracket to help doxygen filtering. + inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { + // Forward declarations. + class IGNITION_GAZEBO_HIDDEN WorldPrivate; + // + /// \class World World.hh ignition/gazebo/World.hh + /// \brief This class provides wrappers around entities and components + /// which are more convenient and straight-forward to use than dealing + /// with the `EntityComponentManager` directly. + /// All the functions provided here are meant to be used with a world + /// entity. + /// + /// For example, given a world's entity, to find the value of its + /// name component, one could use the entity-component manager (`ecm`) + /// directly as follows: + /// + /// std::string name = ecm.Component(entity)->Data(); + /// + /// Using this class however, the same information can be obtained with + /// a simpler function call: + /// + /// World world(entity); + /// std::string name = world.Name(ecm); + class IGNITION_GAZEBO_VISIBLE World { + /// \brief Constructor + /// \param[in] _entity World entity + public: explicit World(gazebo::Entity _entity = kNullEntity); + + /// \brief Copy constructor + /// \param[in] _world World to copy. + public: World(const World &_world); + + /// \brief Move constructor + /// \param[in] _world World to move. + public: World(World &&_world) noexcept; + + /// \brief Move assignment operator. + /// \param[in] _world World component to move. + /// \return Reference to this. + public: World &operator=(World &&_world) noexcept; + + /// \brief Copy assignment operator. + /// \param[in] _world World to copy. + /// \return Reference to this. + public: World &operator=(const World &_world); + + /// \brief Destructor + public: virtual ~World(); + + /// \brief Get the entity which this World is related to. + /// \return World entity. + public: gazebo::Entity Entity() const; + + /// \brief Check whether this world correctly refers to an entity that + /// has a components::World. + /// \param[in] _ecm Entity-component manager. + /// \return True if it's a valid world in the manager. + public: bool Valid(const EntityComponentManager &_ecm) const; + + /// \brief Get the world's unscoped name. + /// \param[in] _ecm Entity-component manager. + /// \return World's name or nullopt if the entity does not have a + /// components::Name component + public: std::optional Name( + const EntityComponentManager &_ecm) const; + + /// \brief Get the gravity in m/s^2. + /// \param[in] _ecm Entity-component manager. + /// \return Gravity vector or nullopt if the entity does not + /// have a components::Gravity component. + public: std::optional Gravity( + const EntityComponentManager &_ecm) const; + + /// \brief Get the magnetic field in Tesla. + /// \param[in] _ecm Entity-component manager. + /// \return Magnetic field vector or nullopt if the entity does not + /// have a components::MagneticField component. + public: std::optional MagneticField( + const EntityComponentManager &_ecm) const; + + /// \brief Get atmosphere information. + /// \param[in] _ecm Entity-component manager. + /// \return Magnetic field vector or nullopt if the entity does not + /// have a components::Atmosphere component. + public: std::optional Atmosphere( + const EntityComponentManager &_ecm) const; + + /// \brief Get the ID of a light entity which is an immediate child of + /// this world. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _name Light name. + /// \return Light entity. + public: gazebo::Entity LightByName(const EntityComponentManager &_ecm, + const std::string &_name) const; + + /// \brief Get the ID of a actor entity which is an immediate child of + /// this world. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _name Actor name. + /// \return Actor entity. + public: gazebo::Entity ActorByName(const EntityComponentManager &_ecm, + const std::string &_name) const; + + /// \brief Get the ID of a model entity which is an immediate child of + /// this world. + /// \param[in] _ecm Entity-component manager. + /// \param[in] _name Model name. + /// \return Model entity. + public: gazebo::Entity ModelByName(const EntityComponentManager &_ecm, + const std::string &_name) const; + + /// \brief Get all lights which are immediate children of this world. + /// \param[in] _ecm Entity-component manager. + /// \return All lights in this world. + public: std::vector Lights( + const EntityComponentManager &_ecm) const; + + /// \brief Get all actors which are immediate children of this world. + /// \param[in] _ecm Entity-component manager. + /// \return All actors in this world. + public: std::vector Actors( + const EntityComponentManager &_ecm) const; + + /// \brief Get all models which are immediate children of this world. + /// \param[in] _ecm Entity-component manager. + /// \return All models in this world. + public: std::vector Models( + const EntityComponentManager &_ecm) const; + + /// \brief Get the number of lights which are immediate children of this + /// world. + /// \param[in] _ecm Entity-component manager. + /// \return Number of lights in this world. + public: uint64_t LightCount(const EntityComponentManager &_ecm) const; + + /// \brief Get the number of actors which are immediate children of this + /// world. + /// \param[in] _ecm Entity-component manager. + /// \return Number of actors in this world. + public: uint64_t ActorCount(const EntityComponentManager &_ecm) const; + + /// \brief Get the number of models which are immediate children of this + /// world. + /// \param[in] _ecm Entity-component manager. + /// \return Number of models in this world. + public: uint64_t ModelCount(const EntityComponentManager &_ecm) const; + + /// \brief Pointer to private data. + private: std::unique_ptr dataPtr; + }; + } + } +} +#endif diff --git a/include/ignition/gazebo/components/AngularVelocityCmd.hh b/include/ignition/gazebo/components/AngularVelocityCmd.hh index 77edfd277a..1a22171456 100644 --- a/include/ignition/gazebo/components/AngularVelocityCmd.hh +++ b/include/ignition/gazebo/components/AngularVelocityCmd.hh @@ -32,14 +32,14 @@ namespace gazebo inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { namespace components { - /// \brief A component type that contains angular velocity cmd of an entity - /// represented by ignition::math::Vector3d. + /// \brief A component type that contains the commanded angular velocity of + /// an entity, in its own frame, represented by ignition::math::Vector3d. using AngularVelocityCmd = Component; IGN_GAZEBO_REGISTER_COMPONENT( "ign_gazebo_components.AngularVelocityCmd", AngularVelocityCmd) - /// \brief A component type that contains angular velocity cmd + /// \brief A component type that contains the commanded angular velocity /// of an entity in the world frame represented by ignition::math::Vector3d. using WorldAngularVelocityCmd = Component; diff --git a/include/ignition/gazebo/components/LinearVelocityCmd.hh b/include/ignition/gazebo/components/LinearVelocityCmd.hh index e68eac2eeb..cf03bea0ce 100644 --- a/include/ignition/gazebo/components/LinearVelocityCmd.hh +++ b/include/ignition/gazebo/components/LinearVelocityCmd.hh @@ -32,15 +32,17 @@ namespace gazebo inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { namespace components { - /// \brief A component type that contains linear velocity of an entity - /// represented by ignition::math::Vector3d. + // \brief A component type that contains the commanded linear velocity of an + /// entity represented by ignition::math::Vector3d, expressed in the entity's + /// frame. using LinearVelocityCmd = Component< math::Vector3d, class LinearVelocityCmdTag>; IGN_GAZEBO_REGISTER_COMPONENT( "ign_gazebo_components.LinearVelocityCmd", LinearVelocityCmd) - /// \brief A component type that contains linear velocity of an entity in the - /// world frame represented by ignition::math::Vector3d. + /// \brief A component type that contains the commanded linear velocity of an + /// entity represented by ignition::math::Vector3d, expressed in the world + /// frame. using WorldLinearVelocityCmd = Component; IGN_GAZEBO_REGISTER_COMPONENT( diff --git a/include/ignition/gazebo/components/LogPlaybackStatistics.hh b/include/ignition/gazebo/components/LogPlaybackStatistics.hh new file mode 100644 index 0000000000..973eec3857 --- /dev/null +++ b/include/ignition/gazebo/components/LogPlaybackStatistics.hh @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 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 IGNITION_GAZEBO_COMPONENTS_LogPlaybackStatistics_HH_ +#define IGNITION_GAZEBO_COMPONENTS_LogPlaybackStatistics_HH_ + +#include +#include +#include +#include +#include +#include + +namespace ignition +{ +namespace gazebo +{ +// Inline bracket to help doxygen filtering. +inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { +namespace components +{ + /// \brief A component type that contains log playback, + /// systems::LogPlayback, information. + /// The log playback is created from world entity upon the playback plugin + /// being loaded + using LogPlaybackStatistics = Component; + IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.LogPlaybackStatistics", + LogPlaybackStatistics) +} +} +} +} + +#endif diff --git a/include/ignition/gazebo/components/RenderEngineGuiPlugin.hh b/include/ignition/gazebo/components/RenderEngineGuiPlugin.hh new file mode 100644 index 0000000000..e2539e1331 --- /dev/null +++ b/include/ignition/gazebo/components/RenderEngineGuiPlugin.hh @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 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 IGNITION_GAZEBO_COMPONENTS_RENDERENGINEGUIPLUGIN_HH_ +#define IGNITION_GAZEBO_COMPONENTS_RENDERENGINEGUIPLUGIN_HH_ + +#include +#include +#include +#include +#include + +namespace ignition +{ +namespace gazebo +{ +// Inline bracket to help doxygen filtering. +inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { +namespace components +{ + /// \brief Holds the render engine gui shared library. + using RenderEngineGuiPlugin = Component; + IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.RenderEngineGuiPlugin", + RenderEngineGuiPlugin) +} +} +} +} + +#endif diff --git a/include/ignition/gazebo/components/RenderEngineServerPlugin.hh b/include/ignition/gazebo/components/RenderEngineServerPlugin.hh new file mode 100644 index 0000000000..6d32db368e --- /dev/null +++ b/include/ignition/gazebo/components/RenderEngineServerPlugin.hh @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 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 IGNITION_GAZEBO_COMPONENTS_RENDERENGINESERVERPLUGIN_HH_ +#define IGNITION_GAZEBO_COMPONENTS_RENDERENGINESERVERPLUGIN_HH_ + +#include +#include +#include +#include +#include + +namespace ignition +{ +namespace gazebo +{ +// Inline bracket to help doxygen filtering. +inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { +namespace components +{ + /// \brief Holds the render engine server shared library. + using RenderEngineServerPlugin = Component; + IGN_GAZEBO_REGISTER_COMPONENT( + "ign_gazebo_components.RenderEngineServerPlugin", + RenderEngineServerPlugin) +} +} +} +} + +#endif diff --git a/include/ignition/gazebo/components/SlipComplianceCmd.hh b/include/ignition/gazebo/components/SlipComplianceCmd.hh new file mode 100644 index 0000000000..f8122b7c41 --- /dev/null +++ b/include/ignition/gazebo/components/SlipComplianceCmd.hh @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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 IGNITION_GAZEBO_COMPONENTS_SLIPCOMPLIANCECMD_HH_ +#define IGNITION_GAZEBO_COMPONENTS_SLIPCOMPLIANCECMD_HH_ + +#include + +#include +#include + +#include +#include "ignition/gazebo/components/Component.hh" + +namespace ignition +{ +namespace gazebo +{ +// Inline bracket to help doxygen filtering. +inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { +namespace components +{ + /// \brief A component type that contains the slip compliance parameters to be + /// set on a collision. The 0 and 1 index values correspond to the slip + /// compliance parameters in friction direction 1 (fdir1) and friction + /// direction 2 (fdir2) respectively. + using SlipComplianceCmd = + Component, class SlipComplianceCmdTag>; + IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.SlipComplianceCmd ", + SlipComplianceCmd) +} +} +} +} +#endif diff --git a/include/ignition/gazebo/detail/EntityComponentManager.hh b/include/ignition/gazebo/detail/EntityComponentManager.hh index ed08397619..0ea2777849 100644 --- a/include/ignition/gazebo/detail/EntityComponentManager.hh +++ b/include/ignition/gazebo/detail/EntityComponentManager.hh @@ -78,6 +78,18 @@ ComponentTypeT *EntityComponentManager::Component(const ComponentKey &_key) this->ComponentImplementation(_key)); } +////////////////////////////////////////////////// +template +std::optional + EntityComponentManager::ComponentData(const Entity _entity) const +{ + auto comp = this->Component(_entity); + if (!comp) + return std::nullopt; + + return std::make_optional(comp->Data()); +} + ////////////////////////////////////////////////// template const ComponentTypeT *EntityComponentManager::First() const diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f4259e11d..1c029e2900 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ set (sources SystemLoader.cc Util.cc View.cc + World.cc ${PROTO_PRIVATE_SRC} ${network_sources} ) @@ -78,6 +79,7 @@ set (gtest_sources System_TEST.cc SystemLoader_TEST.cc Util_TEST.cc + World_TEST.cc network/NetworkConfig_TEST.cc network/PeerTracker_TEST.cc network/NetworkManager_TEST.cc diff --git a/src/Conversions.cc b/src/Conversions.cc index b5cc4b1ca5..0f05d55476 100644 --- a/src/Conversions.cc +++ b/src/Conversions.cc @@ -279,17 +279,27 @@ msgs::Material ignition::gazebo::convert(const sdf::Material &_in) if (workflow) { pbrMsg->set_metalness(workflow->Metalness()); - pbrMsg->set_metalness_map(workflow->MetalnessMap()); + pbrMsg->set_metalness_map(workflow->MetalnessMap().empty() ? "" : + asFullPath(workflow->MetalnessMap(), _in.FilePath())); pbrMsg->set_roughness(workflow->Roughness()); - pbrMsg->set_roughness_map(workflow->RoughnessMap()); + pbrMsg->set_roughness_map(workflow->RoughnessMap().empty() ? "" : + asFullPath(workflow->RoughnessMap(), _in.FilePath())); pbrMsg->set_glossiness(workflow->Glossiness()); - pbrMsg->set_glossiness_map(workflow->GlossinessMap()); - pbrMsg->set_specular_map(workflow->SpecularMap()); - pbrMsg->set_albedo_map(workflow->AlbedoMap()); - pbrMsg->set_normal_map(workflow->NormalMap()); - pbrMsg->set_ambient_occlusion_map(workflow->AmbientOcclusionMap()); - pbrMsg->set_environment_map(workflow->EnvironmentMap()); - pbrMsg->set_emissive_map(workflow->EmissiveMap()); + pbrMsg->set_glossiness_map(workflow->GlossinessMap().empty() ? "" : + asFullPath(workflow->GlossinessMap(), _in.FilePath())); + pbrMsg->set_specular_map(workflow->SpecularMap().empty() ? "" : + asFullPath(workflow->SpecularMap(), _in.FilePath())); + pbrMsg->set_albedo_map(workflow->AlbedoMap().empty() ? "" : + asFullPath(workflow->AlbedoMap(), _in.FilePath())); + pbrMsg->set_normal_map(workflow->NormalMap().empty() ? "" : + asFullPath(workflow->NormalMap(), _in.FilePath())); + pbrMsg->set_ambient_occlusion_map( + workflow->AmbientOcclusionMap().empty() ? "" : + asFullPath(workflow->AmbientOcclusionMap(), _in.FilePath())); + pbrMsg->set_environment_map(workflow->EnvironmentMap().empty() ? "" : + asFullPath(workflow->EnvironmentMap(), _in.FilePath())); + pbrMsg->set_emissive_map(workflow->EmissiveMap().empty() ? "" : + asFullPath(workflow->EmissiveMap(), _in.FilePath())); } } return out; @@ -384,12 +394,12 @@ sdf::Actor ignition::gazebo::convert(const msgs::Actor &_in) for (int i = 0; i < _in.animations_size(); ++i) { const auto &anim = _in.animations(i); - auto newAnim = new sdf::Animation(); - newAnim->SetName(anim.name()); - newAnim->SetFilename(anim.filename()); - newAnim->SetScale(anim.scale()); - newAnim->SetInterpolateX(anim.interpolate_x()); - out.AddAnimation(*newAnim); + sdf::Animation newAnim; + newAnim.SetName(anim.name()); + newAnim.SetFilename(anim.filename()); + newAnim.SetScale(anim.scale()); + newAnim.SetInterpolateX(anim.interpolate_x()); + out.AddAnimation(newAnim); } out.SetScriptLoop(_in.script_loop()); out.SetScriptDelayStart(_in.script_delay_start()); @@ -397,19 +407,19 @@ sdf::Actor ignition::gazebo::convert(const msgs::Actor &_in) for (int i = 0; i < _in.trajectories_size(); ++i) { const auto &traj = _in.trajectories(i); - auto newTraj = new sdf::Trajectory(); - newTraj->SetId(traj.id()); - newTraj->SetType(traj.type()); - newTraj->SetTension(traj.tension()); + sdf::Trajectory newTraj; + newTraj.SetId(traj.id()); + newTraj.SetType(traj.type()); + newTraj.SetTension(traj.tension()); for (int j = 0; j < traj.waypoints_size(); ++j) { const auto &point = traj.waypoints(j); - auto newPoint = new sdf::Waypoint(); - newPoint->SetTime(point.time()); - newPoint->SetPose(msgs::Convert(point.pose())); - newTraj->AddWaypoint(*newPoint); + sdf::Waypoint newPoint; + newPoint.SetTime(point.time()); + newPoint.SetPose(msgs::Convert(point.pose())); + newTraj.AddWaypoint(newPoint); } - out.AddTrajectory(*newTraj); + out.AddTrajectory(newTraj); } return out; } diff --git a/src/EntityComponentManager_TEST.cc b/src/EntityComponentManager_TEST.cc index b61a327d3d..a2de6a632d 100644 --- a/src/EntityComponentManager_TEST.cc +++ b/src/EntityComponentManager_TEST.cc @@ -464,45 +464,69 @@ TEST_P(EntityComponentManagerFixture, ComponentValues) const auto *value = manager.Component(eInt); ASSERT_NE(nullptr, value); EXPECT_EQ(123, value->Data()); + + auto data = manager.ComponentData(eInt); + EXPECT_EQ(123, data); } { const auto *value = manager.Component(eDouble); ASSERT_NE(nullptr, value); EXPECT_DOUBLE_EQ(0.123, value->Data()); + + auto data = manager.ComponentData(eDouble); + EXPECT_EQ(0.123, data); } { const auto *value = manager.Component(eIntDouble); ASSERT_NE(nullptr, value); EXPECT_EQ(456, value->Data()); + + auto data = manager.ComponentData(eIntDouble); + EXPECT_EQ(456, data); } { const auto *value = manager.Component(eIntDouble); ASSERT_NE(nullptr, value); EXPECT_DOUBLE_EQ(0.456, value->Data()); + + auto data = manager.ComponentData(eIntDouble); + EXPECT_EQ(0.456, data); } // Failure cases { const auto *value = manager.Component(eDouble); ASSERT_EQ(nullptr, value); + + auto data = manager.ComponentData(eDouble); + EXPECT_EQ(std::nullopt, data); } { const auto *value = manager.Component(eInt); ASSERT_EQ(nullptr, value); + + auto data = manager.ComponentData(eInt); + EXPECT_EQ(std::nullopt, data); } { const auto *value = manager.Component(999); ASSERT_EQ(nullptr, value); + + auto data = manager.ComponentData(999); + EXPECT_EQ(std::nullopt, data); } { const auto *value = manager.Component(999); ASSERT_EQ(nullptr, value); + + auto data = manager.ComponentData(999); + EXPECT_EQ(std::nullopt, data); } } diff --git a/src/LevelManager.cc b/src/LevelManager.cc index e49d6a46ca..b414d65685 100644 --- a/src/LevelManager.cc +++ b/src/LevelManager.cc @@ -44,6 +44,8 @@ #include "ignition/gazebo/components/PerformerLevels.hh" #include "ignition/gazebo/components/PhysicsEnginePlugin.hh" #include "ignition/gazebo/components/Pose.hh" +#include "ignition/gazebo/components/RenderEngineGuiPlugin.hh" +#include "ignition/gazebo/components/RenderEngineServerPlugin.hh" #include "ignition/gazebo/components/Scene.hh" #include "ignition/gazebo/components/Wind.hh" #include "ignition/gazebo/components/World.hh" @@ -98,6 +100,14 @@ void LevelManager::ReadLevelPerformerInfo() components::PhysicsEnginePlugin( this->runner->serverConfig.PhysicsEngine())); + this->runner->entityCompMgr.CreateComponent(this->worldEntity, + components::RenderEngineServerPlugin( + this->runner->serverConfig.RenderEngineServer())); + + this->runner->entityCompMgr.CreateComponent(this->worldEntity, + components::RenderEngineGuiPlugin( + this->runner->serverConfig.RenderEngineGui())); + auto worldElem = this->runner->sdfWorld->Element(); // Create Wind diff --git a/src/Link.cc b/src/Link.cc index eaed613c47..6289b7909f 100644 --- a/src/Link.cc +++ b/src/Link.cc @@ -18,6 +18,8 @@ #include #include "ignition/gazebo/components/AngularVelocity.hh" +#include "ignition/gazebo/components/CanonicalLink.hh" +#include "ignition/gazebo/components/Collision.hh" #include "ignition/gazebo/components/ExternalWorldWrenchCmd.hh" #include "ignition/gazebo/components/Inertial.hh" #include "ignition/gazebo/components/Joint.hh" @@ -28,6 +30,8 @@ #include "ignition/gazebo/components/Name.hh" #include "ignition/gazebo/components/ParentEntity.hh" #include "ignition/gazebo/components/Pose.hh" +#include "ignition/gazebo/components/Visual.hh" +#include "ignition/gazebo/components/WindMode.hh" #include "ignition/gazebo/Link.hh" @@ -90,11 +94,7 @@ bool Link::Valid(const EntityComponentManager &_ecm) const ////////////////////////////////////////////////// std::optional Link::Name(const EntityComponentManager &_ecm) const { - auto comp = _ecm.Component(this->dataPtr->id); - if (!comp) - return std::nullopt; - - return std::make_optional(comp->Data()); + return _ecm.ComponentData(this->dataPtr->id); } ////////////////////////////////////////////////// @@ -108,15 +108,76 @@ std::optional Link::ParentModel(const EntityComponentManager &_ecm) const return std::optional(parent->Data()); } +////////////////////////////////////////////////// +Entity Link::CollisionByName(const EntityComponentManager &_ecm, + const std::string &_name) const +{ + return _ecm.EntityByComponents( + components::ParentEntity(this->dataPtr->id), + components::Name(_name), + components::Collision()); +} + +////////////////////////////////////////////////// +Entity Link::VisualByName(const EntityComponentManager &_ecm, + const std::string &_name) const +{ + return _ecm.EntityByComponents( + components::ParentEntity(this->dataPtr->id), + components::Name(_name), + components::Visual()); +} + +////////////////////////////////////////////////// +std::vector Link::Collisions(const EntityComponentManager &_ecm) const +{ + return _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Collision()); +} + +////////////////////////////////////////////////// +std::vector Link::Visuals(const EntityComponentManager &_ecm) const +{ + return _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Visual()); +} + +////////////////////////////////////////////////// +uint64_t Link::CollisionCount(const EntityComponentManager &_ecm) const +{ + return this->Collisions(_ecm).size(); +} + +////////////////////////////////////////////////// +uint64_t Link::VisualCount(const EntityComponentManager &_ecm) const +{ + return this->Visuals(_ecm).size(); +} + +////////////////////////////////////////////////// +bool Link::IsCanonical(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + return comp != nullptr; +} + +////////////////////////////////////////////////// +bool Link::WindMode(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + if (comp) + return comp->Data(); + + return false; +} + ////////////////////////////////////////////////// std::optional Link::WorldPose( const EntityComponentManager &_ecm) const { - auto worldPose = _ecm.Component(this->dataPtr->id); - if (!worldPose) - return std::nullopt; - - return std::make_optional(worldPose->Data()); + return _ecm.ComponentData(this->dataPtr->id); } ////////////////////////////////////////////////// @@ -136,13 +197,7 @@ std::optional Link::WorldInertialPose( std::optional Link::WorldLinearVelocity( const EntityComponentManager &_ecm) const { - auto worldLinVel = - _ecm.Component(this->dataPtr->id); - - if (!worldLinVel) - return std::nullopt; - - return std::make_optional(worldLinVel->Data()); + return _ecm.ComponentData(this->dataPtr->id); } ////////////////////////////////////////////////// @@ -169,26 +224,16 @@ std::optional Link::WorldLinearVelocity( std::optional Link::WorldAngularVelocity( const EntityComponentManager &_ecm) const { - auto worldAngVel = - _ecm.Component(this->dataPtr->id); - - if (!worldAngVel) - return std::nullopt; - - return std::make_optional(worldAngVel->Data()); + return _ecm.ComponentData( + this->dataPtr->id); } ////////////////////////////////////////////////// std::optional Link::WorldLinearAcceleration( const EntityComponentManager &_ecm) const { - auto worldLinAccel = - _ecm.Component(this->dataPtr->id); - - if (!worldLinAccel) - return std::nullopt; - - return std::make_optional(worldLinAccel->Data()); + return _ecm.ComponentData( + this->dataPtr->id); } ////////////////////////////////////////////////// diff --git a/src/Model.cc b/src/Model.cc index 6af4d332b3..d9776b94a3 100644 --- a/src/Model.cc +++ b/src/Model.cc @@ -20,6 +20,11 @@ #include "ignition/gazebo/components/Model.hh" #include "ignition/gazebo/components/Name.hh" #include "ignition/gazebo/components/ParentEntity.hh" +#include "ignition/gazebo/components/PoseCmd.hh" +#include "ignition/gazebo/components/SelfCollide.hh" +#include "ignition/gazebo/components/SourceFilePath.hh" +#include "ignition/gazebo/components/Static.hh" +#include "ignition/gazebo/components/WindMode.hh" #include "ignition/gazebo/Model.hh" class ignition::gazebo::ModelPrivate @@ -81,6 +86,46 @@ std::string Model::Name(const EntityComponentManager &_ecm) const return ""; } +////////////////////////////////////////////////// +bool Model::Static(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + if (comp) + return comp->Data(); + + return false; +} + +////////////////////////////////////////////////// +bool Model::SelfCollide(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + if (comp) + return comp->Data(); + + return false; +} + +////////////////////////////////////////////////// +bool Model::WindMode(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + if (comp) + return comp->Data(); + + return false; +} + +////////////////////////////////////////////////// +std::string Model::SourceFilePath(const EntityComponentManager &_ecm) const +{ + auto comp = _ecm.Component(this->dataPtr->id); + if (comp) + return comp->Data(); + + return ""; +} + ////////////////////////////////////////////////// Entity Model::JointByName(const EntityComponentManager &_ecm, const std::string &_name) @@ -101,3 +146,50 @@ Entity Model::LinkByName(const EntityComponentManager &_ecm, components::Link()); } +////////////////////////////////////////////////// +std::vector Model::Joints(const EntityComponentManager &_ecm) const +{ + return _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Joint()); +} + +////////////////////////////////////////////////// +std::vector Model::Links(const EntityComponentManager &_ecm) const +{ + return _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Link()); +} + +////////////////////////////////////////////////// +uint64_t Model::JointCount(const EntityComponentManager &_ecm) const +{ + return this->Joints(_ecm).size(); +} + +////////////////////////////////////////////////// +uint64_t Model::LinkCount(const EntityComponentManager &_ecm) const +{ + return this->Links(_ecm).size(); +} + +////////////////////////////////////////////////// +void Model::SetWorldPoseCmd(EntityComponentManager &_ecm, + const math::Pose3d &_pose) +{ + auto poseCmdComp = _ecm.Component( + this->dataPtr->id); + if (!poseCmdComp) + { + _ecm.CreateComponent(this->dataPtr->id, components::WorldPoseCmd(_pose)); + } + else + { + poseCmdComp->SetData(_pose, + [](const math::Pose3d &, const math::Pose3d &){return false;}); + _ecm.SetChanged(this->dataPtr->id, + components::WorldPoseCmd::typeId, ComponentState::OneTimeChange); + } +} + diff --git a/src/SdfEntityCreator.cc b/src/SdfEntityCreator.cc index c4e03986d1..414e871cd8 100644 --- a/src/SdfEntityCreator.cc +++ b/src/SdfEntityCreator.cc @@ -81,6 +81,10 @@ class ignition::gazebo::SdfEntityCreatorPrivate /// only after we have their scoped name. public: std::map newSensors; + /// \brief Keep track of new models being added, so we load their plugins + /// only after we have their scoped name. + public: std::map newModels; + /// \brief Keep track of new visuals being added, so we load their plugins /// only after we have their scoped name. public: std::map newVisuals; @@ -217,6 +221,41 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model) { IGN_PROFILE("SdfEntityCreator::CreateEntities(sdf::Model)"); + // todo(anyone) Support multiple canonical links in nested models + // This version of CreateEntties keeps track whether or not to create a + // canonical link in a model tree using the second arg in this recursive + // function. We also override child nested models static property if parent + // model is static + auto ent = this->CreateEntities(_model, true, false); + + // Load all model plugins afterwards, so we get scoped name for nested models. + for (const auto &[entity, element] : this->dataPtr->newModels) + { + this->dataPtr->eventManager->Emit(entity, element); + } + this->dataPtr->newModels.clear(); + + // Load sensor plugins after model, so we get scoped name. + for (const auto &[entity, element] : this->dataPtr->newSensors) + { + this->dataPtr->eventManager->Emit(entity, element); + } + this->dataPtr->newSensors.clear(); + + // Load visual plugins after model, so we get scoped name. + for (const auto &[entity, element] : this->dataPtr->newVisuals) + { + this->dataPtr->eventManager->Emit(entity, element); + } + this->dataPtr->newVisuals.clear(); + + return ent; +} + +////////////////////////////////////////////////// +Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model, + bool _createCanonicalLink, bool _staticParent) +{ // Entity Entity modelEntity = this->dataPtr->ecm->CreateEntity(); @@ -226,8 +265,9 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model) components::Pose(ResolveSdfPose(_model->SemanticPose()))); this->dataPtr->ecm->CreateComponent(modelEntity, components::Name(_model->Name())); + bool isStatic = _model->Static() || _staticParent; this->dataPtr->ecm->CreateComponent(modelEntity, - components::Static(_model->Static())); + components::Static(isStatic)); this->dataPtr->ecm->CreateComponent( modelEntity, components::WindMode(_model->EnableWind())); this->dataPtr->ecm->CreateComponent( @@ -239,6 +279,7 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model) // the parent frame until we get frames working. // Links + bool canonicalLinkCreated = false; for (uint64_t linkIndex = 0; linkIndex < _model->LinkCount(); ++linkIndex) { @@ -246,11 +287,14 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model) auto linkEntity = this->CreateEntities(link); this->SetParent(linkEntity, modelEntity); - if ((_model->CanonicalLinkName().empty() && linkIndex == 0) || - (link == _model->CanonicalLink())) + + if (_createCanonicalLink && + ((_model->CanonicalLinkName().empty() && linkIndex == 0) || + (link == _model->CanonicalLink()))) { this->dataPtr->ecm->CreateComponent(linkEntity, components::CanonicalLink()); + canonicalLinkCreated = true; } // Set wind mode if the link didn't override it @@ -271,27 +315,29 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model) this->SetParent(jointEntity, modelEntity); } - // Model plugins - this->dataPtr->eventManager->Emit(modelEntity, - _model->Element()); - - // Load sensor plugins after model, so we get scoped name. - for (const auto &[entity, element] : this->dataPtr->newSensors) + // Nested Models + for (uint64_t modelIndex = 0; modelIndex < _model->ModelCount(); + ++modelIndex) { - this->dataPtr->eventManager->Emit(entity, element); + auto nestedModel = _model->ModelByIndex(modelIndex); + + // Create nested model. Make sure to only create canonical link component + // in the nested model if a canonical link has not been created in this + // model yet. Also override static propery of the nested model if this model + // is static + auto nestedModelEntity = this->CreateEntities(nestedModel, + (_createCanonicalLink && !canonicalLinkCreated), isStatic); + + this->SetParent(nestedModelEntity, modelEntity); } - this->dataPtr->newSensors.clear(); // Store the model's SDF DOM to be used when saving the world to file this->dataPtr->ecm->CreateComponent( modelEntity, components::ModelSdf(*_model)); - // Load visual plugins after model, so we get scoped name. - for (const auto &[entity, element] : this->dataPtr->newVisuals) - { - this->dataPtr->eventManager->Emit(entity, element); - } - this->dataPtr->newVisuals.clear(); + // Keep track of models so we can load their plugins after loading the entire + // model and having its full scoped name. + this->dataPtr->newModels[modelEntity] = _model->Element(); return modelEntity; } diff --git a/src/SdfGenerator.cc b/src/SdfGenerator.cc index 7201fd4800..abf62a2cbf 100644 --- a/src/SdfGenerator.cc +++ b/src/SdfGenerator.cc @@ -24,6 +24,7 @@ #include "ignition/gazebo/components/Light.hh" #include "ignition/gazebo/components/Model.hh" #include "ignition/gazebo/components/Name.hh" +#include "ignition/gazebo/components/ParentEntity.hh" #include "ignition/gazebo/components/Pose.hh" #include "ignition/gazebo/components/SourceFilePath.hh" #include "ignition/gazebo/components/World.hh" @@ -293,6 +294,12 @@ namespace sdf_generator [&](const Entity &_modelEntity, const components::Model *, const components::ModelSdf *_modelSdf) { + // skip nested models as they are not direct children of world + auto parentComp = _ecm.Component( + _modelEntity); + if (parentComp && parentComp->Data() != _entity) + return true; + auto modelDir = common::parentPath(_modelSdf->Data().Element()->FilePath()); const std::string modelName = diff --git a/src/ServerConfig.cc b/src/ServerConfig.cc index 296f9263a7..fbb61135ca 100644 --- a/src/ServerConfig.cc +++ b/src/ServerConfig.cc @@ -225,6 +225,8 @@ class ignition::gazebo::ServerConfigPrivate logRecordCompressPath(_cfg->logRecordCompressPath), resourceCache(_cfg->resourceCache), physicsEngine(_cfg->physicsEngine), + renderEngineServer(_cfg->renderEngineServer), + renderEngineGui(_cfg->renderEngineGui), plugins(_cfg->plugins), networkRole(_cfg->networkRole), networkSecondaries(_cfg->networkSecondaries), @@ -268,6 +270,14 @@ class ignition::gazebo::ServerConfigPrivate /// \brief File containing physics engine plugin. If empty, DART will be used. public: std::string physicsEngine = ""; + /// \brief File containing render engine server plugin. If empty, OGRE2 + /// will be used. + public: std::string renderEngineServer = ""; + + /// \brief File containing render engine gui plugin. If empty, OGRE2 + /// will be used. + public: std::string renderEngineGui = ""; + /// \brief List of plugins to load. public: std::list plugins; @@ -510,6 +520,30 @@ void ServerConfig::SetPhysicsEngine(const std::string &_physicsEngine) this->dataPtr->physicsEngine = _physicsEngine; } +///////////////////////////////////////////////// +const std::string &ServerConfig::RenderEngineServer() const +{ + return this->dataPtr->renderEngineServer; +} + +///////////////////////////////////////////////// +void ServerConfig::SetRenderEngineServer(const std::string &_renderEngineServer) +{ + this->dataPtr->renderEngineServer = _renderEngineServer; +} + +///////////////////////////////////////////////// +const std::string &ServerConfig::RenderEngineGui() const +{ + return this->dataPtr->renderEngineGui; +} + +///////////////////////////////////////////////// +void ServerConfig::SetRenderEngineGui(const std::string &_renderEngineGui) +{ + this->dataPtr->renderEngineGui = _renderEngineGui; +} + ///////////////////////////////////////////////// void ServerConfig::AddPlugin(const ServerConfig::PluginInfo &_info) { diff --git a/src/Util.cc b/src/Util.cc index 4e655ccf3f..5b5995ae9e 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -25,6 +25,7 @@ #include #include +#include "ignition/gazebo/components/Actor.hh" #include "ignition/gazebo/components/Collision.hh" #include "ignition/gazebo/components/Joint.hh" #include "ignition/gazebo/components/Light.hh" @@ -84,47 +85,14 @@ std::string scopedName(const Entity &_entity, auto name = nameComp->Data(); // Get entity type - std::string prefix; - if (_ecm.Component(entity)) - { - prefix = "world"; - } - else if (_ecm.Component(entity)) - { - prefix = "model"; - } - else if (_ecm.Component(entity)) - { - prefix = "light"; - } - else if (_ecm.Component(entity)) - { - prefix = "link"; - } - else if (_ecm.Component(entity)) - { - prefix = "collision"; - } - else if (_ecm.Component(entity)) - { - prefix = "visual"; - } - else if (_ecm.Component(entity)) - { - prefix = "joint"; - } - else if (_ecm.Component(entity)) - { - prefix = "sensor"; - } - else + std::string prefix = entityTypeStr(entity, _ecm); + if (prefix.empty()) { ignwarn << "Skipping entity [" << name << "] when generating scoped name, entity type not known." << std::endl; } - auto parentComp = _ecm.Component(entity); if (!prefix.empty()) { @@ -148,6 +116,117 @@ std::string scopedName(const Entity &_entity, return result; } +////////////////////////////////////////////////// +ComponentTypeId entityTypeId(const Entity &_entity, + const EntityComponentManager &_ecm) +{ + ComponentTypeId type{kComponentTypeIdInvalid}; + + if (_ecm.Component(_entity)) + { + type = components::World::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Model::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Light::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Link::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Collision::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Visual::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Joint::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Sensor::typeId; + } + else if (_ecm.Component(_entity)) + { + type = components::Actor::typeId; + } + + return type; +} + +////////////////////////////////////////////////// +std::string entityTypeStr(const Entity &_entity, + const EntityComponentManager &_ecm) +{ + std::string type; + + if (_ecm.Component(_entity)) + { + type = "world"; + } + else if (_ecm.Component(_entity)) + { + type = "model"; + } + else if (_ecm.Component(_entity)) + { + type = "light"; + } + else if (_ecm.Component(_entity)) + { + type = "link"; + } + else if (_ecm.Component(_entity)) + { + type = "collision"; + } + else if (_ecm.Component(_entity)) + { + type = "visual"; + } + else if (_ecm.Component(_entity)) + { + type = "joint"; + } + else if (_ecm.Component(_entity)) + { + type = "sensor"; + } + else if (_ecm.Component(_entity)) + { + type = "actor"; + } + + return type; +} + +////////////////////////////////////////////////// +Entity worldEntity(const Entity &_entity, + const EntityComponentManager &_ecm) +{ + auto entity = _entity; + while (nullptr == _ecm.Component(entity)) + { + // Keep going up the tree + auto parentComp = _ecm.Component(entity); + if (!parentComp) + { + entity = kNullEntity; + break; + } + entity = parentComp->Data(); + } + return entity; +} + ////////////////////////////////////////////////// std::string removeParentScope(const std::string &_name, const std::string &_delim) @@ -313,6 +392,30 @@ void addResourcePaths(const std::vector &_paths) // SDF is evaluated at find call systemPaths->SetFilePathEnv(systemPaths->FilePathEnv()); } + +////////////////////////////////////////////////// +ignition::gazebo::Entity topLevelModel(const Entity &_entity, + const EntityComponentManager &_ecm) +{ + auto entity = _entity; + + // check if parent is a model + auto parentComp = _ecm.Component(entity); + while (parentComp) + { + // check if parent is a model + auto parentEntity = parentComp->Data(); + auto modelComp = _ecm.Component( + parentEntity); + if (!modelComp) + break; + + // set current model entity + entity = parentEntity; + parentComp = _ecm.Component(entity); + } + return entity; +} } } } diff --git a/src/Util_TEST.cc b/src/Util_TEST.cc index ebb6865706..501fdb5939 100644 --- a/src/Util_TEST.cc +++ b/src/Util_TEST.cc @@ -16,8 +16,10 @@ */ #include +#include #include +#include "ignition/gazebo/components/Actor.hh" #include "ignition/gazebo/components/Collision.hh" #include "ignition/gazebo/components/Joint.hh" #include "ignition/gazebo/components/Light.hh" @@ -47,14 +49,16 @@ TEST(UtilTest, ScopedName) // - sensorB // - modelC // - linkC - // - collision + // - collisionC // - visualC // - jointC // - modelCC // - linkCC + // - actorD // World auto worldEntity = ecm.CreateEntity(); + EXPECT_EQ(kNullEntity, gazebo::worldEntity(worldEntity, ecm)); ecm.CreateComponent(worldEntity, components::World()); ecm.CreateComponent(worldEntity, components::Name("world_name")); @@ -130,6 +134,12 @@ TEST(UtilTest, ScopedName) ecm.CreateComponent(linkCCEntity, components::Name("linkCC_name")); ecm.CreateComponent(linkCCEntity, components::ParentEntity(modelCCEntity)); + // Actor D + auto actorDEntity = ecm.CreateEntity(); + ecm.CreateComponent(actorDEntity, components::Actor(sdf::Actor())); + ecm.CreateComponent(actorDEntity, components::Name("actorD_name")); + ecm.CreateComponent(actorDEntity, components::ParentEntity(worldEntity)); + // Check names EXPECT_EQ(scopedName(worldEntity, ecm), "world/world_name"); EXPECT_EQ(scopedName(lightAEntity, ecm, "::"), @@ -158,6 +168,8 @@ TEST(UtilTest, ScopedName) "world/world_name/model/modelC_name/model/modelCC_name"); EXPECT_EQ(scopedName(linkCCEntity, ecm), "world/world_name/model/modelC_name/model/modelCC_name/link/linkCC_name"); + EXPECT_EQ(scopedName(actorDEntity, ecm, "::"), + "world::world_name::actor::actorD_name"); // check name without prefix EXPECT_EQ(scopedName(worldEntity, ecm, "/", false), "world_name"); @@ -185,6 +197,115 @@ TEST(UtilTest, ScopedName) "world_name/modelC_name/modelCC_name"); EXPECT_EQ(scopedName(linkCCEntity, ecm, "/", false), "world_name/modelC_name/modelCC_name/linkCC_name"); + EXPECT_EQ(scopedName(actorDEntity, ecm, "::", false), + "world_name::actorD_name"); + + // World entity + EXPECT_EQ(worldEntity, gazebo::worldEntity(worldEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(lightAEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(modelBEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(linkBEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(lightBEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(sensorBEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(modelCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(linkCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(collisionCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(visualCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(jointCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(modelCCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(linkCCEntity, ecm)); + EXPECT_EQ(worldEntity, gazebo::worldEntity(actorDEntity, ecm)); + EXPECT_EQ(kNullEntity, gazebo::worldEntity(kNullEntity, ecm)); +} + +///////////////////////////////////////////////// +TEST(UtilTest, EntityTypeId) +{ + EntityComponentManager ecm; + + auto entity = ecm.CreateEntity(); + EXPECT_EQ(kComponentTypeIdInvalid, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::World()); + EXPECT_EQ(components::World::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Model()); + EXPECT_EQ(components::Model::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Light()); + EXPECT_EQ(components::Light::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Link()); + EXPECT_EQ(components::Link::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Visual()); + EXPECT_EQ(components::Visual::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Collision()); + EXPECT_EQ(components::Collision::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Joint()); + EXPECT_EQ(components::Joint::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Sensor()); + EXPECT_EQ(components::Sensor::typeId, entityTypeId(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Actor()); + EXPECT_EQ(components::Actor::typeId, entityTypeId(entity, ecm)); +} + +///////////////////////////////////////////////// +TEST(UtilTest, EntityTypeStr) +{ + EntityComponentManager ecm; + + auto entity = ecm.CreateEntity(); + EXPECT_TRUE(entityTypeStr(entity, ecm).empty()); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::World()); + EXPECT_EQ("world", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Model()); + EXPECT_EQ("model", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Light()); + EXPECT_EQ("light", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Link()); + EXPECT_EQ("link", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Visual()); + EXPECT_EQ("visual", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Collision()); + EXPECT_EQ("collision", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Joint()); + EXPECT_EQ("joint", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Sensor()); + EXPECT_EQ("sensor", entityTypeStr(entity, ecm)); + + entity = ecm.CreateEntity(); + ecm.CreateComponent(entity, components::Actor()); + EXPECT_EQ("actor", entityTypeStr(entity, ecm)); } ///////////////////////////////////////////////// @@ -285,3 +406,60 @@ TEST(UtilTest, AsFullPath) } #endif } + +///////////////////////////////////////////////// +TEST(UtilTest, TopLevelModel) +{ + EntityComponentManager ecm; + + // world + // - modelA + // - linkA + // - modelB + // - linkB + // - modelC + + // World + auto worldEntity = ecm.CreateEntity(); + ecm.CreateComponent(worldEntity, components::World()); + ecm.CreateComponent(worldEntity, components::Name("world_name")); + + // Model A + auto modelAEntity = ecm.CreateEntity(); + ecm.CreateComponent(modelAEntity, components::Model()); + ecm.CreateComponent(modelAEntity, components::Name("modelA_name")); + ecm.CreateComponent(modelAEntity, components::ParentEntity(worldEntity)); + + // Link A - Child of Model A + auto linkAEntity = ecm.CreateEntity(); + ecm.CreateComponent(linkAEntity, components::Link()); + ecm.CreateComponent(linkAEntity, components::Name("linkA_name")); + ecm.CreateComponent(linkAEntity, components::ParentEntity(modelAEntity)); + + // Model B - nested inside Model A + auto modelBEntity = ecm.CreateEntity(); + ecm.CreateComponent(modelBEntity, components::Model()); + ecm.CreateComponent(modelBEntity, components::Name("modelB_name")); + ecm.CreateComponent(modelBEntity, components::ParentEntity(modelAEntity)); + + // Link B - child of Model B + auto linkBEntity = ecm.CreateEntity(); + ecm.CreateComponent(linkBEntity, components::Link()); + ecm.CreateComponent(linkBEntity, components::Name("linkB_name")); + ecm.CreateComponent(linkBEntity, components::ParentEntity(modelBEntity)); + + // Model C + auto modelCEntity = ecm.CreateEntity(); + ecm.CreateComponent(modelCEntity, components::Model()); + ecm.CreateComponent(modelCEntity, components::Name("modelC_name")); + ecm.CreateComponent(modelCEntity, components::ParentEntity(worldEntity)); + + // model A, link A, model B and link B should have model A as top level entity + EXPECT_EQ(modelAEntity, topLevelModel(modelAEntity, ecm)); + EXPECT_EQ(modelAEntity, topLevelModel(linkAEntity, ecm)); + EXPECT_EQ(modelAEntity, topLevelModel(modelBEntity, ecm)); + EXPECT_EQ(modelAEntity, topLevelModel(linkBEntity, ecm)); + + // model C should have itself as the top level entity + EXPECT_EQ(modelCEntity, topLevelModel(modelCEntity, ecm)); +} diff --git a/src/World.cc b/src/World.cc new file mode 100644 index 0000000000..333a0f430c --- /dev/null +++ b/src/World.cc @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2020 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 "ignition/gazebo/components/Actor.hh" +#include "ignition/gazebo/components/Atmosphere.hh" +#include "ignition/gazebo/components/Gravity.hh" +#include "ignition/gazebo/components/Light.hh" +#include "ignition/gazebo/components/MagneticField.hh" +#include "ignition/gazebo/components/Model.hh" +#include "ignition/gazebo/components/Name.hh" +#include "ignition/gazebo/components/ParentEntity.hh" +#include "ignition/gazebo/components/World.hh" +#include "ignition/gazebo/World.hh" + +class ignition::gazebo::WorldPrivate +{ + /// \brief Id of world entity. + public: Entity id{kNullEntity}; +}; + +using namespace ignition; +using namespace gazebo; + +////////////////////////////////////////////////// +World::World(gazebo::Entity _entity) + : dataPtr(std::make_unique()) +{ + this->dataPtr->id = _entity; +} + +///////////////////////////////////////////////// +World::World(const World &_world) + : dataPtr(std::make_unique(*_world.dataPtr)) +{ +} + +///////////////////////////////////////////////// +World::World(World &&_world) noexcept = default; + +////////////////////////////////////////////////// +World::~World() = default; + +///////////////////////////////////////////////// +World &World::operator=(const World &_world) +{ + *this->dataPtr = (*_world.dataPtr); + return *this; +} + +///////////////////////////////////////////////// +World &World::operator=(World &&_world) noexcept = default; + +////////////////////////////////////////////////// +Entity World::Entity() const +{ + return this->dataPtr->id; +} + +////////////////////////////////////////////////// +bool World::Valid(const EntityComponentManager &_ecm) const +{ + return nullptr != _ecm.Component(this->dataPtr->id); +} + +////////////////////////////////////////////////// +std::optional World::Name(const EntityComponentManager &_ecm) const +{ + return _ecm.ComponentData(this->dataPtr->id); +} + +////////////////////////////////////////////////// +std::optional World::Atmosphere( + const EntityComponentManager &_ecm) const +{ + return _ecm.ComponentData(this->dataPtr->id); +} + +////////////////////////////////////////////////// +std::optional World::Gravity( + const EntityComponentManager &_ecm) const +{ + return _ecm.ComponentData(this->dataPtr->id); +} + +////////////////////////////////////////////////// +std::optional World::MagneticField( + const EntityComponentManager &_ecm) const +{ + return _ecm.ComponentData(this->dataPtr->id); +} + +////////////////////////////////////////////////// +Entity World::LightByName(const EntityComponentManager &_ecm, + const std::string &_name) const +{ + // Can't use components::Light in EntityByComponents, see + // https://github.com/ignitionrobotics/ign-gazebo/issues/376 + auto entities = _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Name(_name)); + + for (const auto &entity : entities) + { + if (_ecm.Component(entity)) + return entity; + } + return kNullEntity; +} + +////////////////////////////////////////////////// +Entity World::ActorByName(const EntityComponentManager &_ecm, + const std::string &_name) const +{ + // Can't use components::Actor in EntityByComponents, see + // https://github.com/ignitionrobotics/ign-gazebo/issues/376 + auto entities = _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Name(_name)); + + for (const auto &entity : entities) + { + if (_ecm.Component(entity)) + return entity; + } + return kNullEntity; +} + +////////////////////////////////////////////////// +Entity World::ModelByName(const EntityComponentManager &_ecm, + const std::string &_name) const +{ + return _ecm.EntityByComponents( + components::ParentEntity(this->dataPtr->id), + components::Name(_name), + components::Model()); +} + +////////////////////////////////////////////////// +std::vector World::Lights(const EntityComponentManager &_ecm) const +{ + // Can't use components::Light in EntityByComponents, see + // https://github.com/ignitionrobotics/ign-gazebo/issues/376 + auto entities = _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id)); + + std::vector result; + for (const auto &entity : entities) + { + if (_ecm.Component(entity)) + result.push_back(entity); + } + return result; +} + +////////////////////////////////////////////////// +std::vector World::Actors(const EntityComponentManager &_ecm) const +{ + // Can't use components::Actor in EntityByComponents, see + // https://github.com/ignitionrobotics/ign-gazebo/issues/376 + auto entities = _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id)); + + std::vector result; + for (const auto &entity : entities) + { + if (_ecm.Component(entity)) + result.push_back(entity); + } + return result; +} + +////////////////////////////////////////////////// +std::vector World::Models(const EntityComponentManager &_ecm) const +{ + return _ecm.EntitiesByComponents( + components::ParentEntity(this->dataPtr->id), + components::Model()); +} + +////////////////////////////////////////////////// +uint64_t World::LightCount(const EntityComponentManager &_ecm) const +{ + return this->Lights(_ecm).size(); +} + +////////////////////////////////////////////////// +uint64_t World::ActorCount(const EntityComponentManager &_ecm) const +{ + return this->Actors(_ecm).size(); +} + +////////////////////////////////////////////////// +uint64_t World::ModelCount(const EntityComponentManager &_ecm) const +{ + return this->Models(_ecm).size(); +} + diff --git a/src/World_TEST.cc b/src/World_TEST.cc new file mode 100644 index 0000000000..7c3a03d532 --- /dev/null +++ b/src/World_TEST.cc @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 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 "ignition/gazebo/World.hh" + +///////////////////////////////////////////////// +TEST(WorldTest, Constructor) +{ + ignition::gazebo::World worldNull; + EXPECT_EQ(ignition::gazebo::kNullEntity, worldNull.Entity()); + + ignition::gazebo::Entity id(3); + ignition::gazebo::World world(id); + + EXPECT_EQ(id, world.Entity()); +} + +///////////////////////////////////////////////// +TEST(WorldTest, CopyConstructor) +{ + ignition::gazebo::Entity id(3); + ignition::gazebo::World world(id); + + // Marked nolint because we are specifically testing copy + // constructor here (clang wants unnecessary copies removed) + ignition::gazebo::World worldCopy(world); // NOLINT + EXPECT_EQ(world.Entity(), worldCopy.Entity()); +} + +///////////////////////////////////////////////// +TEST(WorldTest, CopyAssignmentOperator) +{ + ignition::gazebo::Entity id(3); + ignition::gazebo::World world(id); + + ignition::gazebo::World worldCopy; + worldCopy = world; + EXPECT_EQ(world.Entity(), worldCopy.Entity()); +} + +///////////////////////////////////////////////// +TEST(WorldTest, MoveConstructor) +{ + ignition::gazebo::Entity id(3); + ignition::gazebo::World world(id); + + ignition::gazebo::World worldMoved(std::move(world)); + EXPECT_EQ(id, worldMoved.Entity()); +} + +///////////////////////////////////////////////// +TEST(WorldTest, MoveAssignmentOperator) +{ + ignition::gazebo::Entity id(3); + ignition::gazebo::World world(id); + + ignition::gazebo::World worldMoved; + worldMoved = std::move(world); + EXPECT_EQ(id, worldMoved.Entity()); +} diff --git a/src/cmd/cmdgazebo.rb.in b/src/cmd/cmdgazebo.rb.in index d19038c694..ccbb88e03d 100755 --- a/src/cmd/cmdgazebo.rb.in +++ b/src/cmd/cmdgazebo.rb.in @@ -40,97 +40,109 @@ COMMON_OPTIONS = ' --versions Show the available versions.' COMMANDS = { 'gazebo' => - "Run and manage Gazebo simulations. \n"\ - " \n"\ - " ign gazebo [options] [file] \n"\ - " \n"\ - " \n"\ - "Available Options: \n"\ - " -g Run only the GUI. \n"\ + "Run and manage Gazebo simulations. \n"\ + " \n"\ + " ign gazebo [options] [file] \n"\ + " \n"\ + " \n"\ + "Available Options: \n"\ + " -g Run only the GUI. \n"\ "\n"\ - " --iterations [arg] Number of iterations to execute. \n"\ + " --iterations [arg] Number of iterations to execute. \n"\ "\n"\ - " --levels Use the level system. The default is false,\n"\ - " which loads all models. It's always true \n"\ - " with --network-role. \n"\ + " --levels Use the level system. The default is false, \n"\ + " which loads all models. It's always true \n"\ + " with --network-role. \n"\ "\n"\ - " --network-role [arg] Participant role used in a distributed \n"\ - " simulation environment. Role is one of \n"\ - " [primary, secondary]. It implies --levels. \n"\ + " --network-role [arg] Participant role used in a distributed \n"\ + " simulation environment. Role is one of \n"\ + " [primary, secondary]. It implies --levels. \n"\ "\n"\ - " --network-secondaries [arg] Number of secondary participants expected \n"\ - " to join a distributed simulation \n"\ - " environment. (Primary only). \n"\ + " --network-secondaries [arg] Number of secondary participants expected \n"\ + " to join a distributed simulation \n"\ + " environment. (Primary only). \n"\ "\n"\ - " --record Use logging system to record states and \n"\ - " console messages to the default location, \n"\ - " in ~/.ignition/gazebo/log. \n"\ + " --record Use logging system to record states and \n"\ + " console messages to the default location, \n"\ + " in ~/.ignition/gazebo/log. \n"\ "\n"\ - " --record-path [arg] Implicitly invokes --record, and specifies \n"\ - " custom path to put recorded files. Argument\n"\ - " is path to record states and console \n"\ - " messages. Specifying this argument will \n"\ - " enable console logging to a console.log \n"\ - " file in the specified path. \n"\ + " --record-path [arg] Implicitly invokes --record, and specifies \n"\ + " custom path to put recorded files. Argument \n"\ + " is path to record states and console \n"\ + " messages. Specifying this argument will \n"\ + " enable console logging to a console.log \n"\ + " file in the specified path. \n"\ "\n"\ - " --record-resources Implicitly invokes --record, and records \n"\ - " meshes and material files, in addition to \n"\ - " states and console messages. \n"\ + " --record-resources Implicitly invokes --record, and records \n"\ + " meshes and material files, in addition to \n"\ + " states and console messages. \n"\ "\n"\ - " --record-topic [arg] Specify the name of an additional topic to \n"\ - " record. Implicitly invokes --record. \n"\ - " Zero or more topics can be specified by \n"\ - " using multiple --record-topic options. \n"\ - " Regular expressions can be used, which \n"\ - " likely requires quotes. A default set of \n"\ - " topics are also recorded, which support \n"\ - " simulation state playback. Enable debug \n"\ - " console output with the -v 4 option \n"\ - " and look for 'Recording default topic' in \n"\ - " order to determine the default set of \n"\ - " topics. \n"\ - " Examples: \n"\ - " 1. Record all topics. \n"\ - " --record-topic \".*\" \n"\ - " 2. Record only the /stats topic. \n"\ - " --record-topic /stats \n"\ - " 3. Record the /stats and /clock topics. \n"\ - " --record-topic /stats \ \n"\ - " --record-topic /clock \n"\ + " --record-topic [arg] Specify the name of an additional topic to \n"\ + " record. Implicitly invokes --record. \n"\ + " Zero or more topics can be specified by \n"\ + " using multiple --record-topic options. \n"\ + " Regular expressions can be used, which \n"\ + " likely requires quotes. A default set of \n"\ + " topics are also recorded, which support \n"\ + " simulation state playback. Enable debug \n"\ + " console output with the -v 4 option \n"\ + " and look for 'Recording default topic' in \n"\ + " order to determine the default set of \n"\ + " topics. \n"\ + " Examples: \n"\ + " 1. Record all topics. \n"\ + " --record-topic \".*\" \n"\ + " 2. Record only the /stats topic. \n"\ + " --record-topic /stats \n"\ + " 3. Record the /stats and /clock topics. \n"\ + " --record-topic /stats \ \n"\ + " --record-topic /clock \n"\ "\n"\ - " --log-overwrite When recording, overwrite existing files. \n"\ - " Only valid if recording is enabled. \n"\ + " --log-overwrite When recording, overwrite existing files. \n"\ + " Only valid if recording is enabled. \n"\ "\n"\ - " --log-compress When recording, compress final log files. \n"\ - " Only valid if recording is enabled. \n"\ + " --log-compress When recording, compress final log files. \n"\ + " Only valid if recording is enabled. \n"\ "\n"\ - " --playback [arg] Use logging system to play back states. \n"\ - " Argument is path to recorded states. \n"\ + " --playback [arg] Use logging system to play back states. \n"\ + " Argument is path to recorded states. \n"\ "\n"\ - " -r Run simulation on start. \n"\ + " -r Run simulation on start. \n"\ "\n"\ - " -s Run only the server (headless mode). This \n"\ - " overrides -g, if it is also present. \n"\ + " -s Run only the server (headless mode). This \n"\ + " overrides -g, if it is also present. \n"\ "\n"\ - " -v [ --verbose ] [arg] Adjust the level of console output (0~4). \n"\ - " The default verbosity is 1, use -v without \n"\ - " arguments for level 3. \n"\ + " -v [ --verbose ] [arg] Adjust the level of console output (0~4). \n"\ + " The default verbosity is 1, use -v without \n"\ + " arguments for level 3. \n"\ "\n"\ - " --gui-config [arg] Ignition GUI configuration file to load. \n"\ - " If no config is given, the configuration in\n"\ - " the SDF file is used. And if that's not \n"\ - " provided, the default installed config is \n"\ - " used. \n"\ + " --gui-config [arg] Ignition GUI configuration file to load. \n"\ + " If no config is given, the configuration in \n"\ + " the SDF file is used. And if that's not \n"\ + " provided, the default installed config is \n"\ + " used. \n"\ "\n"\ - " --physics-engine [arg] Ignition Physics engine plugin to load. \n"\ - " Gazebo will use DART by default. \n"\ - " (ignition-physics-dartsim-plugin) \n"\ - " Make sure custom plugins are in \n"\ - " IGN_GAZEBO_PHYSICS_ENGINE_PATH. \n"\ + " --physics-engine [arg] Ignition Physics engine plugin to load. \n"\ + " Gazebo will use DART by default. \n"\ + " (ignition-physics-dartsim-plugin) \n"\ + " Make sure custom plugins are in \n"\ + " IGN_GAZEBO_PHYSICS_ENGINE_PATH. \n"\ "\n"\ - " --version Print Gazebo version information. \n"\ + " --render-engine [arg] Ignition Rendering engine plugin to load for \n"\ + " both the server and the GUI. Gazebo will use \n"\ + " OGRE2 by default. (ogre2) \n"\ "\n"\ - " -z [arg] Update rate in Hertz. \n"\ + " --render-engine-gui [arg] Ignition Rendering engine plugin to load for \n"\ + " the GUI. Gazebo will use OGRE2 by default. \n"\ + " (ogre2) \n"\ + "\n"\ + " --render-engine-server [arg] Ignition Rendering engine plugin to load for \n"\ + " the server. Gazebo will use OGRE2 by default. \n"\ + " (ogre2) \n"\ + "\n"\ + " --version Print Gazebo version information. \n"\ + "\n"\ + " -z [arg] Update rate in Hertz. \n"\ "\n"+ COMMON_OPTIONS + "\n\n" + "Environment variables: \n"\ @@ -203,7 +215,9 @@ class Cmd 'server' => 0, 'verbose' => '1', 'gui_config' => '', - 'physics_engine' => '' + 'physics_engine' => '', + 'rendering_engine_gui' => '', + 'rendering_engine_server' => '' } usage = COMMANDS[args[0]] @@ -270,6 +284,16 @@ class Cmd opts.on('--physics-engine [arg]', String) do |e| options['physics_engine'] = e end + opts.on('--render-engine-gui [arg]', String) do |g| + options['render_engine_gui'] = g + end + opts.on('--render-engine-server [arg]', String) do |k| + options['render_engine_server'] = k + end + opts.on('--render-engine [arg]', String) do |f| + options['render_engine_gui'] = f + options['render_engine_server'] = f + end opts.on('--version') do options['version'] = '1' end @@ -388,11 +412,19 @@ class Cmd Importer.extern 'int runServer(const char *, int, int, float, int, const char *, int, int, const char *, int, int, int, const char *, const char *, - const char *, const char *)' + const char *, const char *, const char *, + const char *)' # Import the runGui function Importer.extern 'int runGui(const char *)' + # If playback is specified, and the user has not specified a + # custom gui config, set the gui config to load the playback + # gui config + if (options['playback'] != '' and options['gui_config'] == '') + options['gui_config'] = "_playback_" + end + # Neither the -s nor -g options were used, so run both the server # and gui. if options['server'] == 0 && options['gui'] == 0 @@ -407,6 +439,7 @@ class Cmd options['record-path'], options['record-resources'], options['log-overwrite'], options['log-compress'], options['playback'], options['physics_engine'], + options['render_engine_server'], options['render_engine_gui'], options['file'], options['record-topics'].join(':')) end @@ -441,6 +474,7 @@ class Cmd options['record-path'], options['record-resources'], options['log-overwrite'], options['log-compress'], options['playback'], options['physics_engine'], + options['render_engine_server'], options['render_engine_gui'], options['file'], options['record-topics'].join(':')) # Otherwise run the gui else options['gui'] diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 9e311ea071..5d53622322 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -45,6 +45,7 @@ set(CMAKE_AUTORCC OFF) install(TARGETS ${gui_target} DESTINATION ${IGN_LIB_INSTALL_DIR}) install (FILES gui.config DESTINATION ${IGN_DATA_INSTALL_DIR}/gui) +install (FILES playback_gui.config DESTINATION ${IGN_DATA_INSTALL_DIR}/gui) # Tests set (gtest_sources diff --git a/src/gui/Gui.cc b/src/gui/Gui.cc index 82b08c55c1..b375e912fe 100644 --- a/src/gui/Gui.cc +++ b/src/gui/Gui.cc @@ -77,14 +77,21 @@ std::unique_ptr createGui( // add import path so we can load custom modules app->Engine()->addImportPath(IGN_GAZEBO_GUI_PLUGIN_INSTALL_DIR); + std::string defaultGuiConfigName = "gui.config"; // Set default config file for Gazebo std::string defaultConfig; if (nullptr == _defaultGuiConfig) { + // The playback flag (and not the gui-config flag) was + // specified from the command line + if (nullptr != _guiConfig && std::string(_guiConfig) == "_playback_") + { + defaultGuiConfigName = "playback_gui.config"; + } ignition::common::env(IGN_HOMEDIR, defaultConfig); defaultConfig = ignition::common::joinPaths(defaultConfig, ".ignition", - "gazebo", "gui.config"); + "gazebo", defaultGuiConfigName); } else { @@ -156,14 +163,9 @@ std::unique_ptr createGui( std::size_t runnerCount = 0; // Configuration file from command line - if (_guiConfig != nullptr && std::strlen(_guiConfig) > 0) + if (_guiConfig != nullptr && std::strlen(_guiConfig) > 0 && + std::string(_guiConfig) != "_playback_") { - if (!app->LoadConfig(_guiConfig)) - { - ignwarn << "Failed to load config file[" << _guiConfig << "]." - << std::endl; - } - // Use the first world name with the config file // TODO(anyone) Most of ign-gazebo's transport API includes the world name, // which makes it complicated to mix configurations across worlds. @@ -173,6 +175,13 @@ std::unique_ptr createGui( &ignition::gazebo::GuiRunner::OnPluginAdded); ++runnerCount; runner->setParent(ignition::gui::App()); + + // Load plugins after runner is up + if (!app->LoadConfig(_guiConfig)) + { + ignwarn << "Failed to load config file[" << _guiConfig << "]." + << std::endl; + } } // GUI configuration from SDF (request to server) else @@ -242,7 +251,7 @@ std::unique_ptr createGui( if (!ignition::common::exists(defaultConfig)) { auto installedConfig = ignition::common::joinPaths( - IGNITION_GAZEBO_GUI_CONFIG_PATH, "gui.config"); + IGNITION_GAZEBO_GUI_CONFIG_PATH, defaultGuiConfigName); if (!ignition::common::copyFile(installedConfig, defaultConfig)) { ignerr << "Failed to copy installed config [" << installedConfig diff --git a/src/gui/gui.config b/src/gui/gui.config index 4a7d9afce0..42ecaceec3 100644 --- a/src/gui/gui.config +++ b/src/gui/gui.config @@ -112,7 +112,7 @@ false - 200 + 250 50 floating false diff --git a/src/gui/playback_gui.config b/src/gui/playback_gui.config new file mode 100644 index 0000000000..50cffa6992 --- /dev/null +++ b/src/gui/playback_gui.config @@ -0,0 +1,97 @@ + + + + + 1000 + 845 +