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
+
+
+
+
+
+
+
+
+
+
+
+
+ 3D View
+ false
+ docked
+
+
+ ogre2
+ scene
+ 0.4 0.4 0.4
+ 0.8 0.8 0.8
+ 6 0 6 0 0.5 3.14
+
+
+
+
+
+ World control
+ false
+ false
+ 72
+ 121
+ 1
+
+ floating
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+ 90
+ 350
+ 1
+ #66666666
+
+ floating
+
+
+
+
+
+
+
+
+
+
+ false
+ docked
+
+
+
+
+
+
+ false
+ docked
+
+
diff --git a/src/gui/plugins/CMakeLists.txt b/src/gui/plugins/CMakeLists.txt
index dc89b104fe..2da32427c6 100644
--- a/src/gui/plugins/CMakeLists.txt
+++ b/src/gui/plugins/CMakeLists.txt
@@ -85,6 +85,7 @@ add_subdirectory(align_tool)
add_subdirectory(component_inspector)
add_subdirectory(entity_tree)
add_subdirectory(grid_config)
+add_subdirectory(playback_scrubber)
add_subdirectory(plotting)
add_subdirectory(resource_spawner)
add_subdirectory(scene3d)
diff --git a/src/gui/plugins/align_tool/AlignTool.cc b/src/gui/plugins/align_tool/AlignTool.cc
index a8ab9d36e0..20c56f0cb5 100644
--- a/src/gui/plugins/align_tool/AlignTool.cc
+++ b/src/gui/plugins/align_tool/AlignTool.cc
@@ -93,10 +93,10 @@ AlignTool::AlignTool()
: GuiSystem(), dataPtr(std::make_unique())
{
// Deselect all entities upon loading plugin
- auto deselectEvent = new gui::events::DeselectAllEntities(true);
+ gui::events::DeselectAllEntities deselectEvent(true);
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild(),
- deselectEvent);
+ &deselectEvent);
}
/////////////////////////////////////////////////
diff --git a/src/gui/plugins/component_inspector/ComponentInspector.cc b/src/gui/plugins/component_inspector/ComponentInspector.cc
index 5ef105ece8..de0cf8afee 100644
--- a/src/gui/plugins/component_inspector/ComponentInspector.cc
+++ b/src/gui/plugins/component_inspector/ComponentInspector.cc
@@ -48,7 +48,9 @@
#include "ignition/gazebo/components/PerformerAffinity.hh"
#include "ignition/gazebo/components/Pose.hh"
#include "ignition/gazebo/components/PoseCmd.hh"
+#include "ignition/gazebo/components/SelfCollide.hh"
#include "ignition/gazebo/components/Sensor.hh"
+#include "ignition/gazebo/components/SourceFilePath.hh"
#include "ignition/gazebo/components/Static.hh"
#include "ignition/gazebo/components/Visual.hh"
#include "ignition/gazebo/components/WindMode.hh"
@@ -77,6 +79,9 @@ namespace ignition::gazebo
/// \brief Entity type, such as 'world' or 'model'.
public: QString type;
+ /// \brief Nested model or not
+ public: bool nestedModel = false;
+
/// \brief Whether currently locked on a given entity
public: bool locked{false};
@@ -309,6 +314,17 @@ void ComponentInspector::Update(const UpdateInfo &,
if (typeId == components::Model::typeId)
{
this->SetType("model");
+
+ // check if entity is nested model
+ auto parentComp = _ecm.Component(
+ this->dataPtr->entity);
+ if (parentComp)
+ {
+ auto modelComp = _ecm.Component(parentComp->Data());
+ this->dataPtr->nestedModel = (modelComp);
+ }
+ this->NestedModelChanged();
+
continue;
}
@@ -517,6 +533,13 @@ void ComponentInspector::Update(const UpdateInfo &,
if (comp)
setData(item, comp->Data());
}
+ else if (typeId == components::SelfCollide::typeId)
+ {
+ auto comp =
+ _ecm.Component(this->dataPtr->entity);
+ if (comp)
+ setData(item, comp->Data());
+ }
else if (typeId == components::SensorTopic::typeId)
{
auto comp =
@@ -524,10 +547,10 @@ void ComponentInspector::Update(const UpdateInfo &,
if (comp)
setData(item, comp->Data());
}
- else if (typeId == components::TrajectoryPose::typeId)
+ else if (typeId == components::SourceFilePath::typeId)
{
- auto comp = _ecm.Component(
- this->dataPtr->entity);
+ auto comp =
+ _ecm.Component(this->dataPtr->entity);
if (comp)
setData(item, comp->Data());
}
@@ -705,6 +728,12 @@ void ComponentInspector::OnPose(double _x, double _y, double _z, double _roll,
this->dataPtr->node.Request(poseCmdService, req, cb);
}
+/////////////////////////////////////////////////
+bool ComponentInspector::NestedModel() const
+{
+ return this->dataPtr->nestedModel;
+}
+
// Register this plugin
IGNITION_ADD_PLUGIN(ignition::gazebo::ComponentInspector,
ignition::gui::Plugin)
diff --git a/src/gui/plugins/component_inspector/ComponentInspector.hh b/src/gui/plugins/component_inspector/ComponentInspector.hh
index 6c71a4fc63..470c7b508f 100644
--- a/src/gui/plugins/component_inspector/ComponentInspector.hh
+++ b/src/gui/plugins/component_inspector/ComponentInspector.hh
@@ -178,6 +178,13 @@ namespace gazebo
NOTIFY PausedChanged
)
+ /// \brief Nested Model
+ Q_PROPERTY(
+ bool nestedModel
+ READ NestedModel
+ NOTIFY NestedModelChanged
+ )
+
/// \brief Constructor
public: ComponentInspector();
@@ -200,6 +207,13 @@ namespace gazebo
public: Q_INVOKABLE void OnPose(double _x, double _y, double _z,
double _roll, double _pitch, double _yaw);
+ /// \brief Get whether the entity is a nested model or not
+ /// \return True if the entity is a nested model, false otherwise
+ public: Q_INVOKABLE bool NestedModel() const;
+
+ /// \brief Notify that is nested model property has changed
+ signals: void NestedModelChanged();
+
// Documentation inherited
protected: bool eventFilter(QObject *_obj, QEvent *_event) override;
diff --git a/src/gui/plugins/component_inspector/ComponentInspector.qml b/src/gui/plugins/component_inspector/ComponentInspector.qml
index d5a4bc47fa..aa058cae4f 100644
--- a/src/gui/plugins/component_inspector/ComponentInspector.qml
+++ b/src/gui/plugins/component_inspector/ComponentInspector.qml
@@ -44,6 +44,11 @@ Rectangle {
*/
property string entityType: ComponentInspector.type
+ /**
+ * Get if entity is nested model or not
+ */
+ property bool nestedModel : ComponentInspector.nestedModel
+
/**
* Light grey according to theme
*/
diff --git a/src/gui/plugins/component_inspector/Pose3d.qml b/src/gui/plugins/component_inspector/Pose3d.qml
index 5e3a17b872..8d909e6c4c 100644
--- a/src/gui/plugins/component_inspector/Pose3d.qml
+++ b/src/gui/plugins/component_inspector/Pose3d.qml
@@ -41,7 +41,7 @@ Rectangle {
// Read-only / write
property bool readOnly: {
var isModel = entityType == "model"
- return !(isModel)
+ return !(isModel) || nestedModel
}
property int iconWidth: 20
diff --git a/src/gui/plugins/component_inspector/String.qml b/src/gui/plugins/component_inspector/String.qml
index 8a35f62b6a..974ad846d1 100644
--- a/src/gui/plugins/component_inspector/String.qml
+++ b/src/gui/plugins/component_inspector/String.qml
@@ -58,15 +58,28 @@ Rectangle {
id: typeHeader
}
- TextInput {
+ // TODO(anyone) Support write mode
+ Text {
id: content
text: textFromModel(model)
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
color: Material.theme == Material.Light ? "black" : "white"
font.pointSize: 12
- selectByMouse: true // will only work when we enable it
- enabled: false
+ elide: Text.ElideLeft
+
+ ToolTip {
+ visible: ma.containsMouse
+ delay: Qt.styleHints.mousePressAndHoldInterval
+ text: content.text
+ enter: null
+ exit: null
+ }
+ MouseArea {
+ id: ma
+ anchors.fill: content
+ hoverEnabled: true
+ }
}
Item {
diff --git a/src/gui/plugins/entity_tree/EntityTree.cc b/src/gui/plugins/entity_tree/EntityTree.cc
index ae4fbfc1be..09c262141b 100644
--- a/src/gui/plugins/entity_tree/EntityTree.cc
+++ b/src/gui/plugins/entity_tree/EntityTree.cc
@@ -125,8 +125,8 @@ void TreeModel::AddEntity(unsigned int _entity, const QString &_entityName,
if (nullptr == parentItem)
{
- ignerr << "Failed to find parent entity [" << _parentEntity << "]"
- << std::endl;
+ this->pendingEntities.push_back(
+ {_entity, _entityName, _parentEntity, _type});
return;
}
@@ -140,6 +140,19 @@ void TreeModel::AddEntity(unsigned int _entity, const QString &_entityName,
parentItem->appendRow(entityItem);
this->entityItems[_entity] = entityItem;
+
+ // Check if there are pending children
+ auto sep = std::partition(this->pendingEntities.begin(),
+ this->pendingEntities.end(), [&_entity](const EntityInfo &_entityInfo)
+ {
+ return _entityInfo.parentEntity != _entity;
+ });
+
+ for (auto it = sep; it != this->pendingEntities.end(); ++it)
+ {
+ this->AddEntity(it->entity, it->name, it->parentEntity, it->type);
+ }
+ this->pendingEntities.erase(sep, this->pendingEntities.end());
}
/////////////////////////////////////////////////
@@ -155,6 +168,14 @@ void TreeModel::RemoveEntity(unsigned int _entity)
if (nullptr == item)
{
+ // See if it's pending
+ auto toRemove = std::remove_if(this->pendingEntities.begin(),
+ this->pendingEntities.end(), [&_entity](const EntityInfo &_entityInfo)
+ {
+ return _entityInfo.entity == _entity;
+ });
+ this->pendingEntities.erase(toRemove, this->pendingEntities.end());
+
return;
}
@@ -350,19 +371,19 @@ void EntityTree::Update(const UpdateInfo &, EntityComponentManager &_ecm)
void EntityTree::OnEntitySelectedFromQml(unsigned int _entity)
{
std::vector entitySet {_entity};
- auto event = new gui::events::EntitiesSelected(entitySet, true);
+ gui::events::EntitiesSelected event(entitySet, true);
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild(),
- event);
+ &event);
}
/////////////////////////////////////////////////
void EntityTree::DeselectAllEntities()
{
- auto event = new gui::events::DeselectAllEntities(true);
+ gui::events::DeselectAllEntities event(true);
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild(),
- event);
+ &event);
}
/////////////////////////////////////////////////
diff --git a/src/gui/plugins/entity_tree/EntityTree.hh b/src/gui/plugins/entity_tree/EntityTree.hh
index cbe577a3d7..228a140a57 100644
--- a/src/gui/plugins/entity_tree/EntityTree.hh
+++ b/src/gui/plugins/entity_tree/EntityTree.hh
@@ -20,6 +20,7 @@
#include