gazebo_simulation

ROS package to better communicate with Gazebo.

simulation/src/gazebo_simulation
├── launch
│   ├── test
│   │   ├── automatic_drive.test
│   │   ├── car_model_generation.test
│   │   ├── car_state_node.test
│   │   └── model_plugin_link.test
│   ├── automatic_drive.launch
│   ├── car_state_node.launch
│   ├── gazebo_rate_control_node.launch
│   ├── master.launch
│   ├── record_random_drive.launch
│   ├── road_editor.launch
│   ├── spawn_car.launch
│   └── world.launch
├── msg
│   ├── CarState.msg
│   ├── SetModelPose.msg
│   └── SetModelTwist.msg
├── param
│   ├── automatic_drive
│   │   ├── test
│   │   │   └── path.yaml
│   │   ├── default.yaml
│   │   └── path.yaml
│   ├── car_specs
│   │   └── dr_drift
│   │       ├── camera.yaml
│   │       ├── car_specs.yaml
│   │       ├── model.urdf
│   │       └── static_coordinate_systems.yaml
│   ├── car_state
│   │   ├── default.yaml
│   │   └── topics.yaml
│   ├── gazebo_rate_control
│   │   ├── default.yaml
│   │   └── topics.yaml
│   └── model_plugin_link
│       ├── default.yaml
│       └── topics.yaml
├── res
│   ├── KITcar_Logo.svg
│   └── simulation.rviz
├── scripts
│   ├── automatic_drive_node
│   ├── car_state_node
│   ├── car_state_visualization_node
│   ├── gazebo_rate_control_node
│   └── generate_dr_drift
├── src
│   ├── automatic_drive
│   │   ├── __init__.py
│   │   └── node.py
│   ├── car_model
│   │   ├── camera_specs.py
│   │   ├── car_specs.py
│   │   ├── dr_drift.py
│   │   ├── __init__.py
│   │   └── tof_sensors.py
│   ├── car_state
│   │   ├── __init__.py
│   │   ├── node.py
│   │   └── visualization.py
│   ├── gazebo_rate_control
│   │   ├── index.rst
│   │   ├── __init__.py
│   │   └── node.py
│   ├── model_plugin_link
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── model_plugin_link.cpp
│   │   └── model_plugin_link.h
│   ├── world_plugin_link
│   │   ├── CMakeLists.txt
│   │   ├── world_plugin_link.cpp
│   │   └── world_plugin_link.h
│   └── __init__.py
├── test
│   ├── test_automatic_drive
│   ├── test_car_model_generation
│   ├── test_car_state_node
│   └── test_model_plugin_link
├── CMakeLists.txt
├── __init__.py
├── package.xml
└── setup.py

21 directories, 64 files

master.launch

The master.launch master_launch file includes all necessary components to run the simulation locally. Refer to the actual source code for more details on available parameters.

Launch

Start the complete simulation with

roslaunch gazebo_simulation master.launch

See also

Getting Started for more details.

Model of the Car

An important part of the simulation is the vehicle it self. It should be a realistic representation of the real car. In our case we do not simulate the actual tire movement and basically move a box around the simulated world. This simplifies the model significantly! Nevertheless, the sensors must be defined and should be as close to their real specifications as possible. Instead of calculating or estimating their position and calibrations, the sensors specifications are extracted from the car_specs ROS package within KITcar_brain.

Gazebo allows to define models using the urdf standard. However, defining a model consisting of multiple parts and sensors is repetitive. So instead of writing the urdf by hand, there’s a Python script that generates it!

Generate Dr. Drift

Generate a new model definition of Dr. Drift and an updated calibration by running:

rosrun gazebo_simulation generate_dr_drift

Behind the scenes, there are multiple things going on:

  1. The car_specs and camera_specs are loaded using simulation.src.gazebo_simulation.src.car_model.car_specs.CarSpecs and simulation.src.gazebo_simulation.src.car_model.camera_specs.CameraSpecs.

  1. The model of Dr.Drift is defined as an simulation.utils.urdf.core.XmlObject in simulation.src.gazebo_simulation.src.car_model.dr_drift. Using the urdf package allows to define classes for the individual parts of the vehicle.

  1. The model, the car specs and the camera calibration is saved to simulation/src/gazebo_simulation/param/car_specs/dr_drift/.

