Repo at https://github.com/RTIS-Lab/f1tenth_gym_docker.
Make sure to pull all the submodules using
git clone --recurse-submodules
. If you’ve already cloned, usegit submodule update --init --recursive
Processes within a docker container are isolated from the rest of the system, and can only interact with the host through specifically defined ways. This is useful for portability, since the container can run on any system that has docker installed. This is similar to running things in a virtual machine, but has much less overhead. This setup is split into two main components: the simulator itself, and the vehicle control packages. Each is confined to it’s own docker container. The two containers communicate with each other over ROS (Robot Operating System) topics. The intention is that the simulator can expose the same topics & services as the real vehicle, so that the same control packages can be used in both environments.
The simulator is a python package, originally taken from https://github.com/f1tenth/f1tenth_gym. It implements the OpenAI Gym interface, which is common for reinforcement learning environments. Here, it’s wrapped with a script that makes the simulator interfaces available over ROS.
The simulator code is in f1tenth_gym_ros
. The code controlling physics, lidar simulation, etc is in f1tenth_gym
, and the wrapper is in f1tenth_gym_ros
. A Dockerfile
is included that installs the gym package, ROS dependencies, and starts the wrapper script.
The control code is in f1tenth_drive
. This folder is set up as a normal ROS2 workspace, along with a Dockerfile
that installs the necessary dependencies.
At the top level, there is a docker-compose.yml
file that sets up the two containers and sets up a network for the two containers to communicate over. To make development easier, it binds the ROS workspace as a volume, so changes made to the files on the host machine are reflected in the container at runtime, so a full rebuild is not required to test changes.
The docker-compose.yml
also has a third container for visualization, which constains a small desktop environment with rviz. That constainer is commented out by default (Kurt recommends using Foxglove (installed on the host) instead, but in some specific situations rviz is necessary).
(Optional, but highly recommended) Install VS Code, along with the Docker and Remote Containers extensions.
Install Foxglove Studio
docker compose up
. Depending on your system, you may need to run this as root.Do not use
docker-compose
(note the dash). It might work on some systems, fail on others, or even be missing.docker compose
is guaranteed to make the newer docker-compose v2 functionality available, which this project relies on.
docker exec -it f1tenth_sim-driver-1 /bin/bash
.The container name may depend on the name of the folder containing the
docker-compose.yml
file. You may need to replacef1tenth_sim
with the name of the containing folder, but rundocker ps
to get the container’s name for your system.
If you have VS Code installed with the Remote Containers extension, you can open the root directory in VS Code, and run “Dev Containers: Reopen in Container”. The root folder has a .devcontainer
that informs VS Code how to connect to the container, as well as what extensions to load into it. Terminals started from this environment will already be inside the container!
To build the workspace, run colcon build
from the root of the workspace. If freshly started from docker compose
, the workspace will already be built.
Start Foxglove Studio, and open a rosbridge connection to ws://localhost:9090
. This will allow you to visualize the topics being published by the simulator.
The driver container already sources the correct ROS dependencies, so you can run ros2 launch
and ros2 run
commands from the driver container.
/drive
: an AckermannDriveStamped
message, that contains a target speed value and steering angle. Publish to this to control the vehicle.
/scan
: a LaserScan
message, that contains the lidar scan data. Subscribe to this to get the lidar data. This publishes 1080 points, with a 270 degree field of view at 40Hz.
/ego_racecar/odom
: a Odometry
message, that contains the vehicle’s position and velocity. Subscribe to this to get the vehicle’s position. This outputs ground-truth data, and is not a realistic representation of the vehicle’s sensors. The type and name of this topic is different on the real vehicle, and depends on the data source.
/run_auto
: A Bool
message, that contains a boolean value. Publish a true value to this topic to start the vehicle’s automatic control package. Your driving code should listen to this topic, and only publish to /drive
when /run_auto
is true. This topic is published by the teleop node whenever the correct button is pressed on a gamepad.
Most of our control code is in the kw_f110_drive
package. Right now, our focus is on driving without depending on location data, and only using the lidar data.
CMake will build with release settings by default, which removes debugging information. Build with colcon build --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
(or -DCMAKE_BUILD_TYPE=Debug
) to get line numbers in valgrind results.
Before running any valgrind commands in a container, run ulimit -n 1024
within it. Some of the launch files, like mapless_drive.xml
, have commented sections that add valgrind to the launch steps.
// TODO: add instructions for valgrind usage in ros2 launch files