Using libgazebo
External programs can use libgazebo to interact with the Gazebo simulator. libgazebo is a simple C library that allows other programs to peek and poke into a running simulation; through this library, programs may read sensor data from and send commands to simulated devices. The Player device server, for example, uses libgazebo in this way.Normal users will interact with Gazebo via player and need not be aware of this library. This chapter is included primarily to aid those who either wish to add a new type of interface to the simulator, or who wish to write their own custom control programs (by-passing player entirely).
Python bindings for libgazebo are also available.
Architecture
libgazebo uses interprocess communication (IPC) to allow a program to exchange data with a running simulator. Hereafter, we shall refer to the simulator as the server and the program as the client. Thus, for example, when using player to interact with Gazebo, Gazebo is the server and player is the client.The details of the underlying IPC are entirely hidden by libgazebo, which should be treated as a black box for passing data back and forth to the server. Currently, the only limitation users need be aware of is that both server and client must reside on the same machine; they cannot be run in separate locations across a network.
Devices and Interfaces
libgazebo makes the familiar distinction between devices and interfaces. In Gazebo, a device is a fully parameterized model, representing a particular real-world object such as a Pioneer2AT robot or a SICK LMS200 laser. An interface, on the other hand, is a general specification for an entire class of devices, such as position or laser. Thus, a Pioneer2AT device will present a position interface, while the SICK LMS200 will present a laser interface.The complete set of interfaces supported by libgazebo is described here. Note that these interfaces should not be confused with the interfaces defined by Player. Currently, these two sets of interfaces are fairly similar, but there is no guarantee that they will remain so in future.
Using libgazebo
Client programs must connect both to a specific server and a specific set of devices within that server. The following code snippet illustrates the general behavior:
// simple.c - works with simple.world // compile with: // gcc -Wall -g3 `pkg-config --cflags gazebo` -c -o simple.o simple.c // gcc simple.o -o simple `pkg-config --libs gazebo` // Thanks to Kevin Knoedler for various fixes. #include <stdio.h> #include <gazebo.h> int main (int argc, char *argv[]) { int i; gz_client_t *client; gz_position_t *position; int server_id; int client_id; // Assume one server and one client server_id = 0; client_id = 0; // Print all errors gz_error_init(1, 9); // Create a client object client = gz_client_alloc(); // Connect to the server if (gz_client_connect_wait(client, server_id, client_id) != 0) return -1; // Create a position interface position = gz_position_alloc(); // Connect to device on server if (gz_position_open(position, client, "robot1") != 0) return -1; // Read some data for (i = 0; i < 10; i++) { // Wait for new data gz_client_wait(client); // Lock it gz_position_lock(position, 1); // Print the current odometric position printf("%0.3f %0.3f\n", position->data->pos[0], position->data->pos[1]); // Unlock it gz_position_unlock(position); } // Close the interface and free object gz_position_close(position); gz_position_free(position); // Close the connection and free the client object gz_client_disconnect(client); gz_client_free(client); return 0; }
There are several points to note:
- The value of
server_id
variable must correspond to the server ID specified on the Gazebo command line. By default, the ID is0
, but other values may be specified if the user is running multiple instances of Gazebo simultaneously.
- The value of
client_id
variable must be unique for each client, and bounded in the range GZ_CLIENT_ID_FIRST to GZ_CLIENT_ID_LAST.
- The
device_id
variable specifies a unique device ID; the value of this variable must correspond to the device ID specified in the Gazebo world file.
- Any attempt to connect to a device using an unsupported interface will result in the
open
function returning an error. For example, if the device specified bydevice_id
is actually a laser, attempting to open it usinggz_position_open()
will result in an error.
- Do not use the
create
anddestroy
functions associated with each interface; these are reserved for use by Gazebo only. Useopen
andclose
instead.
This example can be demonstrated using the follow world file:
<?xml version="1.0"?> <gz:world xmlns:gz='http://playerstage.sourceforge.net/gazebo/xmlschema/#gz' xmlns:model='http://playerstage.sourceforge.net/gazebo/xmlschema/#model' xmlns:sensor='http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor' xmlns:window='http://playerstage.sourceforge.net/gazebo/xmlschema/#window' xmlns:param='http://playerstage.sourceforge.net/gazebo/xmlschema/#params' xmlns:ui='http://playerstage.sourceforge.net/gazebo/xmlschema/#params'> <model:ObserverCam> <id>userCam0</id> <xyz>-0.506 0.894 0.865</xyz> <rpy>0 26 -23</rpy> <imageSize>640 480</imageSize> </model:ObserverCam> <model:LightSource> <id>light1</id> <xyz>0.0 10.0 100.0</xyz> </model:LightSource> <model:GroundPlane> <id>ground1</id> <color>0 0.5 0</color> </model:GroundPlane> <model:Pioneer2AT> <id>robot1</id> <xyz>0.0 0.0 0</xyz> </model:Pioneer2AT> </gz:world>
Compiling and Linking Programs With libgazebo
All public functions are declared ingazebo.h
and defined in libgazebo.a
. The default install scripts put these in sensible places, so your compiler should pick them up automatically. Nevertheless, the recommended way to build applications is using the pkg-config
mechanism; the compile and link lines should look something like this:
gcc -Wall -g3 `pkg-config --cflags gazebo` -c -o simple.o simple.c gcc simple.o -o simple `pkg-config --libs gazebo`