Gazebo - samdrew/betaflight_gazebo GitHub Wiki

Gazebo

Gazebo is a simulator that provides lots of useful off-the-shelf components and a flexible architecture for building and testing physical components in a virtual world. It is undergoing active development, provides good backwards compatibility, and is heavily used alongside ROS2 (although we will not be relying on ROS in this guide).

This guide is assuming no prior experience with Gazebo.

Versions and Naming

The first thing to be aware about Gazebo is there are two simulators which use the same name and some of the same version numbers. The first is Gazebo, now known as Gazebo Classic, while the second is Ignition, now known as Gz Sim or just Gazebo. I mention this because when reading something about "Gazebo 8" online, it might be referring to either of Gazebo Classic from 2018 or Gazebo Ignition from 2023, and without being aware of this upfront many instructions found on the internet don't make sense.

By Open Robotics - https://gazebosim.org/about, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=143467601

This is often countered by the naming, where Gazebo Ignition tries to use alphabetical naming scheme, rather than numerical. Throughout this guide we will only be working with the Gazebo Ignition stream, and perpetuating the ambiguity we will just be referring to it as Gazebo.

Getting started

The documentation for installing Gazebo is available on their website gazebosim.org. This works well for default scenarios, however there are caveats for running on a Ubuntu VM, running on a Mac (Apple Silicon) due to the ARM architecture and driver support.

Execution on ARM Ubuntu

I am running Ubuntu 24.04 on Parallels, with Rosetta disabled. There is no reason this wouldn't work on other platforms.

Graphics issues

Gazebo uses Ogre2 as its rendering engine, however running this in the default parallels instance crashes. There are two ways to work around this:

  1. Run with ogre (instead of ogre2)
  2. Disable video hardware acceleration in VM.

Option number 1 severely limits the visual fidelity, while option number 2 reduces rendering speed to single digit fps. Neither of these are good. It should be possible to split server and GUI services making use of the GZ_PARTITION environment variable, and allowing the GUI to execute on the VM host (ie Mac), however I have been unable to get this to work correctly from Ubuntu (server) -> Mac (GUI), however it works fine for Ubuntu -> Ubuntu (conditional on models being at the same path on both systems).

Running Gazebo

Executing a basic sim in Gazebo is relatively simple, as demonstrated by the example included after installation in the Getting Started guide above.

gz sim shapes.sdf

This loads a basic simulation with 6 objects. This can then be run and the ellipsoid will fall over after about 5 seconds of sim time.

To get a better understanding of the simulator, select the sphere, and in the model properties Expand the 'Pose' settings. Change the pose so that Pose Y is 0.6, and Z is 2.5. When the model is run, it will hit the cube, followed by the ellipsoid, before rolling off. Changing Pose Y to 0.5 or 0.502, will demonstrate various different behaviours, as the sphere makes contact with the cube at different relative positions.

Running other worlds

I don't fully understand the Gazebo architecture, however functionally it consists of worlds, that have models, which are themselves made up of other models and plugins. All of these are loaded from the various path parameters and default locations for Gazebo.

PATH Parameters

Gazebo loads resources (Models, Worlds and Plugins) based on both default locations and Path Parameters. Note the path parameters have changed name across versions. For Gazebo Garden/Harmonic/Ionic the prefix is GZ_SIM_

Alternatively there are also default locations resources can be stored so that they will be loaded, including ~/.gz/sim/plugins for .so plugins.

echo "export GZ_SIM_RESOURCE_PATH=${HOME}/betaflight_gazebo/models:/home/sam/betaflight_gazebo/worlds:${GZ_SIM_RESOURCE_PATH}" >> $HOME/.bashrc
echo "export GZ_SIM_SYSTEM_PLUGIN_PATH=${HOME}/betaflight_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH}" >> $HOME/.bashrc
source ~/.bashrc

Troubleshooting

Here I am documenting various errors I encountered in the hopes that others finding the same issue will help find ways to work around them.

QT Ogre2 failed with Acceleration enabled

Error:

[warning] [Application.cc:933] [GUI] [QT] Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt.
You must not let any exception whatsoever propagate through Qt code.
If that is not possible, in Qt 5 you must at least reimplement
QCoreApplication::notify() and catch all exceptions there.

terminate called after throwing an instance of 'Ogre::RenderingAPIException'
  what():  OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 100000001PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at ./RenderSystems/GL3Plus/src/GLSL/OgreGLSLShader.cpp (line 361)
Stack trace (most recent call last) in thread 2962:
#10   Object "[0xffffffffffffffff]", at 0xffffffffffffffff, in
#9    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xf1fca127ba4b, in
#8    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xf1fca121597b, in
#7    Object "/lib/aarch64-linux-gnu/libQt5Core.so.5", at 0xf1fc984b4e4b, in
#6    Object "/lib/aarch64-linux-gnu/libQt5Core.so.5", at 0xf1fc984907e7, in qTerminate()
#5    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xf1fc9c0a0e03, in std::terminate()
#4    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xf1fc9c0aa56f, in
#3    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xf1fc9c0ad4d7, in __gnu_cxx::__verbose_terminate_handler()
#2    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xf1fca11b7dff, in abort
#1    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xf1fca11ccb3b, in gsignal
#0    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xf1fca1217628, in
Aborted (Signal sent by tkill() 2872 1000)

Issue:

Ogre2 does not work correctly with arm64 VMs and Hardware Accelerated OpenGL. See more details here.

Workaround:

(Fidelity) Force Software acceleration, either at the VM level by disabling hardware acceleration, or the appropriate mesa environment variable (eg export LIBGL_DRI3_DISABLE=1).

(Speed) Use ogre as the rendering engine, by including --render-engine ogre in the gz command to start your simulation. The physical behaviour should be the same, but the rendering lacks lighting detail, and some features are unsupported.

Unfortunately to the best of my knowledge this is an either/or situation when running on a VM within MacOS.