Gazebo 11 uses the gz-common Profiler to check and visualize the performance of the different threads, functions and methods.
Gazebo 9 uses an internal fork of Ignition Common's profiler.
To use the compiler, Gazebo must be compiled from source with the CMake flag
-DENALE_PROFILER=1
, for example:
cmake .. --cmake-args -DENABLE_PROFILER=1
For example, if you are using colcon
to compile Gazebo:
colcon build --cmake-args -DENABLE_PROFILER=1
After compiling Gazebo, launch the world you want to profile. For example,
gazebo profiler.world
There's a convenient launcher script (Linux and macOS) for starting Remotery.
On Gazebo 11:
ign_remotery_vis
On Gazebo 9:
gz_remotery_vis
The script should open the profiler output in a browser.
Profile data for each process goes to a different port, which can be chosen on the top of the page:
gzserver
to port 1500gzclient
to port 1501You should see plots corresponding to different theads, for example:
gzserver
[Ode,Bullet,Symbody,Dart]Physics
SensorManager
The following image shows the sensor manager timeline. In this case we
have 5 different sensors: gps
, imu
, magnetometer
, altimeter
and contact
.
You can see what is the duration of the sensor manager loop (50ms) and
how long it takes to update all the sensors (around 0.177ms), the rest
of the time the thead will be sleeping.
You can see the update time of each sensor, all the sensors have two subtasks: generate data and then publish this data (fill the data structure and publish it).
In the following two images you can see the evolution of the OdePhysics
and gzserver
loops.
Using Gazebo 11, you can add profiler points to any Gazebo plugin. This is not possible on Gazebo 9.
If you want to add the profiler to your own Gazebo plugins you need to follow these steps:
Include the header
#include <ignition/common/Profiler.hh>
Link against the profiler library
target_link_libraries(<your plugin name>
...
${IGNITION-COMMON_LIBRARIES}
)
Add profiler macros to the update method or other periodic methods:
IGN_PROFILE("WindPlugin::OnUpdate");
IGN_PROFILE_BEGIN("Update");
...
IGN_PROFILE_END();
Classes that inherit from gazebo::sensors::Sensor
already have the macros
in the UpdateImpl
method. This method is called periodically and it's in
charge of generating the data and publishing it.
Classes that inherit from gazebo::*Plugin
can connect to the periodic world
update event with gazebo::event::Events::ConnectWorldUpdateBegin
. See the
WindPlugin
for example, this will call the WindPlugin::OnUpdate
method for
every simulation iteration:
this->dataPtr->updateConnection = event::Events::ConnectWorldUpdateBegin(
std::bind(&WindPlugin::OnUpdate, this));
That callback is a good place to put the macros above.