diff --git a/.github/ci/after_make.sh b/.github/ci/after_make.sh
index 2e1e59fce2..7e3bdeb02c 100755
--- a/.github/ci/after_make.sh
+++ b/.github/ci/after_make.sh
@@ -6,12 +6,3 @@ set -e
# Install (needed for some tests)
make install
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib
-
-# For gz-tools
-export GZ_CONFIG_PATH=/usr/local/share/gz
-
-# For rendering / window tests
-Xvfb :1 -screen 0 1280x1024x24 &
-export DISPLAY=:1.0
-export RENDER_ENGINE_VALUES=ogre2
-export MESA_GL_VERSION_OVERRIDE=3.3
diff --git a/.github/ci/before_cmake.sh b/.github/ci/before_cmake.sh
new file mode 100755
index 0000000000..308074bc46
--- /dev/null
+++ b/.github/ci/before_cmake.sh
@@ -0,0 +1,9 @@
+#!/bin/sh -l
+
+set -x
+
+# For rendering / window tests
+Xvfb :1 -screen 0 1280x1024x24 &
+export DISPLAY=:1.0
+export RENDER_ENGINE_VALUES=ogre2
+export MESA_GL_VERSION_OVERRIDE=3.3
diff --git a/.github/ci/packages.apt b/.github/ci/packages.apt
index 77df164d6e..efde86b28b 100644
--- a/.github/ci/packages.apt
+++ b/.github/ci/packages.apt
@@ -2,35 +2,34 @@ freeglut3-dev
libbenchmark-dev
libfreeimage-dev
libglew-dev
-libgz-cmake3-dev
-libgz-common5-dev
-libgz-fuel-tools9-dev
-libgz-gui8-dev
-libgz-math7-eigen3-dev
-libgz-msgs10-dev
-libgz-physics7-dev
-libgz-plugin2-dev
-libgz-rendering8-dev
-libgz-sensors8-dev
+libgz-cmake4-dev
+libgz-common6-dev
+libgz-fuel-tools10-dev
+libgz-gui9-dev
+libgz-math8-eigen3-dev
+libgz-msgs11-dev
+libgz-physics8-dev
+libgz-plugin3-dev
+libgz-rendering9-dev
+libgz-sensors9-dev
libgz-tools2-dev
-libgz-transport13-dev
-libgz-utils2-cli-dev
+libgz-transport14-dev
+libgz-utils3-cli-dev
libogre-1.9-dev
libogre-next-2.3-dev
libprotobuf-dev
libprotoc-dev
-libsdformat14-dev
+libsdformat15-dev
libtinyxml2-dev
libxi-dev
libxmu-dev
libpython3-dev
-python3-distutils
-python3-gz-math7
-python3-gz-msgs10
-python3-gz-transport13
+python3-gz-math8
+python3-gz-msgs11
+python3-gz-transport14
python3-pybind11
python3-pytest
-python3-sdformat14
+python3-sdformat15
qml-module-qt-labs-folderlistmodel
qml-module-qt-labs-settings
qml-module-qtgraphicaleffects
@@ -45,3 +44,5 @@ qtdeclarative5-dev
qtquickcontrols2-5-dev
uuid-dev
xvfb
+x11-utils
+mesa-utils
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a0ce61b450..a011e2abda 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,6 +7,8 @@ on:
- 'ign-gazebo[0-9]'
- 'gz-sim[0-9]?'
- 'main'
+
+# Every time you make a push to your PR, it cancel immediately the previous checks,
# and start a new one. The other runner will be available more quickly to your PR.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@@ -28,7 +30,23 @@ jobs:
uses: gazebo-tooling/action-gz-ci@jammy
with:
# per bug https://github.com/gazebosim/gz-sim/issues/1409
- cmake-args: '-DBUILD_DOCS=OFF'
+ cmake-args: '-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_DOCS=OFF'
codecov-enabled: true
cppcheck-enabled: true
cpplint-enabled: true
+ noble-ci:
+ runs-on: ubuntu-latest
+ name: Ubuntu Noble CI
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - uses: actions/setup-python@v3
+ - uses: pre-commit/action@v3.0.0
+ with:
+ extra_args: --all-files
+ - name: Compile and test
+ id: ci
+ uses: gazebo-tooling/action-gz-ci@noble
+ with:
+ # per bug https://github.com/gazebosim/gz-sim/issues/1409
+ cmake-args: '-DCMAKE_INSTALL_PREFIX=/usr -DBUILD_DOCS=OFF'
diff --git a/.github/workflows/package_xml.yml b/.github/workflows/package_xml.yml
new file mode 100644
index 0000000000..4bd4a9aa0b
--- /dev/null
+++ b/.github/workflows/package_xml.yml
@@ -0,0 +1,11 @@
+name: Validate package.xml
+
+on:
+ pull_request:
+
+jobs:
+ package-xml:
+ runs-on: ubuntu-latest
+ name: Validate package.xml
+ steps:
+ - uses: gazebo-tooling/action-gz-ci/validate_package_xml@jammy
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 503f447c1b..9f309499c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,16 +1,16 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
#============================================================================
# Initialize the project
#============================================================================
-project(gz-sim8 VERSION 8.3.0)
-set (GZ_DISTRIBUTION "Harmonic")
+project(gz-sim9 VERSION 9.0.0)
+set (GZ_DISTRIBUTION "Ionic")
#============================================================================
# Find gz-cmake
#============================================================================
# If you get an error at this line, you need to install gz-cmake
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
#============================================================================
# Configure the project
@@ -66,7 +66,7 @@ cmake_dependent_option(USE_DIST_PACKAGES_FOR_PYTHON
#============================================================================
# Setting this policy enables using the protobuf_MODULE_COMPATIBLE
-# set command in CMake versions older than 13.13
+# set command when cmake_minimum_required is less than 3.13
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# This option is needed to use the PROTOBUF_GENERATE_CPP
# in case protobuf is found with the CMake config files
@@ -74,28 +74,28 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# as protobuf could be find transitively by any dependency
set(protobuf_MODULE_COMPATIBLE TRUE)
-gz_find_package(sdformat14 REQUIRED)
-set(SDF_VER ${sdformat14_VERSION_MAJOR})
+gz_find_package(sdformat15 REQUIRED)
+set(SDF_VER ${sdformat15_VERSION_MAJOR})
#--------------------------------------
# Find gz-plugin
-gz_find_package(gz-plugin2 REQUIRED COMPONENTS loader register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+gz_find_package(gz-plugin3 REQUIRED COMPONENTS loader register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
#--------------------------------------
# Find gz-transport
-gz_find_package(gz-transport13 REQUIRED COMPONENTS log parameters)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+gz_find_package(gz-transport14 REQUIRED COMPONENTS log parameters)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
#--------------------------------------
# Find gz-msgs
-gz_find_package(gz-msgs10 REQUIRED)
-set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR})
+gz_find_package(gz-msgs11 REQUIRED)
+set(GZ_MSGS_VER ${gz-msgs11_VERSION_MAJOR})
#--------------------------------------
# Find gz-common
# Always use the profiler component to get the headers, regardless of status.
-gz_find_package(gz-common5
+gz_find_package(gz-common6
COMPONENTS
av
events
@@ -104,17 +104,17 @@ gz_find_package(gz-common5
profiler
REQUIRED
)
-set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR})
+set(GZ_COMMON_VER ${gz-common6_VERSION_MAJOR})
#--------------------------------------
# Find gz-fuel_tools
-gz_find_package(gz-fuel_tools9 REQUIRED)
-set(GZ_FUEL_TOOLS_VER ${gz-fuel_tools9_VERSION_MAJOR})
+gz_find_package(gz-fuel_tools10 REQUIRED)
+set(GZ_FUEL_TOOLS_VER ${gz-fuel_tools10_VERSION_MAJOR})
#--------------------------------------
# Find gz-gui
-gz_find_package(gz-gui8 REQUIRED)
-set(GZ_GUI_VER ${gz-gui8_VERSION_MAJOR})
+gz_find_package(gz-gui9 REQUIRED)
+set(GZ_GUI_VER ${gz-gui9_VERSION_MAJOR})
gz_find_package (Qt5
COMPONENTS
Core
@@ -125,18 +125,18 @@ gz_find_package (Qt5
#--------------------------------------
# Find gz-physics
-gz_find_package(gz-physics7
+gz_find_package(gz-physics8
COMPONENTS
heightmap
mesh
sdf
REQUIRED
)
-set(GZ_PHYSICS_VER ${gz-physics7_VERSION_MAJOR})
+set(GZ_PHYSICS_VER ${gz-physics8_VERSION_MAJOR})
#--------------------------------------
# Find gz-sensors
-gz_find_package(gz-sensors8 REQUIRED
+gz_find_package(gz-sensors9 REQUIRED
# component order is important
COMPONENTS
# non-rendering
@@ -164,17 +164,17 @@ gz_find_package(gz-sensors8 REQUIRED
thermal_camera
wide_angle_camera
)
-set(GZ_SENSORS_VER ${gz-sensors8_VERSION_MAJOR})
+set(GZ_SENSORS_VER ${gz-sensors9_VERSION_MAJOR})
#--------------------------------------
# Find gz-rendering
-gz_find_package(gz-rendering8 REQUIRED)
-set(GZ_RENDERING_VER ${gz-rendering8_VERSION_MAJOR})
+gz_find_package(gz-rendering9 REQUIRED)
+set(GZ_RENDERING_VER ${gz-rendering9_VERSION_MAJOR})
#--------------------------------------
# Find gz-math
-gz_find_package(gz-math7 REQUIRED COMPONENTS eigen3)
-set(GZ_MATH_VER ${gz-math7_VERSION_MAJOR})
+gz_find_package(gz-math8 REQUIRED COMPONENTS eigen3)
+set(GZ_MATH_VER ${gz-math8_VERSION_MAJOR})
#--------------------------------------
# Find if gz command is available
@@ -190,8 +190,8 @@ set(GZ_TOOLS_VER 2)
#--------------------------------------
# Find gz-utils
-gz_find_package(gz-utils2 REQUIRED COMPONENTS cli)
-set(GZ_UTILS_VER ${gz-utils2_VERSION_MAJOR})
+gz_find_package(gz-utils3 REQUIRED COMPONENTS cli)
+set(GZ_UTILS_VER ${gz-utils3_VERSION_MAJOR})
#--------------------------------------
# Find protobuf
@@ -199,7 +199,7 @@ gz_find_package(GzProtobuf
REQUIRED
COMPONENTS all
PRETTY Protobuf)
-set(Protobuf_IMPORT_DIRS ${gz-msgs10_INCLUDE_DIRS})
+set(Protobuf_IMPORT_DIRS ${gz-msgs11_INCLUDE_DIRS})
#--------------------------------------
# Find python
diff --git a/Changelog.md b/Changelog.md
index cb821fd2cc..620f3f922a 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,366 @@
+## Gazebo Sim 9.x
+
+### Gazebo Sim 9.0.0 (2024-09-25)
+
+1. **Baseline:** this includes all changes from 8.6.0 and earlier.
+
+1. Miscellaneous documentation fixes
+ * [Pull request #2634](https://github.com/gazebosim/gz-sim/pull/2634)
+ * [Pull request #2632](https://github.com/gazebosim/gz-sim/pull/2632)
+ * [Pull request #2628](https://github.com/gazebosim/gz-sim/pull/2628)
+ * [Pull request #2631](https://github.com/gazebosim/gz-sim/pull/2631)
+ * [Pull request #2627](https://github.com/gazebosim/gz-sim/pull/2627)
+ * [Pull request #2625](https://github.com/gazebosim/gz-sim/pull/2625)
+ * [Pull request #2622](https://github.com/gazebosim/gz-sim/pull/2622)
+ * [Pull request #2607](https://github.com/gazebosim/gz-sim/pull/2607)
+ * [Pull request #2606](https://github.com/gazebosim/gz-sim/pull/2606)
+ * [Pull request #2602](https://github.com/gazebosim/gz-sim/pull/2602)
+ * [Pull request #2601](https://github.com/gazebosim/gz-sim/pull/2601)
+ * [Pull request #2603](https://github.com/gazebosim/gz-sim/pull/2603)
+ * [Pull request #2578](https://github.com/gazebosim/gz-sim/pull/2578)
+ * [Pull request #2592](https://github.com/gazebosim/gz-sim/pull/2592)
+ * [Pull request #2582](https://github.com/gazebosim/gz-sim/pull/2582)
+ * [Pull request #2585](https://github.com/gazebosim/gz-sim/pull/2585)
+ * [Pull request #2576](https://github.com/gazebosim/gz-sim/pull/2576)
+ * [Pull request #2573](https://github.com/gazebosim/gz-sim/pull/2573)
+ * [Pull request #2571](https://github.com/gazebosim/gz-sim/pull/2571)
+ * [Pull request #2574](https://github.com/gazebosim/gz-sim/pull/2574)
+ * [Pull request #2564](https://github.com/gazebosim/gz-sim/pull/2564)
+ * [Pull request #2563](https://github.com/gazebosim/gz-sim/pull/2563)
+ * [Pull request #2562](https://github.com/gazebosim/gz-sim/pull/2562)
+ * [Pull request #2553](https://github.com/gazebosim/gz-sim/pull/2553)
+
+1. Fix log playback GUI display
+ * [Pull request #2611](https://github.com/gazebosim/gz-sim/pull/2611)
+ * [Pull request #2619](https://github.com/gazebosim/gz-sim/pull/2619)
+
+1. Add tutorial + example SDF for shadow texture size
+ * [Pull request #2597](https://github.com/gazebosim/gz-sim/pull/2597)
+
+1. Fix making breadcrumb static if it's a nested model
+ * [Pull request #2593](https://github.com/gazebosim/gz-sim/pull/2593)
+
+1. Update physics system error msg when plugin can not be loaded
+ * [Pull request #2604](https://github.com/gazebosim/gz-sim/pull/2604)
+
+1. Fix configuring global illumination GUI plugin parameters
+ * [Pull request #2594](https://github.com/gazebosim/gz-sim/pull/2594)
+
+1. Fix particle emitter color range image path warning
+ * [Pull request #2560](https://github.com/gazebosim/gz-sim/pull/2560)
+
+1. Fix empty gui world file
+ * [Pull request #2591](https://github.com/gazebosim/gz-sim/pull/2591)
+
+1. Fix crash on windows due to invalid log directory path
+ * [Pull request #2589](https://github.com/gazebosim/gz-sim/pull/2589)
+
+1. Use ogre2 for DEM worlds
+ * [Pull request #2586](https://github.com/gazebosim/gz-sim/pull/2586)
+
+1. Fix crash when running the optical tactile sensor world
+ * [Pull request #2561](https://github.com/gazebosim/gz-sim/pull/2561)
+
+1. Prevent follow actor plugin from crashing when actor is removed
+ * [Pull request #2577](https://github.com/gazebosim/gz-sim/pull/2577)
+ * [Pull request #2584](https://github.com/gazebosim/gz-sim/pull/2584)
+
+1. Fix hydrodynamics deprecation warning.
+ * [Pull request #2579](https://github.com/gazebosim/gz-sim/pull/2579)
+
+1. Removed actor population world due to bad merge
+ * [Pull request #2581](https://github.com/gazebosim/gz-sim/pull/2581)
+
+1. Fixed warning joint trayectory sdf
+ * [Pull request #2580](https://github.com/gazebosim/gz-sim/pull/2580)
+
+1. Fix looking up camera name in camera lens system
+ * [Pull request #2559](https://github.com/gazebosim/gz-sim/pull/2559)
+
+1. Add a flexible mechanism to combine user and default plugins
+ * [Pull request #2497](https://github.com/gazebosim/gz-sim/pull/2497)
+
+1. Fix crash at exit due to a race condition with new signal handler
+ * [Pull request #2545](https://github.com/gazebosim/gz-sim/pull/2545)
+
+1. Remove from test worlds
+ * [Pull request #2551](https://github.com/gazebosim/gz-sim/pull/2551)
+
+1. Consolidate entity creation.
+ * [Pull request #2452](https://github.com/gazebosim/gz-sim/pull/2452)
+ * [Pull request #2527](https://github.com/gazebosim/gz-sim/pull/2527)
+ * [Pull request #2546](https://github.com/gazebosim/gz-sim/pull/2546)
+
+1. Add cmake install prefix
+ * [Pull request #2539](https://github.com/gazebosim/gz-sim/pull/2539)
+
+1. Fix UNIT_Server_TEST failure caused by change in behavior of `gz::common::SignalHandler`
+ * [Pull request #2537](https://github.com/gazebosim/gz-sim/pull/2537)
+
+1. Fix SphericalCoordinates deprecation warnings
+ * [Pull request #2535](https://github.com/gazebosim/gz-sim/pull/2535)
+
+1. Revert behavior change introduced in #2452
+
+1. Specify System::PreUpdate, Update execution order
+ * [Pull request #2487](https://github.com/gazebosim/gz-sim/pull/2487)
+
+1. Add System interface to set default priority
+ * [Pull request #2500](https://github.com/gazebosim/gz-sim/pull/2500)
+
+1. Force Qt to use xcb plugin on Wayland
+ * [Pull request #2526](https://github.com/gazebosim/gz-sim/pull/2526)
+
+1. Physics: set link velocity from VelocityReset components
+ * [Pull request #2489](https://github.com/gazebosim/gz-sim/pull/2489)
+
+1. ForceTorque system: write WrenchMeasured to ECM
+ * [Pull request #2494](https://github.com/gazebosim/gz-sim/pull/2494)
+
+1. Remove unused var
+ * [Pull request #2524](https://github.com/gazebosim/gz-sim/pull/2524)
+
+1. Deprecate use of added mass via hydrodynamics
+ * [Pull request #2493](https://github.com/gazebosim/gz-sim/pull/2493)
+
+1. Make sure steering joints exist before updating velocity / odometry in AckermannSteering plugin
+ * [Pull request #2521](https://github.com/gazebosim/gz-sim/pull/2521)
+
+1. Fix ResourceSpawner
+ * [Pull request #2490](https://github.com/gazebosim/gz-sim/pull/2490)
+
+1. gui_system_plugin: clarify description in README
+ * [Pull request #2253](https://github.com/gazebosim/gz-sim/pull/2253)
+
+1. Fix adding system to non-existent entity
+ * [Pull request #2516](https://github.com/gazebosim/gz-sim/pull/2516)
+
+1. Remove ignition related deprecations
+ * [Pull request #2505](https://github.com/gazebosim/gz-sim/pull/2505)
+
+1. Fix #2458 - Checking linkEnity is empty
+ * [Pull request #2509](https://github.com/gazebosim/gz-sim/pull/2509)
+
+1. Specify System::PreUpdate, Update execution order
+ * [Pull request #2487](https://github.com/gazebosim/gz-sim/pull/2487)
+
+1. Improve signal handling
+ * [Pull request #2501](https://github.com/gazebosim/gz-sim/pull/2501)
+
+1. Initialize threadsNeedCleanUp
+ * [Pull request #2503](https://github.com/gazebosim/gz-sim/pull/2503)
+
+1. Added support for spacecraft thrusters
+ * [Pull request #2431](https://github.com/gazebosim/gz-sim/pull/2431)
+
+1. Remove systems if their parent entity is removed
+ * [Pull request #2232](https://github.com/gazebosim/gz-sim/pull/2232)
+
+1. Disable rendering tests that are failing on github actions
+ * [Pull request #2480](https://github.com/gazebosim/gz-sim/pull/2480)
+
+1. Fix warnings generated by NetworkConfigTest
+ * [Pull request #2469](https://github.com/gazebosim/gz-sim/pull/2469)
+
+1. Support visualizing mesh collisions with convex decomposition
+ * [Pull request #2352](https://github.com/gazebosim/gz-sim/pull/2352)
+
+1. Remove python3-distutils from package.xml
+ * [Pull request #2450](https://github.com/gazebosim/gz-sim/pull/2450)
+
+1. shapes.sdf example: bump to 1.12, add cone shape
+ * [Pull request #2448](https://github.com/gazebosim/gz-sim/pull/2448)
+
+1. Adding cone primitives.
+ * [Pull request #2410](https://github.com/gazebosim/gz-sim/pull/2410)
+ * [Pull request #2449](https://github.com/gazebosim/gz-sim/pull/2449)
+
+1. Enable 24.04 CI, require cmake 3.22.1
+ * [Pull request #2420](https://github.com/gazebosim/gz-sim/pull/2420)
+
+1. Parse and set bullet solver iterations
+ * [Pull request #2351](https://github.com/gazebosim/gz-sim/pull/2351)
+
+1. ForceTorque system: improve readability
+ * [Pull request #2403](https://github.com/gazebosim/gz-sim/pull/2403)
+
+1. Fix warn unused variable in test
+ * [Pull request #2388](https://github.com/gazebosim/gz-sim/pull/2388)
+
+1. Physics: remove VelocityCmd at each time step
+ * [Pull request #2228](https://github.com/gazebosim/gz-sim/pull/2228)
+
+1. Regroup tutorials into four categories
+ * [Pull request #2109](https://github.com/gazebosim/gz-sim/pull/2109)
+
+1. Remove HIDE_SYMBOLS_BY_DEFAULT: replace by a default configuration in gz-cmake.
+ * [Pull request #2283](https://github.com/gazebosim/gz-sim/pull/2283)
+
+1. Enable HIDE_SYMBOLS_BY_DEFAULT + linux patches
+ * [Pull request #2248](https://github.com/gazebosim/gz-sim/pull/2248)
+
+1. Use sdf FindElement API to avoid const_cast
+ * [Pull request #2231](https://github.com/gazebosim/gz-sim/pull/2231)
+
+1. Bumps in Ionic: gz-sim9
+ * [Pull request #2205](https://github.com/gazebosim/gz-sim/pull/2205)
+ * [Pull request #2211](https://github.com/gazebosim/gz-sim/pull/2211)
+
## Gazebo Sim 8.x
+### Gazebo Sim 8.6.0 (2024-07-25)
+
+1. Fix error resolving gazebo classic material when loading world
+ * [Pull request #2492](https://github.com/gazebosim/gz-sim/pull/2492)
+
+1. Remove systems if their parent entity is removed
+ * [Pull request #2232](https://github.com/gazebosim/gz-sim/pull/2232)
+
+1. Fix warnings generated by NetworkConfigTest
+ * [Pull request #2469](https://github.com/gazebosim/gz-sim/pull/2469)
+
+1. Fix lidar visualization when `gz_frame_id` is specified
+ * [Pull request #2481](https://github.com/gazebosim/gz-sim/pull/2481)
+
+1. Backport convex decomposition visualization
+ * [Pull request #2454](https://github.com/gazebosim/gz-sim/pull/2454)
+
+1. Add UserCommands plugin to GPU lidar sensor example
+ * [Pull request #2479](https://github.com/gazebosim/gz-sim/pull/2479)
+
+1. Check if any entity actually has a ContactSensorData component before calling GetContactsFromLastStep
+ * [Pull request #2474](https://github.com/gazebosim/gz-sim/pull/2474)
+
+1. Enable tests on macOS
+ * [Pull request #2468](https://github.com/gazebosim/gz-sim/pull/2468)
+
+1. Update description of reset_sensors test
+ * [Pull request #2467](https://github.com/gazebosim/gz-sim/pull/2467)
+
+1. Magnetometer: correct field calculation
+ * [Pull request #2460](https://github.com/gazebosim/gz-sim/pull/2460)
+
+1. Address a couple of todos in Conversion.cc
+ * [Pull request #2461](https://github.com/gazebosim/gz-sim/pull/2461)
+
+1. Correct name of sensor in warning message
+ * [Pull request #2457](https://github.com/gazebosim/gz-sim/pull/2457)
+
+1. Set max contacts for collision pairs
+ * [Pull request #2270](https://github.com/gazebosim/gz-sim/pull/2270)
+
+1. Add GravityEnabled boolean component
+ * [Pull request #2451](https://github.com/gazebosim/gz-sim/pull/2451)
+
+1. Add support for no gravity link
+ * [Pull request #2398](https://github.com/gazebosim/gz-sim/pull/2398)
+
+1. Handle sdf::Geometry::EMPTY in conversions
+ * [Pull request #2430](https://github.com/gazebosim/gz-sim/pull/2430)
+
+1. Use topicFromScopedName in a few systems
+ * [Pull request #2427](https://github.com/gazebosim/gz-sim/pull/2427)
+
+1. Fix typo in a comment
+ * [Pull request #2429](https://github.com/gazebosim/gz-sim/pull/2429)
+
+### Gazebo Sim 8.5.0 (2024-06-26)
+
+1. Backport: Adding cone primitives
+ * [Pull request #2404](https://github.com/gazebosim/gz-sim/pull/2404)
+
+1. Permit to run gz sim -g on Windows
+ * [Pull request #2382](https://github.com/gazebosim/gz-sim/pull/2382)
+
+1. Parse voxel resolution SDF param when decomposing meshes
+ * [Pull request #2445](https://github.com/gazebosim/gz-sim/pull/2445)
+
+1. Fix model command api test
+ * [Pull request #2444](https://github.com/gazebosim/gz-sim/pull/2444)
+
+1. Add tutorial for using the Pose component
+ * [Pull request #2219](https://github.com/gazebosim/gz-sim/pull/2219)
+
+1. Do not update sensors if it a triggered sensor
+ * [Pull request #2443](https://github.com/gazebosim/gz-sim/pull/2443)
+
+### Gazebo Sim 8.4.0 (2024-06-12)
+
+1. Add pause run tutorial
+ * [Pull request #2383](https://github.com/gazebosim/gz-sim/pull/2383)
+
+1. Fix warning message to show precise jump back in time duration
+ * [Pull request #2435](https://github.com/gazebosim/gz-sim/pull/2435)
+
+1. Optimize rendering sensor pose updates
+ * [Pull request #2425](https://github.com/gazebosim/gz-sim/pull/2425)
+
+1. Remove a few extra zeros from some sdf files
+ * [Pull request #2426](https://github.com/gazebosim/gz-sim/pull/2426)
+
+1. Use VERSION_GREATER_EQUAL in cmake logic
+ * [Pull request #2418](https://github.com/gazebosim/gz-sim/pull/2418)
+
+1. Support mesh optimization when using AttachMeshShapeFeature
+ * [Pull request #2417](https://github.com/gazebosim/gz-sim/pull/2417)
+
+1. Rephrase cmake comment about CMP0077
+ * [Pull request #2419](https://github.com/gazebosim/gz-sim/pull/2419)
+
+1. Fix CMake warnings in Noble
+ * [Pull request #2397](https://github.com/gazebosim/gz-sim/pull/2397)
+
+1. Update sensors with pending trigger immediately in Sensors system
+ * [Pull request #2408](https://github.com/gazebosim/gz-sim/pull/2408)
+
+1. Add missing algorithm include
+ * [Pull request #2414](https://github.com/gazebosim/gz-sim/pull/2414)
+
+1. Add Track and Follow options in gui EntityContextMenu
+ * [Pull request #2402](https://github.com/gazebosim/gz-sim/pull/2402)
+
+1. ForceTorque system: improve readability
+ * [Pull request #2403](https://github.com/gazebosim/gz-sim/pull/2403)
+
+1. LTA Dynamics System
+ * [Pull request #2241](https://github.com/gazebosim/gz-sim/pull/2241)
+
+1. Remove Empty Test File
+ * [Pull request #2396](https://github.com/gazebosim/gz-sim/pull/2396)
+
+1. Fix GCC/CMake warnings for Noble
+ * [Pull request #2375](https://github.com/gazebosim/gz-sim/pull/2375)
+
+1. Fix warn unused variable in test
+ * [Pull request #2388](https://github.com/gazebosim/gz-sim/pull/2388)
+
+1. Fix name of gz-fuel_tools in package.xml
+ * [Pull request #2386](https://github.com/gazebosim/gz-sim/pull/2386)
+
+1. Add package.xml
+ * [Pull request #2337](https://github.com/gazebosim/gz-sim/pull/2337)
+
+1. Fix namespace and class links in documentation references that use namespace `gz`
+ * [Pull request #2385](https://github.com/gazebosim/gz-sim/pull/2385)
+
+1. Fix ModelPhotoShootTest test failures
+ * [Pull request #2294](https://github.com/gazebosim/gz-sim/pull/2294)
+
+1. Enable StoreResolvedURIs when loading SDF
+ * [Pull request #2349](https://github.com/gazebosim/gz-sim/pull/2349)
+
+1. Drop python3-disttutils from apt packages files
+ * [Pull request #2374](https://github.com/gazebosim/gz-sim/pull/2374)
+
+1. Added example world for `DopplerVelocityLogSystem`
+ * [Pull request #2373](https://github.com/gazebosim/gz-sim/pull/2373)
+
+1. Fix Gazebo/White and refactored MaterialParser
+ * [Pull request #2302](https://github.com/gazebosim/gz-sim/pull/2302)
+
+1. Support for Gazebo materials
+ * [Pull request #2269](https://github.com/gazebosim/gz-sim/pull/2269)
+
### Gazebo Sim 8.3.0 (2024-04-11)
1. Use relative install paths for plugin shared libraries and gz-tools data
@@ -310,6 +671,65 @@
## Gazebo Sim 7.x
+### Gazebo Sim 7.8.0 (2024-07-22)
+
+1. Added support for spacecraft thrusters
+ * [Pull request #2431](https://github.com/gazebosim/gz-sim/pull/2431)
+
+1. Disable rendering tests that are failing on github actions
+ * [Pull request #2480](https://github.com/gazebosim/gz-sim/pull/2480)
+
+1. Consolidate entity creation.
+ * [Pull request #2452](https://github.com/gazebosim/gz-sim/pull/2452)
+
+1. Set max contacts for collision pairs
+ * [Pull request #2270](https://github.com/gazebosim/gz-sim/pull/2270)
+
+1. Add GravityEnabled boolean component
+ * [Pull request #2451](https://github.com/gazebosim/gz-sim/pull/2451)
+
+1. Add support for no gravity link
+ * [Pull request #2398](https://github.com/gazebosim/gz-sim/pull/2398)
+
+1. Handle sdf::Geometry::EMPTY in conversions
+ * [Pull request #2430](https://github.com/gazebosim/gz-sim/pull/2430)
+
+1. Use topicFromScopedName in a few systems
+ * [Pull request #2427](https://github.com/gazebosim/gz-sim/pull/2427)
+
+1. Fix typo in a comment
+ * [Pull request #2429](https://github.com/gazebosim/gz-sim/pull/2429)
+
+1. Remove a few extra zeros from some sdf files
+ * [Pull request #2426](https://github.com/gazebosim/gz-sim/pull/2426)
+
+1. Use VERSION_GREATER_EQUAL in cmake logic
+ * [Pull request #2418](https://github.com/gazebosim/gz-sim/pull/2418)
+
+1. Rephrase cmake comment about CMP0077
+ * [Pull request #2419](https://github.com/gazebosim/gz-sim/pull/2419)
+
+1. ForceTorque system: improve readability
+ * [Pull request #2403](https://github.com/gazebosim/gz-sim/pull/2403)
+
+1. LTA Dynamics System
+ * [Pull request #2241](https://github.com/gazebosim/gz-sim/pull/2241)
+
+1. Fix namespace and class links in documentation references that use namespace `gz`
+ * [Pull request #2385](https://github.com/gazebosim/gz-sim/pull/2385)
+
+1. Fix ModelPhotoShootTest test failures
+ * [Pull request #2294](https://github.com/gazebosim/gz-sim/pull/2294)
+
+1. update sdf version
+ * [Pull request #2313](https://github.com/gazebosim/gz-sim/pull/2313)
+
+1. Fix Gazebo/White and refactored MaterialParser
+ * [Pull request #2302](https://github.com/gazebosim/gz-sim/pull/2302)
+
+1. Support for Gazebo materials
+ * [Pull request #2269](https://github.com/gazebosim/gz-sim/pull/2269)
+
### Gazebo Sim 7.7.0 (2024-01-17)
1. Allow using plugin file names and environment variables compatible with Garden and later
@@ -3713,6 +4133,36 @@
## Gazebo Sim 3.x
+### Gazebo Sim 3.15.1 (2024-01-05)
+
+1. Update github action workflows
+ * [Pull request #2237](https://github.com/gazebosim/gz-sim/pull/2237)
+ * [Pull request #1988](https://github.com/gazebosim/gz-sim/pull/1988)
+
+1. Fix macOS test failures by registering components in the core library
+ * [Pull request #2220](https://github.com/gazebosim/gz-sim/pull/2220)
+
+1. Bump Fuel model version in test
+ * [Pull request #2190](https://github.com/gazebosim/gz-sim/pull/2190)
+
+1. Fix a minor issue in the documentation of the server API
+ * [Pull request #2067](https://github.com/gazebosim/gz-sim/pull/2067)
+
+1. Use sdf::Element::FindElement instead of GetElement in ApplyLinkWrench
+ * [Pull request #2052](https://github.com/gazebosim/gz-sim/pull/2052)
+
+1. Adds a warning if the `Server` method of a `TestFixture` is called before `Finalize`
+ * [Pull request #2047](https://github.com/gazebosim/gz-sim/pull/2047)
+
+1. Protobuf: Do not require version 3 do support Protobuf 4.23.2 (23.2)
+ * [Pull request #2006](https://github.com/gazebosim/gz-sim/pull/2006)
+
+1. Print an error message when trying to load SDF files that don't contain a ``
+ * [Pull request #1998](https://github.com/gazebosim/gz-sim/pull/1998)
+
+1. Enable GzWeb visualization of markers by republishing service requests on a topic
+ * [Pull request #1994](https://github.com/gazebosim/gz-sim/pull/1994)
+
### Gazebo Sim 3.15.0 (2023-05-08)
1. Speed up Resource Spawner load time by fetching model list asynchronously
diff --git a/Migration.md b/Migration.md
index a1df392c5c..4f6632b474 100644
--- a/Migration.md
+++ b/Migration.md
@@ -5,6 +5,25 @@ Deprecated code produces compile-time warnings. These warning serve as
notification to users that their code should be upgraded. The next major
release will remove the deprecated code.
+## Gazebo Sim 8.x to 9.0
+
+ * **Modified**:
+ + In the Physics system, all `*VelocityCmd` components are now deleted after
+ each time step, whereas previously the component values were set to `0`
+ after each time step. Persistent velocity commands should be reapplied at
+ each time step.
+ + Default priority values are specified for the `Physics` and `UserCommands`
+ systems to ensure that `Physics::Update` and `UserCommands::PreUpdate`
+ execute before systems with default execution priority. Several constants
+ for system priority are defined in `gz/sim/System.hh`.
+ + The ForceTorque system has been changed from updating sensor data during
+ the parallelized `PostUpdate` phase to use the sequential `Update` phase
+ and writing directly to the ECM if a sensor entity has a `WrenchMeasured`
+ component. The ForceTorque system priority is specified to use the
+ `gz::sim::systems::kPostPhysicsSensorPriority` constant to ensure that its
+ `Update` phase executes after `Physics::Update` and before systems with
+ default priority.
+
## Gazebo Sim 7.x to 8.0
* **Deprecated**
+ `gz::sim::components::Factory::Register(const std::string &_type, ComponentDescriptorBase *_compDesc)` and
diff --git a/README.md b/README.md
index 4a0440eaa9..695107209d 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,10 @@
Build | Status
-- | --
-Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-sim/tree/gz-sim8/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-sim/tree/gz-sim8)
-Ubuntu Jammy | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_sim-ci-gz-sim8-jammy-amd64)](https://build.osrfoundation.org/job/gz_sim-ci-gz-sim8-jammy-amd64)
-Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_sim-ci-gz-sim8-homebrew-amd64)](https://build.osrfoundation.org/job/gz_sim-ci-gz-sim8-homebrew-amd64)
-Windows | [![Build Status](https://build.osrfoundation.org/job/gz_sim-8-win/badge/icon)](https://build.osrfoundation.org/job/gz_sim-8-win/)
+Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-sim/tree/gz-sim9/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-sim/tree/gz-sim9)
+Ubuntu Noble | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_sim-ci-gz-sim9-noble-amd64)](https://build.osrfoundation.org/job/gz_sim-ci-gz-sim9-noble-amd64)
+Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_sim-ci-gz-sim9-homebrew-amd64)](https://build.osrfoundation.org/job/gz_sim-ci-gz-sim9-homebrew-amd64)
+Windows | [![Build Status](https://build.osrfoundation.org/job/gz_sim-9-win/badge/icon)](https://build.osrfoundation.org/job/gz_sim-9-win/)
Gazebo Sim is an open source robotics simulator. Through Gazebo Sim, users have access to high fidelity physics, rendering, and sensor models. Additionally, users and developers have multiple points of entry to simulation including a graphical user interface, plugins, and asynchronous message passing and services.
@@ -32,10 +32,10 @@ Gazebo Sim is derived from [Gazebo Classic](http://classic.gazebosim.org) and re
[Folder Structure](#folder-structure)
-[Code of Conduct](#code-of-conduct)
-
[Contributing](#contributing)
+[Code of Conduct](#code-of-conduct)
+
[Versioning](#versioning)
[License](#license)
@@ -78,7 +78,7 @@ introspection and control.
# Install
-See the [installation tutorial](https://gazebosim.org/api/sim/8/install.html).
+See the [installation tutorial](https://gazebosim.org/api/sim/9/install.html).
# Usage
@@ -99,39 +99,30 @@ gz sim -h
In the event that the installation is a mix of Debian and from source, command
line tools from `gz-tools` may not work correctly.
-A workaround for a single package is to define the environment variable
-`GZ_CONFIG_PATH` to point to the location of the Gazebo library installation,
-where the YAML file for the package is found, such as
+A workaround is to define the environment variable
+`GZ_CONFIG_PATH` to point to the different locations of the Gazebo libraries installations,
+where the YAML files for the packages are found, such as
```
-export GZ_CONFIG_PATH=/usr/local/share/gz
+export GZ_CONFIG_PATH=/usr/local/share/gz:$HOME/ws/install/share/gz
```
-However, that environment variable only takes a single path, which means if the
-installations from source are in different locations, only one can be specified.
+where `$HOME/ws` is an example colcon workspace used to build Gazebo.
-Another workaround for working with multiple Gazebo libraries on the command
-line is using symbolic links to each library's YAML file.
-```
-mkdir ~/.gz/tools/configs -p
-cd ~/.gz/tools/configs/
-ln -s /usr/local/share/gz/fuel8.yaml .
-ln -s /usr/local/share/gz/transport13.yaml .
-ln -s /usr/local/share/gz/transportlog13.yaml .
-...
-export GZ_CONFIG_PATH=$HOME/.gz/tools/configs
-```
-
-This issue is tracked [here](https://github.com/gazebosim/gz-tools/issues/8).
+On Windows, `gz sim` (i.e. running both server and GUI in one command) doesn't yet work.
+To run Gazebo Sim on Windows, you need to run the server in one terminal (`gz sim -s `)
+and the GUI in another terminal (`gz sim -g `). Remember this when reading through
+all Gazebo Sim tutorials. Also remember that Conda and `install\setup.bat` need to be sourced
+in both terminals (as well as any changes to `GZ_PARTITION` and other environment variables).
# Documentation
-See the [installation tutorial](https://gazebosim.org/api/sim/8/install.html).
+See the [installation tutorial](https://gazebosim.org/api/sim/9/install.html).
# Testing
-See the [installation tutorial](https://gazebosim.org/api/sim/8/install.html).
+See the [installation tutorial](https://gazebosim.org/api/sim/9/install.html).
-See the [Writing Tests section of the contributor guide](https://github.com/gazebosim/gz-sim/blob/main/CONTRIBUTING.md#writing-tests) for help creating or modifying tests.
+See the [Writing Tests section of the contributor guide](https://gazebosim.org/docs/all/contributing/#writing-tests) for help creating or modifying tests.
# Folder Structure
@@ -154,7 +145,7 @@ gz-sim
│ ├── performance Performance tests.
│ ├── plugins Plugins used in tests.
│ ├── regression Regression tests.
-│ └── tutorials Tutorials, written in markdown.
+├── tutorials Tutorials, written in markdown.
├── Changelog.md Changelog.
├── CMakeLists.txt CMake build script.
├── Migration.md Migration guide.
@@ -163,8 +154,8 @@ gz-sim
# Contributing
-Please see
-[CONTRIBUTING.md](https://github.com/gazebosim/gz-sim/blob/main/CONTRIBUTING.md).
+Please see the
+[contribution guide](https://gazebosim.org/docs/all/contributing/).
# Code of Conduct
diff --git a/docker/Dockerfile.nightly b/docker/Dockerfile.nightly
index 6fb0d6bf7b..4dee43a1d5 100644
--- a/docker/Dockerfile.nightly
+++ b/docker/Dockerfile.nightly
@@ -11,19 +11,19 @@ RUN scripts/enable_nightly.sh
RUN apt-get update \
&& apt-get install -y \
- libgz-cmake3-dev \
- libgz-common5-dev \
- libgz-fuel-tools9-dev \
- libgz-math7-eigen3-dev \
- libgz-plugin2-dev \
- libgz-physics7-dev \
- libgz-rendering8-dev \
+ libgz-cmake4-dev \
+ libgz-common6-dev \
+ libgz-fuel-tools10-dev \
+ libgz-math8-eigen3-dev \
+ libgz-plugin3-dev \
+ libgz-physics8-dev \
+ libgz-rendering9-dev \
libgz-tools2-dev \
- libgz-transport13-dev \
- libgz-gui8-dev \
- libgz-msgs10-dev \
- libgz-sensors8-dev \
- libsdformat14-dev
+ libgz-transport14-dev \
+ libgz-gui9-dev \
+ libgz-msgs11-dev \
+ libgz-sensors9-dev \
+ libsdformat15-dev
COPY . gz-sim
RUN cd gz-sim \
diff --git a/docker/scripts/build_gz.sh b/docker/scripts/build_gz.sh
index 914705f60f..d1ed98317e 100755
--- a/docker/scripts/build_gz.sh
+++ b/docker/scripts/build_gz.sh
@@ -2,7 +2,7 @@
# Command line parameters:
# 1 - github organization name. For example gazebosim or osrf.
# 2 - the name of the Gazebo repository. For example gz-math.
-# 3 - the name of the branch. For example gz-math7
+# 3 - the name of the branch. For example gz-math8
set -o errexit
set -o verbose
diff --git a/docker/scripts/upload_json_benchmark.sh b/docker/scripts/upload_json_benchmark.sh
index 1cbe1e8cef..10fb0a4349 100755
--- a/docker/scripts/upload_json_benchmark.sh
+++ b/docker/scripts/upload_json_benchmark.sh
@@ -2,7 +2,7 @@
# Command line parameters:
# 1 - github organization name. For example gazebosim or osrf.
# 2 - the name of the Gazebo repository. For example gz-math.
-# 3 - the name of the branch. For example gz-math7
+# 3 - the name of the branch. For example gz-math8
set -o errexit
set -o verbose
diff --git a/examples/plugin/command_actor/CMakeLists.txt b/examples/plugin/command_actor/CMakeLists.txt
index a01caa9607..be6f6918ff 100644
--- a/examples/plugin/command_actor/CMakeLists.txt
+++ b/examples/plugin/command_actor/CMakeLists.txt
@@ -1,15 +1,15 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
project(CommandActor)
-find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
+find_package(gz-sim9 REQUIRED)
add_library(CommandActor SHARED CommandActor.cc)
set_property(TARGET CommandActor PROPERTY CXX_STANDARD 17)
target_link_libraries(CommandActor
PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
- PRIVATE gz-sim8::gz-sim8)
+ PRIVATE gz-sim9::gz-sim9)
diff --git a/examples/plugin/custom_component/CMakeLists.txt b/examples/plugin/custom_component/CMakeLists.txt
index d7f6a23ae6..7e2c0b1478 100644
--- a/examples/plugin/custom_component/CMakeLists.txt
+++ b/examples/plugin/custom_component/CMakeLists.txt
@@ -1,17 +1,17 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
project(CustomComponentPlugin)
-find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
+find_package(gz-sim9 REQUIRED)
add_library(CustomComponentPlugin SHARED
CustomComponentPlugin.cc
)
set_property(TARGET CustomComponentPlugin PROPERTY CXX_STANDARD 17)
target_link_libraries(CustomComponentPlugin
PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
- PRIVATE gz-sim8::gz-sim8)
+ PRIVATE gz-sim9::gz-sim9)
diff --git a/examples/plugin/custom_sensor_system/CMakeLists.txt b/examples/plugin/custom_sensor_system/CMakeLists.txt
index 32bb92dac3..6aef7ce712 100644
--- a/examples/plugin/custom_sensor_system/CMakeLists.txt
+++ b/examples/plugin/custom_sensor_system/CMakeLists.txt
@@ -1,17 +1,17 @@
-cmake_minimum_required(VERSION 3.11.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
project(OdometerSystem)
-gz_find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+gz_find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-gz_find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+gz_find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
-find_package(gz-sensors8 REQUIRED)
-set(GZ_SENSORS_VER ${gz-sensors8_VERSION_MAJOR})
+find_package(gz-sensors9 REQUIRED)
+set(GZ_SENSORS_VER ${gz-sensors9_VERSION_MAJOR})
# Fetch the custom sensor example from gz-sensors
# Users won't commonly use this to fetch their sensors. The sensor may be part
@@ -20,17 +20,18 @@ include(FetchContent)
FetchContent_Declare(
sensors_clone
GIT_REPOSITORY https://github.com/gazebosim/gz-sensors
- GIT_TAG gz-sensors8
+ GIT_TAG gz-sensors${GZ_SENSORS_VER}
)
FetchContent_Populate(sensors_clone)
add_subdirectory(${sensors_clone_SOURCE_DIR}/examples/custom_sensor ${sensors_clone_BINARY_DIR})
add_library(${PROJECT_NAME} SHARED ${PROJECT_NAME}.cc)
target_link_libraries(${PROJECT_NAME}
- PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
- PRIVATE gz-sim${GZ_SIM_VER}::gz-sim${GZ_SIM_VER}
- PRIVATE gz-sensors${GZ_SENSORS_VER}::gz-sensors${GZ_SENSORS_VER}
- PRIVATE odometer
+ PRIVATE
+ gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
+ gz-sim${GZ_SIM_VER}::gz-sim${GZ_SIM_VER}
+ gz-sensors${GZ_SENSORS_VER}::gz-sensors${GZ_SENSORS_VER}
+ odometer
)
target_include_directories(${PROJECT_NAME}
PUBLIC ${sensors_clone_SOURCE_DIR}/examples/custom_sensor)
diff --git a/examples/plugin/custom_sensor_system/README.md b/examples/plugin/custom_sensor_system/README.md
index 47700bc7fe..7d47ddb04b 100644
--- a/examples/plugin/custom_sensor_system/README.md
+++ b/examples/plugin/custom_sensor_system/README.md
@@ -10,7 +10,7 @@ It uses the odometer created on this example:
From the root of the `gz-sim` repository, do the following to build the example:
~~~
-cd examples/plugins/custom_sensor_system
+cd examples/plugin/custom_sensor_system
mkdir build
cd build
cmake ..
@@ -27,7 +27,7 @@ the `odometer.sdf` file that's going to be loaded.
Before starting Gazebo, we must make sure it can find the plugin by doing:
~~~
-cd examples/plugins/custom_sensor_system
+cd examples/plugin/custom_sensor_system
export GZ_SIM_SYSTEM_PLUGIN_PATH=`pwd`/build
~~~
diff --git a/examples/plugin/gui_system_plugin/CMakeLists.txt b/examples/plugin/gui_system_plugin/CMakeLists.txt
index 3a682f11ff..d2da6a83d9 100644
--- a/examples/plugin/gui_system_plugin/CMakeLists.txt
+++ b/examples/plugin/gui_system_plugin/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
if(POLICY CMP0100)
cmake_policy(SET CMP0100 NEW)
@@ -8,7 +8,7 @@ project(GuiSystemPlugin)
set(CMAKE_AUTOMOC ON)
-find_package(gz-sim8 REQUIRED COMPONENTS gui)
+find_package(gz-sim9 REQUIRED COMPONENTS gui)
QT5_ADD_RESOURCES(resources_RCC ${PROJECT_NAME}.qrc)
@@ -17,5 +17,5 @@ add_library(${PROJECT_NAME} SHARED
${resources_RCC}
)
target_link_libraries(${PROJECT_NAME}
- PRIVATE gz-sim8::gui
+ PRIVATE gz-sim9::gui
)
diff --git a/examples/plugin/gui_system_plugin/README.md b/examples/plugin/gui_system_plugin/README.md
index ac8e21d9da..e85a0bb769 100644
--- a/examples/plugin/gui_system_plugin/README.md
+++ b/examples/plugin/gui_system_plugin/README.md
@@ -2,10 +2,10 @@
This example shows how to create a GUI system plugin.
-Gazebo supports any kind of Gazebo GUI plugin
-(`gz::gui::Plugin`). Gazebo GUI plugins are a special type of Gazebo
-GUI plugin which also have access to entity and component updates coming from
-the server.
+Gazebo supports any kind of GUI plugin
+(`gz-gui` library: `gz::gui::Plugin`). However, GuiSystem plugins
+(`gz-sim` library: `gz::sim::GuiSystem`) are a special type of GUI plugin,
+which also have access to entity and component updates coming from the server.
See `GuiSystemPluginPlugin.hh` for more information.
diff --git a/examples/plugin/hello_world/CMakeLists.txt b/examples/plugin/hello_world/CMakeLists.txt
index 135d6288ce..d1a6adc2fd 100644
--- a/examples/plugin/hello_world/CMakeLists.txt
+++ b/examples/plugin/hello_world/CMakeLists.txt
@@ -1,14 +1,14 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
project(Hello_world)
-gz_find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+gz_find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-gz_find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+gz_find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_library(HelloWorld SHARED HelloWorld.cc)
set_property(TARGET HelloWorld PROPERTY CXX_STANDARD 17)
diff --git a/examples/plugin/priority_printer_plugin/CMakeLists.txt b/examples/plugin/priority_printer_plugin/CMakeLists.txt
new file mode 100644
index 0000000000..e5497abb73
--- /dev/null
+++ b/examples/plugin/priority_printer_plugin/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
+
+find_package(gz-cmake4 REQUIRED)
+
+project(Priority_printer)
+
+gz_find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
+
+gz_find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
+
+add_library(PriorityPrinter SHARED PriorityPrinter.cc)
+set_property(TARGET PriorityPrinter PROPERTY CXX_STANDARD 17)
+target_link_libraries(PriorityPrinter
+ PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
+ PRIVATE gz-sim${GZ_SIM_VER}::gz-sim${GZ_SIM_VER})
diff --git a/examples/plugin/priority_printer_plugin/PriorityPrinter.cc b/examples/plugin/priority_printer_plugin/PriorityPrinter.cc
new file mode 100644
index 0000000000..164596d968
--- /dev/null
+++ b/examples/plugin/priority_printer_plugin/PriorityPrinter.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+// We'll use a string and the gzmsg command below for a brief example.
+// Remove these includes if your plugin doesn't need them.
+#include
+#include
+#include
+
+// This header is required to register plugins. It's good practice to place it
+// in the cc file, like it's done here.
+#include
+
+// Don't forget to include the plugin's header.
+#include "PriorityPrinter.hh"
+
+// This is required to register the plugin. Make sure the interfaces match
+// what's in the header.
+GZ_ADD_PLUGIN(
+ priority_printer::PriorityPrinter,
+ gz::sim::System,
+ priority_printer::PriorityPrinter::ISystemConfigure,
+ priority_printer::PriorityPrinter::ISystemPreUpdate,
+ priority_printer::PriorityPrinter::ISystemUpdate)
+
+using namespace priority_printer;
+
+void PriorityPrinter::Configure(
+ const gz::sim::Entity &_entity,
+ const std::shared_ptr &_sdf,
+ gz::sim::EntityComponentManager &_ecm,
+ gz::sim::EventManager &_eventMgr)
+{
+ // Parse priority value as a string for printing
+ const std::string priorityElementName {gz::sim::System::kPriorityElementName};
+ if (_sdf && _sdf->HasElement(priorityElementName))
+ {
+ this->systemPriority = _sdf->Get(priorityElementName);
+ }
+
+ const std::string labelElementName {"label"};
+ if (_sdf && _sdf->HasElement(labelElementName))
+ {
+ this->systemLabel = _sdf->Get(labelElementName);
+ }
+}
+
+void PriorityPrinter::PreUpdate(const gz::sim::UpdateInfo &_info,
+ gz::sim::EntityComponentManager &/*_ecm*/)
+{
+ gzmsg << "PreUpdate: "
+ << "Iteration " << _info.iterations
+ << ", system priority " << this->systemPriority
+ << ", system label " << this->systemLabel
+ << '\n';
+}
+
+void PriorityPrinter::Update(const gz::sim::UpdateInfo &_info,
+ gz::sim::EntityComponentManager &/*_ecm*/)
+{
+ gzmsg << "Update: "
+ << "Iteration " << _info.iterations
+ << ", system priority " << this->systemPriority
+ << ", system label " << this->systemLabel
+ << '\n';
+}
diff --git a/examples/plugin/priority_printer_plugin/PriorityPrinter.hh b/examples/plugin/priority_printer_plugin/PriorityPrinter.hh
new file mode 100644
index 0000000000..741c2f596c
--- /dev/null
+++ b/examples/plugin/priority_printer_plugin/PriorityPrinter.hh
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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 EXAMPLE_PLUGIN_PRIORITYPRINTER_HH_
+#define EXAMPLE_PLUGIN_PRIORITYPRINTER_HH_
+
+#include
+#include
+#include
+
+namespace priority_printer
+{
+ // This plugin prints the number of elapsed simulation iterations,
+ // this system's priority value from the XML configuration,
+ // and a custom label from the XML configuration during the Update callback.
+ class PriorityPrinter:
+ public gz::sim::System,
+ public gz::sim::ISystemConfigure,
+ public gz::sim::ISystemPreUpdate,
+ public gz::sim::ISystemUpdate
+ {
+ public: void Configure(const gz::sim::Entity &_entity,
+ const std::shared_ptr &_sdf,
+ gz::sim::EntityComponentManager &_ecm,
+ gz::sim::EventManager &_eventMgr) override;
+
+ public: void PreUpdate(const gz::sim::UpdateInfo &_info,
+ gz::sim::EntityComponentManager &_ecm) override;
+
+ public: void Update(const gz::sim::UpdateInfo &_info,
+ gz::sim::EntityComponentManager &_ecm) override;
+
+ public: std::string systemPriority{"unset"};
+ public: std::string systemLabel{"unset"};
+ };
+}
+#endif
diff --git a/examples/plugin/priority_printer_plugin/README.md b/examples/plugin/priority_printer_plugin/README.md
new file mode 100644
index 0000000000..670c269979
--- /dev/null
+++ b/examples/plugin/priority_printer_plugin/README.md
@@ -0,0 +1,128 @@
+# Priority Printer
+
+This example illustrates how to control the order of execution of System
+PreUpdate and Update callbacks. As documented in
+[gz/sim/System.hh](https://github.com/gazebosim/gz-sim/tree/main/include/gz/sim/System.hh),
+the PreUpdate and Update phases are executed sequentially in the same
+thread, and the order of execution of these phases can be
+controlled by specifying a signed integer priority value for the System
+in its XML configuration. The default priority value is zero, and
+smaller values are executed earlier. Systems with the same priority
+value are executed in the order in which they are loaded.
+
+## Build
+
+From the root of the `gz-sim` repository, do the following to build the example:
+
+~~~
+cd gz-sim/examples/plugins/priority_printer
+mkdir build
+cd build
+cmake ..
+make
+~~~
+
+This will generate the `PriorityPrinter` library under `build`.
+
+## Run
+
+Multiple instances of the `PriorityPrinter` plugin are added to the
+[priority\_printer\_plugin.sdf](priority_printer_plugin.sdf) world file
+with various priority values and unique labels corresponding to the order
+in which the plugins are specified ("first" for the first plugin and so on).
+Without priority values, the systems would be executed in the order they are
+specified in XML ("first", then "second", etc.).
+With the priority values specified, the systems with smallest integer priority
+values are executed first. For systems with the same priority value, the
+system that is specified earlier in the XML file will be executed first.
+
+Before starting Gazebo, we must make sure it can find the plugin by doing:
+
+~~~
+cd gz-sim/examples/plugins/priority_printer
+export GZ_SIM_SYSTEM_PLUGIN_PATH=`pwd`/build
+~~~
+
+Then load the example world and run for 5 iterations:
+
+ gz sim -v 3 priority_printer_plugin.sdf -s -r --iterations 5
+
+You should see green messages on the terminal like those given below.
+Note that the system with priority `-100` was executed first, despite being
+the fifth system in the XML ordering. There are two instances of systems with
+the same priority value: the fourth and sixth systems with priority 0 (with
+"unset" defaulting to 0) and the first and seventh systems with priority 100.
+In each case, the system declared earlier in XML executed first.
+
+```
+[Msg] PreUpdate: Iteration 1, system priority -100, system label fifth
+[Msg] PreUpdate: Iteration 1, system priority -10, system label third
+[Msg] PreUpdate: Iteration 1, system priority unset, system label fourth
+[Msg] PreUpdate: Iteration 1, system priority 0, system label sixth
+[Msg] PreUpdate: Iteration 1, system priority 10, system label second
+[Msg] PreUpdate: Iteration 1, system priority 100, system label first
+[Msg] PreUpdate: Iteration 1, system priority 100, system label seventh
+[Msg] Update: Iteration 1, system priority -100, system label fifth
+[Msg] Update: Iteration 1, system priority -10, system label third
+[Msg] Update: Iteration 1, system priority unset, system label fourth
+[Msg] Update: Iteration 1, system priority 0, system label sixth
+[Msg] Update: Iteration 1, system priority 10, system label second
+[Msg] Update: Iteration 1, system priority 100, system label first
+[Msg] Update: Iteration 1, system priority 100, system label seventh
+[Msg] PreUpdate: Iteration 2, system priority -100, system label fifth
+[Msg] PreUpdate: Iteration 2, system priority -10, system label third
+[Msg] PreUpdate: Iteration 2, system priority unset, system label fourth
+[Msg] PreUpdate: Iteration 2, system priority 0, system label sixth
+[Msg] PreUpdate: Iteration 2, system priority 10, system label second
+[Msg] PreUpdate: Iteration 2, system priority 100, system label first
+[Msg] PreUpdate: Iteration 2, system priority 100, system label seventh
+[Msg] Update: Iteration 2, system priority -100, system label fifth
+[Msg] Update: Iteration 2, system priority -10, system label third
+[Msg] Update: Iteration 2, system priority unset, system label fourth
+[Msg] Update: Iteration 2, system priority 0, system label sixth
+[Msg] Update: Iteration 2, system priority 10, system label second
+[Msg] Update: Iteration 2, system priority 100, system label first
+[Msg] Update: Iteration 2, system priority 100, system label seventh
+[Msg] PreUpdate: Iteration 3, system priority -100, system label fifth
+[Msg] PreUpdate: Iteration 3, system priority -10, system label third
+[Msg] PreUpdate: Iteration 3, system priority unset, system label fourth
+[Msg] PreUpdate: Iteration 3, system priority 0, system label sixth
+[Msg] PreUpdate: Iteration 3, system priority 10, system label second
+[Msg] PreUpdate: Iteration 3, system priority 100, system label first
+[Msg] PreUpdate: Iteration 3, system priority 100, system label seventh
+[Msg] Update: Iteration 3, system priority -100, system label fifth
+[Msg] Update: Iteration 3, system priority -10, system label third
+[Msg] Update: Iteration 3, system priority unset, system label fourth
+[Msg] Update: Iteration 3, system priority 0, system label sixth
+[Msg] Update: Iteration 3, system priority 10, system label second
+[Msg] Update: Iteration 3, system priority 100, system label first
+[Msg] Update: Iteration 3, system priority 100, system label seventh
+[Msg] PreUpdate: Iteration 4, system priority -100, system label fifth
+[Msg] PreUpdate: Iteration 4, system priority -10, system label third
+[Msg] PreUpdate: Iteration 4, system priority unset, system label fourth
+[Msg] PreUpdate: Iteration 4, system priority 0, system label sixth
+[Msg] PreUpdate: Iteration 4, system priority 10, system label second
+[Msg] PreUpdate: Iteration 4, system priority 100, system label first
+[Msg] PreUpdate: Iteration 4, system priority 100, system label seventh
+[Msg] Update: Iteration 4, system priority -100, system label fifth
+[Msg] Update: Iteration 4, system priority -10, system label third
+[Msg] Update: Iteration 4, system priority unset, system label fourth
+[Msg] Update: Iteration 4, system priority 0, system label sixth
+[Msg] Update: Iteration 4, system priority 10, system label second
+[Msg] Update: Iteration 4, system priority 100, system label first
+[Msg] Update: Iteration 4, system priority 100, system label seventh
+[Msg] PreUpdate: Iteration 5, system priority -100, system label fifth
+[Msg] PreUpdate: Iteration 5, system priority -10, system label third
+[Msg] PreUpdate: Iteration 5, system priority unset, system label fourth
+[Msg] PreUpdate: Iteration 5, system priority 0, system label sixth
+[Msg] PreUpdate: Iteration 5, system priority 10, system label second
+[Msg] PreUpdate: Iteration 5, system priority 100, system label first
+[Msg] PreUpdate: Iteration 5, system priority 100, system label seventh
+[Msg] Update: Iteration 5, system priority -100, system label fifth
+[Msg] Update: Iteration 5, system priority -10, system label third
+[Msg] Update: Iteration 5, system priority unset, system label fourth
+[Msg] Update: Iteration 5, system priority 0, system label sixth
+[Msg] Update: Iteration 5, system priority 10, system label second
+[Msg] Update: Iteration 5, system priority 100, system label first
+[Msg] Update: Iteration 5, system priority 100, system label seventh
+```
diff --git a/examples/plugin/priority_printer_plugin/priority_printer_plugin.sdf b/examples/plugin/priority_printer_plugin/priority_printer_plugin.sdf
new file mode 100644
index 0000000000..e60d75a497
--- /dev/null
+++ b/examples/plugin/priority_printer_plugin/priority_printer_plugin.sdf
@@ -0,0 +1,36 @@
+
+
+
+
+
+ 100
+
+
+
+ 10
+
+
+
+ -10
+
+
+
+
+
+
+ -100
+
+
+
+ 0
+
+
+
+ 100
+
+
+
+
diff --git a/examples/plugin/rendering_plugins/CMakeLists.txt b/examples/plugin/rendering_plugins/CMakeLists.txt
index 8668676cf0..983cd746a1 100644
--- a/examples/plugin/rendering_plugins/CMakeLists.txt
+++ b/examples/plugin/rendering_plugins/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
if(POLICY CMP0100)
cmake_policy(SET CMP0100 NEW)
@@ -7,14 +7,14 @@ endif()
project(RenderingPlugins)
# Common to both plugins
-find_package(gz-rendering8 REQUIRED)
+find_package(gz-rendering9 REQUIRED)
# GUI plugin
set(GUI_PLUGIN RenderingGuiPlugin)
set(CMAKE_AUTOMOC ON)
-find_package(gz-gui8 REQUIRED)
+find_package(gz-gui9 REQUIRED)
QT5_ADD_RESOURCES(resources_RCC ${GUI_PLUGIN}.qrc)
@@ -24,21 +24,21 @@ add_library(${GUI_PLUGIN} SHARED
)
target_link_libraries(${GUI_PLUGIN}
PRIVATE
- gz-gui8::gz-gui8
- gz-rendering8::gz-rendering8
+ gz-gui9::gz-gui9
+ gz-rendering9::gz-rendering9
)
# Server plugin
set(SERVER_PLUGIN RenderingServerPlugin)
-find_package(gz-plugin2 REQUIRED COMPONENTS register)
-find_package(gz-sim8 REQUIRED)
+find_package(gz-plugin3 REQUIRED COMPONENTS register)
+find_package(gz-sim9 REQUIRED)
add_library(${SERVER_PLUGIN} SHARED ${SERVER_PLUGIN}.cc)
set_property(TARGET ${SERVER_PLUGIN} PROPERTY CXX_STANDARD 17)
target_link_libraries(${SERVER_PLUGIN}
PRIVATE
- gz-plugin2::gz-plugin2
- gz-sim8::gz-sim8
- gz-rendering8::gz-rendering8
+ gz-plugin3::gz-plugin3
+ gz-sim9::gz-sim9
+ gz-rendering9::gz-rendering9
)
diff --git a/examples/plugin/reset_plugin/CMakeLists.txt b/examples/plugin/reset_plugin/CMakeLists.txt
index 824d84176a..3a9e97329a 100644
--- a/examples/plugin/reset_plugin/CMakeLists.txt
+++ b/examples/plugin/reset_plugin/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(ResetPlugins)
-find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_library(JointPositionRandomizer SHARED JointPositionRandomizer.cc)
target_link_libraries(JointPositionRandomizer
diff --git a/examples/plugin/system_plugin/CMakeLists.txt b/examples/plugin/system_plugin/CMakeLists.txt
index 0a0e5ba789..1a651f6bca 100644
--- a/examples/plugin/system_plugin/CMakeLists.txt
+++ b/examples/plugin/system_plugin/CMakeLists.txt
@@ -1,15 +1,15 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
-find_package(gz-cmake3 REQUIRED)
+find_package(gz-cmake4 REQUIRED)
project(SampleSystem)
-find_package(gz-plugin2 REQUIRED COMPONENTS register)
-set(GZ_PLUGIN_VER ${gz-plugin2_VERSION_MAJOR})
+find_package(gz-plugin3 REQUIRED COMPONENTS register)
+set(GZ_PLUGIN_VER ${gz-plugin3_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
+find_package(gz-sim9 REQUIRED)
add_library(SampleSystem SHARED SampleSystem.cc SampleSystem2.cc)
set_property(TARGET SampleSystem PROPERTY CXX_STANDARD 17)
target_link_libraries(SampleSystem
PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER}
- PRIVATE gz-sim8::gz-sim8)
+ PRIVATE gz-sim9::gz-sim9)
diff --git a/examples/scripts/python_api/systems/test_system.py b/examples/scripts/python_api/systems/test_system.py
index b5d03347b0..a10aef1fec 100644
--- a/examples/scripts/python_api/systems/test_system.py
+++ b/examples/scripts/python_api/systems/test_system.py
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from gz.math7 import Vector3d
-from gz.sim8 import Model, Link
+from gz.math8 import Vector3d
+from gz.sim9 import Model, Link
import random
diff --git a/examples/scripts/python_api/testFixture.py b/examples/scripts/python_api/testFixture.py
index 5be3afa6dc..820d281dd3 100755
--- a/examples/scripts/python_api/testFixture.py
+++ b/examples/scripts/python_api/testFixture.py
@@ -24,9 +24,9 @@
import os
-from gz.common5 import set_verbosity
-from gz.sim8 import TestFixture, World, world_entity
-from gz.math7 import Vector3d
+from gz.common6 import set_verbosity
+from gz.sim9 import TestFixture, World, world_entity
+from gz.math8 import Vector3d
set_verbosity(4)
diff --git a/examples/standalone/acoustic_comms_demo/CMakeLists.txt b/examples/standalone/acoustic_comms_demo/CMakeLists.txt
index 2129e946e1..73a7dddde9 100644
--- a/examples/standalone/acoustic_comms_demo/CMakeLists.txt
+++ b/examples/standalone/acoustic_comms_demo/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-acoustic-comms-demo)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_executable(acoustic_comms_demo acoustic_comms_demo.cc)
target_link_libraries(acoustic_comms_demo
diff --git a/examples/standalone/comms/CMakeLists.txt b/examples/standalone/comms/CMakeLists.txt
index 19d11f99f6..a1c6e7c55b 100644
--- a/examples/standalone/comms/CMakeLists.txt
+++ b/examples/standalone/comms/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-comms)
-find_package(gz-transport13 QUIET REQUIRED)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
add_executable(publisher publisher.cc)
target_link_libraries(publisher
diff --git a/examples/standalone/custom_server/CMakeLists.txt b/examples/standalone/custom_server/CMakeLists.txt
index cf1e917e89..2fbbc64fdb 100644
--- a/examples/standalone/custom_server/CMakeLists.txt
+++ b/examples/standalone/custom_server/CMakeLists.txt
@@ -1,10 +1,10 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-custom-server)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- find_package(gz-sim8 REQUIRED)
- set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+ find_package(gz-sim9 REQUIRED)
+ set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_executable(custom_server custom_server.cc)
target_link_libraries(custom_server
diff --git a/examples/standalone/each_performance/CMakeLists.txt b/examples/standalone/each_performance/CMakeLists.txt
index 6f756f12e5..98b94029eb 100644
--- a/examples/standalone/each_performance/CMakeLists.txt
+++ b/examples/standalone/each_performance/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-each-performance)
-find_package(gz-sim8 QUIET REQUIRED)
+find_package(gz-sim9 QUIET REQUIRED)
add_executable(each each.cc)
target_link_libraries(each
- gz-sim8::core)
+ gz-sim9::core)
diff --git a/examples/standalone/entity_creation/CMakeLists.txt b/examples/standalone/entity_creation/CMakeLists.txt
index d41479eafa..445f7eab69 100644
--- a/examples/standalone/entity_creation/CMakeLists.txt
+++ b/examples/standalone/entity_creation/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-entity-creation)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
add_executable(entity_creation entity_creation.cc)
target_link_libraries(entity_creation
diff --git a/examples/standalone/external_ecm/CMakeLists.txt b/examples/standalone/external_ecm/CMakeLists.txt
index d06850d284..24f8d78594 100644
--- a/examples/standalone/external_ecm/CMakeLists.txt
+++ b/examples/standalone/external_ecm/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-external-ecm)
-find_package(gz-sim8 REQUIRED)
+find_package(gz-sim9 REQUIRED)
add_executable(external_ecm external_ecm.cc)
target_link_libraries(external_ecm
- gz-sim8::core)
+ gz-sim9::core)
diff --git a/examples/standalone/gtest_setup/CMakeLists.txt b/examples/standalone/gtest_setup/CMakeLists.txt
index 376497eeaf..99a24e3fb7 100644
--- a/examples/standalone/gtest_setup/CMakeLists.txt
+++ b/examples/standalone/gtest_setup/CMakeLists.txt
@@ -1,22 +1,23 @@
-cmake_minimum_required(VERSION 3.11.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(GTestSetup)
# Find Gazebo
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
# Fetch and configure GTest
include(FetchContent)
FetchContent_Declare(
googletest
- URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
+ DOWNLOAD_EXTRACT_TIMESTAMP TRUE
+ # Version 1.14. Use commit hash to prevent tag relocation
+ URL https://github.com/google/googletest/archive/f8d7d77c06936315286eb55f8de22cd23c188571.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
-include(Dart)
# Generate tests
foreach(TEST_TARGET
diff --git a/examples/standalone/joy_to_twist/CMakeLists.txt b/examples/standalone/joy_to_twist/CMakeLists.txt
index 2344583176..c2ea401431 100644
--- a/examples/standalone/joy_to_twist/CMakeLists.txt
+++ b/examples/standalone/joy_to_twist/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-joy-to-twist)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
-find_package(sdformat14 REQUIRED)
-set(SDF_VER ${sdformat14_VERSION_MAJOR})
+find_package(sdformat15 REQUIRED)
+set(SDF_VER ${sdformat15_VERSION_MAJOR})
add_executable(joy_to_twist joy_to_twist.cc)
target_link_libraries(joy_to_twist
diff --git a/examples/standalone/joystick/CMakeLists.txt b/examples/standalone/joystick/CMakeLists.txt
index 2a4f593633..2a066a8e89 100644
--- a/examples/standalone/joystick/CMakeLists.txt
+++ b/examples/standalone/joystick/CMakeLists.txt
@@ -1,14 +1,14 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
# joystick currently works only on linux
project(gz-sim-joystick)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
- set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+ find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+ set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
- find_package(sdformat14 REQUIRED)
- set(SDF_VER ${sdformat14_VERSION_MAJOR})
+ find_package(sdformat15 REQUIRED)
+ set(SDF_VER ${sdformat15_VERSION_MAJOR})
add_executable(joystick joystick.cc)
target_link_libraries(joystick
diff --git a/examples/standalone/keyboard/CMakeLists.txt b/examples/standalone/keyboard/CMakeLists.txt
index 04227710c7..9d96cb7ef4 100644
--- a/examples/standalone/keyboard/CMakeLists.txt
+++ b/examples/standalone/keyboard/CMakeLists.txt
@@ -1,19 +1,19 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-keyboard)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
- set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+ find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+ set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
- find_package(sdformat14 REQUIRED)
- set(SDF_VER ${sdformat14_VERSION_MAJOR})
+ find_package(sdformat15 REQUIRED)
+ set(SDF_VER ${sdformat15_VERSION_MAJOR})
- find_package(gz-msgs10 REQUIRED)
- set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR})
+ find_package(gz-msgs11 REQUIRED)
+ set(GZ_MSGS_VER ${gz-msgs11_VERSION_MAJOR})
- find_package(gz-common5 REQUIRED)
- set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR})
+ find_package(gz-common6 REQUIRED)
+ set(GZ_COMMON_VER ${gz-common6_VERSION_MAJOR})
add_executable(keyboard keyboard.cc)
target_link_libraries(keyboard
diff --git a/examples/standalone/light_control/CMakeLists.txt b/examples/standalone/light_control/CMakeLists.txt
index 0f3de2e3e7..9f3ee16e4c 100644
--- a/examples/standalone/light_control/CMakeLists.txt
+++ b/examples/standalone/light_control/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-light-control)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_executable(light_control light_control.cc)
target_link_libraries(light_control
diff --git a/examples/standalone/lrauv_control/CMakeLists.txt b/examples/standalone/lrauv_control/CMakeLists.txt
index f0cbc94a03..6c075de8dd 100644
--- a/examples/standalone/lrauv_control/CMakeLists.txt
+++ b/examples/standalone/lrauv_control/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-lrauv-control)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_executable(lrauv_control lrauv_control.cc)
target_link_libraries(lrauv_control
diff --git a/examples/standalone/lrauv_control/lrauv_control.py b/examples/standalone/lrauv_control/lrauv_control.py
index 8f7ad2cf21..56eb0088aa 100644
--- a/examples/standalone/lrauv_control/lrauv_control.py
+++ b/examples/standalone/lrauv_control/lrauv_control.py
@@ -26,10 +26,10 @@
# $ python3 lrauv_control.py 0.5 0.78 0.174
#
-from gz.msgs10.double_pb2 import Double
-from gz.msgs10.odometry_pb2 import Odometry
-from gz.math7 import Quaterniond, Vector3d
-from gz.transport13 import Node
+from gz.msgs11.double_pb2 import Double
+from gz.msgs11.odometry_pb2 import Odometry
+from gz.math8 import Quaterniond, Vector3d
+from gz.transport14 import Node
from threading import Lock
diff --git a/examples/standalone/marker/CMakeLists.txt b/examples/standalone/marker/CMakeLists.txt
index bbca4e481d..f3bd3b655b 100644
--- a/examples/standalone/marker/CMakeLists.txt
+++ b/examples/standalone/marker/CMakeLists.txt
@@ -1,16 +1,16 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-marker)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- find_package(gz-transport13 QUIET REQUIRED)
- set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+ find_package(gz-transport14 QUIET REQUIRED)
+ set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
- find_package(gz-common5 REQUIRED)
- set(GZ_COMMON_VER ${gz-common5_VERSION_MAJOR})
+ find_package(gz-common6 REQUIRED)
+ set(GZ_COMMON_VER ${gz-common6_VERSION_MAJOR})
- find_package(gz-msgs10 REQUIRED)
- set(GZ_MSGS_VER ${gz-msgs10_VERSION_MAJOR})
+ find_package(gz-msgs11 REQUIRED)
+ set(GZ_MSGS_VER ${gz-msgs11_VERSION_MAJOR})
add_executable(marker marker.cc)
target_link_libraries(marker
diff --git a/examples/standalone/multi_lrauv_race/CMakeLists.txt b/examples/standalone/multi_lrauv_race/CMakeLists.txt
index 6bffdef142..69049f2ad0 100644
--- a/examples/standalone/multi_lrauv_race/CMakeLists.txt
+++ b/examples/standalone/multi_lrauv_race/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-multi-lrauv-race)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
-find_package(gz-sim8 REQUIRED)
-set(GZ_SIM_VER ${gz-sim8_VERSION_MAJOR})
+find_package(gz-sim9 REQUIRED)
+set(GZ_SIM_VER ${gz-sim9_VERSION_MAJOR})
add_executable(multi_lrauv_race multi_lrauv_race.cc)
target_link_libraries(multi_lrauv_race
diff --git a/examples/standalone/multi_lrauv_race/multi_lrauv_race.py b/examples/standalone/multi_lrauv_race/multi_lrauv_race.py
index fa565feed1..aff979c158 100644
--- a/examples/standalone/multi_lrauv_race/multi_lrauv_race.py
+++ b/examples/standalone/multi_lrauv_race/multi_lrauv_race.py
@@ -26,8 +26,8 @@
# before for other python examples. You can use then following:
# $ export PYTHONPATH=$PYTHONPATH:/install/lib/python
-from gz.msgs10.double_pb2 import Double
-from gz.transport13 import Node
+from gz.msgs11.double_pb2 import Double
+from gz.transport14 import Node
import random
import time
diff --git a/examples/standalone/scene_requester/CMakeLists.txt b/examples/standalone/scene_requester/CMakeLists.txt
index e47e8eac87..049877d3db 100644
--- a/examples/standalone/scene_requester/CMakeLists.txt
+++ b/examples/standalone/scene_requester/CMakeLists.txt
@@ -1,9 +1,9 @@
-cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.22.1 FATAL_ERROR)
project(gz-sim-scene-requester)
-find_package(gz-transport13 QUIET REQUIRED OPTIONAL_COMPONENTS log)
-set(GZ_TRANSPORT_VER ${gz-transport13_VERSION_MAJOR})
+find_package(gz-transport14 QUIET REQUIRED OPTIONAL_COMPONENTS log)
+set(GZ_TRANSPORT_VER ${gz-transport14_VERSION_MAJOR})
add_executable(scene_requester scene_requester.cc)
target_link_libraries(scene_requester
diff --git a/examples/worlds/actors_population.sdf b/examples/worlds/actors_population.sdf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/examples/worlds/camera_sensor.sdf b/examples/worlds/camera_sensor.sdf
index 3d967d701e..0cee711b47 100644
--- a/examples/worlds/camera_sensor.sdf
+++ b/examples/worlds/camera_sensor.sdf
@@ -8,23 +8,11 @@
0.001
1.0
-
-
ogre2
-
-
-
-
1.0 1.0 1.0
@@ -32,103 +20,22 @@
true
+
+ true
+
-
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
-
-
-
-
-
- floating
- 5
- 5
- false
-
-
-
-
- false
- 5
- 5
- floating
- false
-
-
-
-
- false
- 5
- 5
- floating
- false
-
-
-
-
- false
- 5
- 5
- floating
- false
-
-
-
-
-
- World control
- false
- false
- 72
- 1
-
- floating
-
-
-
-
-
-
- true
- true
- true
- true
-
-
-
-
-
-
- World stats
- false
- false
- 110
- 290
- 1
-
- floating
-
-
-
-
-
-
- true
- true
- true
- true
+ -3 0 3 0 0.5 0
@@ -137,20 +44,6 @@
camera
-
-
-
-
- docked
-
-
-
-
-
-
- docked
-
-
diff --git a/examples/worlds/contact_sensor.sdf b/examples/worlds/contact_sensor.sdf
index c37f7f259b..0714c34bf7 100644
--- a/examples/worlds/contact_sensor.sdf
+++ b/examples/worlds/contact_sensor.sdf
@@ -9,22 +9,7 @@ Run the following to print out contacts,
-->
-
-
-
-
-
-
-
-
+
false
diff --git a/examples/worlds/dem_monterey_bay.sdf b/examples/worlds/dem_monterey_bay.sdf
index 7f2d170121..39539ca1f2 100644
--- a/examples/worlds/dem_monterey_bay.sdf
+++ b/examples/worlds/dem_monterey_bay.sdf
@@ -22,7 +22,7 @@
docked
- ogre
+ ogre2
scene
0 0 0
0.8 0.8 0.8
diff --git a/examples/worlds/dem_moon.sdf b/examples/worlds/dem_moon.sdf
index a1de71ad5e..047607d3f1 100644
--- a/examples/worlds/dem_moon.sdf
+++ b/examples/worlds/dem_moon.sdf
@@ -29,7 +29,7 @@
docked
- ogre
+ ogre2
scene
0 0 0
0.8 0.8 0.8
diff --git a/examples/worlds/dem_volcano.sdf b/examples/worlds/dem_volcano.sdf
index f48b2779a4..f2f766b869 100644
--- a/examples/worlds/dem_volcano.sdf
+++ b/examples/worlds/dem_volcano.sdf
@@ -21,7 +21,7 @@
docked
- ogre
+ ogre2
scene
0 0 0
0.8 0.8 0.8
diff --git a/examples/worlds/dvl_world.sdf b/examples/worlds/dvl_world.sdf
new file mode 100644
index 0000000000..0b599a3cb4
--- /dev/null
+++ b/examples/worlds/dvl_world.sdf
@@ -0,0 +1,291 @@
+
+
+
+
+
+
+ 0.0 1.0 1.0
+
+ 0.0 0.7 0.8
+
+ false
+
+
+
+ 0.001
+ 1.0
+
+
+
+
+
+
+
+
+ 1000
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+ true
+
+
+
+
+ 0 0 1
+
+ 300000 300000
+
+
+ 1.0
+
+
+
+
+
+ true
+ 0 0 -100 0 0 0
+
+
+
+
+ 0 0 1
+
+ 300000 300000
+
+
+
+
+
+ 0.5 0.5 0.5
+ 0.5 0.5 0.5
+
+
+
+ 0 0 1
+
+ 300000 300000
+
+
+
+
+
+
+
+ 0 0 -80 0 0 1.57
+ https://fuel.gazebosim.org/1.0/accurrent/models/MBARI Tethys LRAUV
+
+
+
+ -0.60 0 -0.16 0 0 180
+ 1
+ 1
+ /dvl/velocity
+
+ phased_array
+
+
+ 2
+ 45
+ 30
+
+
+ 2
+ 135
+ 30
+
+
+ 2
+ -45
+ 30
+
+
+ 2
+ -135
+ 30
+
+
+
+
+ best
+
+
+ 0.002
+
+ false
+
+
+
+ 0.01
+ 100.
+ 0.1
+
+ 0 0 0 0 0 -1.570796
+
+
+
+
+
+
+
+
+
+
+ horizontal_fins_joint
+ 0.1
+
+
+
+ vertical_fins_joint
+ 0.1
+
+
+
+ tethys
+ 0
+ propeller_joint
+ 0.004422
+ 1000
+ 0.2
+
+
+
+
+
+
+ 1000
+ 4.13
+ -1.1
+ 0.2
+ 0.03
+ 0.17
+ 0
+ 0.0244
+ 0 1 0
+ 1 0 0
+ vertical_fins
+ 0 0 0
+
+
+
+
+ 1000
+ 4.13
+ -1.1
+ 0.2
+ 0.03
+ 0.17
+ 0
+ 0.0244
+ 0 0 1
+ 1 0 0
+ horizontal_fins
+ 0 0 0
+
+
+
+
+ base_link
+ -4.876161
+ -126.324739
+ -126.324739
+ 0
+ -33.46
+ -33.46
+ -6.2282
+ 0
+ -601.27
+ 0
+ -601.27
+ 0
+ -0.1916
+ 0
+ -632.698957
+ 0
+ -632.698957
+ 0
+
+
+
+
diff --git a/examples/worlds/empty_gui.sdf b/examples/worlds/empty_gui.sdf
index 0975a4f142..54df8c2e31 100644
--- a/examples/worlds/empty_gui.sdf
+++ b/examples/worlds/empty_gui.sdf
@@ -37,6 +37,10 @@ This example helps illustrate the interaction of the MinimalScene with other GUI
+
+ false
+
+
diff --git a/examples/worlds/gpu_lidar_sensor.sdf b/examples/worlds/gpu_lidar_sensor.sdf
index 1e1a69cfd9..756de3eb34 100644
--- a/examples/worlds/gpu_lidar_sensor.sdf
+++ b/examples/worlds/gpu_lidar_sensor.sdf
@@ -22,6 +22,10 @@
filename="gz-sim-scene-broadcaster-system"
name="gz::sim::systems::SceneBroadcaster">
+
+
true
diff --git a/examples/worlds/ground_spacecraft_testbed.sdf b/examples/worlds/ground_spacecraft_testbed.sdf
new file mode 100644
index 0000000000..9d061f2fdd
--- /dev/null
+++ b/examples/worlds/ground_spacecraft_testbed.sdf
@@ -0,0 +1,77 @@
+
+
+
+
+ 0 0 -9.8066
+
+ 0.001
+ 1.0
+
+
+
+
+
+
+
+
+ ogre2
+
+
+ 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 1
+ 100 100
+
+
+
+
+
+
+ 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 0 0 0
+ https://fuel.gazebosim.org/1.0/proque/models/kth_freeflyer
+
+
+
diff --git a/examples/worlds/joint_trajectory_controller.sdf b/examples/worlds/joint_trajectory_controller.sdf
index 2f9508bd49..d6b62a5b8c 100644
--- a/examples/worlds/joint_trajectory_controller.sdf
+++ b/examples/worlds/joint_trajectory_controller.sdf
@@ -479,10 +479,10 @@
RR_velocity_control_link1
1 0 0
+
+ 0.02
+
-
- 0.02
-
0 0 0.1 0 0 0
@@ -490,10 +490,10 @@
RR_velocity_control_link2
1 0 0
+
+ 0.01
+
-
- 0.01
-
+
+
+
+
+ 0.001
+
+ 1
+
+
+ 0 0 -9.81
+
+
+
+
+
+
+
+
+
+ 1.097
+
+
+
+ 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
+
+
+
+ true
+
+
+
+
+ 0 0 1
+ 100 100
+
+
+
+
+
+
+ 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.gazebosim.org/1.0/hkotze/models/airship
+
+
+
+
diff --git a/examples/worlds/mimic_fast_slow_pendulums_world.sdf b/examples/worlds/mimic_fast_slow_pendulums_world.sdf
index b42c8bc73a..7386bd3dac 100644
--- a/examples/worlds/mimic_fast_slow_pendulums_world.sdf
+++ b/examples/worlds/mimic_fast_slow_pendulums_world.sdf
@@ -16,6 +16,10 @@
1
+
+ gz-physics-bullet-featherstone-plugin
+
+
true
0 0 10 0 0 0
diff --git a/examples/worlds/quadcopter.sdf b/examples/worlds/quadcopter.sdf
index 4b00c86c15..1ec3eaa18e 100644
--- a/examples/worlds/quadcopter.sdf
+++ b/examples/worlds/quadcopter.sdf
@@ -17,18 +17,6 @@
0.001
1.0
-
-
-
-
-
-
diff --git a/examples/worlds/sensors.sdf b/examples/worlds/sensors.sdf
index 9717bb11b3..8ca7b63789 100644
--- a/examples/worlds/sensors.sdf
+++ b/examples/worlds/sensors.sdf
@@ -38,6 +38,7 @@
+ 10
+
+
+
+ 0.1 0.1 0.1
+ 0.0 0.0 0.0
+
+
+
+
+
+ ogre2
+ -10 0 7 0 0.5 0
+
+ 8192
+
+
+
+
+
+
+
+
+
+ 0 0 8 0 0 0
+ 1 1 1 1
+ 0 0 0 0
+
+ 50
+ 0
+ 0
+ 0
+
+ true
+ -2 2 -1.5
+ 1.0
+
+
+
+
+ 0 0 0 0 0 -1.57
+
+ https://fuel.gazebosim.org/1.0/OpenRobotics/models/Garden Mascot
+
+
+
+
+ -5 0 -0.5 0 0 0
+ true
+
+
+
+
+ 15 15 1
+
+
+
+
+
+
+ 15 15 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
diff --git a/examples/worlds/shapes.sdf b/examples/worlds/shapes.sdf
index 1d75661b49..5d020a8c32 100644
--- a/examples/worlds/shapes.sdf
+++ b/examples/worlds/shapes.sdf
@@ -1,12 +1,13 @@
-
-
+
+
+
1.0 1.0 1.0
@@ -240,5 +241,36 @@ Try moving a model:
+
+
+ 0 4.5 0.5 0 0 0
+
+
+ 1
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+ 1 0.47 0 1
+ 1 0.47 0 1
+ 1 0.47 0 1
+
+
+
+
diff --git a/examples/worlds/spacecraft.sdf b/examples/worlds/spacecraft.sdf
new file mode 100644
index 0000000000..b28090c283
--- /dev/null
+++ b/examples/worlds/spacecraft.sdf
@@ -0,0 +1,51 @@
+
+
+
+
+ 0 0 0
+
+ 0.001
+ 1.0
+
+
+
+
+
+
+
+
+ ogre2
+
+
+ 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
+
+
+ 0 0 0 0 0 0
+ https://fuel.gazebosim.org/1.0/proque/models/dart/7
+
+
+
diff --git a/src/System_TEST.cc b/include/gz/sim/Constants.hh
similarity index 61%
rename from src/System_TEST.cc
rename to include/gz/sim/Constants.hh
index e238456085..96d281ccc7 100644
--- a/src/System_TEST.cc
+++ b/include/gz/sim/Constants.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Open Source Robotics Foundation
+ * Copyright (C) 2024 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.
@@ -13,15 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
-#include
+#ifndef GZ_SIM_CONSTANTS_HH_
+#define GZ_SIM_CONSTANTS_HH_
-#include "gz/sim/System.hh"
+#include "gz/sim/config.hh"
+#include
-using namespace gz;
-
-/////////////////////////////////////////////////
-TEST(System, Constructor)
+namespace gz::sim
+{
+// Inline bracket to help doxygen filtering.
+inline namespace GZ_SIM_VERSION_NAMESPACE
{
+ constexpr std::string_view kPoliciesTag{"gz:policies"};
}
+} // namespace gz::sim
+
+#endif
diff --git a/include/gz/sim/EntityComponentManager.hh b/include/gz/sim/EntityComponentManager.hh
index b87ada778c..2a20d159fc 100644
--- a/include/gz/sim/EntityComponentManager.hh
+++ b/include/gz/sim/EntityComponentManager.hh
@@ -675,6 +675,14 @@ namespace gz
/// \return True if there are components marked for removal.
public: bool HasRemovedComponents() const;
+ /// \brief Get an Entity based on a name component that is associated
+ /// with the entity.
+ /// \param[in] _name Name associated with the Entity
+ /// \return The Entity, if an Entity with the given name exists,
+ /// otherwise return std::nullopt.
+ public: std::optional EntityByName(
+ const std::string &_name) const;
+
/// \brief Clear the list of newly added entities so that a call to
/// EachAdded after this will have no entities to iterate. This function
/// is protected to facilitate testing.
@@ -828,6 +836,9 @@ namespace gz
friend class GuiRunner;
friend class SimulationRunner;
+ // Make SystemManager friend so it has access to removals
+ friend class SystemManager;
+
// Make network managers friends so they have control over component
// states. Like the runners, the managers are internal.
friend class NetworkManagerPrimary;
diff --git a/include/gz/sim/Link.hh b/include/gz/sim/Link.hh
index 842e287025..18037896a7 100644
--- a/include/gz/sim/Link.hh
+++ b/include/gz/sim/Link.hh
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -277,6 +278,14 @@ namespace gz
public: std::optional WorldInertiaMatrix(
const EntityComponentManager &_ecm) const;
+ /// \brief Get the fluid added mass matrix in the world frame.
+ /// \param[in] _ecm Entity-component manager.
+ /// \return Fluide added matrix in world frame, returns nullopt if link
+ /// does not have components components::Inertial and
+ /// components::WorldPose.
+ public: std::optional WorldFluidAddedMassMatrix(
+ const EntityComponentManager &_ecm) const;
+
/// \brief Get the rotational and translational kinetic energy of the
/// link with respect to the world frame.
/// \param[in] _ecm Entity-component manager.
diff --git a/include/gz/sim/Model.hh b/include/gz/sim/Model.hh
index 9de49ea0a1..ddb0e8130d 100644
--- a/include/gz/sim/Model.hh
+++ b/include/gz/sim/Model.hh
@@ -137,6 +137,14 @@ namespace gz
public: sim::Entity LinkByName(const EntityComponentManager &_ecm,
const std::string &_name) const;
+ /// \brief Get the ID of a nested model entity which is an immediate
+ /// child of this model.
+ /// \param[in] _ecm Entity-component manager.
+ /// \param[in] _name Nested model name.
+ /// \return Nested model entity.
+ public: sim::Entity ModelByName(const EntityComponentManager &_ecm,
+ const std::string &_name) const;
+
/// \brief Get all joints which are immediate children of this model.
/// \param[in] _ecm Entity-component manager.
/// \return All joints in this model.
@@ -167,6 +175,12 @@ namespace gz
/// \return Number of links in this model.
public: uint64_t LinkCount(const EntityComponentManager &_ecm) const;
+ /// \brief Get the number of nested models which are immediate children
+ /// of this model.
+ /// \param[in] _ecm Entity-component manager.
+ /// \return Number of nested models in this model.
+ public: uint64_t ModelCount(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.
diff --git a/include/gz/sim/Primitives.hh b/include/gz/sim/Primitives.hh
index 84bc8344f5..b90b9e7553 100644
--- a/include/gz/sim/Primitives.hh
+++ b/include/gz/sim/Primitives.hh
@@ -35,6 +35,7 @@ namespace gz
{
kBox,
kCapsule,
+ kCone,
kCylinder,
kEllipsoid,
kSphere,
@@ -67,8 +68,8 @@ namespace gz
/// \brief Return an SDF string of one of the available primitive shape or
/// light types.
/// \param[in] _typeName Type name of the of shape or light to retrieve.
- /// Must be one of: box, sphere, cylinder, capsule, ellipsoid, directional,
- /// point, or spot.
+ /// Must be one of: box, sphere, cylinder, cone, capsule, ellipsoid,
+ /// directional, point, or spot.
/// \return String containing SDF description of primitive shape or light.
/// Empty string if the _typeName is invalid.
std::string GZ_SIM_VISIBLE
diff --git a/include/gz/sim/SdfEntityCreator.hh b/include/gz/sim/SdfEntityCreator.hh
index 8e5292ef10..be96451b8a 100644
--- a/include/gz/sim/SdfEntityCreator.hh
+++ b/include/gz/sim/SdfEntityCreator.hh
@@ -93,6 +93,13 @@ namespace gz
/// \return World entity.
public: Entity CreateEntities(const sdf::World *_world);
+ /// \brief Create all entities that exist in the sdf::World object and
+ /// load their plugins.
+ /// \param[in] _world SDF world object.
+ /// \param[in] _worldEntity The world entity object.
+ public: void CreateEntities(const sdf::World *_world,
+ Entity _worldEntity);
+
/// \brief Create all entities that exist in the sdf::Model object and
/// load their plugins. Also loads plugins of child sensors.
/// \param[in] _model SDF model object.
@@ -186,6 +193,9 @@ namespace gz
private: Entity CreateEntities(const sdf::Model *_model,
bool _staticParent);
+ /// \brief Load plugins for all models
+ private: void LoadModelPlugins();
+
/// \brief Pointer to private data.
private: std::unique_ptr dataPtr;
};
diff --git a/include/gz/sim/ServerConfig.hh b/include/gz/sim/ServerConfig.hh
index bfb0e3e362..d32e0c4fcb 100644
--- a/include/gz/sim/ServerConfig.hh
+++ b/include/gz/sim/ServerConfig.hh
@@ -60,6 +60,14 @@ namespace gz
kSdfString,
};
+ /// \brief SDF error behavior
+ public: enum class SdfErrorBehavior
+ {
+ /// \brief Exit the server immediately
+ EXIT_IMMEDIATELY,
+ /// \brief Continue loading the server if possible
+ CONTINUE_LOADING
+ };
class PluginInfoPrivate;
/// \brief Information about a plugin that should be loaded by the
@@ -386,7 +394,17 @@ namespace gz
const std::string &_apiBackend);
/// \return Api backend for gui. See SetRenderEngineGuiApiBackend()
- const std::string &RenderEngineGuiApiBackend() const;
+ public: const std::string &RenderEngineGuiApiBackend() const;
+
+ /// \brief Set the server behavior when SDF errors are encountered while
+ //// loading the server.
+ /// \param[in] _behavior Server behavior when SDF errors are encounted.
+ public: void SetBehaviorOnSdfErrors(SdfErrorBehavior _behavior);
+
+ /// \brief Get the behavior when SDF errors are encountered while
+ //// loading the server.
+ /// \return Server behavior when SDF errors are encounted.
+ public: SdfErrorBehavior BehaviorOnSdfErrors() const;
/// \brief Instruct simulation to attach a plugin to a specific
/// entity when simulation starts.
diff --git a/include/gz/sim/System.hh b/include/gz/sim/System.hh
index cc0139161e..327f9bddbe 100644
--- a/include/gz/sim/System.hh
+++ b/include/gz/sim/System.hh
@@ -17,6 +17,7 @@
#ifndef GZ_SIM_SYSTEM_HH_
#define GZ_SIM_SYSTEM_HH_
+#include
#include
#include
@@ -64,6 +65,14 @@ namespace gz
/// * Used to read out results at the end of a simulation step to be used
/// for sensor or controller updates.
///
+ /// The PreUpdate and Update phases are executed sequentially in the same
+ /// thread, while the PostUpdate phase is executed in parallel in multiple
+ /// threads. The order of execution of PreUpdate and Update phases can be
+ /// controlled by specifying a signed integer Priority value for the System
+ /// in its XML configuration. The default Priority value is zero, and
+ /// smaller values are executed earlier. Systems with the same Priority
+ /// value are executed in the order in which they are loaded.
+ ///
/// It's important to note that UpdateInfo::simTime does not refer to the
/// current time, but the time reached after the PreUpdate and Update calls
/// have finished. So, if any of the *Update functions are called with
@@ -74,6 +83,19 @@ namespace gz
/// simulation is started un-paused.
class System
{
+ /// \brief Signed integer type used for specifying priority of the
+ /// execution order of PreUpdate and Update phases.
+ public: using PriorityType = int32_t;
+
+ /// \brief Default priority value for execution order of the PreUpdate
+ /// and Update phases.
+ public: constexpr static PriorityType kDefaultPriority = {0};
+
+ /// \brief Name of the XML element from which the priority value will be
+ /// parsed.
+ public: constexpr static std::string_view kPriorityElementName =
+ {"gz:system_priority"};
+
/// \brief Constructor
public: System() = default;
@@ -81,6 +103,31 @@ namespace gz
public: virtual ~System() = default;
};
+ /// \brief Define constant priority values for specific systems.
+ namespace systems
+ {
+ /// \brief Default priority value for the UserCommands system, with a very
+ /// negative value to indicate that it should run before most systems in
+ /// order to modify the ECM in response to user commands received over
+ /// gz-transport. This is especially important for user commands that add
+ /// objects to the world.
+ constexpr System::PriorityType kUserCommandsPriority = -16384;
+
+ /// \brief A suggested priority value for a system that should execute
+ /// before the Physics system.
+ constexpr System::PriorityType kPrePhysicsPriority = -128;
+
+ /// \brief Default priority value for the Physics system, with a negative
+ /// value ensuring that it will run before systems with priority
+ /// System::kDefaultPriority.
+ constexpr System::PriorityType kPhysicsPriority = -64;
+
+ /// \brief A suggested priority value for sensor systems that should
+ /// execute after the Physics system but before the systems with priority
+ /// System::kDefaultPriority.
+ constexpr System::PriorityType kPostPhysicsSensorPriority = -32;
+ }
+
/// \class ISystemConfigure ISystem.hh gz/sim/System.hh
/// \brief Interface for a system that implements optional configuration
///
@@ -102,6 +149,20 @@ namespace gz
EventManager &_eventMgr) = 0;
};
+ /// \class ISystemConfigure ISystem.hh gz/sim/System.hh
+ /// \brief Interface for a system that implements optional configuration
+ /// of the default priority value.
+ ///
+ /// ConfigurePriority is called before the system is instantiated to
+ /// override System::kDefaultPriority. It can still be overridden by the
+ /// XML priority element.
+ class ISystemConfigurePriority {
+ /// \brief Configure the default priority of the system, which can still
+ /// be overridden by the XML priority element.
+ /// \return The default priority for the system.
+ public: virtual System::PriorityType ConfigurePriority() = 0;
+ };
+
/// \class ISystemConfigureParameters ISystem.hh gz/sim/System.hh
/// \brief Interface for a system that declares parameters.
///
diff --git a/include/gz/sim/Util.hh b/include/gz/sim/Util.hh
index e8e4bed0e0..de0585e5c0 100644
--- a/include/gz/sim/Util.hh
+++ b/include/gz/sim/Util.hh
@@ -316,6 +316,13 @@ namespace gz
/// \return The loaded mesh or null if the mesh can not be loaded.
GZ_SIM_VISIBLE const common::Mesh *loadMesh(const sdf::Mesh &_meshSdf);
+ /// \brief Optimize input mesh.
+ /// \param[in] _meshSdf Mesh SDF DOM with mesh optimization parameters
+ /// \param[in] _mesh Input mesh to optimize.
+ /// \return The optimized mesh or null if the mesh can not be optimized.
+ GZ_SIM_VISIBLE const common::Mesh *optimizeMesh(const sdf::Mesh &_meshSdf,
+ const common::Mesh &_mesh);
+
/// \brief Environment variable holding resource paths.
const std::string kResourcePathEnv{"GZ_SIM_RESOURCE_PATH"};
diff --git a/include/gz/sim/components/AngularVelocityReset.hh b/include/gz/sim/components/AngularVelocityReset.hh
new file mode 100644
index 0000000000..11292852ed
--- /dev/null
+++ b/include/gz/sim/components/AngularVelocityReset.hh
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 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 GZ_SIM_COMPONENTS_WORLDANGULARVELOCITYRESET_HH_
+#define GZ_SIM_COMPONENTS_WORLDANGULARVELOCITYRESET_HH_
+
+#include
+#include
+#include
+#include
+#include
+
+namespace gz
+{
+namespace sim
+{
+// Inline bracket to help doxygen filtering.
+inline namespace GZ_SIM_VERSION_NAMESPACE {
+namespace components
+{
+ /// \brief Angular velocity of an entity, in its own frame
+ /// and in SI units (rad/s). The angular velocity is
+ // represented by gz::math::Vector3d.
+ using AngularVelocityReset = Component;
+ GZ_SIM_REGISTER_COMPONENT(
+ "gz_sim_components.AngularVelocityReset", AngularVelocityReset)
+
+ /// \brief Angular velocity of an entity in the world frame
+ /// and in SI units (rad/s). The angular velocity is
+ // represented by gz::math::Vector3d.
+ using WorldAngularVelocityReset = Component;
+ GZ_SIM_REGISTER_COMPONENT(
+ "gz_sim_components.WorldAngularVelocityReset", WorldAngularVelocityReset)
+}
+}
+}
+}
+
+#endif
diff --git a/include/gz/sim/components/Factory.hh b/include/gz/sim/components/Factory.hh
index 393c770a9d..afe139f33d 100644
--- a/include/gz/sim/components/Factory.hh
+++ b/include/gz/sim/components/Factory.hh
@@ -17,6 +17,7 @@
#ifndef GZ_SIM_COMPONENTS_FACTORY_HH_
#define GZ_SIM_COMPONENTS_FACTORY_HH_
+#include
#include
#include
#include
@@ -282,17 +283,6 @@ namespace components
std::string debugEnv;
gz::common::env("GZ_DEBUG_COMPONENT_FACTORY", debugEnv);
- if (debugEnv != "true")
- {
- gz::common::env("IGN_DEBUG_COMPONENT_FACTORY", debugEnv);
- if (debugEnv == "true")
- {
- std::cerr << "Environment variable [IGN_DEBUG_COMPONENT_FACTORY] "
- << "is deprecated! Please use [GZ_DEBUG_COMPONENT_FACTORY]"
- << "instead." << std::endl;
- }
- }
-
if (debugEnv == "true")
{
std::cout << "Registering [" << ComponentTypeT::typeName << "]"
diff --git a/include/gz/sim/components/Gravity.hh b/include/gz/sim/components/Gravity.hh
index 82ba3d036a..a4b8ac352d 100644
--- a/include/gz/sim/components/Gravity.hh
+++ b/include/gz/sim/components/Gravity.hh
@@ -36,6 +36,11 @@ namespace components
/// \brief Store the gravity acceleration.
using Gravity = Component;
GZ_SIM_REGISTER_COMPONENT("gz_sim_components.Gravity", Gravity)
+
+ /// \brief Store the gravity acceleration.
+ using GravityEnabled = Component;
+ GZ_SIM_REGISTER_COMPONENT(
+ "gz_sim_components.GravityEnabled", GravityEnabled)
}
}
}
diff --git a/include/gz/sim/components/LinearVelocityReset.hh b/include/gz/sim/components/LinearVelocityReset.hh
new file mode 100644
index 0000000000..c7343105f3
--- /dev/null
+++ b/include/gz/sim/components/LinearVelocityReset.hh
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 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 GZ_SIM_COMPONENTS_WORLDLINEARVELOCITYRESET_HH_
+#define GZ_SIM_COMPONENTS_WORLDLINEARVELOCITYRESET_HH_
+
+#include
+#include
+#include
+#include
+#include
+
+namespace gz
+{
+namespace sim
+{
+// Inline bracket to help doxygen filtering.
+inline namespace GZ_SIM_VERSION_NAMESPACE {
+namespace components
+{
+ /// \brief Linear velocity of an entity in its own frame
+ /// and in SI units (m/s). The linear velocity is
+ /// represented by gz::math::Vector3d.
+ using LinearVelocityReset = Component;
+ GZ_SIM_REGISTER_COMPONENT(
+ "gz_sim_components.LinearVelocityReset", LinearVelocityReset)
+
+ /// \brief Linear velocity of an entity in the world frame
+ /// and in SI units (m/s). The linear velocity is
+ /// represented by gz::math::Vector3d.
+ using WorldLinearVelocityReset = Component;
+ GZ_SIM_REGISTER_COMPONENT(
+ "gz_sim_components.WorldLinearVelocityReset", WorldLinearVelocityReset)
+}
+}
+}
+}
+
+#endif
diff --git a/include/gz/sim/components/Performer.hh b/include/gz/sim/components/Performer.hh
index 2323b67275..58c0092047 100644
--- a/include/gz/sim/components/Performer.hh
+++ b/include/gz/sim/components/Performer.hh
@@ -17,6 +17,7 @@
#ifndef GZ_SIM_COMPONENTS_PERFORMER_HH_
#define GZ_SIM_COMPONENTS_PERFORMER_HH_
+#include
#include
#include
@@ -34,6 +35,11 @@ namespace components
/// \brief This component identifies an entity as being a performer.
using Performer = Component;
GZ_SIM_REGISTER_COMPONENT("gz_sim_components.Performer", Performer)
+
+ /// \brief This component contains the performer reference name.
+ using PerformerRef = Component;
+ GZ_SIM_REGISTER_COMPONENT("gz_sim_components.PerformerRef", PerformerRef)
}
}
}
diff --git a/include/gz/sim/components/Physics.hh b/include/gz/sim/components/Physics.hh
index e486c0d0b9..22f6b3f849 100644
--- a/include/gz/sim/components/Physics.hh
+++ b/include/gz/sim/components/Physics.hh
@@ -17,6 +17,7 @@
#ifndef GZ_SIM_COMPONENTS_PHYSICS_HH_
#define GZ_SIM_COMPONENTS_PHYSICS_HH_
+#include
#include
#include
@@ -65,6 +66,12 @@ namespace components
class PhysicsSolverTag, serializers::StringSerializer>;
GZ_SIM_REGISTER_COMPONENT("gz_sim_components.PhysicsSolver",
PhysicsSolver)
+
+ /// \brief The number of solver iterations for each step.
+ using PhysicsSolverIterations = Component;
+ GZ_SIM_REGISTER_COMPONENT("gz_sim_components.PhysicsSolverIterations",
+ PhysicsSolverIterations)
}
}
}
diff --git a/include/gz/sim/components/WrenchMeasured.hh b/include/gz/sim/components/WrenchMeasured.hh
new file mode 100644
index 0000000000..74c350514b
--- /dev/null
+++ b/include/gz/sim/components/WrenchMeasured.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 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 GZ_SIM_COMPONENTS_WRENCHMEASURED_HH_
+#define GZ_SIM_COMPONENTS_WRENCHMEASURED_HH_
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace gz
+{
+namespace sim
+{
+// Inline bracket to help doxygen filtering.
+inline namespace GZ_SIM_VERSION_NAMESPACE {
+
+namespace components
+{
+/// \brief Wrench measured by a ForceTorqueSensor in SI units (Nm for torque,
+/// N for force).
+/// The wrench is expressed in the Sensor frame and the force component is
+/// applied at the sensor origin.
+/// \note The term Wrench is used here to mean a pair of 3D vectors representing
+/// torque and force quantities expressed in a given frame and where the force
+/// is applied at the origin of the frame. This is different from the Wrench
+/// used in screw theory.
+/// \note The value of force_offset in msgs::Wrench is ignored for this
+/// component. The force is assumed to be applied at the origin of the sensor
+/// frame.
+using WrenchMeasured =
+ Component;
+GZ_SIM_REGISTER_COMPONENT("gz_sim_components.WrenchMeasured",
+ WrenchMeasured)
+} // namespace components
+}
+}
+}
+
+#endif
diff --git a/package.xml b/package.xml
new file mode 100644
index 0000000000..507b36f440
--- /dev/null
+++ b/package.xml
@@ -0,0 +1,54 @@
+
+
+
+ gz-sim9
+ 9.0.0
+ Gazebo Sim : A Robotic Simulator
+ Michael Carroll
+ Apache License 2.0
+ https://github.com/gazebosim/gz-sim
+
+ cmake
+
+ benchmark
+ glut
+ gz-cmake4
+ gz-common6
+ gz-fuel_tools10
+ gz-gui9
+ gz-math8
+ gz-msgs11
+ gz-physics8
+ gz-plugin3
+ gz-rendering9
+ gz-sensors9
+ gz-tools2
+ gz-transport14
+ gz-utils3
+ libfreeimage-dev
+ libglew-dev
+ libxi-dev
+ libxmu-dev
+ protobuf-dev
+ pybind11-dev
+ qml-module-qt-labs-folderlistmodel
+ qml-module-qt-labs-settings
+ qml-module-qtgraphicaleffects
+ qml-module-qtquick-controls2
+ qml-module-qtquick-controls
+ qml-module-qtquick-dialogs
+ qml-module-qtquick-layouts
+ qml-module-qtquick2
+ qtbase5-dev
+ qtdeclarative5-dev
+ sdformat15
+ tinyxml2
+ uuid
+
+ xvfb
+ python3-pytest
+
+
+ cmake
+
+
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 3069e98752..98bbe66650 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,22 +1,6 @@
-if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
- # pybind11 logic for setting up a debug build when both a debug and release
- # python interpreter are present in the system seems to be pretty much broken.
- # This works around the issue.
- set(PYTHON_LIBRARIES "${PYTHON_DEBUG_LIBRARIES}")
-endif()
-
-
if(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION)
- if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
- execute_process(
- COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
- from distutils import sysconfig as sc
- print(sc.get_python_lib(plat_specific=True))"
- OUTPUT_VARIABLE Python3_SITEARCH
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- else()
- # Get install variable from Python3 module
- # Python3_SITEARCH is available from 3.12 on, workaround if needed:
+ if(NOT Python3_SITEARCH)
+ # Get variable from Python3 module
find_package(Python3 COMPONENTS Interpreter)
endif()
@@ -31,7 +15,6 @@ else()
set(GZ_PYTHON_INSTALL_PATH ${GZ_LIB_INSTALL_DIR}/python)
endif()
-set(GZ_PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
set(GZ_PYTHON_INSTALL_PATH "${GZ_PYTHON_INSTALL_PATH}/gz")
# Set the build location and install location for a CPython extension
@@ -101,7 +84,7 @@ if (BUILD_TESTING)
world_TEST
)
- execute_process(COMMAND "${GZ_PYTHON_EXECUTABLE}" -m pytest --version
+ execute_process(COMMAND "${Python3_EXECUTABLE}" -m pytest --version
OUTPUT_VARIABLE PYTEST_output
ERROR_VARIABLE PYTEST_error
RESULT_VARIABLE PYTEST_result)
@@ -115,10 +98,10 @@ if (BUILD_TESTING)
foreach (test ${python_tests})
if (pytest_FOUND)
add_test(NAME ${test} COMMAND
- "${GZ_PYTHON_EXECUTABLE}" -m pytest "${CMAKE_SOURCE_DIR}/python/test/${test}.py" --junitxml "${CMAKE_BINARY_DIR}/test_results/UNIT_${test}.xml")
+ "${Python3_EXECUTABLE}" -m pytest "${CMAKE_SOURCE_DIR}/python/test/${test}.py" --junitxml "${CMAKE_BINARY_DIR}/test_results/UNIT_${test}.xml")
else()
add_test(NAME ${test} COMMAND
- "${GZ_PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/python/test/${test}.py")
+ "${Python3_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/python/test/${test}.py")
endif()
set(_env_vars)
diff --git a/python/src/gz/sim/Joint.cc b/python/src/gz/sim/Joint.cc
index 307289ec44..328e4d51cf 100644
--- a/python/src/gz/sim/Joint.cc
+++ b/python/src/gz/sim/Joint.cc
@@ -94,7 +94,22 @@ void defineSimJoint(py::object module)
py::arg("ecm"),
py::arg("limits"),
"Set the effort limits on a joint axis.")
- .def("set_position_imits", &gz::sim::Joint::SetPositionLimits,
+ .def("set_position_imits",
+ [](pybind11::object &self, EntityComponentManager &_ecm,
+ const std::vector &_limits)
+ {
+ auto warnings = pybind11::module::import("warnings");
+ auto builtins = pybind11::module::import("builtins");
+ warnings.attr("warn")(
+ "set_position_imits() is deprecated, use set_position_limits() instead.",
+ builtins.attr("DeprecationWarning"));
+
+ return self.attr("set_position_limits")(_ecm, _limits);
+ },
+ py::arg("ecm"),
+ py::arg("limits"),
+ "Set the position limits on a joint axis.")
+ .def("set_position_limits", &gz::sim::Joint::SetPositionLimits,
py::arg("ecm"),
py::arg("limits"),
"Set the position limits on a joint axis.")
diff --git a/python/test/gz_test_deps/common.py b/python/test/gz_test_deps/common.py
index d28e66e5e5..60f802749d 100644
--- a/python/test/gz_test_deps/common.py
+++ b/python/test/gz_test_deps/common.py
@@ -1 +1 @@
-from gz.common5 import *
+from gz.common6 import *
diff --git a/python/test/gz_test_deps/math.py b/python/test/gz_test_deps/math.py
index cb2860c798..d84d0a4777 100644
--- a/python/test/gz_test_deps/math.py
+++ b/python/test/gz_test_deps/math.py
@@ -1 +1 @@
-from gz.math7 import *
+from gz.math8 import *
diff --git a/python/test/gz_test_deps/msgs.py b/python/test/gz_test_deps/msgs.py
index e91bef7942..c28bb81ef3 100644
--- a/python/test/gz_test_deps/msgs.py
+++ b/python/test/gz_test_deps/msgs.py
@@ -1,3 +1,3 @@
import sys
-import gz.msgs10
-sys.modules["gz_test_deps.msgs"] = gz.msgs10
+import gz.msgs11
+sys.modules["gz_test_deps.msgs"] = gz.msgs11
diff --git a/python/test/gz_test_deps/sdformat.py b/python/test/gz_test_deps/sdformat.py
index 51cec2889b..5d34df703e 100644
--- a/python/test/gz_test_deps/sdformat.py
+++ b/python/test/gz_test_deps/sdformat.py
@@ -1 +1 @@
-from sdformat14 import *
+from sdformat15 import *
diff --git a/python/test/gz_test_deps/sim.py b/python/test/gz_test_deps/sim.py
index 38c3164e14..c41dc0aff9 100644
--- a/python/test/gz_test_deps/sim.py
+++ b/python/test/gz_test_deps/sim.py
@@ -1 +1 @@
-from gz.sim8 import *
+from gz.sim9 import *
diff --git a/python/test/gz_test_deps/transport.py b/python/test/gz_test_deps/transport.py
index 242eeb064a..0c95691f87 100644
--- a/python/test/gz_test_deps/transport.py
+++ b/python/test/gz_test_deps/transport.py
@@ -1 +1 @@
-from gz.transport13 import *
+from gz.transport14 import *
diff --git a/python/test/joint_test.sdf b/python/test/joint_test.sdf
index 4c9d79345c..078f3974b7 100644
--- a/python/test/joint_test.sdf
+++ b/python/test/joint_test.sdf
@@ -1,8 +1,8 @@
-
-
+
+
diff --git a/python/test/sensor_TEST.py b/python/test/sensor_TEST.py
index aba4c61ca9..61068c3fa3 100755
--- a/python/test/sensor_TEST.py
+++ b/python/test/sensor_TEST.py
@@ -33,11 +33,11 @@ def test_model(self):
file_path = os.path.dirname(os.path.realpath(__file__))
fixture = TestFixture(os.path.join(file_path, 'joint_test.sdf'))
- def on_post_udpate_cb(_info, _ecm):
+ def on_post_update_cb(_info, _ecm):
self.post_iterations += 1
- def on_pre_udpate_cb(_info, _ecm):
- self.pre_iterations += 1
+ def on_update_cb(_info, _ecm):
+ self.iterations += 1
world_e = world_entity(_ecm)
self.assertNotEqual(K_NULL_ENTITY, world_e)
w = World(world_e)
@@ -53,19 +53,19 @@ def on_pre_udpate_cb(_info, _ecm):
# Pose Test
self.assertEqual(Pose3d(0, 1, 0, 0, 0, 0), sensor.pose(_ecm))
# Topic Test
- if self.pre_iterations <= 1:
+ if self.iterations <= 1:
self.assertEqual(None, sensor.topic(_ecm))
else:
self.assertEqual('sensor_topic_test', sensor.topic(_ecm))
# Parent Test
self.assertEqual(j.entity(), sensor.parent(_ecm))
- def on_udpate_cb(_info, _ecm):
- self.iterations += 1
+ def on_pre_update_cb(_info, _ecm):
+ self.pre_iterations += 1
- fixture.on_post_update(on_post_udpate_cb)
- fixture.on_update(on_udpate_cb)
- fixture.on_pre_update(on_pre_udpate_cb)
+ fixture.on_post_update(on_post_update_cb)
+ fixture.on_update(on_update_cb)
+ fixture.on_pre_update(on_pre_update_cb)
fixture.finalize()
server = fixture.server()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e23c1a866a..d4a5589b19 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,11 +11,11 @@ get_target_property(msgs_desc_file
gz_msgs_generate_messages_impl(
MSGS_GEN_SCRIPT
- ${gz-msgs10_PROTO_GENERATOR_SCRIPT}
+ ${gz-msgs11_PROTO_GENERATOR_SCRIPT}
FACTORY_GEN_SCRIPT
- ${gz-msgs10_FACTORY_GENERATOR_SCRIPT}
+ ${gz-msgs11_FACTORY_GENERATOR_SCRIPT}
GZ_PROTOC_PLUGIN
- ${gz-msgs10_PROTO_GENERATOR_PLUGIN}
+ ${gz-msgs11_PROTO_GENERATOR_PLUGIN}
INPUT_PROTOS
${gz_msgs_proto_files}
PROTO_PACKAGE
@@ -124,7 +124,6 @@ set (gtest_sources
SimulationRunner_TEST.cc
SystemLoader_TEST.cc
SystemManager_TEST.cc
- System_TEST.cc
TestFixture_TEST.cc
Util_TEST.cc
World_TEST.cc
@@ -307,10 +306,8 @@ foreach(CMD_TEST
# and executables in a common CMAKE_RUNTIME_OUTPUT_DIRECTORY, so that the .dll are found
# as they are in the same directory where the executable is loaded. For tests that are
# launched via Ruby, this does not work, so we need to manually add CMAKE_RUNTIME_OUTPUT_DIRECTORY
- # to the PATH. This is done via the ENVIRONMENT_MODIFICATION that is only available
- # since CMake 3.22. However, if an older CMake is used another trick to install the libraries
- # beforehand
- if (WIN32 AND CMAKE_VERSION STRGREATER "3.22")
+ # to the PATH. This is done via the ENVIRONMENT_MODIFICATION that was added in CMake 3.22.
+ if (WIN32)
set_tests_properties(${CMD_TEST} PROPERTIES
ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endif()
diff --git a/src/Conversions.cc b/src/Conversions.cc
index fbe7587141..d5c054ada9 100644
--- a/src/Conversions.cc
+++ b/src/Conversions.cc
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -53,6 +54,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -176,6 +178,12 @@ msgs::Geometry gz::sim::convert(const sdf::Geometry &_in)
out.mutable_capsule()->set_radius(_in.CapsuleShape()->Radius());
out.mutable_capsule()->set_length(_in.CapsuleShape()->Length());
}
+ else if (_in.Type() == sdf::GeometryType::CONE && _in.ConeShape())
+ {
+ out.set_type(msgs::Geometry::CONE);
+ out.mutable_cone()->set_radius(_in.ConeShape()->Radius());
+ out.mutable_cone()->set_length(_in.ConeShape()->Length());
+ }
else if (_in.Type() == sdf::GeometryType::CYLINDER && _in.CylinderShape())
{
out.set_type(msgs::Geometry::CYLINDER);
@@ -212,6 +220,24 @@ msgs::Geometry gz::sim::convert(const sdf::Geometry &_in)
meshMsg->set_filename(asFullPath(meshSdf->Uri(), meshSdf->FilePath()));
meshMsg->set_submesh(meshSdf->Submesh());
meshMsg->set_center_submesh(meshSdf->CenterSubmesh());
+
+ if (!meshSdf->OptimizationStr().empty())
+ {
+ auto header = out.mutable_header()->add_data();
+ header->set_key("optimization");
+ header->add_value(meshSdf->OptimizationStr());
+ }
+ if (meshSdf->ConvexDecomposition())
+ {
+ auto header = out.mutable_header()->add_data();
+ header->set_key("max_convex_hulls");
+ header->add_value(std::to_string(
+ meshSdf->ConvexDecomposition()->MaxConvexHulls()));
+ header = out.mutable_header()->add_data();
+ header->set_key("voxel_resolution");
+ header->add_value(std::to_string(
+ meshSdf->ConvexDecomposition()->VoxelResolution()));
+ }
}
else if (_in.Type() == sdf::GeometryType::HEIGHTMAP && _in.HeightmapShape())
{
@@ -260,6 +286,10 @@ msgs::Geometry gz::sim::convert(const sdf::Geometry &_in)
}
}
}
+ else if (_in.Type() == sdf::GeometryType::EMPTY)
+ {
+ out.set_type(msgs::Geometry::EMPTY);
+ }
else
{
gzerr << "Geometry type [" << static_cast(_in.Type())
@@ -293,6 +323,16 @@ sdf::Geometry gz::sim::convert(const msgs::Geometry &_in)
out.SetCapsuleShape(capsuleShape);
}
+ else if (_in.type() == msgs::Geometry::CONE && _in.has_cone())
+ {
+ out.SetType(sdf::GeometryType::CONE);
+
+ sdf::Cone coneShape;
+ coneShape.SetRadius(_in.cone().radius());
+ coneShape.SetLength(_in.cone().length());
+
+ out.SetConeShape(coneShape);
+ }
else if (_in.type() == msgs::Geometry::CYLINDER && _in.has_cylinder())
{
out.SetType(sdf::GeometryType::CYLINDER);
@@ -341,6 +381,24 @@ sdf::Geometry gz::sim::convert(const msgs::Geometry &_in)
meshShape.SetSubmesh(_in.mesh().submesh());
meshShape.SetCenterSubmesh(_in.mesh().center_submesh());
+ sdf::ConvexDecomposition convexDecomp;
+ for (int i = 0; i < _in.header().data_size(); ++i)
+ {
+ auto data = _in.header().data(i);
+ if (data.key() == "optimization" && data.value_size() > 0)
+ {
+ meshShape.SetOptimization(data.value(0));
+ }
+ if (data.key() == "max_convex_hulls" && data.value_size() > 0)
+ {
+ convexDecomp.SetMaxConvexHulls(std::stoul(data.value(0)));
+ }
+ if (data.key() == "voxel_resolution" && data.value_size() > 0)
+ {
+ convexDecomp.SetVoxelResolution(std::stoul(data.value(0)));
+ }
+ }
+ meshShape.SetConvexDecomposition(convexDecomp);
out.SetMeshShape(meshShape);
}
else if (_in.type() == msgs::Geometry::HEIGHTMAP && _in.has_heightmap())
@@ -848,7 +906,7 @@ msgs::Atmosphere gz::sim::convert(const sdf::Atmosphere &_in)
out.set_type(msgs::Atmosphere::ADIABATIC);
}
// todo(anyone) add mass density to sdf::Atmosphere?
- // out.set_mass_density(_in.MassDensity());k
+ // out.set_mass_density(_in.MassDensity());
return out;
}
@@ -1681,15 +1739,7 @@ msgs::ParticleEmitter gz::sim::convert(const sdf::ParticleEmitter &_in)
}
}
- /// \todo(nkoenig) Modify the particle_emitter.proto file to
- /// have a topic field.
- if (!_in.Topic().empty())
- {
- auto header = out.mutable_header()->add_data();
- header->set_key("topic");
- header->add_value(_in.Topic());
- }
-
+ out.mutable_topic()->set_data(_in.Topic());
out.mutable_particle_scatter_ratio()->set_data(_in.ScatterRatio());
return out;
}
@@ -1744,15 +1794,8 @@ sdf::ParticleEmitter gz::sim::convert(const msgs::ParticleEmitter &_in)
out.SetColorRangeImage(_in.color_range_image().data());
if (_in.has_particle_scatter_ratio())
out.SetScatterRatio(_in.particle_scatter_ratio().data());
-
- for (int i = 0; i < _in.header().data_size(); ++i)
- {
- auto data = _in.header().data(i);
- if (data.key() == "topic" && data.value_size() > 0)
- {
- out.SetTopic(data.value(0));
- }
- }
+ if (_in.has_topic())
+ out.SetTopic(_in.topic().data());
return out;
}
@@ -1770,10 +1813,7 @@ msgs::Projector gz::sim::convert(const sdf::Projector &_in)
out.set_fov(_in.HorizontalFov().Radian());
out.set_texture(_in.Texture().empty() ? "" :
asFullPath(_in.Texture(), _in.FilePath()));
-
- auto header = out.mutable_header()->add_data();
- header->set_key("visibility_flags");
- header->add_value(std::to_string(_in.VisibilityFlags()));
+ out.set_visibility_flags(_in.VisibilityFlags());
return out;
}
@@ -1790,26 +1830,7 @@ sdf::Projector gz::sim::convert(const msgs::Projector &_in)
out.SetHorizontalFov(math::Angle(_in.fov()));
out.SetTexture(_in.texture());
out.SetRawPose(msgs::Convert(_in.pose()));
-
- /// \todo(anyone) add "visibility_flags" field to projector.proto
- for (int i = 0; i < _in.header().data_size(); ++i)
- {
- auto data = _in.header().data(i);
- if (data.key() == "visibility_flags" && data.value_size() > 0)
- {
- try
- {
- out.SetVisibilityFlags(std::stoul(data.value(0)));
- }
- catch (...)
- {
- gzerr << "Failed to parse projector : "
- << data.value(0) << ". Using default value: 0xFFFFFFFF."
- << std::endl;
- out.SetVisibilityFlags(0xFFFFFFFF);
- }
- }
- }
+ out.SetVisibilityFlags(_in.visibility_flags());
return out;
}
diff --git a/src/Conversions_TEST.cc b/src/Conversions_TEST.cc
index 08ac3e1afd..5d0f5345ba 100644
--- a/src/Conversions_TEST.cc
+++ b/src/Conversions_TEST.cc
@@ -463,6 +463,11 @@ TEST(Conversions, GeometryMesh)
meshShape.SetUri("file://watermelon");
meshShape.SetSubmesh("grape");
meshShape.SetCenterSubmesh(true);
+ meshShape.SetOptimization("convex_decomposition");
+ sdf::ConvexDecomposition convexDecomp;
+ convexDecomp.SetMaxConvexHulls(4);
+ convexDecomp.SetVoxelResolution(10000);
+ meshShape.SetConvexDecomposition(convexDecomp);
geometry.SetMeshShape(meshShape);
auto geometryMsg = convert(geometry);
@@ -473,6 +478,15 @@ TEST(Conversions, GeometryMesh)
EXPECT_EQ("file://watermelon", geometryMsg.mesh().filename());
EXPECT_EQ("grape", geometryMsg.mesh().submesh());
EXPECT_TRUE(geometryMsg.mesh().center_submesh());
+ auto header = geometryMsg.header().data(0);
+ EXPECT_EQ("optimization", header.key());
+ EXPECT_EQ("convex_decomposition", header.value(0));
+ header = geometryMsg.header().data(1);
+ EXPECT_EQ("max_convex_hulls", header.key());
+ EXPECT_EQ("4", header.value(0));
+ header = geometryMsg.header().data(2);
+ EXPECT_EQ("voxel_resolution", header.key());
+ EXPECT_EQ("10000", header.value(0));
auto newGeometry = convert(geometryMsg);
EXPECT_EQ(sdf::GeometryType::MESH, newGeometry.Type());
@@ -481,6 +495,11 @@ TEST(Conversions, GeometryMesh)
EXPECT_EQ("file://watermelon", newGeometry.MeshShape()->Uri());
EXPECT_EQ("grape", newGeometry.MeshShape()->Submesh());
EXPECT_TRUE(newGeometry.MeshShape()->CenterSubmesh());
+ EXPECT_EQ("convex_decomposition", newGeometry.MeshShape()->OptimizationStr());
+ auto newConvexDecomp = newGeometry.MeshShape()->ConvexDecomposition();
+ ASSERT_NE(nullptr, newConvexDecomp);
+ EXPECT_EQ(4, newConvexDecomp->MaxConvexHulls());
+ EXPECT_EQ(10000, newConvexDecomp->VoxelResolution());
}
/////////////////////////////////////////////////
@@ -1041,10 +1060,7 @@ TEST(Conversions, ParticleEmitter)
EXPECT_EQ(math::Color(0.4f, 0.5f, 0.6f),
msgs::Convert(emitterMsg.color_end()));
EXPECT_EQ("range_image", emitterMsg.color_range_image().data());
-
- auto header = emitterMsg.header().data(0);
- EXPECT_EQ("topic", header.key());
- EXPECT_EQ("my_topic", header.value(0));
+ EXPECT_EQ("my_topic", emitterMsg.topic().data());
EXPECT_FLOAT_EQ(0.9f, emitterMsg.particle_scatter_ratio().data());
@@ -1094,10 +1110,7 @@ TEST(Conversions, Projector)
EXPECT_NEAR(30, projectorMsg.far_clip(), 1e-3);
EXPECT_NEAR(0.4, projectorMsg.fov(), 1e-3);
EXPECT_EQ("projector.png", projectorMsg.texture());
-
- auto header = projectorMsg.header().data(0);
- EXPECT_EQ("visibility_flags", header.key());
- EXPECT_EQ(0xFF, std::stoul(header.value(0)));
+ EXPECT_EQ(0xFF, projectorMsg.visibility_flags());
// Convert the message back to SDF.
sdf::Projector projector2 = convert(projectorMsg);
@@ -1203,3 +1216,13 @@ TEST(Conversions, MsgsPluginToSdf)
EXPECT_EQ(innerXml, sdfPlugins[1].Contents()[0]->ToString(""));
EXPECT_EQ(innerXml2, sdfPlugins[1].Contents()[1]->ToString(""));
}
+
+/////////////////////////////////////////////////
+TEST(Conversions, GeometryEmpty)
+{
+ sdf::Geometry geometry;
+ geometry.SetType(sdf::GeometryType::EMPTY);
+
+ auto geometryMsg = convert(geometry);
+ EXPECT_EQ(msgs::Geometry::EMPTY, geometryMsg.type());
+}
diff --git a/src/EntityComponentManager.cc b/src/EntityComponentManager.cc
index 5ab9b0a635..2fd4e03c6e 100644
--- a/src/EntityComponentManager.cc
+++ b/src/EntityComponentManager.cc
@@ -2314,3 +2314,15 @@ void EntityComponentManager::ResetTo(const EntityComponentManager &_other)
tmpCopy.ApplyEntityDiff(*this, ecmDiff);
this->CopyFrom(tmpCopy);
}
+
+/////////////////////////////////////////////////
+std::optional EntityComponentManager::EntityByName(
+ const std::string &_name) const
+{
+ std::optional entity;
+ Entity entByName = EntityByComponents(components::Name(_name));
+ if (entByName != kNullEntity)
+ entity = entByName;
+
+ return entity;
+}
diff --git a/src/EntityComponentManager_TEST.cc b/src/EntityComponentManager_TEST.cc
index bc7f03ff99..f7a6c11e7e 100644
--- a/src/EntityComponentManager_TEST.cc
+++ b/src/EntityComponentManager_TEST.cc
@@ -3421,6 +3421,23 @@ TEST_P(EntityComponentManagerFixture,
EXPECT_EQ(321, comp->Data());
}
+//////////////////////////////////////////////////
+TEST_P(EntityComponentManagerFixture, EntityByName)
+{
+ // Create an entity, and give it a name
+ Entity entity = manager.CreateEntity();
+ manager.CreateComponent(entity, components::Name("entity_name_a"));
+
+ // Try to get an entity that doesn't exist
+ std::optional entityByName = manager.EntityByName("a_bad_name");
+ EXPECT_FALSE(entityByName);
+
+ entityByName = manager.EntityByName("entity_name_a");
+ EXPECT_TRUE(entityByName);
+ CompareEntityComponents(manager, entity,
+ *entityByName, true);
+}
+
// Run multiple times. We want to make sure that static globals don't cause
// problems.
INSTANTIATE_TEST_SUITE_P(EntityComponentManagerRepeat,
diff --git a/src/LevelManager.cc b/src/LevelManager.cc
index 0513fb4f30..ab950bc378 100644
--- a/src/LevelManager.cc
+++ b/src/LevelManager.cc
@@ -18,6 +18,7 @@
#include "LevelManager.hh"
#include
+#include
#include
#include
@@ -42,7 +43,6 @@
#include "gz/sim/components/LevelEntityNames.hh"
#include "gz/sim/components/Light.hh"
#include "gz/sim/components/LinearVelocity.hh"
-#include "gz/sim/components/LinearVelocitySeed.hh"
#include "gz/sim/components/MagneticField.hh"
#include "gz/sim/components/Model.hh"
#include "gz/sim/components/Name.hh"
@@ -50,15 +50,9 @@
#include "gz/sim/components/Performer.hh"
#include "gz/sim/components/PerformerLevels.hh"
#include "gz/sim/components/Physics.hh"
-#include "gz/sim/components/PhysicsEnginePlugin.hh"
#include "gz/sim/components/Pose.hh"
-#include "gz/sim/components/RenderEngineGuiPlugin.hh"
-#include "gz/sim/components/RenderEngineServerApiBackend.hh"
-#include "gz/sim/components/RenderEngineServerHeadless.hh"
-#include "gz/sim/components/RenderEngineServerPlugin.hh"
#include "gz/sim/components/Scene.hh"
#include "gz/sim/components/SphericalCoordinates.hh"
-#include "gz/sim/components/Wind.hh"
#include "gz/sim/components/World.hh"
#include "SimulationRunner.hh"
@@ -80,182 +74,57 @@ LevelManager::LevelManager(SimulationRunner *_runner, const bool _useLevels)
this->runner->entityCompMgr,
this->runner->eventMgr);
- this->ReadLevelPerformerInfo();
- this->CreatePerformers();
-
std::string service = transport::TopicUtils::AsValidTopic("/world/" +
- this->runner->sdfWorld->Name() + "/level/set_performer");
+ this->runner->sdfWorld.Name() + "/level/set_performer");
if (service.empty())
{
gzerr << "Failed to generate set_performer topic for world ["
- << this->runner->sdfWorld->Name() << "]" << std::endl;
+ << this->runner->sdfWorld.Name() << "]" << std::endl;
return;
}
this->node.Advertise(service, &LevelManager::OnSetPerformer, this);
}
/////////////////////////////////////////////////
-void LevelManager::ReadLevelPerformerInfo()
+void LevelManager::ReadLevelPerformerInfo(const sdf::World &_world)
{
- // \todo(anyone) Use SdfEntityCreator to avoid duplication
- this->worldEntity = this->runner->entityCompMgr.CreateEntity();
-
- // World components
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::World());
- this->runner->entityCompMgr.CreateComponent(
- this->worldEntity, components::Name(this->runner->sdfWorld->Name()));
-
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::Gravity(this->runner->sdfWorld->Gravity()));
-
- auto physics = this->runner->sdfWorld->PhysicsByIndex(0);
- if (!physics)
- {
- physics = this->runner->sdfWorld->PhysicsDefault();
- }
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::Physics(*physics));
-
- // Populate physics options that aren't accessible outside the Element()
- // See https://github.com/osrf/sdformat/issues/508
- if (physics->Element() && physics->Element()->HasElement("dart"))
- {
- auto dartElem = physics->Element()->GetElement("dart");
-
- if (dartElem->HasElement("collision_detector"))
- {
- auto collisionDetector =
- dartElem->Get("collision_detector");
-
- this->runner->entityCompMgr.CreateComponent(worldEntity,
- components::PhysicsCollisionDetector(collisionDetector));
- }
- if (dartElem->HasElement("solver") &&
- dartElem->GetElement("solver")->HasElement("solver_type"))
- {
- auto solver =
- dartElem->GetElement("solver")->Get("solver_type");
-
- this->runner->entityCompMgr.CreateComponent(worldEntity,
- components::PhysicsSolver(solver));
- }
- }
-
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::MagneticField(this->runner->sdfWorld->MagneticField()));
-
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- 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::RenderEngineServerApiBackend(
- this->runner->serverConfig.RenderEngineServerApiBackend()));
-
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::RenderEngineServerHeadless(
- this->runner->serverConfig.HeadlessRendering()));
-
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::RenderEngineGuiPlugin(
- this->runner->serverConfig.RenderEngineGui()));
-
- auto worldElem = this->runner->sdfWorld->Element();
-
- // Create Wind
- auto windEntity = this->runner->entityCompMgr.CreateEntity();
- this->runner->entityCompMgr.CreateComponent(windEntity, components::Wind());
- this->runner->entityCompMgr.CreateComponent(
- windEntity, components::WorldLinearVelocity(
- this->runner->sdfWorld->WindLinearVelocity()));
- // Initially the wind linear velocity is used as the seed velocity
- this->runner->entityCompMgr.CreateComponent(
- windEntity, components::WorldLinearVelocitySeed(
- this->runner->sdfWorld->WindLinearVelocity()));
-
- this->entityCreator->SetParent(windEntity, this->worldEntity);
-
- // scene
- if (this->runner->sdfWorld->Scene())
- {
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::Scene(*this->runner->sdfWorld->Scene()));
- }
-
- // atmosphere
- if (this->runner->sdfWorld->Atmosphere())
- {
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::Atmosphere(*this->runner->sdfWorld->Atmosphere()));
- }
-
- // spherical coordinates
- if (this->runner->sdfWorld->SphericalCoordinates())
- {
- this->runner->entityCompMgr.CreateComponent(this->worldEntity,
- components::SphericalCoordinates(
- *this->runner->sdfWorld->SphericalCoordinates()));
- }
-
// TODO(anyone) This should probably go somewhere else as it is a global
// constant.
const std::string kPluginName{"gz::sim"};
- sdf::ElementPtr pluginElem;
- // Get the gz::sim plugin element
- for (auto plugin = worldElem->FindElement("plugin"); plugin;
- plugin = plugin->GetNextElement("plugin"))
+ bool found = false;
+ for (const sdf::Plugin &plugin : _world.Plugins())
{
- if (plugin->Get("name") == kPluginName)
+ if (plugin.Name() == kPluginName)
{
- pluginElem = plugin;
+ this->ReadPerformers(plugin);
+ if (this->useLevels)
+ this->ReadLevels(plugin);
+ found = true;
break;
}
}
- if (pluginElem == nullptr)
- {
- if (this->useLevels)
- {
- gzerr << "Could not find a plugin tag with name " << kPluginName
- << ". Levels and distributed simulation will not work.\n";
- }
- }
- else
+ if (!found && this->useLevels)
{
- this->ReadPerformers(pluginElem);
- if (this->useLevels)
- this->ReadLevels(pluginElem);
+ gzerr << "Could not find a plugin tag with name " << kPluginName
+ << ". Levels and distributed simulation will not work.\n";
}
-
- this->ConfigureDefaultLevel();
-
- // Load world plugins.
- this->runner->EventMgr().Emit(this->worldEntity,
- this->runner->sdfWorld->Plugins());
-
- // Store the world's SDF DOM to be used when saving the world to file
- this->runner->entityCompMgr.CreateComponent(
- worldEntity, components::WorldSdf(*this->runner->sdfWorld));
}
/////////////////////////////////////////////////
-void LevelManager::ReadPerformers(const sdf::ElementPtr &_sdf)
+void LevelManager::ReadPerformers(const sdf::Plugin &_plugin)
{
GZ_PROFILE("LevelManager::ReadPerformers");
- if (_sdf == nullptr)
+ sdf::ElementPtr sdf = _plugin.ToElement();
+ if (sdf == nullptr)
return;
- if (_sdf->HasElement("performer"))
+ if (sdf->HasElement("performer"))
{
gzdbg << "Reading performer info\n";
- for (auto performer = _sdf->GetElement("performer"); performer;
+ for (auto performer = sdf->GetElement("performer"); performer;
performer = performer->GetNextElement("performer"))
{
auto name = performer->Get("name");
@@ -263,6 +132,7 @@ void LevelManager::ReadPerformers(const sdf::ElementPtr &_sdf)
Entity performerEntity = this->runner->entityCompMgr.CreateEntity();
// We use the ref to create a parent entity component later on
std::string ref = performer->GetElement("ref")->GetValue()->GetAsString();
+
if (this->performerMap.find(ref) == this->performerMap.end())
{
this->performerMap[ref] = performerEntity;
@@ -281,6 +151,8 @@ void LevelManager::ReadPerformers(const sdf::ElementPtr &_sdf)
geometry.Load(performer->GetElement("geometry"));
this->runner->entityCompMgr.CreateComponent(performerEntity,
components::Performer());
+ this->runner->entityCompMgr.CreateComponent(performerEntity,
+ components::PerformerRef(ref));
this->runner->entityCompMgr.CreateComponent(performerEntity,
components::PerformerLevels());
this->runner->entityCompMgr.CreateComponent(performerEntity,
@@ -288,8 +160,9 @@ void LevelManager::ReadPerformers(const sdf::ElementPtr &_sdf)
this->runner->entityCompMgr.CreateComponent(performerEntity,
components::Geometry(geometry));
- gzmsg << "Created performer [" << performerEntity << " / " << name << "]"
- << std::endl;
+ gzmsg << "Created performer. EntityId[" << performerEntity
+ << "] EntityName[" << name << "] Ref[" << ref << "]"
+ << std::endl;
}
}
@@ -380,16 +253,20 @@ bool LevelManager::OnSetPerformer(const msgs::StringMsg &_req,
}
/////////////////////////////////////////////////
-void LevelManager::ReadLevels(const sdf::ElementPtr &_sdf)
+void LevelManager::ReadLevels(const sdf::Plugin &_plugin)
{
GZ_PROFILE("LevelManager::ReadLevels");
gzdbg << "Reading levels info\n";
- if (_sdf == nullptr)
+ sdf::ElementPtr sdf = _plugin.ToElement();
+ if (sdf == nullptr)
+ return;
+
+ if (!sdf->HasElement("level"))
return;
- for (auto level = _sdf->GetElement("level"); level;
+ for (auto level = sdf->GetElement("level"); level;
level = level->GetNextElement("level"))
{
auto name = level->Get("name");
@@ -440,7 +317,15 @@ void LevelManager::ReadLevels(const sdf::ElementPtr &_sdf)
this->runner->entityCompMgr.CreateComponent(
levelEntity, components::LevelBuffer(buffer));
- this->entityCreator->SetParent(levelEntity, this->worldEntity);
+ auto worldEntity =
+ this->runner->entityCompMgr.EntityByComponents(components::World());
+
+ // All levels start inactive and unloaded.
+ this->UnloadLevel(levelEntity);
+ this->entityCreator->SetParent(levelEntity, worldEntity);
+
+ gzdbg << "Created level with name[" << name << "] and pose["
+ << pose << "]\n";
}
}
@@ -460,11 +345,17 @@ void LevelManager::ConfigureDefaultLevel()
// Models
for (uint64_t modelIndex = 0;
- modelIndex < this->runner->sdfWorld->ModelCount(); ++modelIndex)
+ modelIndex < this->runner->sdfWorld.ModelCount(); ++modelIndex)
{
// There is no sdf::World::ModelByName so we have to iterate by index and
// check if the model is in this level
- auto model = this->runner->sdfWorld->ModelByIndex(modelIndex);
+ auto model = this->runner->sdfWorld.ModelByIndex(modelIndex);
+ if (!this->useLevels)
+ {
+ entityNamesInDefault.insert(model->Name());
+ continue;
+ }
+
// If model is a performer, it will be handled separately
if (this->performerMap.find(model->Name()) != this->performerMap.end())
{
@@ -480,11 +371,18 @@ void LevelManager::ConfigureDefaultLevel()
// Actors
for (uint64_t actorIndex = 0;
- actorIndex < this->runner->sdfWorld->ActorCount(); ++actorIndex)
+ actorIndex < this->runner->sdfWorld.ActorCount(); ++actorIndex)
{
// There is no sdf::World::ActorByName so we have to iterate by index and
// check if the actor is in this level
- auto actor = this->runner->sdfWorld->ActorByIndex(actorIndex);
+ auto actor = this->runner->sdfWorld.ActorByIndex(actorIndex);
+
+ if (!this->useLevels)
+ {
+ entityNamesInDefault.insert(actor->Name());
+ continue;
+ }
+
// If actor is a performer, it will be handled separately
if (this->performerMap.find(actor->Name()) != this->performerMap.end())
{
@@ -501,9 +399,9 @@ void LevelManager::ConfigureDefaultLevel()
// Lights
// We assume no performers are lights
for (uint64_t lightIndex = 0;
- lightIndex < this->runner->sdfWorld->LightCount(); ++lightIndex)
+ lightIndex < this->runner->sdfWorld.LightCount(); ++lightIndex)
{
- auto light = this->runner->sdfWorld->LightByIndex(lightIndex);
+ auto light = this->runner->sdfWorld.LightByIndex(lightIndex);
if (this->entityNamesInLevels.find(light->Name()) ==
this->entityNamesInLevels.end())
{
@@ -514,11 +412,12 @@ void LevelManager::ConfigureDefaultLevel()
// Joints
// We assume no performers are joints
for (uint64_t jointIndex = 0;
- jointIndex < this->runner->sdfWorld->JointCount(); ++jointIndex)
+ jointIndex < this->runner->sdfWorld.JointCount(); ++jointIndex)
{
- auto joint = this->runner->sdfWorld->JointByIndex(jointIndex);
+ auto joint = this->runner->sdfWorld.JointByIndex(jointIndex);
- if (this->entityNamesInLevels.find(joint->Name()) ==
+ if (
+ this->entityNamesInLevels.find(joint->Name()) ==
this->entityNamesInLevels.end())
{
entityNamesInDefault.insert(joint->Name());
@@ -530,57 +429,15 @@ void LevelManager::ConfigureDefaultLevel()
defaultLevel, components::Level());
this->runner->entityCompMgr.CreateComponent(
defaultLevel, components::DefaultLevel());
+ this->runner->entityCompMgr.CreateComponent(
+ defaultLevel, components::Name("default"));
this->runner->entityCompMgr.CreateComponent(
defaultLevel, components::LevelEntityNames(entityNamesInDefault));
- this->entityCreator->SetParent(defaultLevel, this->worldEntity);
-}
-
-/////////////////////////////////////////////////
-void LevelManager::CreatePerformers()
-{
- GZ_PROFILE("LevelManager::CreatePerformers");
-
- if (this->worldEntity == kNullEntity)
- {
- gzerr << "Could not find the world entity while creating performers\n";
- return;
- }
- // Models
- for (uint64_t modelIndex = 0;
- modelIndex < this->runner->sdfWorld->ModelCount(); ++modelIndex)
- {
- auto model = this->runner->sdfWorld->ModelByIndex(modelIndex);
- if (this->performerMap.find(model->Name()) != this->performerMap.end())
- {
- Entity modelEntity = this->entityCreator->CreateEntities(model);
-
- // Make the model a parent of this performer
- this->entityCreator->SetParent(this->performerMap[model->Name()],
- modelEntity);
-
- // Add parent world to the model
- this->entityCreator->SetParent(modelEntity, this->worldEntity);
- }
- }
-
- // Actors
- for (uint64_t actorIndex = 0;
- actorIndex < this->runner->sdfWorld->ActorCount(); ++actorIndex)
- {
- auto actor = this->runner->sdfWorld->ActorByIndex(actorIndex);
- if (this->performerMap.find(actor->Name()) != this->performerMap.end())
- {
- Entity actorEntity = this->entityCreator->CreateEntities(actor);
-
- // Make the actor a parent of this performer
- this->entityCreator->SetParent(this->performerMap[actor->Name()],
- actorEntity);
+ auto worldEntity =
+ this->runner->entityCompMgr.EntityByComponents(components::World());
- // Add parent world to the actor
- this->entityCreator->SetParent(actorEntity, this->worldEntity);
- }
- }
+ this->entityCreator->SetParent(defaultLevel, worldEntity);
}
/////////////////////////////////////////////////
@@ -764,50 +621,27 @@ void LevelManager::UpdateLevelsState()
// Make a list of entity names to unload making sure to leave out the ones
// that have been marked to be loaded above
- std::set entityNamesToUnload;
- for (const auto &toUnload : levelsToUnload)
+ for (const Entity &toUnload : levelsToUnload)
{
- auto entityNames = this->runner->entityCompMgr
- .Component(toUnload)
- ->Data();
-
- for (const auto &name : entityNames)
- {
- if (entityNamesMarked.find(name) == entityNamesMarked.end())
- {
- entityNamesToUnload.insert(name);
- }
- }
+ this->UnloadLevel(toUnload, entityNamesMarked);
}
- // Load and unload the entities
+ // Load the entities
if (entityNamesToLoad.size() > 0)
- {
this->LoadActiveEntities(entityNamesToLoad);
- }
- if (entityNamesToUnload.size() > 0)
- {
- this->UnloadInactiveEntities(entityNamesToUnload);
- }
- // Finally, upadte the list of active levels
+ // Finally, update the list of active levels
for (const auto &level : levelsToLoad)
{
if (!this->IsLevelActive(level))
{
- gzmsg << "Loaded level [" << level << "]" << std::endl;
- this->activeLevels.push_back(level);
- }
- }
+ const components::Name *lvlName =
+ this->runner->entityCompMgr.Component(level);
- auto pendingEnd = this->activeLevels.end();
- for (const auto &toUnload : levelsToUnload)
- {
- gzmsg << "Unloaded level [" << toUnload << "]" << std::endl;
- pendingEnd = std::remove(this->activeLevels.begin(), pendingEnd, toUnload);
+ gzmsg << "Loaded level [" << lvlName->Data() << "]" << std::endl;
+ this->activeLevels.insert(level);
+ }
}
- // Erase from vector
- this->activeLevels.erase(pendingEnd, this->activeLevels.end());
}
/////////////////////////////////////////////////
@@ -815,7 +649,10 @@ void LevelManager::LoadActiveEntities(const std::set &_namesToLoad)
{
GZ_PROFILE("LevelManager::LoadActiveEntities");
- if (this->worldEntity == kNullEntity)
+ auto worldEntity =
+ this->runner->entityCompMgr.EntityByComponents(components::World());
+
+ if (worldEntity == kNullEntity)
{
gzerr << "Could not find the world entity while loading levels\n";
return;
@@ -823,57 +660,60 @@ void LevelManager::LoadActiveEntities(const std::set &_namesToLoad)
// Models
for (uint64_t modelIndex = 0;
- modelIndex < this->runner->sdfWorld->ModelCount(); ++modelIndex)
+ modelIndex < this->runner->sdfWorld.ModelCount(); ++modelIndex)
{
// There is no sdf::World::ModelByName so we have to iterate by index and
// check if the model is in this level
- auto model = this->runner->sdfWorld->ModelByIndex(modelIndex);
- if (_namesToLoad.find(model->Name()) != _namesToLoad.end())
+ auto model = this->runner->sdfWorld.ModelByIndex(modelIndex);
+ if (_namesToLoad.find(model->Name()) != _namesToLoad.end() &&
+ this->runner->EntityByName(model->Name()) == std::nullopt)
{
Entity modelEntity = this->entityCreator->CreateEntities(model);
- this->entityCreator->SetParent(modelEntity, this->worldEntity);
+ this->entityCreator->SetParent(modelEntity, worldEntity);
}
}
// Actors
for (uint64_t actorIndex = 0;
- actorIndex < this->runner->sdfWorld->ActorCount(); ++actorIndex)
+ actorIndex < this->runner->sdfWorld.ActorCount(); ++actorIndex)
{
// There is no sdf::World::ActorByName so we have to iterate by index and
// check if the actor is in this level
- auto actor = this->runner->sdfWorld->ActorByIndex(actorIndex);
- if (_namesToLoad.find(actor->Name()) != _namesToLoad.end())
+ auto actor = this->runner->sdfWorld.ActorByIndex(actorIndex);
+ if (_namesToLoad.find(actor->Name()) != _namesToLoad.end() &&
+ this->runner->EntityByName(actor->Name()) == std::nullopt)
{
Entity actorEntity = this->entityCreator->CreateEntities(actor);
- this->entityCreator->SetParent(actorEntity, this->worldEntity);
+ this->entityCreator->SetParent(actorEntity, worldEntity);
}
}
// Lights
for (uint64_t lightIndex = 0;
- lightIndex < this->runner->sdfWorld->LightCount(); ++lightIndex)
+ lightIndex < this->runner->sdfWorld.LightCount(); ++lightIndex)
{
- auto light = this->runner->sdfWorld->LightByIndex(lightIndex);
- if (_namesToLoad.find(light->Name()) != _namesToLoad.end())
+ auto light = this->runner->sdfWorld.LightByIndex(lightIndex);
+ if (_namesToLoad.find(light->Name()) != _namesToLoad.end() &&
+ this->runner->EntityByName(light->Name()) == std::nullopt)
{
Entity lightEntity = this->entityCreator->CreateEntities(light);
- this->entityCreator->SetParent(lightEntity, this->worldEntity);
+ this->entityCreator->SetParent(lightEntity, worldEntity);
}
}
// Joints
for (uint64_t jointIndex = 0;
- jointIndex < this->runner->sdfWorld->JointCount(); ++jointIndex)
+ jointIndex < this->runner->sdfWorld.JointCount(); ++jointIndex)
{
- auto joint = this->runner->sdfWorld->JointByIndex(jointIndex);
+ auto joint = this->runner->sdfWorld.JointByIndex(jointIndex);
if (_namesToLoad.find(joint->Name()) != _namesToLoad.end())
{
Entity jointEntity = this->entityCreator->CreateEntities(joint);
- this->entityCreator->SetParent(jointEntity, this->worldEntity);
+ this->entityCreator->SetParent(jointEntity, worldEntity);
}
}
@@ -938,8 +778,7 @@ void LevelManager::UnloadInactiveEntities(
/////////////////////////////////////////////////
bool LevelManager::IsLevelActive(const Entity _entity) const
{
- return std::find(this->activeLevels.begin(), this->activeLevels.end(),
- _entity) != this->activeLevels.end();
+ return this->activeLevels.find(_entity) != this->activeLevels.end();
}
/////////////////////////////////////////////////
@@ -982,3 +821,31 @@ int LevelManager::CreatePerformerEntity(const std::string &_name,
this->entityCreator->SetParent(this->performerMap[_name], modelEntity);
return 0;
}
+
+//////////////////////////////////////////////////
+void LevelManager::UnloadLevel(const Entity &_entity,
+ const std::set &_entityNamesMarked)
+{
+ auto entityNames = this->runner->entityCompMgr
+ .Component(_entity)
+ ->Data();
+
+ std::set entityNamesToUnload;
+ for (const auto &name : entityNames)
+ {
+ if (_entityNamesMarked.find(name) == _entityNamesMarked.end())
+ {
+ entityNamesToUnload.insert(name);
+ }
+ }
+
+ if (entityNamesToUnload.size() > 0)
+ {
+ this->UnloadInactiveEntities(entityNamesToUnload);
+ }
+ this->activeLevels.erase(_entity);
+ const components::Name *lvlName =
+ this->runner->entityCompMgr.Component(_entity);
+
+ gzmsg << "Unloaded level [" << lvlName->Data() << "]" << std::endl;
+}
diff --git a/src/LevelManager.hh b/src/LevelManager.hh
index 63e0466533..69e398bd90 100644
--- a/src/LevelManager.hh
+++ b/src/LevelManager.hh
@@ -88,6 +88,15 @@ namespace gz
/// every update cycle
public: void UpdateLevelsState();
+ /// \brief Read level and performer information from the sdf::World
+ /// object
+ /// \param[in] _world The SDF world
+ public: void ReadLevelPerformerInfo(const sdf::World &_world);
+
+ /// \brief Determine which entities belong to the default level and
+ /// schedule them to be loaded
+ public: void ConfigureDefaultLevel();
+
/// \brief Load entities that have been marked for loading.
/// \param[in] _namesToLoad List of of entity names to load
private: void LoadActiveEntities(
@@ -98,27 +107,15 @@ namespace gz
private: void UnloadInactiveEntities(
const std::set &_namesToUnload);
- /// \brief Read level and performer information from the sdf::World
- /// object
- private: void ReadLevelPerformerInfo();
-
- /// \brief Create performers
- /// Assuming that a simulation runner is performer-centered
- private: void CreatePerformers();
-
/// \brief Read information about performers from the sdf Element and
/// create performer entities
- /// \param[in] _sdf sdf::ElementPtr of the gz::sim plugin tag
- private: void ReadPerformers(const sdf::ElementPtr &_sdf);
+ /// \param[in] _plugin sdf::Plugin of the gz::sim plugin tag
+ private: void ReadPerformers(const sdf::Plugin &_plugin);
/// \brief Read information about levels from the sdf Element and
/// create level entities
- /// \param[in] _sdf sdf::ElementPtr of the gz::sim plugin tag
- private: void ReadLevels(const sdf::ElementPtr &_sdf);
-
- /// \brief Determine which entities belong to the default level and
- /// schedule them to be loaded
- private: void ConfigureDefaultLevel();
+ /// \param[in] _plugin sdf::Plugin of the gz::sim plugin tag
+ private: void ReadLevels(const sdf::Plugin &_plugin);
/// \brief Determine if a level is active
/// \param[in] _entity Entity of level to be checked
@@ -145,8 +142,11 @@ namespace gz
private: int CreatePerformerEntity(const std::string &_name,
const sdf::Geometry &_geom);
+ private: void UnloadLevel(const Entity &_entity,
+ const std::set &_entityNamesMarked = {});
+
/// \brief List of currently active levels
- private: std::vector activeLevels;
+ private: std::set activeLevels;
/// \brief Names of entities that are currently active (loaded).
private: std::set activeEntityNames;
@@ -161,9 +161,6 @@ namespace gz
/// \brief Names of all entities that have assigned levels
private: std::set entityNamesInLevels;
- /// \brief Entity of the world.
- private: Entity worldEntity{kNullEntity};
-
/// \brief Flag whether to use levels or not.
private: bool useLevels{false};
diff --git a/src/Link.cc b/src/Link.cc
index 4fef211baf..348923a44a 100644
--- a/src/Link.cc
+++ b/src/Link.cc
@@ -356,6 +356,18 @@ std::optional Link::WorldInertiaMatrix(
math::Inertiald(inertial->Data().MassMatrix(), comWorldPose).Moi());
}
+std::optional Link::WorldFluidAddedMassMatrix(
+ const EntityComponentManager &_ecm) const
+{
+ auto inertial = _ecm.Component(this->dataPtr->id);
+ auto worldPose = _ecm.Component(this->dataPtr->id);
+
+ if (!worldPose || !inertial)
+ return std::nullopt;
+
+ return inertial->Data().FluidAddedMass();
+}
+
//////////////////////////////////////////////////
std::optional Link::WorldKineticEnergy(
const EntityComponentManager &_ecm) const
diff --git a/src/Model.cc b/src/Model.cc
index a23779981f..01f4538fb7 100644
--- a/src/Model.cc
+++ b/src/Model.cc
@@ -148,6 +148,16 @@ Entity Model::LinkByName(const EntityComponentManager &_ecm,
components::Link());
}
+//////////////////////////////////////////////////
+Entity Model::ModelByName(const EntityComponentManager &_ecm,
+ const std::string &_name) const
+{
+ return _ecm.EntityByComponents(
+ components::ParentEntity(this->dataPtr->id),
+ components::Name(_name),
+ components::Model());
+}
+
//////////////////////////////////////////////////
std::vector Model::Joints(const EntityComponentManager &_ecm) const
{
@@ -184,6 +194,12 @@ uint64_t Model::LinkCount(const EntityComponentManager &_ecm) const
return this->Links(_ecm).size();
}
+//////////////////////////////////////////////////
+uint64_t Model::ModelCount(const EntityComponentManager &_ecm) const
+{
+ return this->Models(_ecm).size();
+}
+
//////////////////////////////////////////////////
void Model::SetWorldPoseCmd(EntityComponentManager &_ecm,
const math::Pose3d &_pose)
diff --git a/src/ModelCommandAPI_TEST.cc b/src/ModelCommandAPI_TEST.cc
index 95f5b8b4a4..36e088680a 100644
--- a/src/ModelCommandAPI_TEST.cc
+++ b/src/ModelCommandAPI_TEST.cc
@@ -608,7 +608,7 @@ TEST(ModelCommandAPI, GZ_UTILS_TEST_DISABLED_ON_MAC(RgbdCameraSensor))
// Run without blocking.
server.Run(false, 0, false);
- // Tested command: gz model -m altimeter_mode -l link -s altimeter_sensor
+ // Tested command: gz model -m rgbd_camera -l rgbd_camera_link -s rgbd_camera
{
const std::string cmd = kGzModelCommand
+ "-m rgbd_camera -l rgbd_camera_link -s rgbd_camera";
@@ -657,7 +657,7 @@ TEST(ModelCommandAPI, GZ_UTILS_TEST_DISABLED_ON_MAC(RgbdCameraSensor))
" - Lens intrinsics Fy: 277\n"
" - Lens intrinsics Cx: 160\n"
" - Lens intrinsics Cy: 120\n"
- " - Lens intrinsics skew: 1\n"
+ " - Lens intrinsics skew: 0\n"
" - Visibility mask: 4294967295\n";
EXPECT_EQ(expectedOutput, output);
}
diff --git a/src/Primitives.cc b/src/Primitives.cc
index 4fa93cea54..fcb7f65942 100644
--- a/src/Primitives.cc
+++ b/src/Primitives.cc
@@ -104,6 +104,49 @@ constexpr const char * kSphereSdf = R"(
)";
+/////////////////////////////////////////////////
+constexpr const char * kConeSdf = R"(
+
+
+ 0 0 0.5 0 0 0
+
+
+
+ 0.075
+ 0
+ 0
+ 0.075
+ 0
+ 0.075
+
+ 1.0
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+ 0.3 0.3 0.3 1
+ 0.7 0.7 0.7 1
+ 1 1 1 1
+
+
+
+
+
+)";
+
/////////////////////////////////////////////////
constexpr const char * kCylinderSdf = R"(
@@ -301,6 +344,8 @@ std::string gz::sim::getPrimitiveShape(const PrimitiveShape &_type)
return kBoxSdf;
case PrimitiveShape::kSphere:
return kSphereSdf;
+ case PrimitiveShape::kCone:
+ return kConeSdf;
case PrimitiveShape::kCylinder:
return kCylinderSdf;
case PrimitiveShape::kCapsule:
@@ -339,6 +384,8 @@ std::string gz::sim::getPrimitive(const std::string &_typeName)
return getPrimitiveShape(PrimitiveShape::kSphere);
else if (type == "cylinder")
return getPrimitiveShape(PrimitiveShape::kCylinder);
+ else if (type == "cone")
+ return getPrimitiveShape(PrimitiveShape::kCone);
else if (type == "capsule")
return getPrimitiveShape(PrimitiveShape::kCapsule);
else if (type == "ellipsoid")
@@ -354,6 +401,7 @@ std::string gz::sim::getPrimitive(const std::string &_typeName)
gzwarn << "The valid options are:\n";
gzwarn << " - box\n";
gzwarn << " - sphere\n";
+ gzwarn << " - cone\n";
gzwarn << " - cylinder\n";
gzwarn << " - capsule\n";
gzwarn << " - ellipsoid\n";
diff --git a/src/SdfEntityCreator.cc b/src/SdfEntityCreator.cc
index f4b693533b..2c258c1ad8 100644
--- a/src/SdfEntityCreator.cc
+++ b/src/SdfEntityCreator.cc
@@ -15,12 +15,15 @@
*
*/
+#include
+
#include
#include
#include
#include "gz/sim/Events.hh"
#include "gz/sim/SdfEntityCreator.hh"
+#include "gz/sim/Util.hh"
#include "gz/sim/components/Actor.hh"
#include "gz/sim/components/AirPressureSensor.hh"
@@ -47,11 +50,14 @@
#include "gz/sim/components/JointAxis.hh"
#include "gz/sim/components/JointType.hh"
#include "gz/sim/components/LaserRetro.hh"
+#include "gz/sim/components/Level.hh"
+#include "gz/sim/components/LevelEntityNames.hh"
#include "gz/sim/components/Lidar.hh"
#include "gz/sim/components/Light.hh"
#include "gz/sim/components/LightType.hh"
#include "gz/sim/components/LinearAcceleration.hh"
#include "gz/sim/components/LinearVelocity.hh"
+#include "gz/sim/components/LinearVelocitySeed.hh"
#include "gz/sim/components/Link.hh"
#include "gz/sim/components/LogicalCamera.hh"
#include "gz/sim/components/MagneticField.hh"
@@ -62,8 +68,10 @@
#include "gz/sim/components/NavSat.hh"
#include "gz/sim/components/ParentEntity.hh"
#include "gz/sim/components/ParentLinkName.hh"
-#include
+#include "gz/sim/components/ParticleEmitter.hh"
+#include "gz/sim/components/Performer.hh"
#include "gz/sim/components/Physics.hh"
+#include "gz/sim/components/PhysicsEnginePlugin.hh"
#include "gz/sim/components/Pose.hh"
#include
#include "gz/sim/components/RgbdCamera.hh"
@@ -81,10 +89,12 @@
#include "gz/sim/components/Visibility.hh"
#include "gz/sim/components/Visual.hh"
#include "gz/sim/components/WideAngleCamera.hh"
+#include "gz/sim/components/Wind.hh"
#include "gz/sim/components/WindMode.hh"
#include "gz/sim/components/World.hh"
#include "rendering/MaterialParser/MaterialParser.hh"
+#include "ServerPrivate.hh"
class gz::sim::SdfEntityCreatorPrivate
{
@@ -228,34 +238,85 @@ SdfEntityCreator &SdfEntityCreator::operator=(SdfEntityCreator &&_creator)
//////////////////////////////////////////////////
Entity SdfEntityCreator::CreateEntities(const sdf::World *_world)
{
- GZ_PROFILE("SdfEntityCreator::CreateEntities(sdf::World)");
-
// World entity
Entity worldEntity = this->dataPtr->ecm->CreateEntity();
- // World components
- this->dataPtr->ecm->CreateComponent(worldEntity, components::World());
- this->dataPtr->ecm->CreateComponent(worldEntity,
+ this->CreateEntities(_world, worldEntity);
+ return worldEntity;
+}
+
+//////////////////////////////////////////////////
+void SdfEntityCreator::CreateEntities(const sdf::World *_world,
+ Entity _worldEntity)
+{
+ GZ_PROFILE("SdfEntityCreator::CreateEntities(sdf::World)");
+
+ if (!this->dataPtr->ecm->EntityHasComponentType(
+ _worldEntity, components::World::typeId))
+ {
+ this->dataPtr->ecm->CreateComponent(_worldEntity, components::World());
+ }
+
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
components::Name(_world->Name()));
+ // Gravity
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
+ components::Gravity(_world->Gravity()));
+
+ // MagneticField
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
+ components::MagneticField(_world->MagneticField()));
+
+ // Create Wind
+ auto windEntity = this->dataPtr->ecm->CreateEntity();
+ this->SetParent(windEntity, _worldEntity);
+ this->dataPtr->ecm->CreateComponent(windEntity, components::Wind());
+ this->dataPtr->ecm->CreateComponent(windEntity,
+ components::WorldLinearVelocity(_world->WindLinearVelocity()));
+ // Initially the wind linear velocity is used as the seed velocity
+ this->dataPtr->ecm->CreateComponent(windEntity,
+ components::WorldLinearVelocitySeed(_world->WindLinearVelocity()));
+
+ // Set the parent of each level to the world
+ this->dataPtr->ecm->Each([&](
+ const Entity &_entity,
+ const components::Level *) -> bool
+ {
+ this->SetParent(_entity, _worldEntity);
+ return true;
+ });
+
+ // Get the entities that should be loaded based on level information.
+ std::set levelEntityNames;
+ this->dataPtr->ecm->Each ([&](
+ const Entity &,
+ const components::DefaultLevel *,
+ const components::LevelEntityNames *_names) -> bool
+ {
+ levelEntityNames = _names->Data();
+ return true;
+ });
+
// scene
if (_world->Scene())
{
- this->dataPtr->ecm->CreateComponent(worldEntity,
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
components::Scene(*_world->Scene()));
}
// atmosphere
if (_world->Atmosphere())
{
- this->dataPtr->ecm->CreateComponent(worldEntity,
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
components::Atmosphere(*_world->Atmosphere()));
}
// spherical coordinates
if (_world->SphericalCoordinates())
{
- this->dataPtr->ecm->CreateComponent(worldEntity,
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
components::SphericalCoordinates(*_world->SphericalCoordinates()));
}
@@ -263,35 +324,84 @@ Entity SdfEntityCreator::CreateEntities(const sdf::World *_world)
for (uint64_t modelIndex = 0; modelIndex < _world->ModelCount();
++modelIndex)
{
- auto model = _world->ModelByIndex(modelIndex);
- auto modelEntity = this->CreateEntities(model);
+ const sdf::Model *model = _world->ModelByIndex(modelIndex);
+ if (levelEntityNames.empty() ||
+ levelEntityNames.find(model->Name()) != levelEntityNames.end())
- this->SetParent(modelEntity, worldEntity);
+ {
+ Entity modelEntity = this->CreateEntities(model, false);
+
+ this->SetParent(modelEntity, _worldEntity);
+ }
}
// Actors
for (uint64_t actorIndex = 0; actorIndex < _world->ActorCount();
++actorIndex)
{
- auto actor = _world->ActorByIndex(actorIndex);
- auto actorEntity = this->CreateEntities(actor);
-
- this->SetParent(actorEntity, worldEntity);
+ const sdf::Actor *actor = _world->ActorByIndex(actorIndex);
+ if (levelEntityNames.empty() ||
+ levelEntityNames.find(actor->Name()) != levelEntityNames.end())
+ {
+ Entity actorEntity = this->CreateEntities(actor);
+ this->SetParent(actorEntity, _worldEntity);
+ }
}
// Lights
for (uint64_t lightIndex = 0; lightIndex < _world->LightCount();
++lightIndex)
{
- auto light = _world->LightByIndex(lightIndex);
- auto lightEntity = this->CreateEntities(light);
+ const sdf::Light *light = _world->LightByIndex(lightIndex);
+ if (levelEntityNames.empty() ||
+ levelEntityNames.find(light->Name()) != levelEntityNames.end())
+ {
+ Entity lightEntity = this->CreateEntities(light);
- this->SetParent(lightEntity, worldEntity);
+ this->SetParent(lightEntity, _worldEntity);
+ }
}
- // Gravity
- this->dataPtr->ecm->CreateComponent(worldEntity,
- components::Gravity(_world->Gravity()));
+ // Attach performers to their parent entity
+ this->dataPtr->ecm->Each<
+ components::Performer,
+ components::PerformerRef>([&](
+ const Entity &_entity,
+ const components::Performer *,
+ const components::PerformerRef *_ref) -> bool
+ {
+ std::optional parentEntity =
+ this->dataPtr->ecm->EntityByName(_ref->Data());
+ if (!parentEntity)
+ {
+ // Performers have not been created yet. Try to create the model
+ // or actor and attach the peformer.
+ if (_world->ModelNameExists(_ref->Data()))
+ {
+ const sdf::Model *model = _world->ModelByName(_ref->Data());
+ Entity modelEntity = this->CreateEntities(model, false);
+ this->SetParent(modelEntity, _worldEntity);
+ this->SetParent(_entity, modelEntity);
+ }
+ else if (_world->ActorNameExists(_ref->Data()))
+ {
+ const sdf::Actor *actor = _world->ActorByName(_ref->Data());
+ Entity actorEntity = this->CreateEntities(actor);
+ this->SetParent(actorEntity, _worldEntity);
+ this->SetParent(_entity, actorEntity);
+ }
+ else
+ {
+ gzerr << "Unable to find performer parent entity with name[" <<
+ _ref->Data() << "]. This performer will not adhere to levels.\n";
+ }
+ }
+ else
+ {
+ this->SetParent(_entity, *parentEntity);
+ }
+ return true;
+ });
// Physics
// \todo(anyone) Support picking a specific physics profile
@@ -300,46 +410,56 @@ Entity SdfEntityCreator::CreateEntities(const sdf::World *_world)
{
physics = _world->PhysicsDefault();
}
- this->dataPtr->ecm->CreateComponent(worldEntity,
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
components::Physics(*physics));
// Populate physics options that aren't accessible outside the Element()
// See https://github.com/osrf/sdformat/issues/508
- if (physics->Element() && physics->Element()->HasElement("dart"))
+ if (physics->Element())
{
- auto dartElem = physics->Element()->GetElement("dart");
-
- if (dartElem->HasElement("collision_detector"))
+ if (auto dartElem = physics->Element()->FindElement("dart"))
{
- auto collisionDetector =
- dartElem->Get("collision_detector");
+ if (dartElem->HasElement("collision_detector"))
+ {
+ auto collisionDetector =
+ dartElem->Get("collision_detector");
- this->dataPtr->ecm->CreateComponent(worldEntity,
- components::PhysicsCollisionDetector(collisionDetector));
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
+ components::PhysicsCollisionDetector(collisionDetector));
+ }
+ if (auto solverElem = dartElem->FindElement("solver"))
+ {
+ if (solverElem->HasElement("solver_type"))
+ {
+ auto solver = solverElem->Get("solver_type");
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
+ components::PhysicsSolver(solver));
+ }
+ }
}
- if (dartElem->HasElement("solver") &&
- dartElem->GetElement("solver")->HasElement("solver_type"))
+ if (auto bulletElem = physics->Element()->FindElement("bullet"))
{
- auto solver =
- dartElem->GetElement("solver")->Get("solver_type");
-
- this->dataPtr->ecm->CreateComponent(worldEntity,
- components::PhysicsSolver(solver));
+ if (auto solverElem = bulletElem->FindElement("solver"))
+ {
+ if (solverElem->HasElement("iters"))
+ {
+ uint32_t solverIterations = solverElem->Get("iters");
+ this->dataPtr->ecm->CreateComponent(_worldEntity,
+ components::PhysicsSolverIterations(solverIterations));
+ }
+ }
}
}
- // MagneticField
- this->dataPtr->ecm->CreateComponent(worldEntity,
- components::MagneticField(_world->MagneticField()));
-
- this->dataPtr->eventManager->Emit(worldEntity,
- _world->Plugins());
-
// Store the world's SDF DOM to be used when saving the world to file
this->dataPtr->ecm->CreateComponent(
- worldEntity, components::WorldSdf(*_world));
+ _worldEntity, components::WorldSdf(*_world));
- return worldEntity;
+ this->dataPtr->eventManager->Emit(_worldEntity,
+ _world->Plugins());
+
+ // Load model plugins after the world plugin.
+ this->LoadModelPlugins();
}
//////////////////////////////////////////////////
@@ -350,6 +470,14 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model)
auto ent = this->CreateEntities(_model, false);
// Load all model plugins afterwards, so we get scoped name for nested models.
+ this->LoadModelPlugins();
+
+ return ent;
+}
+
+//////////////////////////////////////////////////
+void SdfEntityCreator::LoadModelPlugins()
+{
for (const auto &[entity, plugins] : this->dataPtr->newModels)
{
this->dataPtr->eventManager->Emit(entity, plugins);
@@ -369,8 +497,6 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Model *_model)
this->dataPtr->eventManager->Emit(entity, plugins);
}
this->dataPtr->newVisuals.clear();
-
- return ent;
}
//////////////////////////////////////////////////
@@ -572,6 +698,13 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Link *_link)
linkEntity, components::WindMode(_link->EnableWind()));
}
+ if (!_link->EnableGravity())
+ {
+ // If disable gravity, create a GravityEnabled component to the entity
+ this->dataPtr->ecm->CreateComponent(
+ linkEntity, components::GravityEnabled(false));
+ }
+
// Visuals
for (uint64_t visualIndex = 0; visualIndex < _link->VisualCount();
++visualIndex)
@@ -801,7 +934,8 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Visual *_visual)
"https://gazebosim.org/api/sim/8/migrationsdf.html#:~:text=Materials " <<
"for details." << std::endl;
std::string scriptUri = visualMaterial.ScriptUri();
- if (scriptUri != "file://media/materials/scripts/gazebo.material") {
+ if (scriptUri != ServerPrivate::kClassicMaterialScriptUri)
+ {
gzwarn << "Custom material scripts are not supported."
<< std::endl;
}
@@ -871,9 +1005,27 @@ Entity SdfEntityCreator::CreateEntities(const sdf::ParticleEmitter *_emitter)
// Entity
Entity emitterEntity = this->dataPtr->ecm->CreateEntity();
+ auto particleEmitterMsg = convert(*_emitter);
+
+ // Update image path
+ // Ideally this is done by gz/sim/src/SceneManager.cc when creating
+ // the particle emitter. However the component stores a msg instead of
+ // an sdf so the sdf FilePath information is lost and rendering is not
+ // able to construct the full path of the image.
+ // \todo(iche033) Consider changing the ParticleEmitter component to
+ // store an sdf::ParticleEmitter object instead of msgs::ParticleEmitter.
+ std::string imagePath = _emitter->ColorRangeImage();
+ if (!imagePath.empty())
+ {
+ std::string path = common::findFile(asFullPath(imagePath,
+ _emitter->Element()->FilePath()));
+ path = path.empty() ? imagePath : path;
+ particleEmitterMsg.mutable_color_range_image()->set_data(path);
+ }
+
// Components
this->dataPtr->ecm->CreateComponent(emitterEntity,
- components::ParticleEmitter(convert(*_emitter)));
+ components::ParticleEmitter(particleEmitterMsg));
this->dataPtr->ecm->CreateComponent(emitterEntity,
components::Pose(ResolveSdfPose(_emitter->SemanticPose())));
this->dataPtr->ecm->CreateComponent(emitterEntity,
diff --git a/src/SdfEntityCreator_TEST.cc b/src/SdfEntityCreator_TEST.cc
index d4cad99d84..e7f7527dc4 100644
--- a/src/SdfEntityCreator_TEST.cc
+++ b/src/SdfEntityCreator_TEST.cc
@@ -107,9 +107,9 @@ TEST_F(SdfEntityCreatorTest, CreateEntities)
EXPECT_TRUE(this->ecm.HasComponentType(components::LaserRetro::typeId));
// Check entities
- // 1 x world + 5 x model + 5 x link + 5 x collision + 5 x visual +
+ // 1 x world + 1 wind + 5 x model + 5 x link + 5 x collision + 5 x visual +
// 1 x light (light + visual)
- EXPECT_EQ(23u, this->ecm.EntityCount());
+ EXPECT_EQ(24u, this->ecm.EntityCount());
// Check worlds
unsigned int worldCount{0};
@@ -685,8 +685,9 @@ TEST_F(SdfEntityCreatorTest, CreateLights)
creator.CreateEntities(root.WorldByIndex(0));
// Check entities
- // 1 x world + 1 x model + 1 x link + 1 x visual + 4 x light (light + visual)
- EXPECT_EQ(12u, this->ecm.EntityCount());
+ // 1 x world + 1 wind + 1 x model + 1 x link + 1 x visual +
+ // 4 x light (light + visual)
+ EXPECT_EQ(13u, this->ecm.EntityCount());
// Check worlds
unsigned int worldCount{0};
@@ -1107,9 +1108,9 @@ TEST_F(SdfEntityCreatorTest, RemoveEntities)
creator.CreateEntities(root.WorldByIndex(0));
// Check entities
- // 1 x world + 4 x model + 4 x link + 4 x collision + 4 x visual
+ // 1 x world + 1 wind + 4 x model + 4 x link + 4 x collision + 4 x visual
// + 1 x light (light + visual)
- EXPECT_EQ(23u, this->ecm.EntityCount());
+ EXPECT_EQ(24u, this->ecm.EntityCount());
auto world = this->ecm.EntityByComponents(components::World());
EXPECT_NE(kNullEntity, world);
@@ -1135,7 +1136,7 @@ TEST_F(SdfEntityCreatorTest, RemoveEntities)
creator.RequestRemoveEntity(models.front());
this->ecm.ProcessEntityRemovals();
- EXPECT_EQ(19u, this->ecm.EntityCount());
+ EXPECT_EQ(20u, this->ecm.EntityCount());
models = this->ecm.ChildrenByComponents(world, components::Model());
ASSERT_EQ(4u, models.size());
@@ -1158,7 +1159,7 @@ TEST_F(SdfEntityCreatorTest, RemoveEntities)
creator.RequestRemoveEntity(models.front(), false);
this->ecm.ProcessEntityRemovals();
- EXPECT_EQ(18u, this->ecm.EntityCount());
+ EXPECT_EQ(19u, this->ecm.EntityCount());
// There's only 1 model left
models = this->ecm.ChildrenByComponents(world, components::Model());
diff --git a/src/Server.cc b/src/Server.cc
index 7aca6f33f3..712f273467 100644
--- a/src/Server.cc
+++ b/src/Server.cc
@@ -121,6 +121,7 @@ Server::Server(const ServerConfig &_config)
}
gzmsg << msg;
sdf::ParserConfig sdfParserConfig = sdf::ParserConfig::GlobalConfig();
+ sdfParserConfig.SetStoreResolvedURIs(true);
sdfParserConfig.SetCalculateInertialConfiguration(
sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD);
errors = this->dataPtr->sdfRoot.LoadSdfString(
@@ -145,6 +146,7 @@ Server::Server(const ServerConfig &_config)
sdf::Root sdfRoot;
sdf::ParserConfig sdfParserConfig = sdf::ParserConfig::GlobalConfig();
+ sdfParserConfig.SetStoreResolvedURIs(true);
sdfParserConfig.SetCalculateInertialConfiguration(
sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD);
@@ -156,7 +158,9 @@ Server::Server(const ServerConfig &_config)
// a black screen (search for "Async resource download" in
// 'src/gui_main.cc'.
errors = sdfRoot.Load(filePath, sdfParserConfig);
- if (errors.empty()) {
+ if (errors.empty() || _config.BehaviorOnSdfErrors() !=
+ ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY)
+ {
if (sdfRoot.Model() == nullptr) {
this->dataPtr->sdfRoot = std::move(sdfRoot);
}
@@ -171,7 +175,9 @@ Server::Server(const ServerConfig &_config)
return;
}
world->AddModel(*sdfRoot.Model());
- if (errors.empty()) {
+ if (errors.empty() || _config.BehaviorOnSdfErrors() !=
+ ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY)
+ {
errors = this->dataPtr->sdfRoot.UpdateGraphs();
}
}
@@ -196,7 +202,11 @@ Server::Server(const ServerConfig &_config)
{
for (auto &err : errors)
gzerr << err << "\n";
- return;
+ if (_config.BehaviorOnSdfErrors() ==
+ ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY)
+ {
+ return;
+ }
}
// Add record plugin
@@ -205,6 +215,11 @@ Server::Server(const ServerConfig &_config)
this->dataPtr->AddRecordPlugin(_config);
}
+ // If we've received a signal before we create entities, the Stop event
+ // won't be propagated to them. Instead, we just quit early here.
+ if (this->dataPtr->signalReceived)
+ return;
+
this->dataPtr->CreateEntities();
// Set the desired update period, this will override the desired RTF given in
diff --git a/src/ServerConfig.cc b/src/ServerConfig.cc
index b8a33fd965..c3562a77fb 100644
--- a/src/ServerConfig.cc
+++ b/src/ServerConfig.cc
@@ -168,9 +168,13 @@ class gz::sim::ServerConfigPrivate
this->timestamp = GZ_SYSTEM_TIME();
+ std::string timeInIso = common::timeToIso(this->timestamp);
+ #ifdef _WIN32
+ std::replace(timeInIso.begin(), timeInIso.end(), ':', '-');
+ #endif
// Set a default log record path
this->logRecordPath = common::joinPaths(home,
- ".gz", "sim", "log", common::timeToIso(this->timestamp));
+ ".gz", "sim", "log", timeInIso);
// If directory already exists, do not overwrite. This could potentially
// happen if multiple simulation instances are started in rapid
@@ -208,7 +212,8 @@ class gz::sim::ServerConfigPrivate
seed(_cfg->seed),
logRecordTopics(_cfg->logRecordTopics),
isHeadlessRendering(_cfg->isHeadlessRendering),
- source(_cfg->source){ }
+ source(_cfg->source),
+ behaviorOnSdfErrors(_cfg->behaviorOnSdfErrors){ }
// \brief The SDF file that the server should load
public: std::string sdfFile = "";
@@ -292,6 +297,10 @@ class gz::sim::ServerConfigPrivate
/// \brief Type of source used.
public: ServerConfig::SourceType source{ServerConfig::SourceType::kNone};
+
+ /// \brief Server loading behavior in presence of SDF errors.
+ public: ServerConfig::SdfErrorBehavior behaviorOnSdfErrors{
+ ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY};
};
//////////////////////////////////////////////////
@@ -598,6 +607,19 @@ const std::string &ServerConfig::RenderEngineGuiApiBackend() const
return this->dataPtr->renderEngineGuiApiBackend;
}
+//////////////////////////////////////////////////
+void ServerConfig::SetBehaviorOnSdfErrors(
+ ServerConfig::SdfErrorBehavior _behavior)
+{
+ this->dataPtr->behaviorOnSdfErrors = _behavior;
+}
+
+//////////////////////////////////////////////////
+ServerConfig::SdfErrorBehavior ServerConfig::BehaviorOnSdfErrors() const
+{
+ return this->dataPtr->behaviorOnSdfErrors;
+}
+
/////////////////////////////////////////////////
void ServerConfig::AddPlugin(const ServerConfig::PluginInfo &_info)
{
@@ -906,19 +928,6 @@ sim::loadPluginInfo(bool _isPlayback)
envConfig,
true);
- if (!configSet)
- {
- configSet = common::env("IGN_GAZEBO_SERVER_CONFIG_PATH",
- envConfig,
- true);
- if (configSet)
- {
- gzwarn << "Config path found using deprecated environment variable "
- << "[IGN_GAZEBO_SERVER_CONFIG_PATH]. Please use "
- << "[GZ_SIM_SERVER_CONFIG_PATH] instead" << std::endl;
- }
- }
-
if (configSet)
{
if (common::exists(envConfig))
@@ -933,7 +942,7 @@ sim::loadPluginInfo(bool _isPlayback)
gzwarn << kServerConfigPathEnv
<< " set but no plugins found\n";
}
- gzdbg << "Loaded (" << ret.size() << ") plugins from file " <<
+ gzdbg << "Loading (" << ret.size() << ") plugins from file " <<
"[" << envConfig << "]\n";
return ret;
@@ -1013,7 +1022,7 @@ sim::loadPluginInfo(bool _isPlayback)
<< "], but no plugins found\n";
}
- gzdbg << "Loaded (" << ret.size() << ") plugins from file " <<
+ gzdbg << "Loading (" << ret.size() << ") plugins from file " <<
"[" << defaultConfig << "]\n";
return ret;
diff --git a/src/ServerPrivate.cc b/src/ServerPrivate.cc
index 80df07819e..83b97363e6 100644
--- a/src/ServerPrivate.cc
+++ b/src/ServerPrivate.cc
@@ -37,6 +37,9 @@
using namespace gz;
using namespace sim;
+const char ServerPrivate::kClassicMaterialScriptUri[] =
+ "file://media/materials/scripts/gazebo.material";
+
/// \brief This struct provides access to the record plugin SDF string
struct LoggingPlugin
{
@@ -112,13 +115,26 @@ ServerPrivate::~ServerPrivate()
//////////////////////////////////////////////////
void ServerPrivate::OnSignal(int _sig)
{
- gzdbg << "Server received signal[" << _sig << "]\n";
- this->Stop();
+ // There's a good chance that objects are being destructed from the previous
+ // signal, so it's not safe to call Stop if we've done it already.
+ if (!this->signalReceived)
+ {
+ this->signalReceived = true;
+ gzdbg << "Server received signal[" << _sig << "]\n";
+ this->Stop();
+ }
}
/////////////////////////////////////////////////
void ServerPrivate::Stop()
{
+ // Stop might be called from the signal handler thread (new in Ionic) instead
+ // of the main thread, so we need to ensure that we keep `ServerPrivate` alive
+ // while the signal handler is still active. We do that by synchronizing on
+ // the `runMutex` here in ServerPrivate::Run right after the call
+ // SimulationRunner::Run returns. That way, `ServerPrivate::Run` cannot return
+ // before the signal handler is finished.
+ std::lock_guard lock(this->runMutex);
this->running = false;
for (std::unique_ptr &runner : this->simRunners)
{
@@ -130,6 +146,13 @@ void ServerPrivate::Stop()
bool ServerPrivate::Run(const uint64_t _iterations,
std::optional _cond)
{
+ // Return early if we've received a signal right before.
+ // The ServerPrivate signal handler would set `running=false`,
+ // but we immediately would set it to true here, which will essentially ignore
+ // the signal. Since we can't reliably use the `running` variable, we return
+ // if `signalReceived` is true
+ if (this->signalReceived)
+ return false;
this->runMutex.lock();
this->running = true;
if (_cond)
@@ -185,6 +208,8 @@ bool ServerPrivate::Run(const uint64_t _iterations,
result = this->workerPool.WaitForResults();
}
+ // See comments ServerPrivate::Stop() for why we lock this mutex here.
+ std::lock_guard lock(this->runMutex);
this->running = false;
return result;
}
@@ -286,14 +311,14 @@ void ServerPrivate::CreateEntities()
for (uint64_t worldIndex = 0; worldIndex <
this->sdfRoot.WorldCount(); ++worldIndex)
{
- auto world = this->sdfRoot.WorldByIndex(worldIndex);
+ sdf::World *world = this->sdfRoot.WorldByIndex(worldIndex);
{
std::lock_guard lock(this->worldsMutex);
this->worldNames.push_back(world->Name());
}
auto runner = std::make_unique(
- world, this->systemLoader, this->config);
+ *world, this->systemLoader, this->config);
runner->SetFuelUriMap(this->fuelUriMap);
this->simRunners.push_back(std::move(runner));
}
@@ -546,6 +571,12 @@ bool ServerPrivate::ResourcePathsResolveService(
//////////////////////////////////////////////////
std::string ServerPrivate::FetchResource(const std::string &_uri)
{
+ // Handle gazebo classic material URIs.
+ // Return original URI string as the SdfEntityCreator checks for this URI
+ if (_uri == kClassicMaterialScriptUri)
+ return _uri;
+
+ // Fetch resource from fuel
auto path =
fuel_tools::fetchResourceWithClient(_uri, *this->fuelClient.get());
diff --git a/src/ServerPrivate.hh b/src/ServerPrivate.hh
index 03128c56e8..7a2ad69344 100644
--- a/src/ServerPrivate.hh
+++ b/src/ServerPrivate.hh
@@ -169,6 +169,10 @@ namespace gz
/// \brief Our signal handler.
public: gz::common::SignalHandler sigHandler;
+ /// \brief Set to true from signal handler. This will be used to
+ /// terminate the server where checking `running` is not sufficient.
+ public: std::atomic signalReceived{false};
+
/// \brief Our system loader.
public: SystemLoaderPtr systemLoader;
@@ -187,6 +191,11 @@ namespace gz
/// Server. It is used in the SDFormat world generator when saving worlds
public: std::unordered_map fuelUriMap;
+ /// \brief Gazebo classic material URI string
+ /// A URI matching this string indicates that it is a gazebo classic
+ /// material.
+ public: static const char kClassicMaterialScriptUri[];
+
/// \brief List of names for all worlds loaded in this server.
private: std::vector worldNames;
diff --git a/src/Server_Rendering_TEST.cc b/src/Server_Rendering_TEST.cc
index b82b0690ee..bad8c2d323 100644
--- a/src/Server_Rendering_TEST.cc
+++ b/src/Server_Rendering_TEST.cc
@@ -130,7 +130,10 @@ TEST_F(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_MAC(LoadSdfModelRelativeUri))
};
gz::sim::ServerConfig serverConfig;
-
+ serverConfig.SetBehaviorOnSdfErrors(
+ ServerConfig::SdfErrorBehavior::CONTINUE_LOADING);
+ EXPECT_EQ(ServerConfig::SdfErrorBehavior::CONTINUE_LOADING,
+ serverConfig.BehaviorOnSdfErrors());
serverConfig.SetSdfFile(common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "models", "relative_resource_uri", "model2.sdf"));
@@ -162,4 +165,16 @@ TEST_F(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_MAC(LoadSdfModelRelativeUri))
}
ASSERT_TRUE(server.RunOnce());
ASSERT_TRUE(server.RunOnce(false));
+
+ // Tell server to stop loading if there are SDF errors
+ // Server should not load because V2's visual mesh URI can not be resolved
+ serverConfig.SetBehaviorOnSdfErrors(
+ ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY);
+ EXPECT_EQ(ServerConfig::SdfErrorBehavior::EXIT_IMMEDIATELY,
+ serverConfig.BehaviorOnSdfErrors());
+ sim::Server server2 = Server(serverConfig);
+ EXPECT_FALSE(server2.HasEntity("relative_resource_uri"));
+ EXPECT_FALSE(server2.HasEntity("L1"));
+ EXPECT_FALSE(server2.HasEntity("V1"));
+ EXPECT_FALSE(server2.HasEntity("V2"));
}
diff --git a/src/Server_TEST.cc b/src/Server_TEST.cc
index e2fba5e054..5f7697eeab 100644
--- a/src/Server_TEST.cc
+++ b/src/Server_TEST.cc
@@ -481,6 +481,7 @@ TEST_P(ServerFixture,
sim::Server server(serverConfig);
EXPECT_EQ(0u, *server.IterationCount());
EXPECT_EQ(3u, *server.EntityCount());
+
EXPECT_EQ(4u, *server.SystemCount());
}
@@ -776,6 +777,7 @@ TEST_P(ServerFixture, SigInt)
EXPECT_TRUE(*server.Running(0));
std::raise(SIGTERM);
+ GZ_SLEEP_MS(20);
EXPECT_FALSE(server.Running());
EXPECT_FALSE(*server.Running(0));
@@ -880,6 +882,7 @@ TEST_P(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_WIN32(AddSystemWhileRunning))
// Stop the server
std::raise(SIGTERM);
+ GZ_SLEEP_MS(20);
EXPECT_FALSE(server.Running());
EXPECT_FALSE(*server.Running(0));
@@ -1012,8 +1015,11 @@ TEST_P(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_WIN32(ResourcePath))
if (mesh)
{
- EXPECT_EQ("model://scheme_resource_uri/meshes/box.dae",
- mesh->Uri());
+ // StoreResolvedURIs is set to true so expect full path
+ EXPECT_NE(std::string::npos,
+ mesh->Uri().find("scheme_resource_uri/meshes/box.dae"));
+ EXPECT_FALSE(common::isRelativePath(mesh->Uri()));
+ EXPECT_TRUE(common::isFile(mesh->Uri()));
}
eachCount++;
diff --git a/src/SimulationRunner.cc b/src/SimulationRunner.cc
index a5ba51e96c..baa2712adc 100644
--- a/src/SimulationRunner.cc
+++ b/src/SimulationRunner.cc
@@ -18,6 +18,7 @@
#include "SimulationRunner.hh"
#include
+#include
#ifdef HAVE_PYBIND11
#include
#endif
@@ -33,8 +34,10 @@
#include
#include
+#include
#include "gz/common/Profiler.hh"
+#include "gz/sim/Constants.hh"
#include "gz/sim/components/Model.hh"
#include "gz/sim/components/Name.hh"
#include "gz/sim/components/Sensor.hh"
@@ -43,8 +46,13 @@
#include "gz/sim/components/ParentEntity.hh"
#include "gz/sim/components/Physics.hh"
#include "gz/sim/components/PhysicsCmd.hh"
+#include "gz/sim/components/PhysicsEnginePlugin.hh"
#include "gz/sim/components/Recreate.hh"
+#include "gz/sim/components/RenderEngineGuiPlugin.hh"
+#include "gz/sim/components/RenderEngineServerHeadless.hh"
+#include "gz/sim/components/RenderEngineServerPlugin.hh"
#include "gz/sim/Events.hh"
+#include "gz/sim/ServerConfig.hh"
#include "gz/sim/SdfEntityCreator.hh"
#include "gz/sim/Util.hh"
#include "gz/transport/TopicUtils.hh"
@@ -89,27 +97,18 @@ struct MaybeGilScopedRelease
//////////////////////////////////////////////////
-SimulationRunner::SimulationRunner(const sdf::World *_world,
+SimulationRunner::SimulationRunner(const sdf::World &_world,
const SystemLoaderPtr &_systemLoader,
const ServerConfig &_config)
- // \todo(nkoenig) Either copy the world, or add copy constructor to the
- // World and other elements.
- : sdfWorld(_world), serverConfig(_config)
+ : sdfWorld(_world), serverConfig(_config)
{
- if (nullptr == _world)
- {
- gzerr << "Can't start simulation runner with null world." << std::endl;
- return;
- }
-
// Keep world name
- this->worldName = transport::TopicUtils::AsValidTopic(_world->Name());
+ this->worldName = transport::TopicUtils::AsValidTopic(_world.Name());
- auto validWorldName = transport::TopicUtils::AsValidTopic(worldName);
if (this->worldName.empty())
{
gzerr << "Can't start simulation runner with this world name ["
- << worldName << "]." << std::endl;
+ << _world.Name() << "]." << std::endl;
return;
}
@@ -119,10 +118,10 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
// Get the physics profile
// TODO(luca): remove duplicated logic in SdfEntityCreator and LevelManager
- auto physics = _world->PhysicsByIndex(0);
+ const sdf::Physics *physics = _world.PhysicsByIndex(0);
if (!physics)
{
- physics = _world->PhysicsDefault();
+ physics = _world.PhysicsDefault();
}
// Step size
@@ -208,9 +207,6 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
std::bind(&SimulationRunner::LoadPlugins, this, std::placeholders::_1,
std::placeholders::_2));
- // Create the level manager
- this->levelMgr = std::make_unique(this, _config.UseLevels());
-
// Check if this is going to be a distributed runner
// Attempt to create the manager based on environment variables.
// If the configuration is invalid, then networkMgr will be `nullptr`.
@@ -248,27 +244,11 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
}
}
- // Load the active levels
- this->levelMgr->UpdateLevelsState();
-
- // Store the initial state of the ECM;
- this->initialEntityCompMgr.CopyFrom(this->entityCompMgr);
-
- // Load any additional plugins from the Server Configuration
- this->LoadServerPlugins(this->serverConfig.Plugins());
-
- // If we have reached this point and no world systems have been loaded, then
- // load a default set of systems.
- if (this->systemMgr->TotalByEntity(
- worldEntity(this->entityCompMgr)).empty())
- {
- gzmsg << "No systems loaded from SDF, loading defaults" << std::endl;
- bool isPlayback = !this->serverConfig.LogPlaybackPath().empty();
- auto plugins = sim::loadPluginInfo(isPlayback);
- this->LoadServerPlugins(plugins);
- }
+ // Create the level manager
+ this->levelMgr = std::make_unique(this,
+ this->serverConfig.UseLevels());
- this->LoadLoggingPlugins(this->serverConfig);
+ this->CreateEntities(_world);
// TODO(louise) Combine both messages into one.
this->node->Advertise("control", &SimulationRunner::OnWorldControl, this);
@@ -283,9 +263,21 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
// Publish empty GUI messages for worlds that have no GUI in the beginning.
// In the future, support modifying GUI from the server at runtime.
- if (_world->Gui())
+ if (_world.Gui())
{
- this->guiMsg = convert(*_world->Gui());
+ this->guiMsg = convert(*_world.Gui());
+
+ auto worldElem = this->sdfWorld.Element();
+ if (worldElem)
+ {
+ auto policies = worldElem->FindElement("gz:policies");
+ if (policies)
+ {
+ auto headerData = this->guiMsg.mutable_header()->add_data();
+ headerData->set_key("gz:policies");
+ headerData->add_value(policies->ToString(""));
+ }
+ }
}
std::string infoService{"gui/info"};
@@ -294,7 +286,7 @@ SimulationRunner::SimulationRunner(const sdf::World *_world,
gzmsg << "Serving GUI information on [" << opts.NameSpace() << "/"
<< infoService << "]" << std::endl;
- gzmsg << "World [" << _world->Name() << "] initialized with ["
+ gzmsg << "World [" << this->worldName << "] initialized with ["
<< physics->Name() << "] physics profile." << std::endl;
std::string genWorldSdfService{"generate_world_sdf"};
@@ -533,12 +525,15 @@ void SimulationRunner::ProcessSystemQueue()
{
auto pending = this->systemMgr->PendingCount();
- if (0 == pending)
+ if (0 == pending && !this->threadsNeedCleanUp)
return;
- // If additional systems are to be added, stop the existing threads.
+ // If additional systems are to be added or have been removed,
+ // stop the existing threads.
this->StopWorkerThreads();
+ this->threadsNeedCleanUp = false;
+
this->systemMgr->ActivatePendingSystems();
unsigned int threadCount =
@@ -597,14 +592,24 @@ void SimulationRunner::UpdateSystems()
{
GZ_PROFILE("PreUpdate");
- for (auto& system : this->systemMgr->SystemsPreUpdate())
- system->PreUpdate(this->currentInfo, this->entityCompMgr);
+ for (auto& [priority, systems] : this->systemMgr->SystemsPreUpdate())
+ {
+ for (auto& system : systems)
+ {
+ system->PreUpdate(this->currentInfo, this->entityCompMgr);
+ }
+ }
}
{
GZ_PROFILE("Update");
- for (auto& system : this->systemMgr->SystemsUpdate())
- system->Update(this->currentInfo, this->entityCompMgr);
+ for (auto& [priority, systems] : this->systemMgr->SystemsUpdate())
+ {
+ for (auto& system : systems)
+ {
+ system->Update(this->currentInfo, this->entityCompMgr);
+ }
+ }
}
{
@@ -922,6 +927,8 @@ void SimulationRunner::Step(const UpdateInfo &_info)
this->ProcessRecreateEntitiesCreate();
// Process entity removals.
+ this->systemMgr->ProcessRemovedEntities(this->entityCompMgr,
+ this->threadsNeedCleanUp);
this->entityCompMgr.ProcessRemoveEntityRequests();
// Process components removals
@@ -1467,19 +1474,7 @@ bool SimulationRunner::RequestRemoveEntity(const std::string &_name,
std::optional SimulationRunner::EntityByName(
const std::string &_name) const
{
- std::optional entity;
- this->entityCompMgr.Each([&](const Entity _entity,
- const components::Name *_entityName)->bool
- {
- if (_entityName->Data() == _name)
- {
- entity = _entity;
- return false;
- }
- return true;
- });
-
- return entity;
+ return this->entityCompMgr.EntityByName(_name);
}
/////////////////////////////////////////////////
@@ -1547,3 +1542,122 @@ void SimulationRunner::SetNextStepAsBlockingPaused(const bool value)
{
this->blockingPausedStepPending = value;
}
+
+//////////////////////////////////////////////////
+void SimulationRunner::CreateEntities(const sdf::World &_world)
+{
+ this->sdfWorld = _world;
+
+ // Instantiate the SDF creator
+ auto creator = std::make_unique(this->entityCompMgr,
+ this->eventMgr);
+
+ // We create the world entity so that the simulation runner can inject
+ // some components
+ Entity worldEntity = this->entityCompMgr.CreateEntity();
+ this->entityCompMgr.CreateComponent(worldEntity, components::World());
+
+ // 1. Level manager read performers and levels. Add components to the
+ // performers and levels so that the SdfEntityCreator knows whether to
+ // create them or not. Make sure to set parents properly
+ // 2. Create entities.
+
+ // Read the level information. This will create components containing
+ // information about which entities should be created for the current
+ // level.
+ this->levelMgr->ReadLevelPerformerInfo(this->sdfWorld);
+
+ // Configure the default level
+ this->levelMgr->ConfigureDefaultLevel();
+
+ // Create components based on the contents of the server configuration.
+ this->entityCompMgr.CreateComponent(worldEntity,
+ components::PhysicsEnginePlugin(this->serverConfig.PhysicsEngine()));
+
+ this->entityCompMgr.CreateComponent(worldEntity,
+ components::RenderEngineServerPlugin(
+ this->serverConfig.RenderEngineServer()));
+
+ this->entityCompMgr.CreateComponent(worldEntity,
+ components::RenderEngineServerHeadless(
+ this->serverConfig.HeadlessRendering()));
+
+ this->entityCompMgr.CreateComponent(worldEntity,
+ components::RenderEngineGuiPlugin(
+ this->serverConfig.RenderEngineGui()));
+
+ // Load the world entities from SDF
+ creator->CreateEntities(&this->sdfWorld, worldEntity);
+
+ // Load the active levels
+ this->levelMgr->UpdateLevelsState();
+
+ // Some entities and component should be removed based on the levels.
+ this->entityCompMgr.ProcessRemoveEntityRequests();
+ this->entityCompMgr.ClearRemovedComponents();
+
+ // Load any additional plugins from the Server Configuration
+ this->LoadServerPlugins(this->serverConfig.Plugins());
+
+ auto loadedWorldPlugins = this->systemMgr->TotalByEntity(worldEntity);
+ // If we have reached this point and no world systems have been loaded, then
+ // load a default set of systems.
+
+ auto worldElem = this->sdfWorld.Element();
+ bool includeServerConfigPlugins = true;
+ if (worldElem)
+ {
+ auto policies = worldElem->FindElement(std::string(kPoliciesTag));
+ if (policies)
+ {
+ includeServerConfigPlugins =
+ policies
+ ->Get("include_server_config_plugins", includeServerConfigPlugins)
+ .first;
+ }
+ }
+
+ if (includeServerConfigPlugins || loadedWorldPlugins.empty())
+ {
+ bool isPlayback = !this->serverConfig.LogPlaybackPath().empty();
+ auto defaultPlugins = gz::sim::loadPluginInfo(isPlayback);
+ if (loadedWorldPlugins.empty())
+ {
+ gzmsg << "No systems loaded from SDF, loading defaults" << std::endl;
+ }
+ else
+ {
+ std::unordered_set loadedWorldPluginFileNames;
+ for (const auto &pl : loadedWorldPlugins)
+ {
+ loadedWorldPluginFileNames.insert(pl.fname);
+ }
+ auto isPluginLoaded =
+ [&loadedWorldPluginFileNames](const ServerConfig::PluginInfo &_pl)
+ {
+ return loadedWorldPluginFileNames.count(_pl.Plugin().Filename()) != 0;
+ };
+
+ // Remove plugin if it's already loaded so as to not duplicate world
+ // plugins.
+ defaultPlugins.remove_if(isPluginLoaded);
+
+ gzdbg << "Additional plugins to load:\n";
+ for (const auto &plugin : defaultPlugins)
+ {
+ gzdbg << plugin.Plugin().Name() << " " << plugin.Plugin().Filename()
+ << "\n";
+ }
+ }
+
+ this->LoadServerPlugins(defaultPlugins);
+ // Load logging plugins after all server plugins so that necessary
+ // plugins such as SceneBroadcaster are loaded first. This might be
+ // a bug or an assumption made in the logging plugins.
+ this->LoadLoggingPlugins(this->serverConfig);
+
+ };
+
+ // Store the initial state of the ECM;
+ this->initialEntityCompMgr.CopyFrom(this->entityCompMgr);
+}
diff --git a/src/SimulationRunner.hh b/src/SimulationRunner.hh
index 438fc329ba..8fe03511e7 100644
--- a/src/SimulationRunner.hh
+++ b/src/SimulationRunner.hh
@@ -77,7 +77,7 @@ namespace gz
/// \param[in] _world Pointer to the SDF world.
/// \param[in] _systemLoader Reference to system manager.
/// \param[in] _useLevels Whether to use levles or not. False by default.
- public: explicit SimulationRunner(const sdf::World *_world,
+ public: explicit SimulationRunner(const sdf::World &_world,
const SystemLoaderPtr &_systemLoader,
const ServerConfig &_config = ServerConfig());
@@ -151,8 +151,8 @@ namespace gz
const sdf::Plugins &_plugins);
/// \brief Load server plugins for a given entity.
- /// \param[in] _config Configuration to load plugins from.
- /// plugins based on the _config contents
+ /// \param[in] _plugins Load any additional plugins from the
+ /// Server Configuration
public: void LoadServerPlugins(
const std::list &_plugins);
@@ -373,6 +373,11 @@ namespace gz
/// Physics component of the world, if any.
public: void UpdatePhysicsParams();
+ /// \brief Create entities for the world simulated by this runner based
+ /// on the provided SDF Root object.
+ /// \param[in] _world SDF world created entities from.
+ public: void CreateEntities(const sdf::World &_world);
+
/// \brief Process entities with the components::Recreate component.
/// Put in a request to make them as removed
private: void ProcessRecreateEntitiesRemove();
@@ -477,8 +482,8 @@ namespace gz
/// \brief Connection to the load plugins event.
private: common::ConnectionPtr loadPluginsConn;
- /// \brief Pointer to the sdf::World object of this runner
- private: const sdf::World *sdfWorld;
+ /// \brief The sdf::World object of this runner
+ private: sdf::World sdfWorld;
/// \brief The real time factor calculated based on sim and real time
/// averages.
@@ -543,6 +548,9 @@ namespace gz
/// at the appropriate time.
private: std::unique_ptr newWorldControlState;
+ /// \brief Set if we need to remove systems due to entity removal
+ private: bool threadsNeedCleanUp{false};
+
private: bool resetInitiated{false};
friend class LevelManager;
};
diff --git a/src/SimulationRunner_TEST.cc b/src/SimulationRunner_TEST.cc
index 10ca3a9406..11bf658287 100644
--- a/src/SimulationRunner_TEST.cc
+++ b/src/SimulationRunner_TEST.cc
@@ -16,7 +16,6 @@
*/
#include
-
#include
#include
@@ -111,7 +110,6 @@ void rootClockCb(const msgs::Clock &_msg)
rootClockMsgs.push_back(_msg);
}
-
/////////////////////////////////////////////////
TEST_P(SimulationRunnerTest, CreateEntities)
{
@@ -124,7 +122,7 @@ TEST_P(SimulationRunnerTest, CreateEntities)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Check component types
EXPECT_TRUE(runner.EntityCompMgr().HasComponentType(
@@ -658,7 +656,7 @@ TEST_P(SimulationRunnerTest, CreateLights)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Check entities
// 1 x world + 1 x (default) level + 1 x wind + 1 x model + 1 x link + 1 x
@@ -928,7 +926,7 @@ TEST_P(SimulationRunnerTest, CreateJointEntities)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Check component types
EXPECT_TRUE(runner.EntityCompMgr().HasComponentType(
@@ -1073,7 +1071,7 @@ TEST_P(SimulationRunnerTest, Time)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Check state
EXPECT_TRUE(runner.Paused());
@@ -1202,7 +1200,7 @@ TEST_P(SimulationRunnerTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(LoadPlugins) )
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Get world entity
Entity worldId{kNullEntity};
@@ -1302,7 +1300,7 @@ TEST_P(SimulationRunnerTest,
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(rootWithout.WorldByIndex(0), systemLoader,
+ SimulationRunner runner(*rootWithout.WorldByIndex(0), systemLoader,
serverConfig);
ASSERT_EQ(2u, runner.SystemCount());
@@ -1333,7 +1331,7 @@ TEST_P(SimulationRunnerTest,
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(rootWithout.WorldByIndex(0), systemLoader,
+ SimulationRunner runner(*rootWithout.WorldByIndex(0), systemLoader,
serverConfig);
// Get world entity
@@ -1414,7 +1412,7 @@ TEST_P(SimulationRunnerTest,
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(rootWithout.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*rootWithout.WorldByIndex(0), systemLoader);
ASSERT_EQ(3u, runner.SystemCount());
common::unsetenv(kServerConfigPathEnv);
}
@@ -1431,7 +1429,7 @@ TEST_P(SimulationRunnerTest,
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(rootWithout.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*rootWithout.WorldByIndex(0), systemLoader);
runner.SetPaused(false);
// Get model entities
@@ -1484,8 +1482,7 @@ TEST_P(SimulationRunnerTest,
EXPECT_TRUE(runner.EntityCompMgr().EntityHasComponentType(sphereEntity,
componentId)) << componentId;
- // Remove entities that have plugin - this is not unloading or destroying
- // the plugin though!
+ // Remove entities that have plugin
auto entityCount = runner.EntityCompMgr().EntityCount();
const_cast(
runner.EntityCompMgr()).RequestRemoveEntity(boxEntity);
@@ -1530,11 +1527,19 @@ TEST_P(SimulationRunnerTest,
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(rootWithout.WorldByIndex(0), systemLoader,
+ SimulationRunner runner(*rootWithout.WorldByIndex(0), systemLoader,
serverConfig);
- // 1 model plugin from SDF and 2 world plugins from config
- ASSERT_EQ(3u, runner.SystemCount());
+ // 1 model plugin from SDF and 1 world plugin from config
+ // and 1 model plugin from theconfig
+ EXPECT_EQ(3u, runner.SystemCount());
+ runner.SetPaused(false);
+ runner.Run(1);
+
+ // Remove the model. Only 1 world plugin should remain.
+ EXPECT_TRUE(runner.RequestRemoveEntity("box"));
+ runner.Run(2);
+ EXPECT_EQ(1u, runner.SystemCount());
}
/////////////////////////////////////////////////
@@ -1549,7 +1554,7 @@ TEST_P(SimulationRunnerTest, GuiInfo)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
// Create requester
transport::Node node;
@@ -1586,7 +1591,7 @@ TEST_P(SimulationRunnerTest, GenerateWorldSdf)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
msgs::SdfGeneratorConfig req;
msgs::StringMsg genWorldSdf;
@@ -1635,7 +1640,7 @@ TEST_P(SimulationRunnerTest, GeneratedSdfHasNoSpuriousPlugins)
// Create simulation runner
auto systemLoader = std::make_shared();
- SimulationRunner runner(root.WorldByIndex(0), systemLoader);
+ SimulationRunner runner(*root.WorldByIndex(0), systemLoader);
msgs::SdfGeneratorConfig req;
msgs::StringMsg genWorldSdf;
diff --git a/src/SystemInternal.hh b/src/SystemInternal.hh
index 0f4d442e4d..17b32b6758 100644
--- a/src/SystemInternal.hh
+++ b/src/SystemInternal.hh
@@ -48,6 +48,8 @@ namespace gz
configure(systemPlugin->QueryInterface()),
configureParameters(
systemPlugin->QueryInterface()),
+ configurePriority(
+ systemPlugin->QueryInterface()),
reset(systemPlugin->QueryInterface()),
preupdate(systemPlugin->QueryInterface()),
update(systemPlugin->QueryInterface()),
@@ -66,6 +68,8 @@ namespace gz
configure(dynamic_cast(_system.get())),
configureParameters(
dynamic_cast(_system.get())),
+ configurePriority(
+ dynamic_cast(_system.get())),
reset(dynamic_cast(_system.get())),
preupdate(dynamic_cast(_system.get())),
update(dynamic_cast(_system.get())),
@@ -95,6 +99,11 @@ namespace gz
/// Will be nullptr if the System doesn't implement this interface.
public: ISystemConfigureParameters *configureParameters = nullptr;
+ /// \brief Access this system via the ISystemConfigurePriority
+ /// interface.
+ /// Will be nullptr if the System doesn't implement this interface.
+ public: ISystemConfigurePriority *configurePriority = nullptr;
+
/// \brief Access this system via the ISystemReset interface
/// Will be nullptr if the System doesn't implement this interface.
public: ISystemReset *reset = nullptr;
diff --git a/src/SystemLoader.cc b/src/SystemLoader.cc
index 582ebbbabf..23409c2188 100644
--- a/src/SystemLoader.cc
+++ b/src/SystemLoader.cc
@@ -64,8 +64,7 @@ class gz::sim::SystemLoaderPrivate
public: bool InstantiateSystemPlugin(const sdf::Plugin &_sdfPlugin,
gz::plugin::PluginPtr &_gzPlugin)
{
- // Deprecated: accept ignition-gazebo-prefixed systems. Remove this on
- // gz-sim9
+ // Deprecated: accept ignition-gazebo-prefixed systems.
std::string deprecatedPrefix{"ignition-gazebo"};
auto filename = _sdfPlugin.Filename();
auto pos = filename.find(deprecatedPrefix);
@@ -125,7 +124,7 @@ class gz::sim::SystemLoaderPrivate
std::string pluginToInstantiate = _sdfPlugin.Name().empty() ?
pluginName : _sdfPlugin.Name();
- // Deprecated: accept ignition plugins. Remove this on gz-sim9
+ // Deprecated: accept ignition plugins.
std::string deprecatedPluginNamePrefix{"ignition::gazebo"};
pos = pluginToInstantiate.find(deprecatedPluginNamePrefix);
if (pos != std::string::npos)
@@ -200,7 +199,6 @@ class gz::sim::SystemLoaderPrivate
// Default plugin search path environment variable
public: std::string pluginPathEnv{"GZ_SIM_SYSTEM_PLUGIN_PATH"};
- public: std::string pluginPathEnvDeprecated{"IGN_GAZEBO_SYSTEM_PLUGIN_PATH"};
/// \brief Plugin loader instace
public: gz::plugin::Loader loader;
diff --git a/src/SystemManager.cc b/src/SystemManager.cc
index fd43f5330d..dcb24902c1 100644
--- a/src/SystemManager.cc
+++ b/src/SystemManager.cc
@@ -16,12 +16,18 @@
*/
#include
+#include
#include
+#include
+#include
#include
+#include "SystemInternal.hh"
#include "gz/sim/components/SystemPluginInfo.hh"
#include "gz/sim/Conversions.hh"
+#include "gz/sim/System.hh"
+#include "gz/sim/Util.hh"
#include "SystemManager.hh"
using namespace gz;
@@ -106,6 +112,24 @@ size_t SystemManager::ActivatePendingSystems()
{
this->systems.push_back(system);
+ PriorityType p {System::kDefaultPriority};
+ if (system.configurePriority)
+ {
+ p = system.configurePriority->ConfigurePriority();
+ }
+ const std::string kPriorityElementName
+ {gz::sim::System::kPriorityElementName};
+ if (system.configureSdf &&
+ system.configureSdf->HasElement(kPriorityElementName))
+ {
+ PriorityType newPriority =
+ system.configureSdf->Get(kPriorityElementName);
+ gzdbg << "Changing priority for system [" << system.name
+ << "] from {" << p
+ << "} to {" << newPriority << "}\n";
+ p = newPriority;
+ }
+
if (system.configure)
this->systemsConfigure.push_back(system.configure);
@@ -116,13 +140,21 @@ size_t SystemManager::ActivatePendingSystems()
this->systemsReset.push_back(system.reset);
if (system.preupdate)
- this->systemsPreupdate.push_back(system.preupdate);
+ {
+ this->systemsPreupdate.try_emplace(p);
+ this->systemsPreupdate[p].push_back(system.preupdate);
+ }
if (system.update)
- this->systemsUpdate.push_back(system.update);
+ {
+ this->systemsUpdate.try_emplace(p);
+ this->systemsUpdate[p].push_back(system.update);
+ }
if (system.postupdate)
+ {
this->systemsPostupdate.push_back(system.postupdate);
+ }
}
this->pendingSystems.clear();
@@ -282,6 +314,7 @@ const std::vector& SystemManager::SystemsConfigure()
return this->systemsConfigure;
}
+//////////////////////////////////////////////////
const std::vector&
SystemManager::SystemsConfigureParameters()
{
@@ -295,13 +328,15 @@ const std::vector &SystemManager::SystemsReset()
}
//////////////////////////////////////////////////
-const std::vector& SystemManager::SystemsPreUpdate()
+const SystemManager::PrioritizedSystems&
+SystemManager::SystemsPreUpdate()
{
return this->systemsPreupdate;
}
//////////////////////////////////////////////////
-const std::vector& SystemManager::SystemsUpdate()
+const SystemManager::PrioritizedSystems&
+SystemManager::SystemsUpdate()
{
return this->systemsUpdate;
}
@@ -334,6 +369,11 @@ bool SystemManager::EntitySystemAddService(const msgs::EntityPlugin_V &_req,
{
std::lock_guard lock(this->systemsMsgMutex);
this->systemsToAdd.push_back(_req);
+
+ // The response is set to true to indicate that the service request is
+ // handled but it does not necessarily mean the system is added
+ // successfully
+ // \todo(iche033) Return false if system is not added successfully?
_res.set_data(true);
return true;
}
@@ -393,8 +433,21 @@ void SystemManager::ProcessPendingEntitySystems()
if (req.plugins().empty())
{
- gzwarn << "Unable to add plugins to Entity: '" << entity
- << "'. No plugins specified." << std::endl;
+ gzerr << "Unable to add plugins to Entity: '" << entity
+ << "'. No plugins specified." << std::endl;
+ continue;
+ }
+
+ // set to world entity if entity id is not specified in the request.
+ if (entity == kNullEntity || entity == 0u)
+ {
+ entity = worldEntity(*this->entityCompMgr);
+ }
+ // otherwise check if entity exists before attempting to load the plugin.
+ else if (!this->entityCompMgr->HasEntity(entity))
+ {
+ gzerr << "Unable to add plugins to Entity: '" << entity
+ << "'. Entity does not exist." << std::endl;
continue;
}
@@ -409,3 +462,147 @@ void SystemManager::ProcessPendingEntitySystems()
}
this->systemsToAdd.clear();
}
+
+template
+struct identity
+{
+ using type = T;
+};
+
+//////////////////////////////////////////////////
+/// TODO(arjo) - When we move to C++20 we can just use erase_if
+/// Removes all items that match the given predicate.
+/// This function runs in O(n) time and uses memory in-place
+template
+void RemoveFromVectorIf(std::vector& vec,
+ typename identity>::type pred)
+{
+ vec.erase(std::remove_if(vec.begin(), vec.end(), pred), vec.end());
+}
+
+//////////////////////////////////////////////////
+void SystemManager::ProcessRemovedEntities(
+ const EntityComponentManager &_ecm,
+ bool &_needsCleanUp)
+{
+ // Note: This function has O(n) time when an entity is removed
+ // where n is number of systems. Ideally we would only iterate
+ // over entities marked for removal but that would involve having
+ // a key value map. This can be marked as a future improvement.
+ if (!_ecm.HasEntitiesMarkedForRemoval())
+ {
+ return;
+ }
+
+ std::unordered_set resetSystemsToBeRemoved;
+ std::unordered_set preupdateSystemsToBeRemoved;
+ std::unordered_set updateSystemsToBeRemoved;
+ std::unordered_set postupdateSystemsToBeRemoved;
+ std::unordered_set configureSystemsToBeRemoved;
+ std::unordered_set
+ configureParametersSystemsToBeRemoved;
+ for (const auto &system : this->systems)
+ {
+ if (_ecm.IsMarkedForRemoval(system.parentEntity))
+ {
+ if (system.reset)
+ {
+ resetSystemsToBeRemoved.insert(system.reset);
+ }
+ if (system.preupdate)
+ {
+ preupdateSystemsToBeRemoved.insert(system.preupdate);
+ }
+ if (system.update)
+ {
+ updateSystemsToBeRemoved.insert(system.update);
+ }
+ if (system.postupdate)
+ {
+ postupdateSystemsToBeRemoved.insert(system.postupdate);
+ // If system with a PostUpdate is marked for removal
+ // mark all worker threads for removal.
+ _needsCleanUp = true;
+ }
+ if (system.configure)
+ {
+ configureSystemsToBeRemoved.insert(system.configure);
+ }
+ if (system.configureParameters)
+ {
+ configureParametersSystemsToBeRemoved.insert(
+ system.configureParameters);
+ }
+ }
+ }
+
+ RemoveFromVectorIf(this->systemsReset,
+ [&](const auto system) {
+ if (resetSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ for (auto it = this->systemsPreupdate.begin();
+ it != this->systemsPreupdate.end();)
+ {
+ RemoveFromVectorIf(it->second,
+ [&](const auto& system) {
+ if (preupdateSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ if (it->second.empty())
+ it = this->systemsPreupdate.erase(it);
+ else
+ ++it;
+ }
+ for (auto it = this->systemsUpdate.begin();
+ it != this->systemsUpdate.end();)
+ {
+ RemoveFromVectorIf(it->second,
+ [&](const auto& system) {
+ if (updateSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ if (it->second.empty())
+ it = this->systemsUpdate.erase(it);
+ else
+ ++it;
+ }
+
+ RemoveFromVectorIf(this->systemsPostupdate,
+ [&](const auto& system) {
+ if (postupdateSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ RemoveFromVectorIf(this->systemsConfigure,
+ [&](const auto& system) {
+ if (configureSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ RemoveFromVectorIf(this->systemsConfigureParameters,
+ [&](const auto& system) {
+ if (configureParametersSystemsToBeRemoved.count(system)) {
+ return true;
+ }
+ return false;
+ });
+ RemoveFromVectorIf(this->systems,
+ [&](const SystemInternal& _arg) {
+ return _ecm.IsMarkedForRemoval(_arg.parentEntity);
+ });
+
+ std::lock_guard lock(this->pendingSystemsMutex);
+ RemoveFromVectorIf(this->pendingSystems,
+ [&](const SystemInternal& _system) {
+ return _ecm.IsMarkedForRemoval(_system.parentEntity);
+ });
+}
diff --git a/src/SystemManager.hh b/src/SystemManager.hh
index acd82c09dc..c9c61c7944 100644
--- a/src/SystemManager.hh
+++ b/src/SystemManager.hh
@@ -19,6 +19,8 @@
#include
+#include
+#include