CarStateNode

The simulation.src.gazebo_simulation.src.car_state.node.CarStateNode subscribes to Gazebo updates and publishes information about the cars current state (position + speed + …) in shape of a CarState Message.

Launch

roslaunch gazebo_simulation car_state_node.launch

By default the parameter rviz is true and simulation.src.gazebo_simulation.src.car_state.visualization.CarStateVisualizationNode is launched as well. Enabling to display the car’s frame and field of view in RVIZ.

GazeboRateControlNode

The simulation.src.gazebo_simulation.src.gazebo_rate_control.node.GazeboRateControlNode can control Gazebo’s maximum update rate to ensure that a specified topic publishes with a large enough rate. It is primarily necessary because Gazebo does not ensure a sensor update rate in Docker containers.

This node is not started in the master.launch file by default. It can be manually started by passing the parameter control_sim_rate:=true or running:

Launch

roslaunch gazebo_simulation gazebo_rate_control_node.launch

ModelPluginLinkNode

It can be attached to Gazebo models by adding

<plugin filename="libmodel_plugin_link.so" name="model_plugin_link"/>

to the model.sdf.

When Gazebo loads a model with the model_plugin_link, a new instance of the model plugin link node is created. The model plugin link node creates two publisher’s:

And two subscribers:

digraph ModelPluginLink {

  node [style=dotted, shape=box]; model [label="Gazebo model"];
  node [style=solid, shape=ellipse]; model_plugin_link_node [label="model_plugin_link"];
  node [shape=box]; pose_topic [label="pose"]; twist_topic [label="twist"];set_pose_topic [label="set_pose"]; set_twist_topic[label="set_twist"];
  node [style=solid, shape=ellipse]; other_nodes;

  model -> model_plugin_link_node [style=dotted, dir=both];

  model_plugin_link_node -> pose_topic;
  model_plugin_link_node -> twist_topic;

  set_twist_topic -> model_plugin_link_node;
  set_pose_topic -> model_plugin_link_node;

  twist_topic -> other_nodes;
  pose_topic -> other_nodes;

  other_nodes -> set_pose_topic;
  other_nodes -> set_twist_topic;

  subgraph topics {
    rank="same"
    pose_topic
    set_pose_topic
    twist_topic
    set_twist_topic
  }
  subgraph gazebo {
    rank="same"
    label="Gazebo"

    model
  }
}

Schema of the Model Plugin Link


WorldPluginLinkNode

The WorldPluginLinkNode is a Gazebo world plugin that allows to interact with worlds in Gazebo easily. In particular, it allows to spawn and remove models from the world.

It can be attached to Gazebo worlds by adding

<plugin filename="libworld_plugin_link.so" name="world_plugin_link" />

to the model.sdf.

When Gazebo loads a world with the world_plugin_link, a new instance of the world plugin link node is created. The model plugin link node creates two subscribers:

  • /simulation/gazebo/world/spawn_sdf_model (string): Receive sdf model definition.

  • /simulation/gazebo/world/remove_model (string): Receive name of the model to be removed.

digraph WorldPluginLink {

  node [style=dotted, shape=box]; world [label="Gazebo world"];
  node [style=solid, shape=ellipse]; world_plugin_link_node [label="world_plugin_link"];
  node [shape=box]; spawn_sdf [label="spawn_sdf_model"]; remove_model [label="remove_model"];
  node [style=solid, shape=ellipse]; other_nodes;

  world -> world_plugin_link_node [style=dotted, dir=both];

  world_plugin_link_node -> spawn_sdf[dir="back"];
  world_plugin_link_node -> remove_model[dir="back"];

  spawn_sdf -> other_nodes[dir="back"];
  remove_model -> other_nodes[dir="back"];

  subgraph gazebo {
    rank="same"
    label="Gazebo"

    world
  }
  subgraph topics {
    rank="same"
    spawn_sdf
    remove_model
  }
}

Schema of the World Plugin Link


AutomaticDriveNode

The simulation.src.gazebo_simulation.src.automatic_drive.node.AutomaticDriveNode moves the car on the right side of the road. It can be used instead of KITcar_brain.

Launch

roslaunch gazebo_simulation automatic_drive.launch

The speed of the car can be modified by passing speed:=… as a launch parameter. (Or by modifying the parameter with rosparam at run-time.)