diff --git a/.github/ci/packages.apt b/.github/ci/packages.apt index bc4c3a55df..efde86b28b 100644 --- a/.github/ci/packages.apt +++ b/.github/ci/packages.apt @@ -2,34 +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-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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e34e6ebc7a..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 }} @@ -32,3 +34,19 @@ jobs: 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/CMakeLists.txt b/CMakeLists.txt index d502043b77..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.6.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 @@ -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 VERSION 8.2.0 +gz_find_package(gz-sensors9 REQUIRED # component order is important COMPONENTS # non-rendering @@ -164,17 +164,17 @@ gz_find_package(gz-sensors8 REQUIRED VERSION 8.2.0 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 b17cc44204..620f3f922a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,211 @@ +## 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) 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 09abde0f62..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,7 +20,7 @@ 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}) 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/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 index 8af962296d..e5497abb73 100644 --- a/examples/plugin/priority_printer_plugin/CMakeLists.txt +++ b/examples/plugin/priority_printer_plugin/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(Priority_printer) -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(PriorityPrinter SHARED PriorityPrinter.cc) set_property(TARGET PriorityPrinter PROPERTY CXX_STANDARD 17) 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 5c127f7f45..99a24e3fb7 100644 --- a/examples/standalone/gtest_setup/CMakeLists.txt +++ b/examples/standalone/gtest_setup/CMakeLists.txt @@ -1,10 +1,10 @@ -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) 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/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/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 - 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/include/gz/sim/Constants.hh b/include/gz/sim/Constants.hh new file mode 100644 index 0000000000..96d281ccc7 --- /dev/null +++ b/include/gz/sim/Constants.hh @@ -0,0 +1,33 @@ +/* + * 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_CONSTANTS_HH_ +#define GZ_SIM_CONSTANTS_HH_ + +#include "gz/sim/config.hh" +#include + +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/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/System.hh b/include/gz/sim/System.hh index f531c1d023..327f9bddbe 100644 --- a/include/gz/sim/System.hh +++ b/include/gz/sim/System.hh @@ -103,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 /// @@ -124,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/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 5f27a130bd..afe139f33d 100644 --- a/include/gz/sim/components/Factory.hh +++ b/include/gz/sim/components/Factory.hh @@ -283,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/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/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 index 8be58c01b4..507b36f440 100644 --- a/package.xml +++ b/package.xml @@ -1,8 +1,8 @@ - gz-sim8 - 8.6.0 + gz-sim9 + 9.0.0 Gazebo Sim : A Robotic Simulator Michael Carroll Apache License 2.0 @@ -12,26 +12,25 @@ benchmark glut - gz-cmake3 - gz-common5 - gz-fuel_tools9 - gz-gui8 - gz-math7 - gz-msgs10 - gz-physics7 - gz-plugin2 - gz-rendering8 - gz-sensors8 + gz-cmake4 + gz-common6 + gz-fuel_tools10 + gz-gui9 + gz-math8 + gz-msgs11 + gz-physics8 + gz-plugin3 + gz-rendering9 + gz-sensors9 gz-tools2 - gz-transport13 - gz-utils2 + gz-transport14 + gz-utils3 libfreeimage-dev libglew-dev libxi-dev libxmu-dev protobuf-dev pybind11-dev - python3-distutils qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qtgraphicaleffects @@ -42,7 +41,7 @@ qml-module-qtquick2 qtbase5-dev qtdeclarative5-dev - sdformat14 + sdformat15 tinyxml2 uuid 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 b3c2917657..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 @@ -306,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} VERSION_GREATER_EQUAL "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/LevelManager.cc b/src/LevelManager.cc index a41a56d335..ab950bc378 100644 --- a/src/LevelManager.cc +++ b/src/LevelManager.cc @@ -18,6 +18,7 @@ #include "LevelManager.hh" #include +#include #include #include 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/SdfEntityCreator.cc b/src/SdfEntityCreator.cc index cd24a61cc3..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" @@ -65,7 +68,7 @@ #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" @@ -235,7 +238,6 @@ SdfEntityCreator &SdfEntityCreator::operator=(SdfEntityCreator &&_creator) ////////////////////////////////////////////////// Entity SdfEntityCreator::CreateEntities(const sdf::World *_world) { - // World entity Entity worldEntity = this->dataPtr->ecm->CreateEntity(); @@ -318,9 +320,6 @@ void SdfEntityCreator::CreateEntities(const sdf::World *_world, components::SphericalCoordinates(*_world->SphericalCoordinates())); } - this->dataPtr->eventManager->Emit(_worldEntity, - _world->Plugins()); - // Models for (uint64_t modelIndex = 0; modelIndex < _world->ModelCount(); ++modelIndex) @@ -330,7 +329,7 @@ void SdfEntityCreator::CreateEntities(const sdf::World *_world, levelEntityNames.find(model->Name()) != levelEntityNames.end()) { - Entity modelEntity = this->CreateEntities(model); + Entity modelEntity = this->CreateEntities(model, false); this->SetParent(modelEntity, _worldEntity); } @@ -380,7 +379,7 @@ void SdfEntityCreator::CreateEntities(const sdf::World *_world, if (_world->ModelNameExists(_ref->Data())) { const sdf::Model *model = _world->ModelByName(_ref->Data()); - Entity modelEntity = this->CreateEntities(model); + Entity modelEntity = this->CreateEntities(model, false); this->SetParent(modelEntity, _worldEntity); this->SetParent(_entity, modelEntity); } @@ -416,32 +415,51 @@ void SdfEntityCreator::CreateEntities(const sdf::World *_world, // 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)); + } + } } } // Store the world's SDF DOM to be used when saving the world to file this->dataPtr->ecm->CreateComponent( _worldEntity, components::WorldSdf(*_world)); + + this->dataPtr->eventManager->Emit(_worldEntity, + _world->Plugins()); + + // Load model plugins after the world plugin. + this->LoadModelPlugins(); } ////////////////////////////////////////////////// @@ -987,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/Server.cc b/src/Server.cc index 86b8b7d1cc..712f273467 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -215,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 ae587f2703..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 @@ -924,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)) @@ -951,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; @@ -1031,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 1d23f81586..83b97363e6 100644 --- a/src/ServerPrivate.cc +++ b/src/ServerPrivate.cc @@ -115,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) { @@ -133,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) @@ -188,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; } diff --git a/src/ServerPrivate.hh b/src/ServerPrivate.hh index cbb298db3f..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; diff --git a/src/Server_TEST.cc b/src/Server_TEST.cc index b07157b094..5f7697eeab 100644 --- a/src/Server_TEST.cc +++ b/src/Server_TEST.cc @@ -442,8 +442,7 @@ TEST_P(ServerFixture, GZ_UTILS_TEST_DISABLED_ON_WIN32(ServerConfigLogRecord)) EXPECT_EQ(0u, *server.IterationCount()); EXPECT_EQ(3u, *server.EntityCount()); - // Only the log record system is needed and therefore loaded. - EXPECT_EQ(1u, *server.SystemCount()); + EXPECT_EQ(4u, *server.SystemCount()); EXPECT_TRUE(serverConfig.LogRecordTopics().empty()); serverConfig.AddLogRecordTopic("test_topic1"); @@ -483,8 +482,7 @@ TEST_P(ServerFixture, EXPECT_EQ(0u, *server.IterationCount()); EXPECT_EQ(3u, *server.EntityCount()); - // Only the log record system is needed and therefore loaded. - EXPECT_EQ(1u, *server.SystemCount()); + EXPECT_EQ(4u, *server.SystemCount()); } EXPECT_FALSE(common::exists(logFile)); @@ -779,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)); @@ -883,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)); diff --git a/src/SimulationRunner.cc b/src/SimulationRunner.cc index ceea22ad49..baa2712adc 100644 --- a/src/SimulationRunner.cc +++ b/src/SimulationRunner.cc @@ -18,6 +18,7 @@ #include "SimulationRunner.hh" #include +#include #ifdef HAVE_PYBIND11 #include #endif @@ -36,6 +37,7 @@ #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" @@ -50,6 +52,7 @@ #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" @@ -263,6 +266,18 @@ SimulationRunner::SimulationRunner(const sdf::World &_world, if (_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"}; @@ -1581,26 +1596,68 @@ void SimulationRunner::CreateEntities(const sdf::World &_world) this->entityCompMgr.ProcessRemoveEntityRequests(); this->entityCompMgr.ClearRemovedComponents(); - this->LoadLoggingPlugins(this->serverConfig); - // 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. - if (this->systemMgr->TotalByEntity(worldEntity).empty()) + + auto worldElem = this->sdfWorld.Element(); + bool includeServerConfigPlugins = true; + if (worldElem) { - gzmsg << "No systems loaded from SDF, loading defaults" << std::endl; - bool isPlayback = !this->serverConfig.LogPlaybackPath().empty(); - auto plugins = gz::sim::loadPluginInfo(isPlayback); - this->LoadServerPlugins(plugins); + 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); - - // 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()) - this->guiMsg = convert(*_world.Gui()); } 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 9d86af1241..dcb24902c1 100644 --- a/src/SystemManager.cc +++ b/src/SystemManager.cc @@ -113,6 +113,10 @@ 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 && @@ -120,6 +124,9 @@ size_t SystemManager::ActivatePendingSystems() { PriorityType newPriority = system.configureSdf->Get(kPriorityElementName); + gzdbg << "Changing priority for system [" << system.name + << "] from {" << p + << "} to {" << newPriority << "}\n"; p = newPriority; } @@ -307,6 +314,7 @@ const std::vector& SystemManager::SystemsConfigure() return this->systemsConfigure; } +////////////////////////////////////////////////// const std::vector& SystemManager::SystemsConfigureParameters() { diff --git a/src/SystemManager_TEST.cc b/src/SystemManager_TEST.cc index 38ad82d726..956cb06810 100644 --- a/src/SystemManager_TEST.cc +++ b/src/SystemManager_TEST.cc @@ -28,6 +28,8 @@ using namespace gz::sim; +constexpr System::PriorityType kPriority = 64; + ///////////////////////////////////////////////// class SystemWithConfigure: public System, @@ -69,6 +71,16 @@ class SystemWithUpdates: const EntityComponentManager &) override {}; }; +///////////////////////////////////////////////// +class SystemWithPrioritizedUpdates: + public SystemWithUpdates, + public ISystemConfigurePriority +{ + // Documentation inherited + public: System::PriorityType ConfigurePriority() override + { return kPriority; } +}; + ///////////////////////////////////////////////// TEST(SystemManager, Constructor) { @@ -127,32 +139,40 @@ TEST(SystemManager, AddSystemNoEcm) EXPECT_EQ(1u, systemMgr.TotalByEntity(configEntity).size()); auto updateSystem = std::make_shared(); + auto prioritizedSystem = + std::make_shared(); Entity updateEntity{456u}; systemMgr.AddSystem(updateSystem, updateEntity, nullptr); + systemMgr.AddSystem(prioritizedSystem, updateEntity, nullptr); EXPECT_EQ(1u, systemMgr.ActiveCount()); - EXPECT_EQ(1u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(2u, systemMgr.PendingCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(1u, systemMgr.SystemsConfigure().size()); EXPECT_EQ(0u, systemMgr.SystemsPreUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsPostUpdate().size()); - EXPECT_EQ(1u, systemMgr.TotalByEntity(updateEntity).size()); + EXPECT_EQ(2u, systemMgr.TotalByEntity(updateEntity).size()); systemMgr.ActivatePendingSystems(); - EXPECT_EQ(2u, systemMgr.ActiveCount()); + EXPECT_EQ(3u, systemMgr.ActiveCount()); EXPECT_EQ(0u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(1u, systemMgr.SystemsConfigure().size()); - // Expect PreUpdate and Update to contain one map entry with Priority 0 and - // a vector of length 1. - EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().size()); + // Expect PreUpdate and Update to contain two map entries: + // 1. Priority {0} and a vector of length 1. + // 2. Priority {kPriority} and a vector of length 1. + EXPECT_EQ(2u, systemMgr.SystemsPreUpdate().size()); EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(kPriority)); EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(0).size()); - EXPECT_EQ(1u, systemMgr.SystemsUpdate().size()); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsUpdate().size()); EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(kPriority)); EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(0).size()); - EXPECT_EQ(1u, systemMgr.SystemsPostUpdate().size()); - EXPECT_EQ(1u, systemMgr.TotalByEntity(updateEntity).size()); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsPostUpdate().size()); + EXPECT_EQ(2u, systemMgr.TotalByEntity(updateEntity).size()); } ///////////////////////////////////////////////// @@ -201,23 +221,37 @@ TEST(SystemManager, AddSystemEcm) EXPECT_EQ(0u, systemMgr.SystemsPostUpdate().size()); auto updateSystem = std::make_shared(); + auto prioritizedSystem = + std::make_shared(); systemMgr.AddSystem(updateSystem, kNullEntity, nullptr); + systemMgr.AddSystem(prioritizedSystem, kNullEntity, nullptr); EXPECT_EQ(1u, systemMgr.ActiveCount()); - EXPECT_EQ(1u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(2u, systemMgr.PendingCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(1u, systemMgr.SystemsConfigure().size()); EXPECT_EQ(0u, systemMgr.SystemsPreUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsPostUpdate().size()); systemMgr.ActivatePendingSystems(); - EXPECT_EQ(2u, systemMgr.ActiveCount()); + EXPECT_EQ(3u, systemMgr.ActiveCount()); EXPECT_EQ(0u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(1u, systemMgr.SystemsConfigure().size()); - EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().size()); - EXPECT_EQ(1u, systemMgr.SystemsUpdate().size()); - EXPECT_EQ(1u, systemMgr.SystemsPostUpdate().size()); + // Expect PreUpdate and Update to contain two map entries: + // 1. Priority {0} and a vector of length 1. + // 2. Priority {kPriority} and a vector of length 1. + EXPECT_EQ(2u, systemMgr.SystemsPreUpdate().size()); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(kPriority)); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(0).size()); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsUpdate().size()); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(kPriority)); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(0).size()); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsPostUpdate().size()); } ///////////////////////////////////////////////// @@ -247,28 +281,42 @@ TEST(SystemManager, AddAndRemoveSystemEcm) auto entity = ecm.CreateEntity(); auto updateSystemWithChild = std::make_shared(); + auto prioritizedSystemWithChild = + std::make_shared(); systemMgr.AddSystem(updateSystemWithChild, entity, nullptr); + systemMgr.AddSystem(prioritizedSystemWithChild, entity, nullptr); // Configure called during AddSystem EXPECT_EQ(1, configSystem->configured); EXPECT_EQ(1, configSystem->configuredParameters); EXPECT_EQ(0u, systemMgr.ActiveCount()); - EXPECT_EQ(2u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(3u, systemMgr.PendingCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(0u, systemMgr.SystemsConfigure().size()); EXPECT_EQ(0u, systemMgr.SystemsPreUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsUpdate().size()); EXPECT_EQ(0u, systemMgr.SystemsPostUpdate().size()); systemMgr.ActivatePendingSystems(); - EXPECT_EQ(2u, systemMgr.ActiveCount()); + EXPECT_EQ(3u, systemMgr.ActiveCount()); EXPECT_EQ(0u, systemMgr.PendingCount()); - EXPECT_EQ(2u, systemMgr.TotalCount()); + EXPECT_EQ(3u, systemMgr.TotalCount()); EXPECT_EQ(1u, systemMgr.SystemsConfigure().size()); - EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().size()); - EXPECT_EQ(1u, systemMgr.SystemsUpdate().size()); - EXPECT_EQ(1u, systemMgr.SystemsPostUpdate().size()); + // Expect PreUpdate and Update to contain two map entries: + // 1. Priority {0} and a vector of length 1. + // 2. Priority {kPriority} and a vector of length 1. + EXPECT_EQ(2u, systemMgr.SystemsPreUpdate().size()); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().count(kPriority)); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(0).size()); + EXPECT_EQ(1u, systemMgr.SystemsPreUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsUpdate().size()); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(0)); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().count(kPriority)); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(0).size()); + EXPECT_EQ(1u, systemMgr.SystemsUpdate().at(kPriority).size()); + EXPECT_EQ(2u, systemMgr.SystemsPostUpdate().size()); // Remove the entity ecm.RequestRemoveEntity(entity); diff --git a/src/Util.cc b/src/Util.cc index 83ce8faf14..4d9a459ed4 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -711,12 +711,15 @@ std::optional sphericalCoordinates(Entity _entity, // lat / lon / elevation in rad / rad / m auto rad = sphericalCoordinatesComp->Data().PositionTransform( - xyzPose.Pos(), - math::SphericalCoordinates::LOCAL2, + math::CoordinateVector3::Metric(xyzPose.Pos()), + math::SphericalCoordinates::LOCAL, math::SphericalCoordinates::SPHERICAL); + if (!rad.has_value() || !rad->IsSpherical()) + return std::nullopt; + // Return degrees - return math::Vector3d(GZ_RTOD(rad.X()), GZ_RTOD(rad.Y()), rad.Z()); + return math::Vector3d(rad->Lat()->Degree(), rad->Lon()->Degree(), *rad->Z()); } ////////////////////////////////////////////////// @@ -747,15 +750,31 @@ std::optional getGridFieldCoordinates( } } auto position = origin->Data().PositionTransform( - _worldPosition, math::SphericalCoordinates::LOCAL2, + math::CoordinateVector3::Metric(_worldPosition), + math::SphericalCoordinates::LOCAL, _gridField->reference); + if (!position.has_value()) + return std::nullopt; + + if (position->IsMetric()) + return position->AsMetricVector(); + + math::Vector3d out; if (_gridField->reference == math::SphericalCoordinates::SPHERICAL && _gridField->units == components::EnvironmentalData::ReferenceUnits::DEGREES) { - position.X(GZ_RTOD(position.X())); - position.Y(GZ_RTOD(position.Y())); + out.X(position->Lat()->Degree()); + out.Y(position->Lon()->Degree()); } - return position; + else + { + out.X(position->Lat()->Radian()); + out.Y(position->Lon()->Radian()); + } + out.Z(*position->Z()); + + // \todo(iche033) Change the return type to math::CoordinateVector3 + return out; } ////////////////////////////////////////////////// diff --git a/src/cmd/cmdsim.rb.in b/src/cmd/cmdsim.rb.in index 65946d3494..866dc83ca5 100755 --- a/src/cmd/cmdsim.rb.in +++ b/src/cmd/cmdsim.rb.in @@ -458,16 +458,6 @@ has properly set the DYLD_LIBRARY_PATH environment variables." else resourcePathEnv = ENV['GZ_SIM_RESOURCE_PATH'] - if resourcePathEnv.nil? - resourcePathEnv = ENV['IGN_GAZEBO_RESOURCE_PATH'] - - if !resourcePathEnv.nil? - puts " -Using deprecated environment variable [IGN_GAZEBO_RESOURCE_PATH]. -Please use [GZ_SIM_RESOURCE_PATH] instead." - end - end - if !resourcePathEnv.nil? resourcePaths = resourcePathEnv.split(':') for resourcePath in resourcePaths diff --git a/src/gui/Gui.cc b/src/gui/Gui.cc index 035d082299..2d6f4549f1 100644 --- a/src/gui/Gui.cc +++ b/src/gui/Gui.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -29,7 +30,10 @@ #include #include #include +#include +#include +#include "gz/sim/Constants.hh" #include "gz/sim/InstallationDirectories.hh" #include "gz/sim/Util.hh" #include "gz/sim/config.hh" @@ -47,6 +51,119 @@ namespace sim { // Inline bracket to help doxygen filtering. inline namespace GZ_SIM_VERSION_NAMESPACE { +namespace { + +std::unique_ptr parseDefaultPlugins( + const std::string &_defaultConfig) +{ + const auto resolvedDefaultConfigPath = + gz::gui::App()->ResolveConfigFile(_defaultConfig); + auto pluginsDoc = std::make_unique(); + if (pluginsDoc->LoadFile(resolvedDefaultConfigPath.c_str()) == + tinyxml2::XML_SUCCESS) + { + // Remove everything that's not a plugin + for (auto elem = pluginsDoc->FirstChildElement(); elem != nullptr;) + { + if (std::strcmp("plugin", elem->Value()) != 0) + { + auto tmp = elem; + elem = elem->NextSiblingElement(); + pluginsDoc->DeleteChild(tmp); + } + else + { + elem = elem->NextSiblingElement(); + } + } + } + + return pluginsDoc; +} + +auto combineUserAndDefaultPlugins( + std::unique_ptr _userPlugins, + const tinyxml2::XMLDocument &_defaultPlugins, bool _includeDefaultPlugins) +{ + if (_includeDefaultPlugins) + { + auto combinedPlugins = std::make_unique(); + _defaultPlugins.DeepCopy(combinedPlugins.get()); + + std::set processedUserPlugins; + for (auto pluginElem = _userPlugins->FirstChildElement("plugin"); + pluginElem != nullptr; + pluginElem = pluginElem->NextSiblingElement("plugin")) + { + const char *pluginFilename = pluginElem->Attribute("filename"); + + bool replacedPlugin{false}; + for (auto elem = combinedPlugins->FirstChildElement("plugin"); + elem != nullptr && processedUserPlugins.count(elem) == 0; + elem = elem->NextSiblingElement("plugin")) + { + if (elem->Attribute("filename", pluginFilename)) + { + auto tmp = elem; + // Insert the replacement + auto clonedPlugin = pluginElem->DeepClone(combinedPlugins.get()); + elem = combinedPlugins->InsertAfterChild(elem, clonedPlugin) + ->ToElement(); + // Remove the original + combinedPlugins->DeleteNode(tmp); + replacedPlugin = true; + } + } + if (!replacedPlugin) + { + auto clonedPlugin = pluginElem->DeepClone(combinedPlugins.get()); + auto insertedElem = combinedPlugins->InsertEndChild(clonedPlugin); + processedUserPlugins.insert(insertedElem ); + } + } + + return combinedPlugins; + } + return _userPlugins; +} + +/// \brief Various policies that affect the behavior of the GUI +struct GuiPolicies +{ + /// \brief Whether to include default plugins + bool includeGuiDefaultPlugins{true}; + + /// \brief Parse policies from a GUI message + /// \param[in] _msg Input message + /// \return A GuiPolicies object populated from parsing the message. + static GuiPolicies ParsePolicies(const msgs::GUI &_msg) + { + GuiPolicies policies; + for (const auto &data : _msg.header().data()) + { + if (data.key() == "gz:policies") + { + tinyxml2::XMLDocument doc; + if (data.value_size() > 0) + { + if (doc.Parse(data.value(0).c_str()) == tinyxml2::XML_SUCCESS) + { + tinyxml2::XMLHandle handle(doc); + auto elem = handle.FirstChildElement(kPoliciesTag.data()) + .FirstChildElement("include_gui_default_plugins") + .ToElement(); + if (elem) + { + elem->QueryBoolText(&policies.includeGuiDefaultPlugins); + } + } + } + } + } + return policies; + } +}; +} namespace gui { /// \brief Get the path to the default config file. If the file doesn't exist @@ -434,6 +551,9 @@ std::unique_ptr createGui( // Load plugins after creating GuiRunner, so they can access worldName if (_loadPluginsFromSdf) { + const auto guiPolicies = GuiPolicies::ParsePolicies(res); + auto userPlugins = std::make_unique(); + std::string pluginsXml = ""; for (int p = 0; p < res.plugin_size(); ++p) { const auto &plugin = res.plugin(p); @@ -444,13 +564,13 @@ std::unique_ptr createGui( if (fileName == "GzScene3D") { std::vector extras{"GzSceneManager", - "InteractiveViewControl", - "CameraTracking", - "MarkerManager", - "SelectEntities", - "EntityContextMenuPlugin", - "Spawn", - "VisualizationCapabilities"}; + "InteractiveViewControl", + "CameraTracking", + "MarkerManager", + "SelectEntities", + "EntityContextMenuPlugin", + "Spawn", + "VisualizationCapabilities"}; std::string msg{ "The [GzScene3D] GUI plugin has been removed since Garden.\n" @@ -460,7 +580,7 @@ std::unique_ptr createGui( for (auto extra : extras) { - msg += "* " + extra + "\n"; + msg += "* " + extra + "\n"; auto newPlugin = res.add_plugin(); newPlugin->set_filename(extra); @@ -478,15 +598,23 @@ std::unique_ptr createGui( fileName = "MinimalScene"; } + pluginsXml += "" + + plugin.innerxml() + "\n"; + } + userPlugins->Parse(pluginsXml.c_str()); - std::string pluginStr = "" + - plugin.innerxml() + ""; - - tinyxml2::XMLDocument pluginDoc; - pluginDoc.Parse(pluginStr.c_str()); + const auto defaultPlugins = parseDefaultPlugins(defaultConfig); + auto pluginsToLoad = combineUserAndDefaultPlugins( + std::move(userPlugins), *defaultPlugins, + guiPolicies.includeGuiDefaultPlugins); - app->LoadPlugin(fileName, - pluginDoc.FirstChildElement("plugin")); + gzdbg << "Loading plugins:\n"; + for (auto pluginElem = pluginsToLoad->FirstChildElement("plugin"); + pluginElem != nullptr; + pluginElem = pluginElem->NextSiblingElement("plugin")) + { + app->LoadPlugin(pluginElem->Attribute("filename"), pluginElem); + gzdbg << pluginElem->Attribute("filename") << "\n"; } } } diff --git a/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.cc b/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.cc index de9149b5b1..97a2912208 100644 --- a/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.cc +++ b/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.cc @@ -21,8 +21,6 @@ #include "GlobalIlluminationCiVct.hh" -#include "gz/rendering/GlobalIlluminationCiVct.hh" - using namespace gz; using namespace sim; diff --git a/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.hh b/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.hh index 13f53e45dc..eacde8b043 100644 --- a/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.hh +++ b/src/gui/plugins/global_illumination_civct/CiVctCascadePrivate.hh @@ -26,18 +26,8 @@ #include "Tsa.hh" -namespace gz -{ - namespace rendering - { - inline namespace GZ_SIM_VERSION_NAMESPACE - { - /// Forward declare the only ptr we need - class CiVctCascade; - typedef std::shared_ptr CiVctCascadePtr; - } // namespace GZ_SIM_GAZEBO_VERSION_NAMESPACE - } // namespace rendering -} // namespace gz + +#include "gz/rendering/GlobalIlluminationCiVct.hh" namespace gz { diff --git a/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.cc b/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.cc index d2b8f4c20c..cfab7f414f 100644 --- a/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.cc +++ b/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.cc @@ -172,13 +172,13 @@ GlobalIlluminationCiVct::~GlobalIlluminationCiVct() } ///////////////////////////////////////////////// -void GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() +bool GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() REQUIRES(this->dataPtr->serviceMutex) { auto loadedEngNames = rendering::loadedEngines(); if (loadedEngNames.empty()) { - return; + return false; } // assume there is only one engine loaded @@ -194,11 +194,11 @@ void GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() { gzerr << "Internal error: failed to load engine [" << engineName << "]. GlobalIlluminationCiVct plugin won't work." << std::endl; - return; + return false; } if (engine->SceneCount() == 0) - return; + return false; // assume there is only one scene // load scene @@ -206,12 +206,13 @@ void GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() if (!scene) { gzerr << "Internal error: scene is null." << std::endl; - return; + return false; } - if (!scene->IsInitialized() || scene->VisualCount() == 0) + if (!scene->IsInitialized() || scene->VisualCount() == 0 || + scene->LightCount() == 0) { - return; + return false; } // Create visual @@ -225,6 +226,7 @@ void GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() << std::endl; gz::gui::App()->findChild()->removeEventFilter(this); + return false; } else { @@ -254,6 +256,7 @@ void GlobalIlluminationCiVct::LoadGlobalIlluminationCiVct() this->OnRefreshCamerasImpl(); } + return true; } /// \brief XML helper to retrieve values and handle errors @@ -358,9 +361,7 @@ void GlobalIlluminationCiVct::LoadConfig( const tinyxml2::XMLElement *_pluginElem) { if (this->title.empty()) - this->title = "Global Illumination (VCT)"; - - std::lock_guard lock(this->dataPtr->serviceMutex); + this->title = "Global Illumination (CI VCT)"; if (auto elem = _pluginElem->FirstChildElement("enabled")) { @@ -447,15 +448,25 @@ bool GlobalIlluminationCiVct::eventFilter(QObject *_obj, QEvent *_event) { if (_event->type() == gz::gui::events::Render::kType) { - // This event is called in Scene3d's RenderThread, so it's safe to make + // This event is called in the render thread, so it's safe to make // rendering calls here - std::lock_guard lock(this->dataPtr->serviceMutex); if (!this->dataPtr->initialized) { - this->LoadGlobalIlluminationCiVct(); + if (this->LoadGlobalIlluminationCiVct()) + { + this->SetEnabled(this->dataPtr->enabled); + this->SetBounceCount(this->dataPtr->bounceCount); + this->SetHighQuality(this->dataPtr->highQuality); + this->SetAnisotropic(this->dataPtr->anisotropic); + this->SetDebugVisualizationMode(this->dataPtr->debugVisMode); + this->EnabledChanged(); + this->LightingChanged(); + this->DebugVisualizationModeChanged(); + } } + std::lock_guard lock(this->dataPtr->serviceMutex); if (this->dataPtr->gi) { if (!this->dataPtr->visualDirty && !this->dataPtr->gi->Enabled() && @@ -563,10 +574,6 @@ bool GlobalIlluminationCiVct::eventFilter(QObject *_obj, QEvent *_event) this->dataPtr->resetRequested = false; } } - else - { - gzerr << "GI pointer is not set" << std::endl; - } } // Standard event processing diff --git a/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.hh b/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.hh index 6ebaee5741..d5327ae32f 100644 --- a/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.hh +++ b/src/gui/plugins/global_illumination_civct/GlobalIlluminationCiVct.hh @@ -103,7 +103,8 @@ inline namespace GZ_SIM_VERSION_NAMESPACE public: bool eventFilter(QObject *_obj, QEvent *_event) override; /// \brief Load the scene and attach LidarVisual to the scene - public: void LoadGlobalIlluminationCiVct(); + /// \return True if GI CIVCT is loaded successfully, false otherwise. + public: bool LoadGlobalIlluminationCiVct(); /// \brief Set debug visualization mode GlogbalIllumination /// \param[in] _mode Index of selected debug visualization mode diff --git a/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.cc b/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.cc index 0d6400c1a5..3abbabaec4 100644 --- a/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.cc +++ b/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.cc @@ -166,13 +166,13 @@ GlobalIlluminationVct::~GlobalIlluminationVct() } ///////////////////////////////////////////////// -void GlobalIlluminationVct::LoadGlobalIlluminationVct() +bool GlobalIlluminationVct::LoadGlobalIlluminationVct() REQUIRES(this->dataPtr->serviceMutex) { auto loadedEngNames = rendering::loadedEngines(); if (loadedEngNames.empty()) { - return; + return false; } // assume there is only one engine loaded @@ -188,11 +188,11 @@ void GlobalIlluminationVct::LoadGlobalIlluminationVct() { gzerr << "Internal error: failed to load engine [" << engineName << "]. GlobalIlluminationVct plugin won't work." << std::endl; - return; + return false; } if (engine->SceneCount() == 0) - return; + return false; // assume there is only one scene // load scene @@ -200,15 +200,16 @@ void GlobalIlluminationVct::LoadGlobalIlluminationVct() if (!scene) { gzerr << "Internal error: scene is null." << std::endl; - return; + return false; } - if (!scene->IsInitialized() || scene->VisualCount() == 0) + if (!scene->IsInitialized() || scene->VisualCount() == 0 || + scene->LightCount() == 0) { - return; + return false; } - // Create lidar visual + // Create GI gzdbg << "Creating GlobalIlluminationVct" << std::endl; auto root = scene->RootVisual(); @@ -219,6 +220,7 @@ void GlobalIlluminationVct::LoadGlobalIlluminationVct() << std::endl; gz::gui::App()->findChild()->removeEventFilter(this); + return false; } else { @@ -228,6 +230,7 @@ void GlobalIlluminationVct::LoadGlobalIlluminationVct() this->dataPtr->scene = scene; this->dataPtr->initialized = true; } + return true; } /// \brief XML helper to retrieve values and handle errors @@ -319,8 +322,6 @@ void GlobalIlluminationVct::LoadConfig(const tinyxml2::XMLElement *_pluginElem) if (this->title.empty()) this->title = "Global Illumination (VCT)"; - std::lock_guard lock(this->dataPtr->serviceMutex); - if (auto elem = _pluginElem->FirstChildElement("enabled")) { GetXmlBool(elem, this->dataPtr->enabled); @@ -394,15 +395,35 @@ bool GlobalIlluminationVct::eventFilter(QObject *_obj, QEvent *_event) { if (_event->type() == gz::gui::events::Render::kType) { - // This event is called in Scene3d's RenderThread, so it's safe to make + // This event is called in render thread, so it's safe to make // rendering calls here - std::lock_guard lock(this->dataPtr->serviceMutex); if (!this->dataPtr->initialized) { - this->LoadGlobalIlluminationVct(); + if (this->LoadGlobalIlluminationVct()) + { + // update properties and notify QML + this->SetEnabled(this->dataPtr->enabled); + this->SetResolutionX(this->dataPtr->resolution[0]); + this->SetResolutionY(this->dataPtr->resolution[1]); + this->SetResolutionZ(this->dataPtr->resolution[2]); + this->SetOctantCountX(this->dataPtr->octantCount[0]); + this->SetOctantCountY(this->dataPtr->octantCount[1]); + this->SetOctantCountZ(this->dataPtr->octantCount[2]); + this->SetBounceCount(this->dataPtr->bounceCount); + this->SetHighQuality(this->dataPtr->highQuality); + this->SetAnisotropic(this->dataPtr->anisotropic); + this->SetConserveMemory(this->dataPtr->conserveMemory); + this->SetThinWallCounter(this->dataPtr->thinWallCounter); + this->SetDebugVisualizationMode(this->dataPtr->debugVisMode); + this->EnabledChanged(); + this->LightingChanged(); + this->SettingsChanged(); + this->DebugVisualizationModeChanged(); + } } + std::lock_guard lock(this->dataPtr->serviceMutex); if (this->dataPtr->gi) { if (this->dataPtr->resetVisual) @@ -485,10 +506,6 @@ bool GlobalIlluminationVct::eventFilter(QObject *_obj, QEvent *_event) this->dataPtr->debugVisualizationDirty = false; } } - else - { - gzerr << "GI pointer is not set" << std::endl; - } } // Standard event processing diff --git a/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.hh b/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.hh index fde6a6979b..19a6d3ec61 100644 --- a/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.hh +++ b/src/gui/plugins/global_illumination_vct/GlobalIlluminationVct.hh @@ -156,7 +156,8 @@ inline namespace GZ_SIM_VERSION_NAMESPACE public: bool eventFilter(QObject *_obj, QEvent *_event) override; /// \brief Load the scene and attach LidarVisual to the scene - public: void LoadGlobalIlluminationVct(); + /// \return True if GI VCT is loaded successfully, false otherwise. + public: bool LoadGlobalIlluminationVct(); /// \brief Set debug visualization mode GlogbalIllumination /// \param[in] _mode Index of selected debug visualization mode diff --git a/src/gui/plugins/joint_position_controller/JointPositionController.hh b/src/gui/plugins/joint_position_controller/JointPositionController.hh index 0e23ca4bc9..172f893f65 100644 --- a/src/gui/plugins/joint_position_controller/JointPositionController.hh +++ b/src/gui/plugins/joint_position_controller/JointPositionController.hh @@ -25,6 +25,17 @@ #include #include +#ifndef _WIN32 +# define JointPositionController_EXPORTS_API \ + __attribute__ ((visibility ("default"))) +#else +# if (defined(JointPositionController_EXPORTS)) +# define JointPositionController_EXPORTS_API __declspec(dllexport) +# else +# define JointPositionController_EXPORTS_API __declspec(dllimport) +# endif +#endif + Q_DECLARE_METATYPE(gz::sim::Entity) namespace gz @@ -36,7 +47,8 @@ namespace gui class JointPositionControllerPrivate; /// \brief Model holding information about joints - class JointsModel : public QStandardItemModel + class JointPositionController_EXPORTS_API JointsModel : + public QStandardItemModel { Q_OBJECT @@ -88,7 +100,8 @@ namespace gui /// ``: Load the widget pointed at the given model, so it's not /// necessary to select it. If a model is given at startup, the plugin starts /// in locked mode. - class JointPositionController : public sim::GuiSystem + class JointPositionController_EXPORTS_API JointPositionController : + public sim::GuiSystem { Q_OBJECT diff --git a/src/gui/plugins/plot_3d/Plot3D.hh b/src/gui/plugins/plot_3d/Plot3D.hh index d3d7836e5a..180f68a785 100644 --- a/src/gui/plugins/plot_3d/Plot3D.hh +++ b/src/gui/plugins/plot_3d/Plot3D.hh @@ -24,6 +24,16 @@ #include "gz/gui/qt.h" +#ifndef _WIN32 +# define Plot3D_EXPORTS_API __attribute__ ((visibility ("default"))) +#else +# if (defined(Plot3D_EXPORTS)) +# define Plot3D_EXPORTS_API __declspec(dllexport) +# else +# define Plot3D_EXPORTS_API __declspec(dllimport) +# endif +#endif + namespace gz { namespace sim @@ -59,7 +69,7 @@ namespace gui /// After this number is reached, the older points start being deleted. /// Defaults to 1000. /// - class Plot3D : public gz::sim::GuiSystem + class Plot3D_EXPORTS_API Plot3D : public gz::sim::GuiSystem { Q_OBJECT diff --git a/src/gui/plugins/video_recorder/VideoRecorder.cc b/src/gui/plugins/video_recorder/VideoRecorder.cc index 1425476071..f6e17abf34 100644 --- a/src/gui/plugins/video_recorder/VideoRecorder.cc +++ b/src/gui/plugins/video_recorder/VideoRecorder.cc @@ -341,7 +341,7 @@ void VideoRecorder::OnStart(const QString &_format) { std::unique_lock lock(this->dataPtr->recordMutex); this->dataPtr->format = _format.toStdString(); - this->dataPtr->filename = "ign_recording." + this->dataPtr->format; + this->dataPtr->filename = "gz_recording." + this->dataPtr->format; this->dataPtr->recordVideo = true; this->dataPtr->recording = true; } diff --git a/src/systems/breadcrumbs/Breadcrumbs.cc b/src/systems/breadcrumbs/Breadcrumbs.cc index 0f22687984..7db739da98 100644 --- a/src/systems/breadcrumbs/Breadcrumbs.cc +++ b/src/systems/breadcrumbs/Breadcrumbs.cc @@ -387,8 +387,33 @@ bool Breadcrumbs::MakeStatic(Entity _entity, EntityComponentManager &_ecm) Entity childLinkEntity = _ecm.EntityByComponents( components::CanonicalLink(), components::ParentEntity(_entity)); + // If the entity does not have a canonical link, it may be a nested model if (childLinkEntity == kNullEntity) - return false; + { + // Find canonical link within nested model + auto findCanonicalLink = [&_ecm](Entity _parent, auto &&_findCanonicalLink) + { + auto nestedEntities = _ecm.EntitiesByComponents( + components::Model(), components::ParentEntity(_parent)); + for (const auto ent : nestedEntities) + { + auto comp = _ecm.Component(ent); + if (comp) + { + return comp->Data(); + } + else + { + // recursively search for canonical link + return _findCanonicalLink(ent, _findCanonicalLink); + } + } + return kNullEntity; + }; + childLinkEntity = findCanonicalLink(_entity, findCanonicalLink); + if (childLinkEntity == kNullEntity) + return false; + } Entity detachableJointEntity = _ecm.CreateEntity(); _ecm.CreateComponent(detachableJointEntity, diff --git a/src/systems/follow_actor/FollowActor.cc b/src/systems/follow_actor/FollowActor.cc index 99d8315882..88f72c3f84 100644 --- a/src/systems/follow_actor/FollowActor.cc +++ b/src/systems/follow_actor/FollowActor.cc @@ -209,7 +209,9 @@ void FollowActor::PreUpdate(const UpdateInfo &_info, this->dataPtr->lastUpdate = _info.simTime; // Is there a follow target? - if (this->dataPtr->targetEntity == kNullEntity) + if (this->dataPtr->targetEntity == kNullEntity || + !_ecm.HasEntity(this->dataPtr->targetEntity) || + !_ecm.HasEntity(this->dataPtr->actorEntity)) return; // Current world pose diff --git a/src/systems/force_torque/ForceTorque.cc b/src/systems/force_torque/ForceTorque.cc index 8792f514d5..42f8454c4a 100644 --- a/src/systems/force_torque/ForceTorque.cc +++ b/src/systems/force_torque/ForceTorque.cc @@ -44,7 +44,9 @@ #include "gz/sim/components/Pose.hh" #include "gz/sim/components/Sensor.hh" #include "gz/sim/components/World.hh" +#include "gz/sim/components/WrenchMeasured.hh" #include "gz/sim/EntityComponentManager.hh" +#include "gz/sim/System.hh" #include "gz/sim/Util.hh" using namespace gz; @@ -77,7 +79,7 @@ class gz::sim::systems::ForceTorquePrivate public: sensors::SensorFactory sensorFactory; /// \brief Keep list of sensors that were created during the previous - /// `PostUpdate`, so that components can be created during the next + /// `Update`, so that components can be created during the next /// `PreUpdate`. public: std::unordered_set newSensors; @@ -128,6 +130,13 @@ ForceTorque::ForceTorque() ////////////////////////////////////////////////// ForceTorque::~ForceTorque() = default; +////////////////////////////////////////////////// +System::PriorityType ForceTorque::ConfigurePriority() +{ + // Execute after Physics::Update but before systems with default priority. + return ::gz::sim::systems::kPostPhysicsSensorPriority; +} + ////////////////////////////////////////////////// void ForceTorque::PreUpdate(const UpdateInfo &/*_info*/, EntityComponentManager &_ecm) @@ -157,10 +166,10 @@ void ForceTorque::PreUpdate(const UpdateInfo &/*_info*/, } ////////////////////////////////////////////////// -void ForceTorque::PostUpdate(const UpdateInfo &_info, - const EntityComponentManager &_ecm) +void ForceTorque::Update(const UpdateInfo &_info, + EntityComponentManager &_ecm) { - GZ_PROFILE("ForceTorque::PostUpdate"); + GZ_PROFILE("ForceTorque::Update"); // \TODO(anyone) Support rewind if (_info.dt < std::chrono::steady_clock::duration::zero()) @@ -176,15 +185,15 @@ void ForceTorque::PostUpdate(const UpdateInfo &_info, if (!_info.paused) { // check to see if update is necessary - // we only update if there is at least one sensor that needs data - // and that sensor has subscribers. + // we only update if there is at least one sensor that needs data. // note: gz-sensors does its own throttling. Here the check is mainly // to avoid doing work in the ForceTorquePrivate::Update function bool needsUpdate = false; for (const auto &[sensorEntity, sensor] : this->dataPtr->entitySensorMap) { if (sensor->NextDataUpdateTime() <= _info.simTime && - sensor->HasConnections()) + (sensor->HasConnections() || + _ecm.Component(sensorEntity) != nullptr)) { needsUpdate = true; break; @@ -203,6 +212,13 @@ void ForceTorque::PostUpdate(const UpdateInfo &_info, // * Apply noise // * Publish to gz-transport topic sensor->Update(_info.simTime, false); + auto wrenchComponent = + _ecm.Component(sensorEntity); + if (wrenchComponent) + { + const auto &measuredWrench = sensor->MeasuredWrench(); + *wrenchComponent = components::WrenchMeasured(measuredWrench); + } } } @@ -444,8 +460,9 @@ void ForceTorquePrivate::RemoveForceTorqueEntities( } GZ_ADD_PLUGIN(ForceTorque, System, + ForceTorque::ISystemConfigurePriority, ForceTorque::ISystemPreUpdate, - ForceTorque::ISystemPostUpdate + ForceTorque::ISystemUpdate ) GZ_ADD_PLUGIN_ALIAS(ForceTorque, "gz::sim::systems::ForceTorque") diff --git a/src/systems/force_torque/ForceTorque.hh b/src/systems/force_torque/ForceTorque.hh index 09b5b7ed70..62e2231e80 100644 --- a/src/systems/force_torque/ForceTorque.hh +++ b/src/systems/force_torque/ForceTorque.hh @@ -41,8 +41,9 @@ namespace systems /// quantites are expressed, not the point of application. class ForceTorque: public System, + public ISystemConfigurePriority, public ISystemPreUpdate, - public ISystemPostUpdate + public ISystemUpdate { /// \brief Constructor public: ForceTorque(); @@ -50,13 +51,16 @@ namespace systems /// \brief Destructor public: ~ForceTorque() override; + /// Documentation inherited + public: System::PriorityType ConfigurePriority() final; + /// Documentation inherited public: void PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ecm) final; /// Documentation inherited - public: void PostUpdate(const UpdateInfo &_info, - const EntityComponentManager &_ecm) final; + public: void Update(const UpdateInfo &_info, + EntityComponentManager &_ecm) final; /// \brief Private data pointer. private: std::unique_ptr dataPtr; diff --git a/src/systems/hydrodynamics/Hydrodynamics.cc b/src/systems/hydrodynamics/Hydrodynamics.cc index 171ca8f021..eed111deff 100644 --- a/src/systems/hydrodynamics/Hydrodynamics.cc +++ b/src/systems/hydrodynamics/Hydrodynamics.cc @@ -340,7 +340,11 @@ void Hydrodynamics::Configure( << "\thttps://github.com/gazebosim/gz-sim/pull/1888" << std::endl; } + // Added mass according to Fossen's equations (p 37) + // Note: Adding added mass here is deprecated and will be removed in + // Gazebo J as this formulation has instabilities. + bool addedMassSpecified = false; this->dataPtr->Ma = Eigen::MatrixXd::Zero(6, 6); for(auto i = 0; i < 6; i++) { @@ -350,12 +354,25 @@ void Hydrodynamics::Configure( prefix += "Dot"; prefix += snameConventionVel[j]; this->dataPtr->Ma(i, j) = SdfParamDouble(_sdf, prefix, 0); + addedMassSpecified = (std::abs(this->dataPtr->Ma(i, j)) > 1e-6) + || addedMassSpecified; } } _sdf->Get("disable_coriolis", this->dataPtr->disableCoriolis, false); - _sdf->Get("disable_added_mass", this->dataPtr->disableAddedMass, false); - + _sdf->Get("disable_added_mass", + this->dataPtr->disableAddedMass, false); + if (!this->dataPtr->disableAddedMass && addedMassSpecified) + { + gzwarn << "The use of added mass through this plugin is deprecated and " + << "will be removed in Gazebo J* as this formulation has instabilities. " + << "We recommend using the SDF `` tag based method " + << "[http://sdformat.org/spec?ver=1.11&elem=link" + << "#inertial_fluid_added_mass]" + << "To get rid of this warning we recommend setting " + << "`` to true and updating your model" + << std::endl; + } // Create model object, to access convenient functions auto model = gz::sim::Model(_entity); diff --git a/src/systems/hydrodynamics/Hydrodynamics.hh b/src/systems/hydrodynamics/Hydrodynamics.hh index 1ada82b467..42d960a0ce 100644 --- a/src/systems/hydrodynamics/Hydrodynamics.hh +++ b/src/systems/hydrodynamics/Hydrodynamics.hh @@ -46,12 +46,12 @@ namespace systems /// quadratic drag and coriolis force. /// /// ### Diagonal terms: - /// * - Added mass in x direction [kg] - /// * - Added mass in y direction [kg] - /// * - Added mass in z direction [kg] - /// * - Added mass in roll direction [kgm^2] - /// * - Added mass in pitch direction [kgm^2] - /// * - Added mass in yaw direction [kgm^2] + /// * - (Deprecated) Added mass in x direction [kg] + /// * - (Deprecated) Added mass in y direction [kg] + /// * - (Deprecated) Added mass in z direction [kg] + /// * - (Deprecated) Added mass in roll direction [kgm^2] + /// * - (Deprecated) Added mass in pitch direction [kgm^2] + /// * - (Deprecated) Added mass in yaw direction [kgm^2] /// * - Quadratic damping, 2nd order, x component [kg/m] /// * - Linear damping, 1st order, x component [kg] /// * - Quadratic damping, 2nd order, y component [kg/m] @@ -70,10 +70,13 @@ namespace systems /// non-diagonal sides. We use the SNAMe convention of naming search terms. /// (x, y, z) correspond to the respective axis. (k, m, n) correspond to /// roll, pitch and yaw. Similarly U, V, W represent velocity vectors in - /// X, Y and Z axis while P, Q, R representangular velocity in roll, pitch + /// X, Y and Z axis while P, Q, R represent angular velocity in roll, pitch /// and yaw axis respectively. /// * Added Mass: <{x|y|z|k|m|n}Dot{U|V|W|P|Q|R}> e.g. - /// Units are either kg or kgm^2 depending on the choice of terms. + /// (Deprecated) Units are either kg or kgm^2 depending on the + /// choice of terms. You should use the sdf method based spec + // for `fluid_added_mass`: + /// http://sdformat.org/spec?ver=1.11&elem=link#inertial_fluid_added_mass /// * Quadratic Damping With abs term (this is probably what you want): /// <{x|y|z|k|m|n}{U|V|W|P|Q|R}abs{U|V|W|P|Q|R}> /// e.g. diff --git a/src/systems/joint_state_publisher/JointStatePublisher.cc b/src/systems/joint_state_publisher/JointStatePublisher.cc index c8085198f4..92b608fdc6 100644 --- a/src/systems/joint_state_publisher/JointStatePublisher.cc +++ b/src/systems/joint_state_publisher/JointStatePublisher.cc @@ -129,7 +129,8 @@ void JointStatePublisher::CreateComponents(EntityComponentManager &_ecm, } // Create joint force component if one doesn't exist - if (!_ecm.EntityHasComponentType(_joint, components::JointForce().TypeId())) + if (!_ecm.EntityHasComponentType(_joint, + components::JointForce().TypeId())) { _ecm.CreateComponent(_joint, components::JointForce()); } diff --git a/src/systems/lens_flare/LensFlare.cc b/src/systems/lens_flare/LensFlare.cc index 8f099d6653..6739bb4e71 100644 --- a/src/systems/lens_flare/LensFlare.cc +++ b/src/systems/lens_flare/LensFlare.cc @@ -128,8 +128,9 @@ void LensFlare::Configure( } // Get Camera Name - this->dataPtr->cameraName = scopedName(this->dataPtr->entity, - _ecm, "::", false); + this->dataPtr->cameraName = + removeParentScope(scopedName(this->dataPtr->entity, + _ecm, "::", false), "::"); // call function that connects to post render event this->dataPtr->postRenderConn = diff --git a/src/systems/lighter_than_air_dynamics/LighterThanAirDynamics.cc b/src/systems/lighter_than_air_dynamics/LighterThanAirDynamics.cc index c895235e22..050cc43674 100644 --- a/src/systems/lighter_than_air_dynamics/LighterThanAirDynamics.cc +++ b/src/systems/lighter_than_air_dynamics/LighterThanAirDynamics.cc @@ -457,8 +457,3 @@ GZ_ADD_PLUGIN( GZ_ADD_PLUGIN_ALIAS( LighterThanAirDynamics, "gz::sim::systems::LighterThanAirDynamics") - -// TODO(CH3): Deprecated, remove on version 8 -GZ_ADD_PLUGIN_ALIAS( - LighterThanAirDynamics, - "ignition::gazebo::systems::LighterThanAirDynamics") diff --git a/src/systems/log/LogPlayback.cc b/src/systems/log/LogPlayback.cc index df759ae79f..b217a35142 100644 --- a/src/systems/log/LogPlayback.cc +++ b/src/systems/log/LogPlayback.cc @@ -510,14 +510,6 @@ void LogPlayback::Update(const UpdateInfo &_info, EntityComponentManager &_ecm) { auto msgType = iter->Type(); - // Support ignition.msgs for backwards compatibility. Remove on gz-sim9 - std::string deprecatedPrefix{"ignition.msgs"}; - auto pos = msgType.find(deprecatedPrefix); - if (pos != std::string::npos) - { - msgType.replace(pos, deprecatedPrefix.size(), "gz.msgs"); - } - if (msgType == "gz.msgs.SerializedState") { msgs::SerializedState msg; diff --git a/src/systems/logical_audio_sensor_plugin/LogicalAudioSensorPlugin.cc b/src/systems/logical_audio_sensor_plugin/LogicalAudioSensorPlugin.cc index a460e620c2..e4d633cd59 100644 --- a/src/systems/logical_audio_sensor_plugin/LogicalAudioSensorPlugin.cc +++ b/src/systems/logical_audio_sensor_plugin/LogicalAudioSensorPlugin.cc @@ -405,7 +405,7 @@ void LogicalAudioSensorPluginPrivate::CreateAudioSource( }; // create services for this source - const auto validName = topicFromScopedName(entity, _ecm, false); + const auto validName = topicFromScopedName(entity, _ecm, true); if (validName.empty()) { gzerr << "Failed to create valid topics with entity scoped name [" @@ -503,7 +503,7 @@ void LogicalAudioSensorPluginPrivate::CreateMicrophone( // create the detection publisher for this microphone auto pub = this->node.Advertise( - topicFromScopedName(entity, _ecm, false) + "/detection"); + topicFromScopedName(entity, _ecm, true) + "/detection"); if (!pub) { gzerr << "Error creating a detection publisher for microphone " diff --git a/src/systems/multicopter_motor_model/MulticopterMotorModel.cc b/src/systems/multicopter_motor_model/MulticopterMotorModel.cc index 2bfe779776..02fa87b774 100644 --- a/src/systems/multicopter_motor_model/MulticopterMotorModel.cc +++ b/src/systems/multicopter_motor_model/MulticopterMotorModel.cc @@ -411,7 +411,8 @@ void MulticopterMotorModel::PreUpdate(const UpdateInfo &_info, const auto parentLinkName = _ecm.Component( this->dataPtr->jointEntity); - this->dataPtr->parentLinkName = parentLinkName->Data(); + if (parentLinkName) + this->dataPtr->parentLinkName = parentLinkName->Data(); } if (this->dataPtr->linkEntity == kNullEntity) @@ -447,14 +448,6 @@ void MulticopterMotorModel::PreUpdate(const UpdateInfo &_info, doUpdateForcesAndMoments = false; } - if (!_ecm.Component( - this->dataPtr->jointEntity)) - { - _ecm.CreateComponent(this->dataPtr->jointEntity, - components::JointVelocityCmd({0})); - doUpdateForcesAndMoments = false; - } - if (!_ecm.Component(this->dataPtr->linkEntity)) { _ecm.CreateComponent(this->dataPtr->linkEntity, components::WorldPose()); @@ -682,11 +675,10 @@ void MulticopterMotorModelPrivate::UpdateForcesAndMoments( refMotorRotVel = this->rotorVelocityFilter->UpdateFilter( this->refMotorInput, this->samplingTime); - const auto jointVelCmd = _ecm.Component( - this->jointEntity); - *jointVelCmd = components::JointVelocityCmd( - {this->turningDirection * refMotorRotVel - / this->rotorVelocitySlowdownSim}); + _ecm.SetComponentData( + this->jointEntity, + {this->turningDirection * refMotorRotVel + / this->rotorVelocitySlowdownSim}); } } } diff --git a/src/systems/optical_tactile_plugin/OpticalTactilePlugin.cc b/src/systems/optical_tactile_plugin/OpticalTactilePlugin.cc index f1d6d618fa..e2bf376e1e 100644 --- a/src/systems/optical_tactile_plugin/OpticalTactilePlugin.cc +++ b/src/systems/optical_tactile_plugin/OpticalTactilePlugin.cc @@ -530,6 +530,7 @@ void OpticalTactilePluginPrivate::Load(const EntityComponentManager &_ecm) int contactSensorCounter = 0; sdf::Sensor depthCameraSdf; components::Pose depthCameraPose = components::Pose(); + std::string depthCameraTopic; for (const Entity &sensor : sensorsInsideLink) { if (_ecm.EntityHasComponentType(sensor, components::DepthCamera::typeId)) @@ -538,6 +539,10 @@ void OpticalTactilePluginPrivate::Load(const EntityComponentManager &_ecm) depthCameraSdf = _ecm.Component(sensor)->Data(); depthCameraPose = *(_ecm.Component(sensor)); + auto depthCameraTopicComp = + _ecm.Component(sensor); + if (depthCameraTopicComp) + depthCameraTopic = depthCameraTopicComp->Data(); } if (_ecm.EntityHasComponentType(sensor, components::ContactSensor::typeId)) @@ -558,16 +563,6 @@ void OpticalTactilePluginPrivate::Load(const EntityComponentManager &_ecm) } // Store depth camera update rate - if (!depthCameraSdf.Element()->HasElement("update_rate")) - { - if (!this->initErrorPrinted) - { - gzerr << "Depth camera should have an value " - << "(only printed once)" << std::endl; - this->initErrorPrinted = true; - } - return; - } this->cameraUpdateRate = depthCameraSdf.UpdateRate(); // Depth camera data is float, so convert Pose3d to Pose3f @@ -581,20 +576,27 @@ void OpticalTactilePluginPrivate::Load(const EntityComponentManager &_ecm) depthCameraPose.Data().Rot().Z()); // Configure subscriber for depth camera images - if (!depthCameraSdf.Element()->HasElement("topic")) + if (depthCameraTopic.empty()) { - gzwarn << "Depth camera publishing to __default__ topic. " - << "It's possible that two depth cameras are publishing into the same " - << "topic" << std::endl; + // get the topic from sdf if the one in sensor topic component is empty + depthCameraTopic = depthCameraSdf.Topic(); } - else + + if (depthCameraTopic.empty()) { - gzdbg << "Depth camera publishing to " - << depthCameraSdf.Topic() << " topic" << std::endl; + if (!this->initErrorPrinted) + { + gzerr << "Depth camera topic is empty. " << std::endl; + this->initErrorPrinted = true; + } + return; } + gzdbg << "Depth camera publishing to " + << depthCameraTopic << " topic" << std::endl; + std::string topic = - "/" + depthCameraSdf.Topic() + "/points"; + "/" + depthCameraTopic + "/points"; if (!this->node.Subscribe(topic, &OpticalTactilePluginPrivate::DepthCameraCallback, this)) { diff --git a/src/systems/physics/Physics.cc b/src/systems/physics/Physics.cc index 28f78e9032..5d12e422b5 100644 --- a/src/systems/physics/Physics.cc +++ b/src/systems/physics/Physics.cc @@ -93,6 +93,7 @@ #include "gz/sim/EntityComponentManager.hh" #include "gz/sim/Model.hh" +#include "gz/sim/System.hh" #include "gz/sim/Util.hh" // Components @@ -100,6 +101,7 @@ #include "gz/sim/components/AngularAcceleration.hh" #include "gz/sim/components/AngularVelocity.hh" #include "gz/sim/components/AngularVelocityCmd.hh" +#include "gz/sim/components/AngularVelocityReset.hh" #include "gz/sim/components/AxisAlignedBox.hh" #include "gz/sim/components/BatterySoC.hh" #include "gz/sim/components/CanonicalLink.hh" @@ -117,13 +119,17 @@ #include "gz/sim/components/JointPositionLimitsCmd.hh" #include "gz/sim/components/JointPositionReset.hh" #include "gz/sim/components/JointType.hh" +#include "gz/sim/components/JointForce.hh" #include "gz/sim/components/JointVelocity.hh" #include "gz/sim/components/JointVelocityCmd.hh" #include "gz/sim/components/JointVelocityLimitsCmd.hh" #include "gz/sim/components/JointVelocityReset.hh" +#include "gz/sim/components/JointForce.hh" +#include "gz/sim/components/JointForceCmd.hh" #include "gz/sim/components/LinearAcceleration.hh" #include "gz/sim/components/LinearVelocity.hh" #include "gz/sim/components/LinearVelocityCmd.hh" +#include "gz/sim/components/LinearVelocityReset.hh" #include "gz/sim/components/Link.hh" #include "gz/sim/components/Model.hh" #include "gz/sim/components/Name.hh" @@ -131,7 +137,6 @@ #include "gz/sim/components/ParentLinkName.hh" #include "gz/sim/components/ExternalWorldWrenchCmd.hh" #include "gz/sim/components/JointTransmittedWrench.hh" -#include "gz/sim/components/JointForceCmd.hh" #include "gz/sim/components/Physics.hh" #include "gz/sim/components/PhysicsEnginePlugin.hh" #include "gz/sim/components/Pose.hh" @@ -432,7 +437,7 @@ class gz::sim::systems::PhysicsPrivate } return true; }}; - /// \brief msgs::Contacts equality comparison function. + /// \brief msgs::Wrench equality comparison function. public: std::function wrenchEql{ [](const msgs::Wrench &_a, const msgs::Wrench &_b) @@ -448,8 +453,6 @@ class gz::sim::systems::PhysicsPrivate /// \brief Environment variable which holds paths to look for engine plugins public: std::string pluginPathEnv = "GZ_SIM_PHYSICS_ENGINE_PATH"; - public: std::string pluginPathEnvDeprecated = \ - "IGN_GAZEBO_PHYSICS_ENGINE_PATH"; ////////////////////////////////////////////////// ////////////// Optional Features ///////////////// @@ -632,7 +635,6 @@ class gz::sim::systems::PhysicsPrivate ////////////////////////////////////////////////// // Nested Models - /// \brief Feature list to construct nested models public: struct NestedModelFeatureList : physics::FeatureList< MinimumFeatureList, @@ -764,6 +766,13 @@ Physics::Physics() : System(), dataPtr(std::make_unique()) { } +////////////////////////////////////////////////// +System::PriorityType Physics::ConfigurePriority() +{ + // Use constant from System.hh + return ::gz::sim::systems::kPhysicsPriority; +} + ////////////////////////////////////////////////// void Physics::Configure(const Entity &_entity, const std::shared_ptr &_sdf, @@ -844,8 +853,8 @@ void Physics::Configure(const Entity &_entity, physics::FeaturePolicy3d>>(); if (classNames.empty()) { - gzerr << "No physics plugins found in library [" << pathToLib << "]." - << std::endl; + gzerr << "No physics plugins implementing required interface found in " + << "library [" << pathToLib << "]." << std::endl; return; } @@ -1034,6 +1043,30 @@ void PhysicsPrivate::CreateWorldEntities(const EntityComponentManager &_ecm, solverFeature->SetSolver(solverComp->Data()); } } + auto solverItersComp = + _ecm.Component(_entity); + if (solverItersComp) + { + auto solverFeature = + this->entityWorldMap.EntityCast( + _entity); + if (!solverFeature) + { + static bool informed{false}; + if (!informed) + { + gzdbg << "Attempting to set physics options, but the " + << "phyiscs engine doesn't support feature " + << "[SolverFeature]. Options will be ignored." + << std::endl; + informed = true; + } + } + else + { + solverFeature->SetSolverIterations(solverItersComp->Data()); + } + } auto physicsComp = _ecm.Component(_entity); @@ -2689,6 +2722,122 @@ void PhysicsPrivate::UpdatePhysics(EntityComponentManager &_ecm) return true; }); + // Reset link linear velocity in world frame + _ecm.Each( + [&](const Entity &_entity, const components::Link *, + const components::WorldLinearVelocityReset *_worldlinearvelocityreset) + { + if (!this->entityLinkMap.HasEntity(_entity)) + { + gzwarn << "Failed to find link [" << _entity + << "]." << std::endl; + return true; + } + + auto linkPtrPhys = this->entityLinkMap.Get(_entity); + if (nullptr == linkPtrPhys) + return true; + + auto freeGroup = linkPtrPhys->FindFreeGroup(); + if (!freeGroup) + return true; + + auto rootLinkPtr = freeGroup->RootLink(); + if (rootLinkPtr != linkPtrPhys) + { + gzdbg << "Attempting to set linear velocity for link [ " << _entity + << " ] which is not root link of the FreeGroup." + << "Velocity won't be set." + << std::endl; + + return true; + } + + this->entityFreeGroupMap.AddEntity(_entity, freeGroup); + + auto worldLinearVelFeature = this->entityFreeGroupMap + .EntityCast(_entity); + if (!worldLinearVelFeature) + { + static bool informed{false}; + if (!informed) + { + gzdbg << "Attempting to set link linear velocity, but the " + << "physics engine doesn't support velocity commands. " + << "Velocity won't be set." + << std::endl; + informed = true; + } + return true; + } + + // Linear velocity in world frame + math::Vector3d worldLinearVel = _worldlinearvelocityreset->Data(); + + worldLinearVelFeature->SetWorldLinearVelocity( + math::eigen3::convert(worldLinearVel)); + + return true; + }); + + // Reset link angular velocity in world frame + _ecm.Each( + [&](const Entity &_entity, const components::Link *, + const components::WorldAngularVelocityReset + *_worldangularvelocityreset) + { + if (!this->entityLinkMap.HasEntity(_entity)) + { + gzwarn << "Failed to find link [" << _entity + << "]." << std::endl; + return true; + } + + auto linkPtrPhys = this->entityLinkMap.Get(_entity); + if (nullptr == linkPtrPhys) + return true; + + auto freeGroup = linkPtrPhys->FindFreeGroup(); + if (!freeGroup) + return true; + + auto rootLinkPtr = freeGroup->RootLink(); + if(rootLinkPtr != linkPtrPhys) + { + gzdbg << "Attempting to set angular velocity for link [ " << _entity + << " ] which is not root link of the FreeGroup." + << "Velocity won't be set." + << std::endl; + + return true; + } + + this->entityFreeGroupMap.AddEntity(_entity, freeGroup); + + auto worldAngularVelFeature = this->entityFreeGroupMap + .EntityCast(_entity); + + if (!worldAngularVelFeature) + { + static bool informed{false}; + if (!informed) + { + gzdbg << "Attempting to set link angular velocity, but the " + << "physics engine doesn't support velocity commands. " + << "Velocity won't be set." + << std::endl; + informed = true; + } + return true; + } + // Angular velocity in world frame + math::Vector3d worldAngularVel = _worldangularvelocityreset->Data(); + + worldAngularVelFeature->SetWorldAngularVelocity( + math::eigen3::convert(worldAngularVel)); + + return true; + }); // Populate bounding box info // Only compute bounding box if component exists to avoid unnecessary @@ -2837,6 +2986,7 @@ void PhysicsPrivate::ResetPhysics(EntityComponentManager &_ecm) { jointPhys->SetVelocity(i, 0.0); jointPhys->SetPosition(i, 0.0); + jointPhys->SetForce(i, 0.0); } return true; @@ -3624,6 +3774,34 @@ void PhysicsPrivate::UpdateSim(EntityComponentManager &_ecm, _ecm.RemoveComponent(entity); } + std::vector entitiesLinearVelocityReset; + _ecm.Each( + [&](const Entity &_entity, + components::WorldLinearVelocityReset *) -> bool + { + entitiesLinearVelocityReset.push_back(_entity); + return true; + }); + + for (const auto entity : entitiesLinearVelocityReset) + { + _ecm.RemoveComponent(entity); + } + + std::vector entitiesAngularVelocityReset; + _ecm.Each( + [&](const Entity &_entity, + components::WorldAngularVelocityReset *) -> bool + { + entitiesAngularVelocityReset.push_back(_entity); + return true; + }); + + for (const auto entity : entitiesAngularVelocityReset) + { + _ecm.RemoveComponent(entity); + } + std::vector entitiesCustomContactSurface; _ecm.Each( [&](const Entity &_entity, @@ -3674,12 +3852,20 @@ void PhysicsPrivate::UpdateSim(EntityComponentManager &_ecm, return true; }); - _ecm.Each( - [&](const Entity &, components::JointVelocityCmd *_vel) -> bool - { - std::fill(_vel->Data().begin(), _vel->Data().end(), 0.0); - return true; - }); + { + std::vector entitiesJointVelocityCmd; + _ecm.Each( + [&](const Entity &_entity, components::JointVelocityCmd *) -> bool + { + entitiesJointVelocityCmd.push_back(_entity); + return true; + }); + + for (const auto entity : entitiesJointVelocityCmd) + { + _ecm.RemoveComponent(entity); + } + } _ecm.Each( [&](const Entity &, components::SlipComplianceCmd *_slip) -> bool @@ -3687,21 +3873,37 @@ void PhysicsPrivate::UpdateSim(EntityComponentManager &_ecm, std::fill(_slip->Data().begin(), _slip->Data().end(), 0.0); return true; }); - GZ_PROFILE_END(); - _ecm.Each( - [&](const Entity &, components::AngularVelocityCmd *_vel) -> bool - { - _vel->Data() = math::Vector3d::Zero; - return true; - }); + { + std::vector entitiesAngularVelocityCmd; + _ecm.Each( + [&](const Entity &_entity, components::AngularVelocityCmd *) -> bool + { + entitiesAngularVelocityCmd.push_back(_entity); + return true; + }); - _ecm.Each( - [&](const Entity &, components::LinearVelocityCmd *_vel) -> bool - { - _vel->Data() = math::Vector3d::Zero; - return true; - }); + for (const auto entity : entitiesAngularVelocityCmd) + { + _ecm.RemoveComponent(entity); + } + } + + { + std::vector entitiesLinearVelocityCmd; + _ecm.Each( + [&](const Entity &_entity, components::LinearVelocityCmd *) -> bool + { + entitiesLinearVelocityCmd.push_back(_entity); + return true; + }); + + for (const auto entity : entitiesLinearVelocityCmd) + { + _ecm.RemoveComponent(entity); + } + } + GZ_PROFILE_END(); // Update joint positions GZ_PROFILE_BEGIN("Joints"); @@ -3738,6 +3940,22 @@ void PhysicsPrivate::UpdateSim(EntityComponentManager &_ecm, } return true; }); + // Update joint Forces + _ecm.Each( + [&](const Entity &_entity, components::Joint *, + components::JointForce *_jointForce) -> bool + { + if (auto jointPhys = this->entityJointMap.Get(_entity)) + { + _jointForce->Data().resize(jointPhys->GetDegreesOfFreedom()); + for (std::size_t i = 0; i < jointPhys->GetDegreesOfFreedom(); + ++i) + { + _jointForce->Data()[i] = jointPhys->GetForce(i); + } + } + return true; + }); GZ_PROFILE_END(); // Update joint transmitteds diff --git a/src/systems/physics/Physics.hh b/src/systems/physics/Physics.hh index 256ee5ac75..698050a9dc 100644 --- a/src/systems/physics/Physics.hh +++ b/src/systems/physics/Physics.hh @@ -87,6 +87,7 @@ namespace systems class Physics: public System, public ISystemConfigure, + public ISystemConfigurePriority, public ISystemReset, public ISystemUpdate { @@ -102,6 +103,9 @@ namespace systems EntityComponentManager &_ecm, EventManager &_eventMgr) final; + /// Documentation inherited + public: System::PriorityType ConfigurePriority() final; + // Documentation inherited public: void Reset(const UpdateInfo &_info, EntityComponentManager &_ecm) final; diff --git a/src/systems/pose_publisher/PosePublisher.cc b/src/systems/pose_publisher/PosePublisher.cc index 28fbbdc8d4..395f3dc9bf 100644 --- a/src/systems/pose_publisher/PosePublisher.cc +++ b/src/systems/pose_publisher/PosePublisher.cc @@ -252,7 +252,7 @@ void PosePublisher::Configure(const Entity &_entity, this->dataPtr->usePoseV = _sdf->Get("use_pose_vector_msg", this->dataPtr->usePoseV).first; - std::string poseTopic = topicFromScopedName(_entity, _ecm, false) + "/pose"; + std::string poseTopic = topicFromScopedName(_entity, _ecm, true) + "/pose"; if (poseTopic.empty()) { poseTopic = "/pose"; diff --git a/src/systems/trajectory_follower/TrajectoryFollower.cc b/src/systems/trajectory_follower/TrajectoryFollower.cc index 1db5e1c2d0..e295686946 100644 --- a/src/systems/trajectory_follower/TrajectoryFollower.cc +++ b/src/systems/trajectory_follower/TrajectoryFollower.cc @@ -111,9 +111,6 @@ class gz::sim::systems::TrajectoryFollowerPrivate /// \brief Whether the trajectory follower behavior should be paused or not. public: bool paused = false; - /// \brief Angular velocity set to zero - public: bool zeroAngVelSet = false; - /// \brief Force angular velocity to be zero when bearing is reached public: bool forceZeroAngVel = false; }; @@ -390,37 +387,22 @@ void TrajectoryFollower::PreUpdate( // Transform the force and torque to the world frame. // Move commands. The vehicle always move forward (X direction). gz::math::Vector3d forceWorld; + gz::math::Vector3d torqueWorld; if (std::abs(bearing.Degree()) <= this->dataPtr->bearingTolerance) { forceWorld = (*comPose).Rot().RotateVector( gz::math::Vector3d(this->dataPtr->forceToApply, 0, 0)); // force angular velocity to be zero when bearing is reached - if (this->dataPtr->forceZeroAngVel && !this->dataPtr->zeroAngVelSet && + if (this->dataPtr->forceZeroAngVel && math::equal (std::abs(bearing.Degree()), 0.0, this->dataPtr->bearingTolerance * 0.5)) { this->dataPtr->link.SetAngularVelocity(_ecm, math::Vector3d::Zero); - this->dataPtr->zeroAngVelSet = true; } } - gz::math::Vector3d torqueWorld; - if (std::abs(bearing.Degree()) > this->dataPtr->bearingTolerance) + else { - // remove angular velocity component otherwise the physics system will set - // the zero ang vel command every iteration - if (this->dataPtr->forceZeroAngVel && this->dataPtr->zeroAngVelSet) - { - auto angVelCmdComp = _ecm.Component( - this->dataPtr->link.Entity()); - if (angVelCmdComp) - { - _ecm.RemoveComponent( - this->dataPtr->link.Entity()); - this->dataPtr->zeroAngVelSet = false; - } - } - int sign = static_cast(std::abs(bearing.Degree()) / bearing.Degree()); torqueWorld = (*comPose).Rot().RotateVector( gz::math::Vector3d(0, 0, sign * this->dataPtr->torqueToApply)); diff --git a/src/systems/user_commands/UserCommands.cc b/src/systems/user_commands/UserCommands.cc index 8f9ba3102c..0eedaa27e5 100644 --- a/src/systems/user_commands/UserCommands.cc +++ b/src/systems/user_commands/UserCommands.cc @@ -80,6 +80,7 @@ #include "gz/sim/EntityComponentManager.hh" #include "gz/sim/Model.hh" #include "gz/sim/SdfEntityCreator.hh" +#include "gz/sim/System.hh" #include "gz/sim/Util.hh" #include "gz/sim/World.hh" #include "gz/sim/components/ContactSensorData.hh" @@ -617,6 +618,13 @@ bool UserCommandsInterface::HasContactSensor(const Entity _collision) return false; } +////////////////////////////////////////////////// +System::PriorityType UserCommands::ConfigurePriority() +{ + // Use constant from System.hh + return ::gz::sim::systems::kUserCommandsPriority; +} + ////////////////////////////////////////////////// void UserCommands::Configure(const Entity &_entity, const std::shared_ptr &_sdf, @@ -1274,7 +1282,6 @@ bool CreateCommand::Execute() // Spherical coordinates if (createMsg->has_spherical_coordinates()) { - gzerr << "HasSphericalCoordinates" << std::endl; auto scComp = this->iface->ecm->Component( this->iface->worldEntity); if (nullptr == scComp) @@ -1286,25 +1293,33 @@ bool CreateCommand::Execute() } else { - // deg to rad - math::Vector3d latLonEle{ + auto vec = math::CoordinateVector3::Spherical( GZ_DTOR(createMsg->spherical_coordinates().latitude_deg()), GZ_DTOR(createMsg->spherical_coordinates().longitude_deg()), - createMsg->spherical_coordinates().elevation()}; - - auto pos = scComp->Data().PositionTransform(latLonEle, + createMsg->spherical_coordinates().elevation()); + auto pos = scComp->Data().PositionTransform(vec, math::SphericalCoordinates::SPHERICAL, - math::SphericalCoordinates::LOCAL2); - - // Override pos and add to yaw - if (!createPose.has_value()) - createPose = math::Pose3d::Zero; - createPose.value().SetX(pos.X()); - createPose.value().SetY(pos.Y()); - createPose.value().SetZ(pos.Z()); - createPose.value().Rot() = math::Quaterniond(0, 0, - GZ_DTOR(createMsg->spherical_coordinates().heading_deg())) * - createPose.value().Rot(); + math::SphericalCoordinates::LOCAL); + + if (!pos.has_value() || !pos->IsMetric()) + { + gzerr << "Trying to create entity [" << desiredName + << "] using spherical coordinates, but spherical to local " + << "position conversion failed. Entity will be created at the " + << "world origin." << std::endl; + } + else + { + // Override pos and add to yaw + if (!createPose.has_value()) + createPose = math::Pose3d::Zero; + createPose.value().SetX(*pos->X()); + createPose.value().SetY(*pos->Y()); + createPose.value().SetZ(*pos->Z()); + createPose.value().Rot() = math::Quaterniond(0, 0, + GZ_DTOR(createMsg->spherical_coordinates().heading_deg())) * + createPose.value().Rot(); + } } } @@ -1694,17 +1709,22 @@ bool SphericalCoordinatesCommand::Execute() return false; } - // deg to rad - math::Vector3d latLonEle{ + auto vec = math::CoordinateVector3::Spherical( GZ_DTOR(sphericalCoordinatesMsg->latitude_deg()), GZ_DTOR(sphericalCoordinatesMsg->longitude_deg()), - sphericalCoordinatesMsg->elevation()}; - - auto pos = scComp->Data().PositionTransform(latLonEle, + sphericalCoordinatesMsg->elevation()); + auto pos = scComp->Data().PositionTransform(vec, math::SphericalCoordinates::SPHERICAL, - math::SphericalCoordinates::LOCAL2); + math::SphericalCoordinates::LOCAL); + if (!pos.has_value() || !pos->IsMetric()) + { + gzerr << "Trying to move entity [" << entity + << "] using spherical coordinates, but spherical to local " + << "position conversion failed." << std::endl; + return false; + } - math::Pose3d pose{pos.X(), pos.Y(), pos.Z(), 0, 0, + math::Pose3d pose{*pos->X(), *pos->Y(), *pos->Z(), 0, 0, GZ_DTOR(sphericalCoordinatesMsg->heading_deg())}; auto poseCmdComp = diff --git a/src/systems/user_commands/UserCommands.hh b/src/systems/user_commands/UserCommands.hh index 0aa396bd00..791fc8548d 100644 --- a/src/systems/user_commands/UserCommands.hh +++ b/src/systems/user_commands/UserCommands.hh @@ -73,6 +73,7 @@ namespace systems class UserCommands final: public System, public ISystemConfigure, + public ISystemConfigurePriority, public ISystemPreUpdate { /// \brief Constructor @@ -87,6 +88,9 @@ namespace systems EntityComponentManager &_ecm, EventManager &_eventMgr) override; + /// Documentation inherited + public: System::PriorityType ConfigurePriority() final; + /// \brief All received commands are queued in order of reception and /// executed in order during PreUpdate. /// \param[in] _info Contains information about the current simulation diff --git a/test/benchmark/ecm_serialize.cc b/test/benchmark/ecm_serialize.cc index 2d976df4db..ad314e9693 100644 --- a/test/benchmark/ecm_serialize.cc +++ b/test/benchmark/ecm_serialize.cc @@ -41,24 +41,24 @@ inline namespace GZ_SIM_VERSION_NAMESPACE { namespace components { using IntComponent = components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.IntComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.IntComponent", IntComponent) using UIntComponent = components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.UIntComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.UIntComponent", UIntComponent) using DoubleComponent = components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.DoubleComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.DoubleComponent", DoubleComponent) using StringComponent = components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.StringComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.StringComponent", StringComponent) using BoolComponent = components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.BoolComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.BoolComponent", BoolComponent) } } diff --git a/test/integration/each_new_removed.cc b/test/integration/each_new_removed.cc index 144381aa43..cbd367b333 100644 --- a/test/integration/each_new_removed.cc +++ b/test/integration/each_new_removed.cc @@ -37,7 +37,7 @@ using namespace gz; using namespace std::chrono_literals; using IntComponent = sim::components::Component; -GZ_SIM_REGISTER_COMPONENT("ign_gazebo_components.IntComponent", +GZ_SIM_REGISTER_COMPONENT("gz_sim_components.IntComponent", IntComponent) class EachNewRemovedFixture : public InternalFixture<::testing::Test> diff --git a/test/integration/examples_build.cc b/test/integration/examples_build.cc index 51cb4ec84a..4b20a80f84 100644 --- a/test/integration/examples_build.cc +++ b/test/integration/examples_build.cc @@ -57,28 +57,6 @@ struct ExampleEntry } }; -////////////////////////////////////////////////// -/// Filter examples that are known to not build or require -/// specific configurations -/// \param[in] _entry Example entry to check -/// \return true if example entry should be built, false otherwise -bool FilterEntry(const ExampleEntry &_entry) -{ - math::SemanticVersion cmakeVersion{std::string(CMAKE_VERSION)}; - if (cmakeVersion < math::SemanticVersion(3, 11, 0) && - (_entry.base == "custom_sensor_system" || - _entry.base == "gtest_setup")) - { - gzdbg << "Skipping [" << _entry.base - << "] test, which requires CMake version " - << ">= 3.11.0. Currently using CMake " - << cmakeVersion - << std::endl; - return false; - } - return true; -} - ////////////////////////////////////////////////// /// Generate a list of examples to be built. std::vector GetExamples() @@ -116,11 +94,6 @@ void ExamplesBuild::Build(const ExampleEntry &_entry) { common::Console::SetVerbosity(4); - if (!FilterEntry(_entry)) - { - GTEST_SKIP(); - } - // Path to examples of the given type ASSERT_TRUE(gz::common::exists(_entry.sourceDir)); diff --git a/test/integration/force_torque_system.cc b/test/integration/force_torque_system.cc index dd4684e627..1841ef1728 100644 --- a/test/integration/force_torque_system.cc +++ b/test/integration/force_torque_system.cc @@ -24,10 +24,15 @@ #include #include +#include "gz/sim/components/ForceTorque.hh" +#include "gz/sim/components/Model.hh" #include "gz/sim/components/Name.hh" #include "gz/sim/components/Sensor.hh" -#include "gz/sim/components/ForceTorque.hh" +#include "gz/sim/components/WrenchMeasured.hh" +#include "gz/sim/Joint.hh" +#include "gz/sim/Link.hh" +#include "gz/sim/Model.hh" #include "gz/sim/Server.hh" #include "gz/sim/SystemLoader.hh" #include "test_config.hh" @@ -43,7 +48,7 @@ class ForceTorqueTest : public InternalFixture<::testing::Test> }; ///////////////////////////////////////////////// -TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(MeasureWeight)) +TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(MeasureWeightTopic)) { using namespace std::chrono_literals; // Start server @@ -59,8 +64,8 @@ TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(MeasureWeight)) // Having iters exactly in sync with update rate can lead to a race condition // in the test between simulation and transport - size_t iters = 999u; - size_t updates = 100u; + const size_t iters = 999u; + const size_t updates = 100u; std::vector wrenches; wrenches.reserve(updates); @@ -100,6 +105,95 @@ TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(MeasureWeight)) } } +///////////////////////////////////////////////// +TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(MeasureWeightECM)) +{ + using namespace std::chrono_literals; + // Start server + ServerConfig serverConfig; + const auto sdfFile = common::joinPaths( + std::string(PROJECT_SOURCE_PATH), "test", "worlds", "force_torque.sdf"); + serverConfig.SetSdfFile(sdfFile); + + Server server(serverConfig); + EXPECT_FALSE(server.Running()); + EXPECT_FALSE(*server.Running(0)); + server.SetUpdatePeriod(1ns); + + // Get entity for //test1/scale/sensor_joint/force_torque_sensor and add + // WrenchMeasured component on first PreUpdate + Entity sensorEntity; + bool firstRun = true; + auto addWrenchComponent = + [&firstRun, &sensorEntity]( + const UpdateInfo &, EntityComponentManager &_ecm) + { + if (firstRun) + { + firstRun = false; + + // Get sensorEntity + auto test1ModelEntity = _ecm.EntityByComponents( + components::Model(), components::Name("test1")); + Model test1Model(test1ModelEntity); + + Model scaleModel(test1Model.ModelByName(_ecm, "scale")); + ASSERT_TRUE(scaleModel.Valid(_ecm)); + + Joint sensorJoint(scaleModel.JointByName(_ecm, "sensor_joint")); + ASSERT_TRUE(sensorJoint.Valid(_ecm)); + + sensorEntity = sensorJoint.SensorByName(_ecm, "force_torque_sensor"); + + // Expect it doesn't yet have WrenchMeasured + EXPECT_EQ(nullptr, + _ecm.Component(sensorEntity)); + + // Add WrenchMeasured + _ecm.CreateComponent(sensorEntity, components::WrenchMeasured()); + + EXPECT_NE(nullptr, + _ecm.Component(sensorEntity)); + } + }; + + // Get the MeasuredWrench for //test1/scale/sensor_joint/force_torque_sensor + msgs::Wrench wrench; + auto getMeasuredWrench = + [&wrench, &sensorEntity](const UpdateInfo &, + const EntityComponentManager &_ecm) + { + auto measuredWrench = + _ecm.Component(sensorEntity); + ASSERT_NE(nullptr, measuredWrench); + if (measuredWrench) + { + wrench = measuredWrench->Data(); + } + }; + + // Add the system + test::Relay testSystem; + testSystem.OnPreUpdate(addWrenchComponent); + testSystem.OnPostUpdate(getMeasuredWrench); + server.AddSystem(testSystem.systemPtr); + server.Run(true, 1, false); + + const size_t iters = 999u; + + // Run server (iters-1) steps, since we already took 1 step above + server.Run(true, iters - 1, false); + ASSERT_EQ(iters, *server.IterationCount()); + + const double kSensorMass = 0.2; + const double kWeightMass = 10; + const double kGravity = 9.8; + const math::Vector3 expectedForce = + math::Vector3d{0, 0, kGravity * (kSensorMass + kWeightMass)}; + EXPECT_EQ(expectedForce, msgs::Convert(wrench.force())); + EXPECT_EQ(math::Vector3d::Zero, msgs::Convert(wrench.torque())); +} + ///////////////////////////////////////////////// TEST_F(ForceTorqueTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(SensorPoseOffset)) { diff --git a/test/integration/log_system.cc b/test/integration/log_system.cc index f867ca731a..a2335cae56 100644 --- a/test/integration/log_system.cc +++ b/test/integration/log_system.cc @@ -774,6 +774,18 @@ TEST_F(LogSystemTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(RecordAndPlayback)) // Start server Server playServer(playServerConfig); + // Simulate a client + gz::transport::Node node; + std::atomic numMsgs = 0; + std::function mockClient = + [&](const msgs::SerializedStepMap &/*_res*/) + { + numMsgs++; + }; + using namespace std::placeholders; + EXPECT_TRUE(node.Subscribe( + "/world/default/state", mockClient)); + // Callback function for entities played back // Compare current pose being played back with the pose from the stateMsg test::Relay playbackPoseTester; @@ -837,6 +849,9 @@ TEST_F(LogSystemTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(RecordAndPlayback)) // checked in the playbackPoseTester playServer.Run(true, 500, false); + // The client should have received some messages. + EXPECT_NE(numMsgs, 0); + // Count the total number of state messages in the log file int nTotal{0}; for (auto it = batch.begin(); it != batch.end(); ++it, ++nTotal) { } diff --git a/test/integration/model.cc b/test/integration/model.cc index f878088631..f4a0f00b2c 100644 --- a/test/integration/model.cc +++ b/test/integration/model.cc @@ -164,6 +164,30 @@ TEST_F(ModelIntegrationTest, SourceFilePath) EXPECT_EQ("/tmp/path", model.SourceFilePath(ecm)); } +////////////////////////////////////////////////// +TEST_F(ModelIntegrationTest, ModelByName) +{ + EntityComponentManager ecm; + + // Model + auto eModel = ecm.CreateEntity(); + Model model(eModel); + EXPECT_EQ(eModel, model.Entity()); + EXPECT_EQ(0u, model.ModelCount(ecm)); + + // Nested Model + auto eNestedModel = ecm.CreateEntity(); + ecm.CreateComponent(eNestedModel, components::Model()); + ecm.CreateComponent(eNestedModel, + components::ParentEntity(eModel)); + ecm.CreateComponent(eNestedModel, + components::Name("nested_model_name")); + + // Check model + EXPECT_EQ(eNestedModel, model.ModelByName(ecm, "nested_model_name")); + EXPECT_EQ(1u, model.ModelCount(ecm)); +} + ////////////////////////////////////////////////// TEST_F(ModelIntegrationTest, LinkByName) { diff --git a/test/integration/physics_system.cc b/test/integration/physics_system.cc index 027005a406..7a50c8c7db 100644 --- a/test/integration/physics_system.cc +++ b/test/integration/physics_system.cc @@ -48,6 +48,7 @@ #include "gz/sim/components/AngularAcceleration.hh" #include "gz/sim/components/AngularVelocity.hh" +#include "gz/sim/components/AngularVelocityReset.hh" #include "gz/sim/components/AxisAlignedBox.hh" #include "gz/sim/components/CanonicalLink.hh" #include "gz/sim/components/Collision.hh" @@ -67,6 +68,7 @@ #include "gz/sim/components/Link.hh" #include "gz/sim/components/LinearAcceleration.hh" #include "gz/sim/components/LinearVelocity.hh" +#include "gz/sim/components/LinearVelocityReset.hh" #include "gz/sim/components/Material.hh" #include "gz/sim/components/Model.hh" #include "gz/sim/components/Name.hh" @@ -747,6 +749,272 @@ TEST_F(PhysicsSystemFixture, EXPECT_NEAR(pos0, positions[1], 0.01); } +///////////////////////////////////////////////// +/// Test linear veocity reset component +TEST_F(PhysicsSystemFixture, + GZ_UTILS_TEST_DISABLED_ON_WIN32(LinearVelocityResetComponent)) +{ + ServerConfig serverConfig; + + const auto sdfFile = std::string(PROJECT_SOURCE_PATH) + + "/test/worlds/diff_drive.sdf"; + + sdf::Root root; + root.Load(sdfFile); + sdf::World *world = root.WorldByIndex(0); + ASSERT_TRUE(nullptr != world); + + // Disable gravity + world->SetGravity(math::Vector3d::Zero); + + serverConfig.SetSdfRoot(root); + + Server server(serverConfig); + + server.SetUpdatePeriod(1ms); + + // Create a system just to get the ECM + EntityComponentManager *ecm{nullptr}; + test::Relay testSystem; + testSystem.OnPreUpdate([&](const UpdateInfo &, + EntityComponentManager &_ecm) + { + ecm = &_ecm; + }); + server.AddSystem(testSystem.systemPtr); + + // Run server and check we have the ECM + EXPECT_EQ(nullptr, ecm); + server.Run(true, 1, false); + EXPECT_NE(nullptr, ecm); + + // Get Link Entity's and objects + const std::string rootLinkName{"chassis"}; + auto rootLinkEntity = ecm->EntityByComponents( + components::Link(), components::Name(rootLinkName)); + Link rootLink(rootLinkEntity); + ASSERT_TRUE(rootLink.Valid(*ecm)); + + const std::string childLinkName{"caster"}; + auto childLinkEntity = ecm->EntityByComponents( + components::Link(), components::Name(childLinkName)); + Link childLink(childLinkEntity); + ASSERT_TRUE(childLink.Valid(*ecm)); + + // Enable velocity checks for each link + rootLink.EnableVelocityChecks(*ecm, true); + childLink.EnableVelocityChecks(*ecm, true); + EXPECT_NE(nullptr, + ecm->Component(rootLinkEntity)); + EXPECT_NE(nullptr, + ecm->Component(childLinkEntity)); + + // Step and expect velocities near zero + server.Run(true, 1, false); + { + auto rootLinkLinearVel = rootLink.WorldLinearVelocity(*ecm); + auto childLinkLinearVel = childLink.WorldLinearVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkLinearVel); + ASSERT_NE(std::nullopt, childLinkLinearVel); + EXPECT_EQ(math::Vector3d::Zero, rootLinkLinearVel); + EXPECT_EQ(math::Vector3d::Zero, childLinkLinearVel); + } + + const math::Vector3d vel0(0.125, -0.5, 3.5); + + // Reset child link velocity to nonzero components (upward in Z) + // This shouldn't do anything, since it is not the root link of its FreeGroup + ecm->CreateComponent(childLinkEntity, + components::WorldLinearVelocityReset(vel0)); + + // Step and expect that all velocities are still zero + server.Run(true, 1, false); + { + auto rootLinkLinearVel = rootLink.WorldLinearVelocity(*ecm); + auto childLinkLinearVel = childLink.WorldLinearVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkLinearVel); + ASSERT_NE(std::nullopt, childLinkLinearVel); + EXPECT_EQ(math::Vector3d::Zero, rootLinkLinearVel); + EXPECT_EQ(math::Vector3d::Zero, childLinkLinearVel); + } + + // Reset root link velocity to nonzero components (upward in Z) + ecm->CreateComponent(rootLinkEntity, + components::WorldLinearVelocityReset(vel0)); + + // Step and expect all links to have similar velocity + server.Run(true, 1, false); + { + auto rootLinkLinearVel = rootLink.WorldLinearVelocity(*ecm); + auto childLinkLinearVel = childLink.WorldLinearVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkLinearVel); + ASSERT_NE(std::nullopt, childLinkLinearVel); + EXPECT_EQ(vel0, rootLinkLinearVel); + EXPECT_EQ(vel0, childLinkLinearVel); + } + // expect that reset component has been removed + EXPECT_EQ(nullptr, + ecm->Component(rootLinkEntity)); + + // Reset root link velocity to zero + ecm->CreateComponent(rootLinkEntity, + components::WorldLinearVelocityReset(math::Vector3d::Zero)); + + // Step and expect all links to have zero velocity + server.Run(true, 1, false); + { + auto rootLinkLinearVel = rootLink.WorldLinearVelocity(*ecm); + auto childLinkLinearVel = childLink.WorldLinearVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkLinearVel); + ASSERT_NE(std::nullopt, childLinkLinearVel); + // TODO(scpeters) figure out why this isn't working + // EXPECT_EQ(math::Vector3d::Zero, rootLinkLinearVel); + // EXPECT_EQ(math::Vector3d::Zero, childLinkLinearVel); + } + // expect that reset component has been removed + EXPECT_EQ(nullptr, + ecm->Component(rootLinkEntity)); +} + +///////////////////////////////////////////////// +/// Test angular veocity reset component +TEST_F(PhysicsSystemFixture, + GZ_UTILS_TEST_DISABLED_ON_WIN32(AngularVelocityResetComponent)) +{ + ServerConfig serverConfig; + + const auto sdfFile = std::string(PROJECT_SOURCE_PATH) + + "/test/worlds/diff_drive.sdf"; + + sdf::Root root; + root.Load(sdfFile); + sdf::World *world = root.WorldByIndex(0); + ASSERT_TRUE(nullptr != world); + + // Disable gravity + world->SetGravity(math::Vector3d::Zero); + + serverConfig.SetSdfRoot(root); + + Server server(serverConfig); + + server.SetUpdatePeriod(1ms); + + // Create a system just to get the ECM + EntityComponentManager *ecm{nullptr}; + test::Relay testSystem; + testSystem.OnPreUpdate([&](const UpdateInfo &, + EntityComponentManager &_ecm) + { + ecm = &_ecm; + }); + server.AddSystem(testSystem.systemPtr); + + // Run server and check we have the ECM + EXPECT_EQ(nullptr, ecm); + server.Run(true, 1, false); + EXPECT_NE(nullptr, ecm); + + // Get model Entity's + const std::string modelName("vehicle"); + auto modelEntity = ecm->EntityByComponents( + components::Model(), components::Name(modelName)); + Model model(modelEntity); + ASSERT_TRUE(model.Valid(*ecm)); + + // Get Link Entity's and objects + const std::string rootLinkName{"chassis"}; + auto rootLinkEntity = ecm->EntityByComponents( + components::Link(), components::Name(rootLinkName)); + Link rootLink(rootLinkEntity); + ASSERT_TRUE(rootLink.Valid(*ecm)); + + const std::string childLinkName{"caster"}; + auto childLinkEntity = ecm->EntityByComponents( + components::Link(), components::Name(childLinkName)); + Link childLink(childLinkEntity); + ASSERT_TRUE(childLink.Valid(*ecm)); + + // Enable velocity checks for each link + rootLink.EnableVelocityChecks(*ecm, true); + childLink.EnableVelocityChecks(*ecm, true); + EXPECT_NE(nullptr, + ecm->Component(rootLinkEntity)); + EXPECT_NE(nullptr, + ecm->Component(childLinkEntity)); + + // Step and expect velocities near zero + server.Run(true, 1, false); + { + auto rootLinkAngularVel = rootLink.WorldAngularVelocity(*ecm); + auto childLinkAngularVel = childLink.WorldAngularVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkAngularVel); + ASSERT_NE(std::nullopt, childLinkAngularVel); + EXPECT_EQ(math::Vector3d::Zero, rootLinkAngularVel); + EXPECT_EQ(math::Vector3d::Zero, childLinkAngularVel); + } + + const math::Pose3d pose0(0, 0, 1, 0, 0, 0); + // To avoid collision with ground plane while rotating + model.SetWorldPoseCmd(*ecm, pose0); + server.Run(true, 1, false); + + const math::Vector3d vel0(0.1, 5.0, 0.1); + + // Reset child link velocity to nonzero components + // This shouldn't do anything, since it is not the root link of its FreeGroup + ecm->CreateComponent(childLinkEntity, + components::WorldAngularVelocityReset(vel0)); + + // Step and expect that all velocities are still zero + server.Run(true, 1, false); + { + auto rootLinkAngularVel = rootLink.WorldAngularVelocity(*ecm); + auto childLinkAngularVel = childLink.WorldAngularVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkAngularVel); + ASSERT_NE(std::nullopt, childLinkAngularVel); + EXPECT_EQ(math::Vector3d::Zero, rootLinkAngularVel); + EXPECT_EQ(math::Vector3d::Zero, childLinkAngularVel); + } + + // Reset root link velocity to nonzero components + ecm->CreateComponent(rootLinkEntity, + components::WorldAngularVelocityReset(vel0)); + + // Step and expect all links to have similar velocity + server.Run(true, 1, false); + { + auto rootLinkAngularVel = rootLink.WorldAngularVelocity(*ecm); + auto childLinkAngularVel = childLink.WorldAngularVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkAngularVel); + ASSERT_NE(std::nullopt, childLinkAngularVel); + EXPECT_EQ(vel0, rootLinkAngularVel); + EXPECT_EQ(vel0, childLinkAngularVel); + } + // expect that reset component has been removed + EXPECT_EQ(nullptr, + ecm->Component(rootLinkEntity)); + + // Reset root link velocity to zero + ecm->CreateComponent(rootLinkEntity, + components::WorldAngularVelocityReset(math::Vector3d::Zero)); + + // Step and expect all links to have zero velocity + server.Run(true, 1, false); + { + auto rootLinkAngularVel = rootLink.WorldAngularVelocity(*ecm); + auto childLinkAngularVel = childLink.WorldAngularVelocity(*ecm); + ASSERT_NE(std::nullopt, rootLinkAngularVel); + ASSERT_NE(std::nullopt, childLinkAngularVel); + // TODO(scpeters) figure out why this isn't working + // EXPECT_EQ(math::Vector3d::Zero, rootLinkLinearVel); + // EXPECT_EQ(math::Vector3d::Zero, childLinkLinearVel); + } + // expect that reset component has been removed + EXPECT_EQ(nullptr, + ecm->Component(rootLinkEntity)); +} + ///////////////////////////////////////////////// /// Test joint veocity reset component TEST_F(PhysicsSystemFixture, @@ -1834,12 +2102,13 @@ TEST_F(PhysicsSystemFixture, PhysicsOptions) serverConfig.SetSdfFile(common::joinPaths(std::string(PROJECT_SOURCE_PATH), "test", "worlds", "physics_options.sdf")); - bool checked{false}; + bool checkedDart{false}; + bool checkedBullet{false}; // Create a system to check components test::Relay testSystem; testSystem.OnPostUpdate( - [&checked](const sim::UpdateInfo &, + [&checkedDart, &checkedBullet](const sim::UpdateInfo &, const sim::EntityComponentManager &_ecm) { _ecm.EachData()); } - checked = true; + checkedDart = true; + return true; + }); + _ecm.Each( + [&](const gz::sim::Entity &, const components::World *, + const components::PhysicsSolverIterations *_solverIters)->bool + { + EXPECT_NE(nullptr, _solverIters); + if (_solverIters) + { + EXPECT_EQ(100, _solverIters->Data()); + } + checkedBullet = true; return true; }); + }); sim::Server server(serverConfig); server.AddSystem(testSystem.systemPtr); server.Run(true, 1, false); - EXPECT_TRUE(checked); + EXPECT_TRUE(checkedDart); + EXPECT_TRUE(checkedBullet); } ///////////////////////////////////////////////// diff --git a/test/integration/reset_sensors.cc b/test/integration/reset_sensors.cc index 7b9c43d492..be9c3b6a38 100644 --- a/test/integration/reset_sensors.cc +++ b/test/integration/reset_sensors.cc @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -336,6 +337,7 @@ TEST_F(ResetFixture, GZ_UTILS_TEST_DISABLED_ON_MAC(HandleReset)) imageReceiver.msgReceived = false; server.Run(true, 2000 - server.IterationCount().value(), false); + std::this_thread::sleep_for(20ms); // Check iterator state EXPECT_EQ(2000u, server.IterationCount().value()); diff --git a/test/media/levels_log/state.tlog b/test/media/levels_log/state.tlog index 9408ea34b8..b9d7e513df 100644 Binary files a/test/media/levels_log/state.tlog and b/test/media/levels_log/state.tlog differ diff --git a/test/test_config.hh.in b/test/test_config.hh.in index 4681208058..89118966c9 100644 --- a/test/test_config.hh.in +++ b/test/test_config.hh.in @@ -23,7 +23,6 @@ #define PROJECT_SOURCE_PATH "${PROJECT_SOURCE_DIR}" #define PROJECT_BINARY_PATH "${CMAKE_BINARY_DIR}" -#define CMAKE_VERSION "${CMAKE_VERSION}" #define GZ_CONFIG_PATH "@CMAKE_BINARY_DIR@/test/conf" @@ -49,6 +48,9 @@ struct TestWorldSansPhysics static std::string world = std::string("" "" "" + "" + " false" + "" "" diff --git a/test/worlds/air_pressure.sdf b/test/worlds/air_pressure.sdf index 0679f9e280..d66cb0fccd 100644 --- a/test/worlds/air_pressure.sdf +++ b/test/worlds/air_pressure.sdf @@ -5,6 +5,9 @@ 0 + + false + diff --git a/test/worlds/air_speed.sdf b/test/worlds/air_speed.sdf index feb3347655..b23d7ee6d5 100644 --- a/test/worlds/air_speed.sdf +++ b/test/worlds/air_speed.sdf @@ -5,6 +5,9 @@ 0 + + false + diff --git a/test/worlds/force_torque.sdf b/test/worlds/force_torque.sdf index 66c7dd9e87..0c90ff63bb 100644 --- a/test/worlds/force_torque.sdf +++ b/test/worlds/force_torque.sdf @@ -5,7 +5,7 @@ 0 - + true diff --git a/test/worlds/joint_trajectory_controller.sdf b/test/worlds/joint_trajectory_controller.sdf index e761ab49b2..78ae047a68 100644 --- a/test/worlds/joint_trajectory_controller.sdf +++ b/test/worlds/joint_trajectory_controller.sdf @@ -324,10 +324,10 @@ RR_velocity_control_link1 1 0 0 + + 0.02 + - - 0.02 - 0 0 0.1 0 0 0 @@ -335,10 +335,10 @@ RR_velocity_control_link2 1 0 0 + + 0.01 + - - 0.01 - pgs + + + 100 + + 0 + + false + diff --git a/tutorials.md.in b/tutorials.md.in index b75967e1ad..b6f895ec5d 100644 --- a/tutorials.md.in +++ b/tutorials.md.in @@ -4,73 +4,83 @@ Welcome to the Gazebo @GZ_DESIGNATION_CAP@ tutorials. These tutorials will guide you through the process of understanding the capabilities of the Gazebo @GZ_DESIGNATION_CAP@ library and how to use the library effectively. -## Getting Started +## Tutorials + +The Tutorials section contains step-by-step instructions with self-contained examples to help you get started using Gazebo. + +### Beginner * \subpage install "Installation": Install instructions. -* \subpage terminology "Terminology": List of terms used across the documentation. -* \subpage gui_config "GUI configuration": Customizing your layout. -* \subpage server_config "Server configuration": Customizing what system plugins are loaded. +* \subpage move_camera_to_model Move camera to model +* \subpage apply_force_torque "Apply Force and Torque": Apply forces and/or torques to models during simulation through the GUI. +* \subpage mouse_drag "Mouse Drag": Move models by dragging them in the scene using forces and torques. * \subpage model_command "Model Command": Use the CLI to get information about the models in a simulation. * \subpage pause_run_simulation "Pause and Run simulation": Use Gazebo transport API to pause and run simulation. * \subpage reset_simulation Reset simulation -* \subpage resources "Finding resources": The different ways in which Gazebo looks for files. -* \subpage debugging "Debugging": Information about debugging Gazebo. +* \subpage headless_rendering "Headless rendering": Access the GPU on a remote machine to produce sensor data without an X server. -### GUI and rendering features +### Intermediate -* \subpage move_camera_to_model Move camera to model -* \subpage model_photo_shoot "Model Photo Shoot" Taking perspective, top, front, and side pictures of a model. -* \subpage videorecorder "Video Recorder": Record videos from the 3D render window. -* \subpage headless_rendering "Headless rendering": Access the GPU on a remote machine to produce sensor data without an X server. -* \subpage apply_force_torque "Apply Force and Torque": Applying forces and/or torques to models during simulation through the GUI. -* \subpage mouse_drag "Mouse Drag": Move models by dragging them in the scene using forces and torques. +* \subpage log "Logging": Record and play back time series of world state. +* \subpage levels "Levels": Load entities on demand in large environments. -### Migration from Gazebo classic +### Advanced -* \subpage migrationplugins "Plugins": Walk through the differences between writing plugins for Gazebo classic and Gazebo -* \subpage migrationsdf "SDF": Migrating SDF files from Gazebo classic to Gazebo -* \subpage migrationworldapi "World API": Guide on what World C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationmodelapi "Model API": Guide on what Model C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationlightapi "Light API": Guide on what Light C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationjointapi "Joint API": Guide on what Joint C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationactorapi "Actor API": Guide on what Actor C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationlinkapi "Link API": Guide on what Link C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage migrationsensorapi "Sensor API": Guide on what Sensor C++ functions to call in Gazebo when migrating from Gazebo classic -* \subpage ardupilot "Case Study": Migrating the ArduPilot ModelPlugin from Gazebo classic to Gazebo. +* \subpage erbtemplate "ERB Template": Use ERB, a templating language, to generate SDF files for simulation worlds. -## Intermediate +## How-to Guides -* \subpage log "Logging": Record and play back time series of world state. -* \subpage light_config "Light config": Configure lights in the scene. -* \subpage levels "Levels": Load entities on demand in large environments. -* \subpage python_interfaces Python interfaces +The How-to Guides provide recipes for specific "How to..." questions or things you may want to do. +They assume some experience. +If you are an absolute beginner, start with the Tutorials section. -### Specific systems and features +### Beginner -* \subpage detachablejoints "Detachable Joints": Creating models that start off rigidly attached and then get detached during simulation. -* \subpage triggeredpublisher "Triggered Publisher": Using the TriggeredPublisher system to orchestrate actions in simulation. +* \subpage gui_config "GUI configuration": Customize your layout. +* \subpage server_config "Server configuration": Customize what system plugins are loaded. +* \subpage model_photo_shoot "Model Photo Shoot" Taking perspective, top, front, and side pictures of a model. +* \subpage videorecorder "Video Recorder": Record videos from the 3D render window. + +### Intermediate + +* \subpage light_config "Light config": Configure lights in the scene. +* \subpage entity_creation "Entity creation": Insert models or lights using services. * \subpage battery "Battery": Keep track of battery charge on robot models. -* \subpage particle_emitter "Particle emitter": Using particle emitters in simulation -* \subpage spherical_coordinates "Spherical coordinates": Working with latitude and longitude +* \subpage particle_emitter "Particle emitter": Use particle emitters in simulation +* \subpage detachablejoints "Detachable Joints": Create models that start off rigidly attached and then get detached during simulation. +* \subpage triggeredpublisher "Triggered Publisher": Use the TriggeredPublisher system to orchestrate actions in simulation. +* \subpage spherical_coordinates "Spherical coordinates": Work with latitude and longitude +* \subpage underwater_vehicles "Underwater Vehicles": Understand how to simulate underwater vehicles * \subpage logicalaudiosensor "Logical Audio Sensor": Using the LogicalAudioSensor system to mimic logical audio emission and detection in simulation. * \subpage auto_inertia_calculation "Automatic Inertia Calculation": Automatically compute inertia values(mass, mass matrix, center of mass) for SDFormat links. * \subpage jointcontrollers "Joint Controllers": Using available joint controller plugins to control joints. +* \subpage shadow_texture_size "Shadow texture size": Change the texture size of shadows casted by lights. -## Advanced users +### Advanced -* \subpage physics "Physics engines": Loading different physics engines. -* \subpage entity_creation "Entity creation": Insert models or lights using services. -* \subpage erbtemplate "ERB Template": Use ERB, a templating language, to generate SDF files for simulation worlds. -* \subpage distributedsimulation "Distributed Simulation": Spread simulation across several processes. +* \subpage physics "Physics engines": Load different physics engines. -## Developers +### Developers * \subpage createsystemplugins "Create System Plugins": Programmatically access simulation using C++ plugins. -* \subpage usingcomponents "Using components": Using components in a system plugin. +* \subpage usingcomponents "Using components": Using components in a system plugin.* * \subpage rendering_plugins "Rendering plugins": Write plugins that use Gazebo Rendering on the server and client. * \subpage test_fixture "Test Fixture": Writing automated CI tests -## 3D modeling help +### Migration from Gazebo classic + +* \subpage migrationplugins "Plugins": Walk through the differences between writing plugins for Gazebo classic and Gazebo +* \subpage migrationsdf "SDF": Migrating SDF files from Gazebo classic to Gazebo +* \subpage migrationworldapi "World API": Guide on what World C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationmodelapi "Model API": Guide on what Model C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationlightapi "Light API": Guide on what Light C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationjointapi "Joint API": Guide on what Joint C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationactorapi "Actor API": Guide on what Actor C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationlinkapi "Link API": Guide on what Link C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage migrationsensorapi "Sensor API": Guide on what Sensor C++ functions to call in Gazebo when migrating from Gazebo classic +* \subpage ardupilot "Case Study": Migrating the ArduPilot ModelPlugin from Gazebo classic to Gazebo. + +### 3D modeling help * \subpage collada_world_exporter "Collada World Exporter": Export an entire world to a single Collada mesh. * \subpage meshtofuel "Importing a Mesh to Fuel": Build a model directory around a mesh so it can be added to the Gazebo Fuel app. @@ -83,7 +93,7 @@ Gazebo @GZ_DESIGNATION_CAP@ library and how to use the library effectively. * \subpage blender_distort_meshes "Blender mesh distortion": Use a Blender Python script to programmatically deform and distort meshes to customized extents. * \subpage blender_procedural_datasets "Generation of Procedural Datasets with Blender": Use Blender with a Python script to generate procedural datasets of SDF models. -## Maritime +### Maritime * \subpage theory_buoyancy "Buoyancy: " Describe the theory of operation of the buoyancy plugin. @@ -103,6 +113,22 @@ underwater robot. * \subpage surface_vehicles "Create a surface vehicle:" How to create a maritime surface robot. + +## Reference + +The reference section contains information that may come in handy for lookup. + +* \subpage resources "Finding resources": The different ways in which Gazebo looks for files. +* \subpage python_interfaces Python interfaces +* \subpage debugging "Debugging": Information about debugging Gazebo. + +## Concepts + +The concepts section explains things that require additional understanding than the scope of the Tutorials and How-to Guides. + +* \subpage terminology "Terminology": List of terms used across the documentation. +* \subpage distributedsimulation "Distributed Simulation": Spread simulation across several processes. + ## License The code associated with this documentation is licensed under an [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/tutorials/adding_system_plugins.md b/tutorials/adding_system_plugins.md index 0df852a22d..8cfa596b63 100644 --- a/tutorials/adding_system_plugins.md +++ b/tutorials/adding_system_plugins.md @@ -1,4 +1,4 @@ -\page adding_system_plugins +\page adding_system_plugins Adding system plugins # Overview @@ -10,15 +10,15 @@ capabilities to it. Make sure to go through the following tutorial first, where you'll learn how to create the vehicle used in this tutorial. -https://gazebosim.org/api/sim/8/create_vehicle.html +\ref create_vehicle ## Related tutorials -https://gazebosim.org/api/sim/8/createsystemplugins.html +\ref createsystemplugins # Adding a system plugin -[This Gazebo tutorial](https://gazebosim.org/api/sim/8/createsystemplugins.html) +[This Gazebo tutorial](https://gazebosim.org/api/sim/9/createsystemplugins.html) describes what is a system plugin in depth. Intuitively, you can envision a system plugin as a piece of code that modifies the behavior of the simulation when the general physics engine does not exactly capture your needs. @@ -46,7 +46,7 @@ your turtle does not sink anymore. ```bash mkdir -p ~/gazebo_maritime/worlds -wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim8/tutorials/files/adding_system_plugins/buoyant_turtle.sdf -O ~/gazebo_maritime/worlds/buoyant_turtle.sdf +wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim9/tutorials/files/adding_system_plugins/buoyant_turtle.sdf -O ~/gazebo_maritime/worlds/buoyant_turtle.sdf export GZ_SIM_RESOURCE_PATH=:$HOME/gazebo_maritime/models gz sim -r ~/gazebo_maritime/worlds/buoyant_turtle.sdf ``` @@ -130,7 +130,7 @@ And run Gazebo: gz sim -r ~/gazebo_maritime/worlds/buoyant_turtle.sdf ``` -Now, when our simple trajectory controller reaches its target and stops appling +Now, when our simple trajectory controller reaches its target and stops applying force, the turtle stops moving acting like the fluid decelerates its motion. Additionally you can notice how the up and down oscillations are also damped by the effect of the hydrodynamics. diff --git a/tutorials/adding_visuals.md b/tutorials/adding_visuals.md index 7df40c70b2..d3f6f7a8a9 100644 --- a/tutorials/adding_visuals.md +++ b/tutorials/adding_visuals.md @@ -1,4 +1,4 @@ -\page adding_visuals +\page adding_visuals Adding visuals # Overview @@ -8,7 +8,7 @@ mesh to our turtle, making it look much better. ## Related tutorials -https://gazebosim.org/api/sim/8/meshtofuel.html +\ref meshtofuel The next tutorials, although still relevant, are from an older version of Gazebo and some details might be different than the current versions: diff --git a/tutorials/blender_distort_meshes.md b/tutorials/blender_distort_meshes.md index 5f619be97f..3db2f88722 100644 --- a/tutorials/blender_distort_meshes.md +++ b/tutorials/blender_distort_meshes.md @@ -25,7 +25,7 @@ If newer versions do not work for you, Blender 2.92 can be found ## Usage Locate or download the Blender Python -[script](https://github.com/gazebosim/gz-sim/blob/gz-sim8/examples/scripts/blender/distort_mesh.py). +[script](https://github.com/gazebosim/gz-sim/blob/main/examples/scripts/blender/distort_mesh.py). Launch the Blender GUI. diff --git a/tutorials/blender_sdf_exporter.md b/tutorials/blender_sdf_exporter.md index 604ea41d0c..e1b193c7cf 100644 --- a/tutorials/blender_sdf_exporter.md +++ b/tutorials/blender_sdf_exporter.md @@ -12,7 +12,7 @@ mesh/materials/lights feature set. As such feel free to customize the script as ## Using the Blender SDF Exporter -1. Download the blender script in [sdf_exporter.py](https://github.com/gazebosim/gz-sim/tree/gz-sim8/examples/scripts/blender/sdf_exporter.py). +1. Download the blender script in [sdf_exporter.py](https://github.com/gazebosim/gz-sim/tree/main/examples/scripts/blender/sdf_exporter.py). 2. Open the script under Blender's Scripting tab and run it. diff --git a/tutorials/create_system_plugins.md b/tutorials/create_system_plugins.md index dec24591d0..7cc3ac0964 100644 --- a/tutorials/create_system_plugins.md +++ b/tutorials/create_system_plugins.md @@ -10,7 +10,7 @@ following entity types: * Actor To create a system plugin for use in the simulation environment, follow the -steps below. +steps below. The fully working example is available [here](https://github.com/gazebosim/gz-sim/tree/gz-sim9/examples/plugin/system_plugin). ## Decide on interfaces to implement @@ -85,16 +85,15 @@ Implement the system class as usual, for example: In your `CMakeLists.txt` add the following ``` -gz_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}) # Add sources for each plugin to be registered. -add_library(SampleSystem SampleSystem.cc SampleSystem2.cc) +add_library(SampleSystem SHARED SampleSystem.cc SampleSystem2.cc) set_property(TARGET SampleSystem PROPERTY CXX_STANDARD 17) target_link_libraries(SampleSystem - gz-common${GZ_COMMON_VER}::gz-common${GZ_COMMON_VER} - gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER} -) + PRIVATE gz-plugin${GZ_PLUGIN_VER}::gz-plugin${GZ_PLUGIN_VER} + PRIVATE gz-sim9::gz-sim9) ``` ## Loading your plugin diff --git a/tutorials/create_vehicle.md b/tutorials/create_vehicle.md index 988fd32ba4..e66002b42e 100644 --- a/tutorials/create_vehicle.md +++ b/tutorials/create_vehicle.md @@ -1,4 +1,4 @@ -\page create_vehicle +\page create_vehicle Create a maritime vehicle # Overview @@ -46,8 +46,8 @@ Create a `model.sdf` file that contains the Simulator Description Format of the model. You can find more information on the [SDF website](http://sdformat.org/). ```xml - - + + true @@ -65,7 +65,7 @@ model. You can find more information on the [SDF website](http://sdformat.org/). - + 1 1 0.009948450858321252 @@ -73,7 +73,7 @@ model. You can find more information on the [SDF website](http://sdformat.org/). - + 0.08 0 0.05 0 0 0 diff --git a/tutorials/entity_creation.md b/tutorials/entity_creation.md index 6772fb1538..8f82e4774a 100644 --- a/tutorials/entity_creation.md +++ b/tutorials/entity_creation.md @@ -55,7 +55,7 @@ gz service --list /world/world_name/state_async ``` -# Factory message +## Factory message To create new entities in the world we need to use the [gz::msgs::EntityFactory](https://gazebosim.org/api/msgs/9/classgz_1_1msgs_1_1EntityFactory.html) @@ -65,7 +65,7 @@ This message allows us to create entities from strings, files, [Lights](https://gazebosim.org/api/msgs/9/classgz_1_1msgs_1_1Light.html) or even clone models. This tutorial introduces how to create entities from SDF strings and light messages. -## Insert an entity based on a string +### Insert an entity based on a string We will open an empty Gazebo world, let's start creating a sphere in the world. In the next snippet you can see how to create models based on strings. @@ -87,7 +87,7 @@ happen. You may see some traces in the console showing this information. There is an option to create a new entity every time that the message is sent by setting `allow_renaming` to true (you can use the method `set_allow_renaming()`). -## Insert a light +### Insert a light To insert a light in the world we have two options: diff --git a/tutorials/files/lander/lander_visuals.png b/tutorials/files/lander/lander_visuals.png index af12dd03a4..51b08228f2 100644 Binary files a/tutorials/files/lander/lander_visuals.png and b/tutorials/files/lander/lander_visuals.png differ diff --git a/tutorials/files/particle_emitter/particle_emitter_scatter_effects.sdf b/tutorials/files/particle_emitter/particle_emitter_scatter_effects.sdf new file mode 100644 index 0000000000..4a1c8e666b --- /dev/null +++ b/tutorials/files/particle_emitter/particle_emitter_scatter_effects.sdf @@ -0,0 +1,309 @@ + + + + + + + 0.001 + 1.0 + + + + ogre2 + + + + + + + + + RGB camera + floating + 350 + 315 + + camera + false + + + + Depth camera + floating + 350 + 315 + 500 + + depth_camera + false + + + + RGBD: image + floating + 350 + 315 + 320 + + rgbd_camera/image + false + + + + RGBD: depth + floating + 350 + 315 + 500 + 320 + + rgbd_camera/depth_image + false + + + + Thermal camera + floating + 350 + 315 + 500 + 640 + + thermal_camera + false + + + + + + + + + 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 + + + + + + + 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/openrobotics/models/fog generator + + + + 8 0 0.5 0 0.0 3.14 + + 0.05 0.05 0.05 0 0 0 + + 0.1 + + 0.000166667 + 0.000166667 + 0.000166667 + + + + + + 0.1 0.1 0.1 + + + + + + + 0.1 0.1 0.1 + + + + + + + 1.047 + + 320 + 240 + + + 0.1 + 100 + + + 1 + 30 + true + camera + + + + 10 + depth_camera + + 1.05 + + 320 + 240 + R_FLOAT32 + + + 0.1 + 100.0 + + + + + " + lidar + 10 + + + + 640 + 1 + -1.396263 + 1.396263 + + + 1 + 0.01 + 0 + 0 + + + + 0.08 + 10.0 + 0.01 + + + 1 + true + + + + true + + + + 8 0 0.5 0 0.0 3.14 + true + + 0.05 0.05 0.05 0 0 0 + + + + 0.1 0.1 0.1 + + + + + + + 0.1 0.1 0.1 + + + + + + 1.047 + + 320 + 240 + + + 0.1 + 100 + + + 1 + 30 + true + rgbd_camera + + + true + + + + 8 0 0.5 0 0.0 3.14 + true + + 0.05 0.05 0.05 0 0 0 + + + + 0.1 0.1 0.1 + + + + + + + 0.1 0.1 0.1 + + + + + + 1.047 + + 320 + 240 + + + 0.1 + 100 + + + 1 + 30 + true + thermal_camera + + + + + + 0 0 0 0 0 1.570796 + rescue_randy + https://fuel.gazebosim.org/1.0/OpenRobotics/models/Rescue Randy + + + + diff --git a/tutorials/files/point_cloud_to_mesh/blob2.jpg b/tutorials/files/point_cloud_to_mesh/blob2.jpg new file mode 100644 index 0000000000..b78a854313 Binary files /dev/null and b/tutorials/files/point_cloud_to_mesh/blob2.jpg differ diff --git a/tutorials/files/point_cloud_to_mesh/blob2.png b/tutorials/files/point_cloud_to_mesh/blob2.png deleted file mode 100644 index 47c23cbf9c..0000000000 Binary files a/tutorials/files/point_cloud_to_mesh/blob2.png and /dev/null differ diff --git a/tutorials/files/point_cloud_to_mesh/error.jpg b/tutorials/files/point_cloud_to_mesh/error.jpg new file mode 100644 index 0000000000..f1d57861cd Binary files /dev/null and b/tutorials/files/point_cloud_to_mesh/error.jpg differ diff --git a/tutorials/files/point_cloud_to_mesh/hidden_polygons2.jpg b/tutorials/files/point_cloud_to_mesh/hidden_polygons2.jpg new file mode 100644 index 0000000000..584a98976b Binary files /dev/null and b/tutorials/files/point_cloud_to_mesh/hidden_polygons2.jpg differ diff --git a/tutorials/files/point_cloud_to_mesh/hidden_polygons2.png b/tutorials/files/point_cloud_to_mesh/hidden_polygons2.png deleted file mode 100644 index 6dfa068610..0000000000 Binary files a/tutorials/files/point_cloud_to_mesh/hidden_polygons2.png and /dev/null differ diff --git a/tutorials/files/point_cloud_to_mesh/min_space.jpg b/tutorials/files/point_cloud_to_mesh/min_space.jpg new file mode 100644 index 0000000000..e19615659b Binary files /dev/null and b/tutorials/files/point_cloud_to_mesh/min_space.jpg differ diff --git a/tutorials/files/point_cloud_to_mesh/min_space.png b/tutorials/files/point_cloud_to_mesh/min_space.png deleted file mode 100644 index 183a67b119..0000000000 Binary files a/tutorials/files/point_cloud_to_mesh/min_space.png and /dev/null differ diff --git a/tutorials/files/shadow_texture_size/shadow_texsize_2k_to_16k.gif b/tutorials/files/shadow_texture_size/shadow_texsize_2k_to_16k.gif new file mode 100644 index 0000000000..09cfabbea8 Binary files /dev/null and b/tutorials/files/shadow_texture_size/shadow_texsize_2k_to_16k.gif differ diff --git a/tutorials/frame_reference.md b/tutorials/frame_reference.md index 3d904fa19e..e720f1242d 100644 --- a/tutorials/frame_reference.md +++ b/tutorials/frame_reference.md @@ -1,4 +1,4 @@ -\page frame_reference +\page frame_reference Frame of reference # Overview @@ -7,7 +7,7 @@ the conventions used in Gazebo. ## Related tutorials -https://gazebosim.org/api/sim/8/spherical_coordinates.html +\ref spherical_coordinates # Gazebo world frame diff --git a/tutorials/gui_config.md b/tutorials/gui_config.md index 9cc42fa1e0..0304f1131a 100644 --- a/tutorials/gui_config.md +++ b/tutorials/gui_config.md @@ -16,10 +16,33 @@ There are a few places where the GUI configuration can come from: 3. The default configuration file at `$HOME/.gz/sim/<#>/gui.config` \*, where `<#>` is Gazebo Sim's major version. -Each of the items above takes precedence over the ones below it. For example, -if a user chooses a `--gui-config`, the SDF's `` element is ignored. And -the default configuration file is only loaded if no configuration is passed -through the command line or the SDF file. +If a configuration file is specified using `--gui-config`, Gazebo will +ignore both the `` element inside the SDF file and the default +configuration file. Otherwise, Gazebo will load plugins by combining +plugins in the `` element and the default configuration file. +How Gazebo combines these plugins is determined by the +`` policy set in ``: + +- `true`: Plugins + from the default configuration file merged with plugins from the SDF file. + Plugins from SDF files take precedence over plugins from + the default configuration file. This means, if a plugin is specified in + both places, by default, only the one specified in the SDF file will be + loaded. If replacement occurs, the replacement + plugin will take the position of the replaced plugin in the order of plugins. + If replacement does not occur, the plugin is appended to the end of the list. + + The main use case for this policy is for users to rely on + the default list of plugins and only add extra plugins they need for the + application. This policy is also useful for overriding the parameters of a small + subset of the default plugins. This is the default setting in + Gazebo Ionic and later. + +- `false`: If + there are any plugins specified in the SDF file, plugins from the default + configuration file are ignored. This allows the user to have complete + control over which plugins are loaded. This is the default setting in + Gazebo Harmonic and earlier. > \* For log-playback, the default file is > `$HOME/.gz/sim/<#>/playback_gui.config` @@ -28,10 +51,9 @@ through the command line or the SDF file. ### Default configuration -Let's try this in practice. First, let's open Gazebo without passing -any arguments: +Let's try this in practice. First, let's open the default Gazebo world: -`gz sim` +`gz sim default.sdf` You should see an empty world with several plugins loaded by default, such as the 3D Scene, the play/pause button, etc. @@ -57,7 +79,7 @@ Let's try customizing it: 3. Reload Gazebo: - `gz sim` + `gz sim default.sdf` Note how the UI is now in dark mode! @@ -75,7 +97,7 @@ will be created with default values: Let's try overriding the default configuration from an SDF file. Open your favorite editor and save this file as `fuel_preview.sdf`: -``` +```xml @@ -84,6 +106,10 @@ favorite editor and save this file as `fuel_preview.sdf`: name="gz::sim::systems::SceneBroadcaster"> + + false + + @@ -137,7 +163,7 @@ Now let's load this world: `gz sim /fuel_preview.sdf` -Notice how the application has only one GUI plugin loaded, the 3D scene, as defined +Notice how the application has only 3 GUI plugins loaded, as defined on the SDF file above. @image html files/gui_config/fuel_preview.png @@ -147,6 +173,75 @@ the same model loaded into the default GUI layout. @image html files/gui_config/fuel_preview_no_gui.png +Now, let's change the policy so that default plugins are included + +```xml + + + + + + + + true + + + + + + + 3D View + false + docked + + + ogre2 + scene + 1.0 1.0 1.0 + 0.4 0.6 1.0 + 8.3 7 7.8 0 0.5 -2.4 + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + + + https://fuel.gazebosim.org/1.0/OpenRobotics/models/Sun + + + + https://fuel.gazebosim.org/1.0/OpenRobotics/models/Gazebo + + + + +``` + +You will now see the same model loaded in the default GUI layout +similar to when you deleted the `` element altogether. Note that this will also +be the behavior if we removed `` tag. + +@image html files/gui_config/fuel_preview_no_gui.png + ### Command line It's often inconvenient to embed your GUI layout directly into every SDF file. diff --git a/tutorials/headless_rendering.md b/tutorials/headless_rendering.md index 6c01ef756d..787755da47 100644 --- a/tutorials/headless_rendering.md +++ b/tutorials/headless_rendering.md @@ -13,7 +13,7 @@ An easier solution is through the use of [EGL](https://www.khronos.org/egl), whi Example usage: ``` -gz sim -v 4 -s --headless-rendering sensors_demo.sdf +DISPLAY= gz sim -v 4 -s -r --headless-rendering sensors_demo.sdf ``` If you are using Gazebo as a library, then you can configure the @@ -63,14 +63,23 @@ here](https://www.ogre3d.org/2021/02/06/ogre-2-2-5-cerberus-released-and-egl-hea ``` sudo reboot ``` -11. [Install Gazebo](https://gazebosim.org/docs/latest/install). -12. Run a Gazebo world that uses OGRE2 with camera sensors using headless rendering. This will enable EGL. +15. [Install Gazebo](https://gazebosim.org/docs/latest/install). +16. Run a Gazebo world that uses OGRE2 with camera sensors using headless rendering. This will enable EGL. ``` - gz sim -v 4 -s -r --headless-rendering sensors_demo.sdf + DISPLAY= gz sim -v 4 -s -r --headless-rendering sensors_demo.sdf ``` -13. Check that simulation is producing sensor data by ssh'ing into the EC2 - instance from a new terminal and echoing a sensor topic. +17. Check that simulation is producing sensor data by ssh'ing into the EC2 + instance from a new terminal and testing the frequency of a sensor topic. ``` ssh -i SSH_PEM_FILE_USED_DURING_LAUNCH ubuntu@EC_INSTANCE_PUBLIC_IP - gz topic -et /thermal_camera + gz topic -ft /thermal_camera + ``` +18. To verify that the EGL backend was used, try the following command: + ``` + grep -R "EGL Subsystem" ~/.gz/rendering/ogre2.log + ``` + Its output should not be empty, e.g.: + ``` + *** Starting EGL Subsystem *** + *** Stopping EGL Subsystem *** ``` diff --git a/tutorials/install.md b/tutorials/install.md index 2e5bbecea7..7ecadbfd3c 100644 --- a/tutorials/install.md +++ b/tutorials/install.md @@ -1,7 +1,8 @@ \page install Installation -These instructions are for installing only Gazebo. If you're interested -in using all the Gazebo libraries, not only Igniton Gazebo, check out this +These instructions are for installing only Gazebo Sim. If you're interested +in using all the Gazebo libraries including gz-launch, or to install all +libraries from source, check out [Gazebo installation](https://gazebosim.org/docs/latest/install). We recommend following the binary install instructions to get up and running as @@ -50,6 +51,27 @@ installing Gazebo from source. brew install gz-sim<#> ``` +### Windows + +1. First, follow the steps 1-4 of [Gazebo source install](https://gazebosim.org/docs/ionic/install_windows_src/#install-dependencies) + tutorial to install Conda, Visual Studio and set up a Conda environment (we'll call it `gz-ws`). + + Do not forget to activate the Conda env (if not already activated) + inside the Visual Studio Command Prompt: + + ``` + conda activate gz-ws + ``` + +2. Now install Gazebo. + + ``` + conda install gz-sim<#> --channel conda-forge + ``` + + Be sure to replace `<#>` with a number value, such as 8 or 9, depending on + which version you need. + ## Source Install Install from source if you're interested in changing the source code or need a @@ -98,7 +120,7 @@ feature which hasn't been released yet. 2. Install dependencies ``` - brew install --only-dependencies ignition-gazebo<#> + brew install --only-dependencies gz-sim<#> ``` 3. Configure and build @@ -115,6 +137,50 @@ feature which hasn't been released yet. sudo make install ``` +### Windows + +1. First, follow the steps 1-4 of [Gazebo source install](https://gazebosim.org/docs/ionic/install_windows_src/#install-dependencies) + tutorial to install Conda, Visual Studio and set up a Conda environment (we'll call it `gz-ws`). + + Do not forget to activate the Conda env (if not already activated) + inside the Visual Studio Command Prompt: + + ``` + conda activate gz-ws + ``` + +2. Install Gazebo dependencies: + + You can view available versions and their dependencies: + ``` + conda search libgz-sim* --channel conda-forge --info + ``` + + Install the dependencies, replacing `<#>` with the required versions: + ``` + conda install gz-cmake<#> gz-common<#> gz-fuel-tools<#> gz-gui<#> gz-math<#> gz-msgs<#> gz-physics<#> gz-plugin<#> gz-rendering<#> gz-sensors<#> gz-tools<#> gz-transport<#> gz-utils<#> sdformat<#> --channel conda-forge + ``` + +3. Navigate to where you would like to build the library, and clone the repository. + ``` + # Optionally, append `-b gz-sim#` (replace # with a number) to check out a specific version + git clone https://github.com/gazebosim/gz-sim.git + ``` + +4. Configure and build + ``` + cd gz-sim + mkdir build + cd build + cmake .. -DBUILD_TESTING=OFF # Optionally, -DCMAKE_INSTALL_PREFIX=path\to\install + cmake --build . --config Release + ``` + +5. Optionally, install + ``` + cmake --install . --config Release + ``` + ## Documentation API documentation and tutorials can be accessed at [https://gazebosim.org/libs/gazebo](https://gazebosim.org/libs/gazebo) @@ -123,7 +189,10 @@ You can also generate the documentation from a clone of this repository by follo 1. You will need [Doxygen](http://www.doxygen.org/). On Ubuntu Doxygen can be installed using ``` + # Linux sudo apt-get install doxygen + # Windows + conda install doxygen --channel conda-forge ``` 2. Clone the repository @@ -137,7 +206,7 @@ You can also generate the documentation from a clone of this repository by follo mkdir build cd build cmake ../ - make doc + cmake --build . --target doc ``` 4. View the documentation by running the following command from the `build` directory. diff --git a/tutorials/joint_controller.md b/tutorials/joint_controller.md index 12b77666e2..ad01d53925 100644 --- a/tutorials/joint_controller.md +++ b/tutorials/joint_controller.md @@ -376,7 +376,7 @@ A detailed description and related parameter of JointTrajectoryController can be The trajectory message can be published or subscribed at `/model/${MODEL_NAME}/joint_trajectory` by default. -Message type: [`JointTrajectory`](https://gazebosim.org/api/msgs/7.2/classignition_1_1msgs_1_1JointTrajectory.html) +Message type: [`JointTrajectory`](https://github.com/gazebosim/gz-msgs/blob/gz-msgs10/proto/gz/msgs/joint_trajectory.proto) ### Example usage: @@ -385,7 +385,7 @@ Let’s set up a new model for this example. A two-linked manipulator arm which - SDF file: ```xml - @@ -653,7 +653,7 @@ gz topic -t "topic_name" -m gz.msgs.JointTrajectory -p ' sec: 1 nsec: 0 } - } + }' ```
diff --git a/tutorials/lander.md b/tutorials/lander.md index ecff012177..3c1552ebfe 100644 --- a/tutorials/lander.md +++ b/tutorials/lander.md @@ -1,4 +1,4 @@ -\page lander +\page lander Create a lander vehicle # Overview @@ -9,17 +9,17 @@ to the surface while they collect sensor measurements. ## Related tutorials -https://gazebosim.org/api/sim/8/create_vehicle.html +\ref create_vehicle -https://gazebosim.org/api/sim/8/adding_visuals.html +\ref adding_visuals -https://gazebosim.org/api/sim/8/frame_reference.html +\ref frame_reference -https://gazebosim.org/api/sim/8/adding_system_plugins.html +\ref adding_system_plugins -https://gazebosim.org/api/sim/8/theory_buoyancy.html +\ref theory_buoyancy -https://gazebosim.org/api/sim/8/theory_hydrodynamics.html +\ref theory_hydrodynamics # Create your vehicle @@ -37,7 +37,7 @@ mkdir -p ~/gazebo_maritime/models/my_lander && cd ~/gazebo_maritime/models/my_la Download the `model.config` file and copy it within that directory: ```bash -wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim8/tutorials/files/lander/model.config -O ~/gazebo_maritime/models/my_lander/model.config +wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim9/tutorials/files/lander/model.config -O ~/gazebo_maritime/models/my_lander/model.config ``` In its simple version, the lander does not have any moving pieces, so the SDF @@ -95,7 +95,7 @@ Let's now add nicer-looking visuals to our lander. Download the following ```bash mkdir ~/gazebo_maritime/models/my_lander/meshes -wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim8/tutorials/files/lander/inkfish-lander.dae -O ~/gazebo_maritime/models/my_lander/meshes/inkfish-lander.dae +wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim9/tutorials/files/lander/inkfish-lander.dae -O ~/gazebo_maritime/models/my_lander/meshes/inkfish-lander.dae ``` Replace the `chassis_visual` element in your `model.sdf` with the following @@ -114,7 +114,7 @@ block: And launch Gazebo to see the results: ```bash -gz sim ~/my_models/my_lander/model.sdf +gz sim ~/gazebo_maritime/models/my_lander/model.sdf ``` Your box should now be replaced with a better looking mesh. @@ -153,7 +153,7 @@ Let's start with the world. Download the following world: ```bash mkdir -p ~/gazebo_maritime/worlds -wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim8/tutorials/files/lander/buoyant_lander.sdf -O ~/gazebo_maritime/worlds/buoyant_lander.sdf +wget https://raw.githubusercontent.com/gazebosim/gz-sim/gz-sim9/tutorials/files/lander/buoyant_lander.sdf -O ~/gazebo_maritime/worlds/buoyant_lander.sdf export GZ_SIM_RESOURCE_PATH=:$HOME/gazebo_maritime/models ``` diff --git a/tutorials/migrating_ardupilot_plugin.md b/tutorials/migrating_ardupilot_plugin.md index e58dd764b2..69bebd3245 100644 --- a/tutorials/migrating_ardupilot_plugin.md +++ b/tutorials/migrating_ardupilot_plugin.md @@ -727,14 +727,14 @@ In the new code we explicitly reference each Gazebo package that we use: ``` # NEW -find_package(sdformat14 REQUIRED) -find_package(gz-common5-all REQUIRED) -find_package(gz-sim8-all REQUIRED) -find_package(gz-math7-all REQUIRED) -find_package(gz-msgs10-all REQUIRED) -find_package(gz-physics7-all REQUIRED) -find_package(gz-sensors8-all REQUIRED) -find_package(gz-transport13-all REQUIRED) +find_package(sdformat15 REQUIRED) +find_package(gz-common6-all REQUIRED) +find_package(gz-sim9-all REQUIRED) +find_package(gz-math8-all REQUIRED) +find_package(gz-msgs11-all REQUIRED) +find_package(gz-physics8-all REQUIRED) +find_package(gz-sensors9-all REQUIRED) +find_package(gz-transport14-all REQUIRED) ``` In the old code we need only refer to the build configuration retrieved from the Gazebo package: diff --git a/tutorials/migration_plugins.md b/tutorials/migration_plugins.md index bad1919e6f..a134f796e8 100644 --- a/tutorials/migration_plugins.md +++ b/tutorials/migration_plugins.md @@ -1,7 +1,7 @@ \page migrationplugins Migration from Gazebo Classic: Plugins Gazebo Classic supports -[6 different C++ plugin types](http://gazebosim.org/tutorials?tut=plugins_hello_world&cat=write_plugin), +[6 different C++ plugin types](https://classic.gazebosim.org/tutorials?tut=plugins_hello_world#PluginTypes), each providing access to different parts of the API, like physics, rendering, sensors, GUI, etc. Due to Gazebo Sim's architecture based on an [ECS](https://en.wikipedia.org/wiki/Entity_component_system) diff --git a/tutorials/migration_sdf.md b/tutorials/migration_sdf.md index 37a6a444c0..a9ae0008db 100644 --- a/tutorials/migration_sdf.md +++ b/tutorials/migration_sdf.md @@ -250,7 +250,7 @@ side-by-side on the same file. Instead, keep separate files and inject the plugi needed. There isn't a built-in mechanism on SDFormat to inject plugins into files yet, -but users can make use of templating tools like [ERB](erb_template.html) +but users can make use of templating tools like [ERB](https://github.com/gazebosim/gz-sim/blob/gz-sim9/tutorials/erb_template.md) and [xacro](http://wiki.ros.org/xacro) to generate SDF files with the correct plugins. ### Default plugins @@ -260,8 +260,8 @@ For example, by default, Gazebo will load all the system plugins defined on the `~/.gz/sim/<#>/server.config` file and all GUI plugins defined on the `~/.gz/sim/<#>/gui.config` file. But the user can always remove plugins from those files, or choose different ones by adding `` tags to the SDF file. -(For more details, see the [Server configuration tutorial](server_config.html) -and the [GUI configuration tutorial](gui_config.html)). +(For more details, see the [Server configuration tutorial](https://github.com/gazebosim/gz-sim/blob/gz-sim9/tutorials/server_config.md) +and the [GUI configuration tutorial](https://github.com/gazebosim/gz-sim/blob/gz-sim9/tutorials/gui_config.md)). This is important to keep in mind when migrating your SDF files, because files that worked on Gazebo classic may need more plugins on Gazebo. diff --git a/tutorials/migration_sensor_api.md b/tutorials/migration_sensor_api.md index de2c996104..b9e3504d23 100644 --- a/tutorials/migration_sensor_api.md +++ b/tutorials/migration_sensor_api.md @@ -61,24 +61,24 @@ Classic | Gazebo -- | -- Category | TODO FillMsg | TODO -Id | `ignition::gazebo::Sensor::Entity` +Id | `gz::sim::Sensor::Entity` IsActive | TODO LastMeasurementTime | TODO LastUpdateTime | TODO -Name | `ignition::gazebo::Sensor::Name` +Name | `gz::sim::Sensor::Name` NextRequiredTimestamp | TODO Noise | TODO -Pose | `ignition::gazebo::Sensor::Pose` +Pose | `gz::sim::Sensor::Pose` ResetLastUpdateTime | TODO -ScopedName | `ignition::gazebo::scopedName` +ScopedName | `gz::sim::scopedName` SetActive | TODO SetPose | TODO SetUpdateRate | TODO -Topic | `ignition::gazebo::Sensor::Topic` -Type | `ignition::gazebo::entityType` +Topic | `gz::sim::Sensor::Topic` +Type | `gz::sim::entityType` UpdateRate | TODO Visualize | TODO -WorldName | `ignition::gazebo::worldEntity` +WorldName | `gz::sim::worldEntity` --- @@ -94,8 +94,8 @@ they deal with entity IDs. Classic | Gazebo -- | -- -ParentId | `ignition::gazebo::Sensor::Parent` -ParentName | `ignition::gazebo::Sensor::Parent` +ParentId | `gz::sim::Sensor::Parent` +ParentName | `gz::sim::Sensor::Parent` --- @@ -124,6 +124,6 @@ Classic | Gazebo ConnectUpdated | TODO Fini | N/A Init | N/A -Load | `ignition::gazebo::SdfEntityCreator::CreateEntities` +Load | `gz::sim::SdfEntityCreator::CreateEntities` Update | Entities are updated by systems --- diff --git a/tutorials/model_photo_shoot.md b/tutorials/model_photo_shoot.md index 7d7209d0f8..0730e337a1 100644 --- a/tutorials/model_photo_shoot.md +++ b/tutorials/model_photo_shoot.md @@ -21,61 +21,53 @@ SDF is used to load and configure the `Model Photo Shoot` plugin. The demo SDF contains a good example of the different options and other related plugins: 1. The physics plugin: - -``` + ``` -``` - -A physics plugin is needed only if the `` option is to -be used. This will allow the `Model Photo Shoot` plugin to set the joints -to random positions. + ``` + A physics plugin is needed only if the `` option is to + be used. This will allow the `Model Photo Shoot` plugin to set the joints + to random positions. 2. The render engine plugin: - -``` + ``` ogre2 - 1, 1, 1 + 1.0, 1.0, 1.0 -``` - -A render plugin is needed to render the image. If `ogre2` is used, as shown in -the example, the `` tag can be used to set the background -of the pictures taken by the plugin. Please note that lights added by the -plugin will also affect the final resulting background color on the images. + ``` + A render plugin is needed to render the image. If `ogre2` is used, as shown in + the example, the `` tag can be used to set the background + of the pictures taken by the plugin. Please note that lights added by the + plugin will also affect the final resulting background color on the images. 3. The model and the photo shoot plugin: - -``` + ``` https://fuel.gazebosim.org/1.0/OpenRobotics/models/Robonaut poses.txt - true + false -``` - -The model is loaded through the `` tag. Then the `model photo shoot` -plugin and its options are specified: - -* ``: (optional) Location to store the camera -translation, scaling data and joints position (if using the -`` option) that can be used to replicate the -pictures using other systems. -* ``: (optional) When set to `true` the joints in the model -will be set to random positions prior to taking the pictures. + ``` + The model is loaded through the `` tag. Then the `model photo shoot` + plugin and its options are specified: + * ``: (optional) Location to store the camera + translation, scaling data and joints position (if using the + `` option) that can be used to replicate the + pictures using other systems. + * ``: (optional) When set to `true` the joints in the model + will be set to random positions prior to taking the pictures. 4. Camera sensor: - -``` + ``` 0 0 0 0 0 0 @@ -99,8 +91,7 @@ will be set to random positions prior to taking the pictures. true -``` - -A `camera sensor` must be added as it will be used by the plugin to take the -pictures. This allows plugin users to set the different parameters of the -camera to their desired values. + ``` + A `camera sensor` must be added as it will be used by the plugin to take the + pictures. This allows plugin users to set the different parameters of the + camera to their desired values. diff --git a/tutorials/move_camera_to_model.md b/tutorials/move_camera_to_model.md index 0ba5287eeb..8b6eac8172 100644 --- a/tutorials/move_camera_to_model.md +++ b/tutorials/move_camera_to_model.md @@ -7,7 +7,7 @@ This tutorial gives an introduction to Gazebo's service `/gui/move_to/model`. Th 1. Load the **View Angle** plugin. This service is only available when the **View Angle** plugin is loaded. 2. Call the service using the request message type `gz.msgs.GUICamera` and the response message type `gz.msgs.Boolean`. The distance to the object is defined as the z coordinate, and the direction of the camera with a quaternion. It's possible to select the projection type. -For example, Let's move the camera to the `box` model looking down from 5 meters away. +For example, Let's move the camera to the `box` model looking down from 5 meters away. This example uses the `shapes.sdf` world. ```bash gz service -s /gui/move_to/model --reqtype gz.msgs.GUICamera --reptype gz.msgs.Boolean -r 'name: "box", pose: {position: {z:5}, orientation: {x:0, y:0, z: -1, w:0}}, projection_type: "orbit"' --timeout 5000 diff --git a/tutorials/particle_tutorial.md b/tutorials/particle_tutorial.md index c0c37e73b5..7150027684 100644 --- a/tutorials/particle_tutorial.md +++ b/tutorials/particle_tutorial.md @@ -97,7 +97,18 @@ The particles are not only a visual effect in simulation, they also have an effe * `gpu_lidar`: The particles have a scattering effect on the lidar range readings. * `thermal_camera`: The particles are not visible in the thermal camera image. -The gif below shows an [example world](https://gist.github.com/iche033/bcd3b7d3f4874e1e707e392d6dbb0aa0) with six different sensors looking at the fog generator with a rescue randy model inside the fog. + +The [particle_emitter_scatter_effects.sdf](https://github.com/gazebosim/gz-sim/blob/gz-sim9/tutorials/files/particle_emitter/particle_emitter_scatter_effects.sdf) +demo world shows six different sensors looking at the fog generator with a rescue randy model inside the fog. + +Download the example world file and launch it to see what it looks like. + +```bash +gz sim -v 4 -r particle_emitter_scatter_effects.sdf +``` + +Navigate to the Visualize Lidar plugin on the right and click on the refresh button to set the lidar topic. You should see the sensor images and lidar visualization like below: + @image html files/particle_emitter/sensor_scatter_tutorial.gif diff --git a/tutorials/physics.md b/tutorials/physics.md index 98a08b8a78..1099560f5a 100644 --- a/tutorials/physics.md +++ b/tutorials/physics.md @@ -10,7 +10,7 @@ by default. Downstream developers may also integrate other physics engines by creating new Gazebo Physics engine plugins. See -[Gazebo Physics](https://gazebosim.org/api/physics/7/tutorials.html)'s +[Gazebo Physics](https://gazebosim.org/api/physics/8/tutorials.html)'s tutorials to learn how to integrate a new engine. ## How Gazebo finds engines @@ -25,20 +25,33 @@ If you've created a custom engine plugin, you can tell Gazebo where to find it by setting the `GZ_SIM_PHYSICS_ENGINE_PATH` environment variable to the directory where the plugin's shared library can be found. -For example, if you've created the following physics engine shared library on -Linux: +For example, if you've created the following physics engine shared library: -`/home/physics_engines/libCustomEngine.so` +``` +# Linux +/home/physics_engines/libCustomEngine.so +# Windows +C:\Users\Robot\physics_engines\CustomEngine.dll +``` You should set the variable as follows: -`export GZ_SIM_PHYSICS_ENGINE_PATH=/home/physics_engines` - +``` +# Linux +export GZ_SIM_PHYSICS_ENGINE_PATH=/home/physics_engines +# Windows +set GZ_SIM_PHYSICS_ENGINE_PATH=C:\Users\Robot\physics_engines +``` If you have several libraries installed in different paths, you can add more paths, for example: -`export GZ_SIM_PHYSICS_ENGINE_PATH=/home/physics_engines:/home/more_engines` +``` +# Linux, separate with : +export GZ_SIM_PHYSICS_ENGINE_PATH=/home/physics_engines:/home/more_engines +# Windows, separate with ; +set GZ_SIM_PHYSICS_ENGINE_PATH=C:\Users\Robot\physics_engines;C:\MoreEngines +``` ## Tell Gazebo what engine to load @@ -47,6 +60,7 @@ There are a few different ways of telling Gazebo which engine to load. For any method, you should provide the name of your plugin's shared library, but the `lib` prefix and the file extension are optional. So in this example, the file is `libCustomEngine.so` but it's enough to set `CustomEngine`. +That is also prefered to support multiple operating systems. ### From SDF @@ -70,7 +84,9 @@ For the example above, you can load it like this: Alternatively, you can choose a plugin from the command line using the `--physics-engine` option, for example: -`gz sim --physics-engine CustomEngine` +``` +gz sim --physics-engine CustomEngine +``` To use an existing alternative engine (e.g. Bullet Featherstone) @@ -96,10 +112,10 @@ Gazebo supports the following physics engine configurations through SDF. These options are available to all physics engines, but not all engines may support them. The default physics engine, DART, supports all these options. -* [//physics/dart/collision_detector](http://sdformat.org/spec?ver=1.8&elem=physics#dart_collision_detector) +* [//physics/dart/collision_detector](http://sdformat.org/spec?ver=1.11&elem=physics#dart_collision_detector) * Options supported by DART: `ode` (default), `bullet`, `fcl`, `dart`. -* [//physics/dart/solver/solver_type](http://sdformat.org/spec?ver=1.8&elem=physics#solver_solver_type) +* [//physics/dart/solver/solver_type](http://sdformat.org/spec?ver=1.11&elem=physics#solver_solver_type) * Options supported by DART: `dantzig` (default), `pgs` ## Troubleshooting @@ -107,12 +123,12 @@ may support them. The default physics engine, DART, supports all these options. > Failed to find plugin [libCustomEngine.so]. Have you checked the > GZ_SIM_PHYSICS_ENGINE_PATH environment variable? -Gazebo can't find out where `libCustomEngine.so` is located. +Gazebo can't find out where `libCustomEngine.so` or `CustomEngine.dll` is located. If that's an engine you believe should be installed with Gazebo Physics, check if the relevant plugin is installed. -If that's a 3rd party engine, find where the `.so` file is installed and add +If that's a 3rd party engine, find where the `.so` or `.dll` file is installed and add that path to the environment variable as described above. > Unable to load the [/home/physics_engines/libCustomEngine.so] library. @@ -120,6 +136,12 @@ that path to the environment variable as described above. There was some problem loading that file. Check that it exists, that you have permissions to access it, and that it's acually a physics engine plugin. +> No physics plugins implementing required interface found in library +> [/home/physics_engines/libCustomEngine.so] + +The library was found but none of the plugins in the library implement the +required interface to be considered a physics plugin. + > No plugins with all required features found in library > [/home/physics_engines/libCustomEngine.so] diff --git a/tutorials/point_cloud_to_mesh.md b/tutorials/point_cloud_to_mesh.md index d0628d8f66..04d710013c 100644 --- a/tutorials/point_cloud_to_mesh.md +++ b/tutorials/point_cloud_to_mesh.md @@ -13,6 +13,7 @@ Next, you’ll need to download CloudCompare. This is the software we will be using to convert our point cloud to a mesh. CloudCompare is free and open source. You can download it [here](http://www.danielgm.net/cc/release/). +This tutorial was created using CloudCompare 1.13.2. ## Converting with CloudCompare @@ -20,7 +21,7 @@ After installing, open CloudCompare and import your point cloud file by going to Depending on the number of points in your point cloud, this could take several minutes. Once loaded, you should see the following tunnel section: -![Opening the point cloud](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/cloudcompare2.png) +\image html files/point_cloud_to_mesh/cloudcompare2.png Many 3D scans will be composed of millions, sometimes hundreds of millions of points. Converting a scan to a 3D model with that many points would be very difficult due to the number of polygons that would be created and the long processing time necessary to compute the normals. @@ -34,13 +35,13 @@ We'll still walk through reducing points, however, to make the process quicker. To reduce the number of points in your cloud, click on the tunnel so a yellow cube outline appears around it, then go to `Edit` > `Subsample`. -![Min. space between points](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/min_space.png) +\image html files/point_cloud_to_mesh/min_space.jpg The number you will need to enter in the `min. space between points` field will vary depending on your point cloud. A value of .01 was sufficient to bring our point cloud to an easy-to-manage 1 million points. Point count is visible in the `Properties` window on the lower left side of the screen. -![Point count of subsample](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/properties.png) +\image html files/point_cloud_to_mesh/properties.png How many points you reduce down to will largely depend on how long you are willing to wait for the point cloud to be converted into a mesh. The more points you start with, the longer it will take to compute the normals and create the mesh. @@ -48,7 +49,7 @@ The more points you start with, the longer it will take to compute the normals a After the operation is complete you’ll have two clouds in your scene: the original point cloud and your subsampled point cloud. Most operations in CloudCompare will create new point clouds and keep the original, so make sure that you have the new point cloud selected before running an operation. -![Selecting the new point cloud](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/secondcloud.png) +\image html files/point_cloud_to_mesh/secondcloud.png ### Create a Polygonal Mesh @@ -59,7 +60,7 @@ A normal is essentially the direction a polygon is facing. To do this, go to `Edit` > `Normals` > `Compute`. You'll see this dialog box: -![Choose Triangulation surface model](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/compute_normals.png) +\image html files/point_cloud_to_mesh/compute_normals.png You’ll see various options in the dialog box that appears. The main thing you’ll want to consider is what `Local surface model` to use. @@ -72,7 +73,7 @@ Now we get to actually convert our point cloud to a mesh. To do this go to `Plugins` > `PoissonRecon`. You'll see this dialog box: -![Octree depth and output density selection](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/outputdensity.png) +\image html files/point_cloud_to_mesh/outputdensity.png The value you enter in the `Octree depth` field will determine the polygon count of the created model. You may have to run the surface reconstruction a couple times with varying values before you land on a polygon count that is suitable for your needs. @@ -93,18 +94,18 @@ Our tunnel has turned into a blob shape. This is because the mesh that CloudCompare creates will always be water tight even if it has to add polygons where there are no points. We just want our tunnels, though, so we need to remove those unnecessary polygons. -![The blob shape](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/blob2.png) +\image html files/point_cloud_to_mesh/blob2.jpg This is where our scalar field comes in. In the mesh's `Properties` window go to `SF display params` and take the left handle in the graph and drag it to the right until it hits the area where the bulk of the scalar field starts. -![Adjusting scalar filed params](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/sf_display.png) +\image html files/point_cloud_to_mesh/sf_display.png This will display only the polygons that were created from the point cloud and hide the polygons used to make the model watertight. The polygons are only hidden however. We still need to actually remove them. -![Display original polygons](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/hidden_polygons2.png) +\image html files/point_cloud_to_mesh/hidden_polygons2.jpg To remove the hidden polygons go to `Edit` > `Scalar fields` > `Filter By Value`. @@ -113,7 +114,11 @@ Hitting export will simply export the mesh within that range. Instead, we'll hit `Split` to create two meshes. One with the polygons inside our specified range and one containing polygons outside that range. -![Splitting the mesh](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/split.png) +\image html files/point_cloud_to_mesh/split.png + +It is possible that you will get error "Visibility table not instantiated". This error causes only the "wanted" part of the mesh to be created when splitting, while the other ("unwanted") part will not be generated. But that is not a problem for our use-case. + +\image html files/point_cloud_to_mesh/error.jpg ### The Completed Model @@ -121,6 +126,8 @@ By hitting `Split` we can view the model before exporting by simply going to `Fi Remember to have the correct mesh selected (`.part`) since choosing `Split` will give you two new meshes, plus you will still have your original, complete mesh. Your file format will depend on the software you want to use but `.obj` is a widely supported format that should work in most 3D applications. -![The completed mesh](https://raw.githubusercontent.com/gazebosim/gz-sim/main/tutorials/files/point_cloud_to_mesh/complete2.png) +Before exporting, check your mesh for holes. If still checked, disable display of the pointcloud, so that only your output mesh is shown. Inspect ground parts of the mesh (or any other parts you are most interested in) and check if there aren't holes in it. If there are some, you can try to repeat the trimming step with more relaxed threshold. + +\image html files/point_cloud_to_mesh/complete2.png You can find more information on CloudCompare and a more in depth look at the tools we used in this tutorial on [the CloudCompare website](https://www.cloudcompare.org/) and the [CloudCompare wiki](https://www.cloudcompare.org/doc/wiki/index.php?title=Main_Page). diff --git a/tutorials/python_interfaces.md b/tutorials/python_interfaces.md index a696512dc0..108080d121 100644 --- a/tutorials/python_interfaces.md +++ b/tutorials/python_interfaces.md @@ -43,7 +43,7 @@ server.run(True, 1000, False) ## Run the example In the -[examples/scripts/python_api](https://github.com/gazebosim/gz-sim/tree/gz-sim8/examples/scripts/python_api) +[examples/scripts/python_api](https://github.com/gazebosim/gz-sim/tree/main/examples/scripts/python_api) folder there is a Python script that shows how to make use of this API. If you compiled Gazebo from source you should modify your `PYTHONPATH`: @@ -82,7 +82,7 @@ post_iterations 1000 pre_iterations 1000 ``` -# Gazebo Systems written in Python +## Gazebo Systems written in Python Gazebo also provides a way to write systems in Python. This is done using the `gz::sim::systems::PythonSystemLoader` system which loads a given python module @@ -96,8 +96,8 @@ Example python system: ```python -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/tutorials/server_config.md b/tutorials/server_config.md index bbab5f5110..650eafe0c4 100644 --- a/tutorials/server_config.md +++ b/tutorials/server_config.md @@ -17,11 +17,26 @@ There are a few places where the plugins can be defined: 3. The default configuration file at `$HOME/.gz/sim/<#>/server.config` \*, where `<#>` is Gazebo Sim's major version. -Each of the items above takes precedence over the ones below it. For example, -if a the SDF file has any `` elements, then the -`GZ_SIM_SERVER_CONFIG_PATH` variable is ignored. And the default configuration -file is only loaded if no plugins are passed through the SDF file or the -environment variable. +The behavior of Gazebo when loading these plugins depends on the +`` policy set in ``: + +- `true`: Plugins + in the SDF file are first loaded, followed by plugins from config files + (either `GZ_SIM_SERVER_CONFIG_PATH` or the default configuration file). + Plugins from SDF files take precedence over plugins from config files, this + means, if a plugin is specified in both places, only the one specified in the + SDF file will be loaded. The main use case for this is for users to rely on + the default list of plugins and only add extra plugins they need for the + application. This is the default setting in Gazebo Ionic and later. + +- `false`: If + there are any plugins specified in the SDF file, plugins from the config files + (either `GZ_SIM_SERVER_CONFIG_PATH` or the default configuration file) are + ignored. This allows the user to have complete control over which plugins are + loaded. This is the default setting in Gazebo Harmonic and earlier. + +In both policy settings, the default configuration file is only loaded if no +plugins are passed through the `GZ_SIM_SERVER_CONFIG_PATH` environment variable. > \* For log-playback, the default file is > `$HOME/.gz/sim/<#>/playback_server.config` @@ -85,7 +100,7 @@ will be created with default values: Let's try overriding the default configuration from an SDF file. Open your favorite editor and save this file as `fuel_preview.sdf`: -``` +```xml @@ -147,8 +162,84 @@ Now let's load this world: `gz sim -r /fuel_preview.sdf` -Notice how the application has only one system plugin loaded, the scene -broadcaster, as defined on the SDF file above. Physics is not loaded, so even +Notice how the application has loaded the scene +broadcaster, as defined on the SDF file above as well as the default plugins +`Physics` and `UserCommands`. Since `SceneBroadcaster` is loaded from the SDF file, +it's not loaded again. We see that the cone falls due to gravity since all the +necessary plugins are loaded. + +@image html files/server_config/from_sdf_no_plugins.gif + +Now, let's modify the SDF file to change the policy `false` + +```xml + + + + + + false + + + + + + + + + + + 3D View + false + docked + + + ogre2 + scene + 1.0 1.0 1.0 + 0.4 0.6 1.0 + 8.3 7 7.8 0 0.5 -2.4 + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + + + https://fuel.gazebosim.org/1.0/OpenRobotics/models/Sun + + + + https://fuel.gazebosim.org/1.0/OpenRobotics/models/Construction Cone + + + + +``` +Let's load this world again: + +`gz sim -r /fuel_preview.sdf` + +Notice how the application has only one system plugin loaded, the `SceneBroadcaster`, +as defined on the SDF file above. `Physics` is not loaded, so even though the simulation is running (started with `-r`), the cone doesn't fall with gravity. @@ -299,3 +390,8 @@ the background color is the default grey, instead of the blue color set on the GUI `GzScene` plugin. @image html files/server_config/camera_env.gif + + +### Order of Execution of Plugins +The order of execution of plugins can be controlled by setting +the `` tag inside ``. See example in examples/plugin/priority_printer_plugin and the associated README.md file to learn more. diff --git a/tutorials/shadow_texture_size.md b/tutorials/shadow_texture_size.md new file mode 100644 index 0000000000..b117370deb --- /dev/null +++ b/tutorials/shadow_texture_size.md @@ -0,0 +1,118 @@ +\page shadow_texture_size Shadow Texture Size + +This tutorial showcases how to change the texture size of shadows casted by lights. + +
+ \image html files/shadow_texture_size/shadow_texsize_2k_to_16k.gif width=60% +
+ +## Texture size options + +Supported texture sizes include: 512px, 1024px, 2048px, 4096px, 8192px, 16384px. + +The default shadow texture size for all lights is 2K. The default max texture size is 16K, but for less powerful computers, it may be a lower value, like 8K. + +## Changing shadow texture size + +The shadow texture size can be changed for the GUI with the usage of the Minimal Scene GUI plugin in the SDF. + +Currently, light type is restricted to only directional light. As a scene should typically have at most one directional light (representing the sun), this will ensure that an increase in shadow texture size does not increase VRAM too much. + +### Example usage for the GUI + +Let's change the shadow texture size for directional light with the SDF file below. (The finished SDF file can be viewed [here](https://github.com/gazebosim/gz-sim/tree/gz-sim9/examples/worlds/shadow_texture_size.sdf).) + +1) Save the below in an SDF file named `shadow_texture_size.sdf`: + +```xml + + + + + 0.1 0.1 0.1 + 0.0 0.0 0.0 + + + + + + ogre2 + -10 0 7 0 0.5 0 + + + + + + + + + 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 + + + + + + +``` + +2) Add the following lines to the Minimal Scene GUI plugin. + +```xml + + 8192 + +``` + +The `` value can be changed as per the Texture size options section. + +3) Open the `shadow_texsize_demo.sdf` world with + +```bash +gz sim shadow_texture_size.sdf +``` + +## Impact on VRAM usage + +Keep in mind that the larger the shadow texture size, the more VRAM is used. Thus, in a scene populated with many lights, changing the directional light's shadow texture size should be fine because there is typically only one directional light in a scene. But if the scene has many point lights and the point light's shadow texture size is increased, the VRAM consumption goes up significantly. diff --git a/tutorials/surface_vehicles.md b/tutorials/surface_vehicles.md index 812edf98ba..a89186a502 100644 --- a/tutorials/surface_vehicles.md +++ b/tutorials/surface_vehicles.md @@ -1,4 +1,4 @@ -\page surface_vehicles +\page surface_vehicles Create a surface vehicle # Overview @@ -8,15 +8,15 @@ with the presence of waves and wind. ## Related tutorials -https://gazebosim.org/api/sim/8/create_vehicle.html +\ref create_vehicle -https://gazebosim.org/api/sim/8/adding_visuals.html +\ref adding_visuals -https://gazebosim.org/api/sim/8/frame_reference.html +\ref frame_reference -https://gazebosim.org/api/sim/8/adding_system_plugins.html +\ref adding_system_plugins -https://gazebosim.org/api/sim/8/theory_hydrodynamics.html +\ref theory_hydrodynamics # Adding an environment diff --git a/tutorials/terminology.md b/tutorials/terminology.md index 7103fee7ec..ec0391475b 100644 --- a/tutorials/terminology.md +++ b/tutorials/terminology.md @@ -26,7 +26,7 @@ to developers touching the source code. * **System**: Logic that operates on all entities that have a given set of components. Systems are plugins that can be loaded at runtime. - Gazebo ships with various systems, and downstream develpers can + Gazebo ships with various systems, and downstream developers can [create their own systems](createsystemplugins.html). * **Entity-component manager** (**ECM**): Provides functions for diff --git a/tutorials/theory_buoyancy.md b/tutorials/theory_buoyancy.md index f464ad8fc1..19bb2dad8d 100644 --- a/tutorials/theory_buoyancy.md +++ b/tutorials/theory_buoyancy.md @@ -1,4 +1,4 @@ -\page theory_buoyancy +\page theory_buoyancy Buoyancy # Overview diff --git a/tutorials/theory_hydrodynamics.md b/tutorials/theory_hydrodynamics.md index 7f2c7cd5a5..d2e3deb47d 100644 --- a/tutorials/theory_hydrodynamics.md +++ b/tutorials/theory_hydrodynamics.md @@ -1,4 +1,4 @@ -\page theory_hydrodynamics +\page theory_hydrodynamics Hydrodynamics # Overview diff --git a/tutorials/triggered_publisher.md b/tutorials/triggered_publisher.md index 5d497dda86..ffad764809 100644 --- a/tutorials/triggered_publisher.md +++ b/tutorials/triggered_publisher.md @@ -16,10 +16,10 @@ Publisher systems can be chained together by showing how the falling of the box can trigger another box to fall. Last, it covers how a service call can be triggered to reset the robot pose. The finished world SDFormat file for this tutorial can be found in -[examples/worlds/triggered_publisher.sdf](https://github.com/gazebosim/gz-sim/blob/gz-sim8/examples/worlds/triggered_publisher.sdf) +[examples/worlds/triggered_publisher.sdf](https://github.com/gazebosim/gz-sim/blob/main/examples/worlds/triggered_publisher.sdf) We will use the differential drive vehicle from -[examples/worlds/diff_drive.sdf](https://github.com/gazebosim/gz-sim/blob/gz-sim8/examples/worlds/diff_drive.sdf), +[examples/worlds/diff_drive.sdf](https://github.com/gazebosim/gz-sim/blob/main/examples/worlds/diff_drive.sdf), but modify the input topic of the `DiffDrive` system to `cmd_vel`. A snippet of the change to the `DiffDrive` system is shown below: diff --git a/tutorials/underwater_vehicles.md b/tutorials/underwater_vehicles.md index 86d76ba995..1efcd90aef 100644 --- a/tutorials/underwater_vehicles.md +++ b/tutorials/underwater_vehicles.md @@ -1,4 +1,4 @@ -\page underwater_vehicles +\page underwater_vehicles Create an underwater vehicle # Overview @@ -11,17 +11,17 @@ guide you through the setup of the [MBARI LRAUV](https://app.gazebosim.org/accur ## Related tutorials -https://gazebosim.org/api/sim/8/create_vehicle.html +\ref create_vehicle -https://gazebosim.org/api/sim/8/adding_visuals.html +\ref adding_visuals -https://gazebosim.org/api/sim/8/frame_reference.html +\ref frame_reference -https://gazebosim.org/api/sim/8/adding_system_plugins.html +\ref adding_system_plugins -https://gazebosim.org/api/sim/8/theory_buoyancy.html +\ref theory_buoyancy -https://gazebosim.org/api/sim/8/theory_hydrodynamics.html +\ref theory_hydrodynamics # Create your vehicle diff --git a/tutorials/video_recorder.md b/tutorials/video_recorder.md index efea6422c2..432bd94f21 100644 --- a/tutorials/video_recorder.md +++ b/tutorials/video_recorder.md @@ -13,12 +13,18 @@ Gazebo that already has this plugin included in the GUI. gz sim -v 4 video_record_dbl_pendulum.sdf ``` -In this demo world, you should see a video recorder icon positioned on the top. +In this demo world, you should see a video recorder icon positioned on the top left area of the window along with other buttons. Clicking on the video recorder button gives you the video format options that are available. @image html files/video_recorder/video_recorder.png +> **NOTE** +> The OGV format might not be supported by the underlying libavcodec implementation. +> This is especially true on Windows with the conda-installed dependencies. +> There is no easy way to add the VP8 codec support except for building +> libavcodec manually and enabling the support. + Once an option is selected, recording starts immediately as indicated by a flashing video recorder icon. At anytime that you wish to stop recording, click on the flashing icon and select `Stop`. A file dialog window should pop up @@ -107,5 +113,5 @@ generated video. The default bitrate is 2Mbps. Since Gazebo Common 3.10.2, there is support for utilizing the power of GPUs to speed up the video encoding process. See the -[Hardware-accelerated Video Encoding tutorial](https://gazebosim.org/api/common/5/hw-encoding.html) +[Hardware-accelerated Video Encoding tutorial](https://gazebosim.org/api/common/6/hw-encoding.html) for more details.