("/model/test_body/cmd_vel");
+ node.Subscribe(_odomTopic, odomCb);
+
+ // Set an angular velocity command that would cause pitch to update from 0
+ // to PI in 1 second, crossing the singularity when pitch is PI/2.
+ const math::Vector3d angVelCmd(0.0, GZ_PI, 0);
+ msgs::Twist msg;
+ msgs::Set(msg.mutable_linear(), math::Vector3d::Zero);
+ msgs::Set(msg.mutable_angular(), angVelCmd);
+ cmdVel.Publish(msg);
+
+ // Run server while the model moves with the velocities set earlier
+ server.Run(true, 1000, false);
+
+ // Poses for 1s
+ ASSERT_EQ(1000u, poses.size());
+
+ int sleep = 0;
+ int maxSleep = 30;
+ // Default publishing frequency for odometryPublisher is 50Hz.
+ for (; (odomAngVels.size() < 50) &&
+ sleep < maxSleep; ++sleep)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+ EXPECT_NE(maxSleep, sleep);
+
+ // Odom for 1s
+ ASSERT_FALSE(odomAngVels.empty());
+ EXPECT_EQ(50u, odomAngVels.size());
+
+ // Check accuracy of velocities published in the odometry message
+ for (size_t i = 1; i < odomAngVels.size(); ++i) {
+ EXPECT_NEAR(odomAngVels[i].X(), angVelCmd[0], 1e-1);
+ EXPECT_NEAR(odomAngVels[i].Y(), angVelCmd[1], 1e-1);
+ EXPECT_NEAR(odomAngVels[i].Z(), angVelCmd[2], 1e-1);
+ }
+ }
+
/// \param[in] _sdfFile SDF file to load.
/// \param[in] _odomTopic Odometry topic.
/// \param[in] _frameId Name of the world-fixed coordinate frame
@@ -624,6 +705,16 @@ TEST_P(OdometryPublisherTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(Movement3d))
"/model/X3/odometry", "/model/X3/pose", "X3/odom", "X3/base_footprint");
}
+/////////////////////////////////////////////////
+TEST_P(OdometryPublisherTest,
+ GZ_UTILS_TEST_DISABLED_ON_WIN32(Movement3dAtSingularity))
+{
+ TestMovement3dAtSingularity(
+ gz::common::joinPaths(PROJECT_SOURCE_PATH,
+ "test", "worlds", "odometry_publisher_3d_singularity.sdf"),
+ "/model/test_body/odometry");
+}
+
/////////////////////////////////////////////////
TEST_P(OdometryPublisherTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(OdomFrameId))
{
diff --git a/test/worlds/camera_sensor_gi_enabled_false.sdf b/test/worlds/camera_sensor_gi_enabled_false.sdf
new file mode 100644
index 0000000000..b8700cf1f9
--- /dev/null
+++ b/test/worlds/camera_sensor_gi_enabled_false.sdf
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+ ogre2
+
+
+ false
+ 16 16 16
+ 1 1 1
+ 6
+ true
+ true
+ 1.0
+ true
+ none
+
+
+
+
+
+
+ 0 0 0
+ 0.1 0.1 0.1
+
+
+
+
+ 0 -0.5 2.5 0 0 0
+ 1 1 1 1
+ 0 0 0 0
+
+ 50
+ 0
+ 0
+ 0.02
+
+ true
+ true
+ 1.0
+
+
+
+
+ 0 5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 -5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 -0.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 8.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 4.5 0 4 0 0 0
+ true
+
+
+
+
+ 1 10 10
+
+
+
+
+
+
+ 1 10 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+
+ 0 -0.5 0.5 0 0 0
+
+
+
+
+ 1 1 1
+
+
+
+
+
+
+
+ 1 1 1
+
+
+
+ 1 0 0 1
+ 1 0 0 1
+ 1 1 1 1
+
+
+
+
+
+
+
+ true
+ 0 0.5 0.5 0 0 -1.57
+
+
+
+
+ 0.1 0.1 0.1
+
+
+
+
+
+
+ 0.1 0.1 0.1
+
+
+
+ 0 0 1 1
+ 0 0 1 1
+ 1 1 1 1
+
+
+
+
+ 1.047
+
+ 320
+ 240
+
+
+ 0.1
+ 100
+
+
+ 30
+ camera
+
+
+
+
+
diff --git a/test/worlds/camera_sensor_gi_enabled_true.sdf b/test/worlds/camera_sensor_gi_enabled_true.sdf
new file mode 100644
index 0000000000..067466da8f
--- /dev/null
+++ b/test/worlds/camera_sensor_gi_enabled_true.sdf
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+ ogre2
+
+
+ true
+ 16 16 16
+ 1 1 1
+ 6
+ true
+ true
+ 1.0
+ true
+ none
+
+
+
+
+
+
+ 0 0 0
+ 0.1 0.1 0.1
+
+
+
+
+ 0 -0.5 2.5 0 0 0
+ 1 1 1 1
+ 0 0 0 0
+
+ 50
+ 0
+ 0
+ 0.02
+
+ true
+ true
+ 1.0
+
+
+
+
+ 0 5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 -5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 -0.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 8.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 4.5 0 4 0 0 0
+ true
+
+
+
+
+ 1 10 10
+
+
+
+
+
+
+ 1 10 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+
+ 0 -0.5 0.5 0 0 0
+
+
+
+
+ 1 1 1
+
+
+
+
+
+
+
+ 1 1 1
+
+
+
+ 1 0 0 1
+ 1 0 0 1
+ 1 1 1 1
+
+
+
+
+
+
+
+ true
+ 0 0.5 0.5 0 0 -1.57
+
+
+
+
+ 0.1 0.1 0.1
+
+
+
+
+
+
+ 0.1 0.1 0.1
+
+
+
+ 0 0 1 1
+ 0 0 1 1
+ 1 1 1 1
+
+
+
+
+ 1.047
+
+ 320
+ 240
+
+
+ 0.1
+ 100
+
+
+ 30
+ camera
+
+
+
+
+
diff --git a/test/worlds/odometry_publisher_3d_singularity.sdf b/test/worlds/odometry_publisher_3d_singularity.sdf
new file mode 100644
index 0000000000..d74288d69f
--- /dev/null
+++ b/test/worlds/odometry_publisher_3d_singularity.sdf
@@ -0,0 +1,97 @@
+
+
+
+
+
+ 0.001
+ 0
+
+
+
+
+
+ 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
+
+
+
+
+
+
+ 0 0 1 0 0 0
+
+
+ 1.5
+
+ 0.0347563
+ 0
+ 0
+ 0.07
+ 0
+ 0.0977
+
+
+
+
+
+ 0.30 0.42 0.11
+
+
+
+
+
+
+ 0.30 0.42 0.11
+
+
+
+
+
+ 0 0 0
+ 0 3.1415 0
+
+
+ 3
+
+
+
+
+
diff --git a/tutorials.md.in b/tutorials.md.in
index b75967e1ad..b3d734544e 100644
--- a/tutorials.md.in
+++ b/tutorials.md.in
@@ -24,6 +24,7 @@ Gazebo @GZ_DESIGNATION_CAP@ library and how to use the library effectively.
* \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 global_illumination "Global illumination": Enable global illumination for the GUI and for the sensor view.
### Migration from Gazebo classic
diff --git a/tutorials/files/global_illumination/global_illumination.gif b/tutorials/files/global_illumination/global_illumination.gif
new file mode 100644
index 0000000000..fbc1435e28
Binary files /dev/null and b/tutorials/files/global_illumination/global_illumination.gif differ
diff --git a/tutorials/files/global_illumination/gui_demo_default.png b/tutorials/files/global_illumination/gui_demo_default.png
new file mode 100644
index 0000000000..516d32dea6
Binary files /dev/null and b/tutorials/files/global_illumination/gui_demo_default.png differ
diff --git a/tutorials/files/global_illumination/gui_demo_with_vct.png b/tutorials/files/global_illumination/gui_demo_with_vct.png
new file mode 100644
index 0000000000..823d23b3dc
Binary files /dev/null and b/tutorials/files/global_illumination/gui_demo_with_vct.png differ
diff --git a/tutorials/frame_reference.md b/tutorials/frame_reference.md
index 3d904fa19e..eae0401ae5 100644
--- a/tutorials/frame_reference.md
+++ b/tutorials/frame_reference.md
@@ -40,7 +40,7 @@ being in the positive z direction and so forth.
If you are creating a model, besides designing its kinematic structure (links
and joints) and physical properties, you need to decide where to place your
model's reference frame. Next are a few examples of our turtle model with three
-differente choices for its reference frame.
+different choices for its reference frame.
@image html files/frame_reference/turtle_frames.png
@@ -57,14 +57,14 @@ left, and `Z` pointing up.
3. Try to match the `Z` value of your reference frame with the point of your
model that contacts the ground or the water. That way, when you spawn your model
-at any point in the world, if you use `z` value of `0`, you know it will
+at any point in the world, if you use `Z` value of `0`, you know it will
smoothly sit on a stable place.
# How to set your model reference frame
There are a few ways to change the reference frame of your model:
-1. Adjust your mesh reference frame. When desigining your mesh you'll be able to
+1. Adjust your mesh reference frame. When designing your mesh you'll be able to
set its reference frame. It's recommended to match the mesh reference frame with
the one you will want in Gazebo for your model.
diff --git a/tutorials/global_illumination.md b/tutorials/global_illumination.md
new file mode 100644
index 0000000000..13ff5bc3a7
--- /dev/null
+++ b/tutorials/global_illumination.md
@@ -0,0 +1,419 @@
+\page global_illumination Global Illumination
+
+This tutorial showcases how to enable real-time global illumination in Gazebo.
+
+
+ \image html files/global_illumination/global_illumination.gif width=60%
+
+
+## About global illumination
+
+Global illumination (GI) techniques account for illumination from indirect light reflections. When GI is enabled, objects not only receive direct light from light sources, but also from indirect light bouncing off of other surfaces, ensuring nice reflections and a more natural appearance.
+
+Gazebo supports two GI methods through the Ogre2 rendering engine, Voxel Cone Tracing (VCT) and Cascaded Image Voxel Cone Tracing (CI VCT).
+
+### Voxel Cone Tracing
+
+A scene rendered with VCT is reliable and good quality, and thus is the best choice for most scenes.
+
+VCT parameters include:
+* **Resolution**
+* **Octant count**
+* **Bounce count**
+* **High quality**
+* **Anisotropic**
+* **Thin wall counter**
+* **Conserve memory**
+* **Debug visualization mode**
+
+### Cascaded Image Voxel Cone Tracing
+
+Compared to VCT, a scene rendered with CI VCT is slightly lower quality, but the scene can be re-voxelized every frame, so it’s much faster when dealing with very large scenes. However, it is more memory-intensive than VCT.
+
+CI VCT parameters include:
+* **Bounce count**
+* **High quality**
+* **Anisotropic**
+* **Debug visualization mode**
+* **Cascade**
+ * **Resolution**
+ * **Octant count**
+ * **Thin wall counter**
+ * **Area half size**
+
+## Enabling global illumination in Gazebo
+
+During simulation, the GUI and the camera sensor view are two different scenes. The GUI scene is rendered on the frontend client process, and the camera sensor scene is rendered on the backend server process. Thus, GI can be enabled on either or both of these processes.
+
+> **Note:** GI solutions require hardware that uses OpenGL4.
+> **Note:** CI VCT must be run with Vulkan as the render engine API backend.
+
+### How to enable global illumination for the GUI
+
+GI can be enabled for the GUI through a GUI plugin. Both VCT and CI VCT are supported for the GUI.
+
+#### Example usage for VCT
+
+1) Open the [global_illumination.sdf](
+https://github.com/gazebosim/gz-sim/tree/gz-sim8/examples/worlds/global_illumination.sdf) world with
+
+```bash
+gz sim global_illumination.sdf
+```
+
+ \image html files/global_illumination/gui_demo_default.png width=60%
+
+
+
+2) From the plugin dropdown, select the Global Illumination Vct plugin.
+
+3) On the card, check the `Enabled` button to enable GI and change the parameter values as desired.
+
+
+ \image html files/global_illumination/gui_demo_with_vct.png width=60%
+
+
+#### Example usage for CI VCT
+
+1) Open the [global_illumination.sdf](
+https://github.com/gazebosim/gz-sim/tree/gz-sim8/examples/worlds/global_illumination.sdf) world using Vulkan with
+
+```bash
+gz sim global_illumination.sdf --render-engine-api-backend vulkan
+```
+
+2) From the plugin dropdown, select the Global Illumination Ci Vct plugin.
+
+3) On the card, check the `Enabled` button to enable GI and change the parameter values as desired.
+
+### How to enable global illumination for the sensor
+
+GI can be enabled for sensors through the `` element in the Sensors System plugin. VCT is supported for the sensor.
+
+#### Example usage with VCT
+
+We will demonstrate how to enable VCT for the sensor with the SDF file below. (The finished SDF file can be viewed [here](
+https://github.com/gazebosim/gz-sim/tree/gz-sim8/examples/worlds/global_illumination.sdf).)
+
+1) Save the below in an SDF file named `gi_demo.sdf`:
+
+```xml
+
+
+
+
+
+
+
+ ogre2
+
+
+
+
+
+
+
+
+ 0.4 0.4 0.4
+ 0 0 0
+
+
+
+
+
+
+ Cornell box GI demo
+ true
+ docked
+
+ ogre2
+ -12 0 4 0 0 0
+
+
+
+ camera
+
+
+
+
+
+
+
+ false
+ 0
+ 50
+ 250
+ 50
+ docked
+ true
+ #777777
+
+
+
+
+ false
+ 5
+ 5
+ floating
+ false
+
+
+
+
+
+
+ 0 0 7.5 0 0 0
+ 1 1 1 1
+ 0.0 0.0 0.0 0
+
+ 50
+ 0
+ 0
+ 0.02
+
+ true
+ false
+ 1.0
+
+
+
+
+ 0 5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 1 0 0 1
+ 1 0 0 1
+ 1 0 0 1
+
+
+
+
+
+
+ 0 -5 4 0 0 0
+ true
+
+
+
+
+ 10 1 10
+
+
+
+
+
+
+ 10 1 10
+
+
+
+ 0 1 0 1
+ 0 1 0 1
+ 0 1 0 1
+
+
+
+
+
+
+ 0 0 -0.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 8.5 0 0 0
+ true
+
+
+
+
+ 10 10 1
+
+
+
+
+
+
+ 10 10 1
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 4.5 0 4 0 0 0
+ true
+
+
+
+
+ 1 10 10
+
+
+
+
+
+
+ 1 10 10
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+
+ -1.5 0 0 0 0 0
+
+
+
+
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/meshes/pump.dae
+ 3 3 3
+
+
+
+
+
+
+
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/meshes/pump.dae
+ 3 3 3
+
+
+
+ 1.0 1.0 1.0
+ 1.0 1.0 1.0
+
+
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/materials/textures/pump_albedo.png
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/materials/textures/pump_roughness.png
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/materials/textures/pump_metallic.png
+ https://fuel.gazebosim.org/1.0/openrobotics/models/pump/1/files/materials/textures/pump_normal.png
+
+
+
+
+
+
+
+
+
+ -15 0 4 0 0.0 0
+ true
+
+ 0.05 0.05 0.05 0 0 0
+
+
+
+ 0.1 0.1 0.1
+
+
+
+
+
+
+ 0.1 0.1 0.1
+
+
+
+
+
+ 1.047
+
+ 2560
+ 1920
+
+
+ 0.1
+ 100
+
+
+ 1
+ 30
+ true
+ camera
+
+
+
+
+
+```
+
+2) Add the `` element to the Sensors System plugin.
+
+```xml
+
+ true
+ 16 16 16
+ 1 1 1
+ 6
+ true
+ true
+ 1.0
+ false
+ none
+
+```
+
+The parameters can be changed from the default values.
+
+3) Open the `gi_demo.sdf` world with
+
+```bash
+gz sim gi_demo.sdf
+```