Skip to content

Start, Check and Stop

Once the Raspberry Pi is set up, these commands start, check and stop the robot. The docker compose commands run on the Raspberry Pi, in the folder ~/diffbot/.docker/robot, where Compose finds compose.yaml and your settings in .env.

Start

Flash the Teensy's firmware first (Microcontroller), and connect the Teensy and the lidar to the Raspberry Pi's USB ports. If the ROS master runs on your PC, start roscore there, in the dev container, before the robot: without the master, the robot's containers stop at once.

On the Raspberry Pi:

1
2
cd ~/diffbot/.docker/robot
docker compose up -d --build

up creates and starts the containers described in compose.yaml: the bringup, and the lidar if COMPOSE_PROFILES=lidar is set. -d runs them in the background and gives you the prompt back. --build builds the image first, from the Dockerfile that compose.yaml names. The first build downloads the official ROS image and compiles the robot's packages on the Raspberry Pi, which takes a while. Later builds reuse the steps whose input didn't change, so they're usually much faster.

Check

On the Raspberry Pi, list the containers:

1
docker compose ps -a

On a robot without a lidar, it shows one container, the bringup, with the status Up. This output, like the one below, was recorded without hardware:

1
2
NAME                      IMAGE                  COMMAND                  SERVICE   CREATED          STATUS          PORTS
diffbot-robot-bringup-1   diffbot-robot:noetic   "/entrypoint.sh rosl…"   bringup   26 seconds ago   Up 26 seconds

With the lidar, a second line follows, for the service lidar. -a lists stopped containers too: a container that stopped shows Exited and a number, its exit code, and its output tells why.

Then follow the containers' output:

1
docker compose logs -f

Each line starts with the container it comes from. Ctrl+C stops following, and the robot keeps running. The bringup's output starts like this, shortened at the .... It was recorded with the robot image without hardware, with this page's example addresses:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
bringup-1  | started roslaunch server http://192.168.1.20:43309/
...
bringup-1  | NODES
bringup-1  |   /diffbot/
bringup-1  |     controller_spawner (controller_manager/spawner)
bringup-1  |     diffbot_base (diffbot_base/diffbot_base)
bringup-1  |     robot_state_publisher (robot_state_publisher/robot_state_publisher)
bringup-1  |     rosserial_base_controller (rosserial_python/serial_node.py)
bringup-1  |
bringup-1  | ROS_MASTER_URI=http://192.168.1.10:11311
bringup-1  |
bringup-1  | process[diffbot/rosserial_base_controller-1]: started with pid [52]
bringup-1  | process[diffbot/diffbot_base-2]: started with pid [53]
bringup-1  | process[diffbot/controller_spawner-3]: started with pid [54]
bringup-1  | process[diffbot/robot_state_publisher-4]: started with pid [55]
...
bringup-1  | [INFO] [1793227440.919570252]: ... Done Initializing DiffBot Hardware Interface
...
bringup-1  | [INFO] [1793227441.364928]: Connecting to /dev/ttyACM0 at 115200 baud
  • started roslaunch server with the Raspberry Pi's address: the bringup got ROS_IP.
  • ROS_MASTER_URI with the PC's address: the bringup uses the master on the PC.
  • NODES and the started lines: the four nodes of bringup.launch run: rosserial, the hardware interface diffbot_base, the controller spawner and the robot state publisher.
  • Connecting to /dev/ttyACM0: rosserial opens the Teensy.

With the Teensy, rosserial then prints Requesting topics..., and a line Setup publisher on … or Setup subscriber on … for each topic of the firmware. The controller spawner ends with Started controllers: joint_state_controller, mobile_base_controller.

The Teensy's lines will be added after the test on the robot (diffbot#109).

Then check on your PC, in the dev container, that the robot's topics have data. A topic that's listed but has no messages isn't enough:

1
2
3
rostopic hz /diffbot/measured_joint_states
rostopic echo -n 1 /diffbot/mobile_base_controller/odom
rostopic hz /diffbot/scan

measured_joint_states comes from the Teensy: messages at a steady rate mean that rosserial talks with the firmware and the encoders are read. odom is the controller's odometry. scan comes from the lidar, if it runs.

Drive

From your PC, first with the wheels off the ground, then slowly on the floor:

1
rosrun teleop_twist_keyboard teleop_twist_keyboard.py cmd_vel:=/diffbot/mobile_base_controller/cmd_vel

Stop

On the Raspberry Pi:

1
docker compose down

down stops and removes the containers. The image stays for the next start, and so do the ROS logs in ~/robot-data. The output that docker compose logs shows is removed with the containers. Before you switch the Raspberry Pi off, shut it down with sudo poweroff, so the SD card isn't written to while the power goes.

All commands

On the Raspberry Pi, in ~/diffbot/.docker/robot:

Task Command
Start, or restart after a change docker compose up -d --build
Is it running? docker compose ps -a
Follow the output docker compose logs -f
Stop docker compose down
Update the code git pull, then docker compose up -d --build
Switch off docker compose down, then sudo poweroff

After the Teensy was reset, reflashed or unplugged

Stop the containers and start them again: docker compose down, then docker compose up -d. A container gets its devices when it starts, and a reconnected Teensy is a new device for the kernel, which the running container doesn't see. A new start also starts a new odometry, so a measurement run ends there.

Running a command in a container

Most ROS commands run on your PC. To run one on the robot itself, for example when no PC is connected:

1
docker compose exec bringup /entrypoint.sh rostopic list
Part From What it does
docker compose Docker Works on the containers that compose.yaml in the current folder describes
exec Docker Runs a command in a running container
bringup compose.yaml The name of the service, the container to run it in
/entrypoint.sh the diffbot repository Our script that loads ROS and the workspace, then runs the rest of the line. Docker runs it when a container starts, but exec starts a new process without it, so the command names it
rostopic list ROS The command itself

docker compose exec bringup /entrypoint.sh bash opens a shell in the container, with ROS loaded.

Logs

The robot's messages end up in three places.

What the containers print

Everything that the bringup and the lidar driver print, as in Check above. Docker keeps it on the Raspberry Pi, at most 100 MB per container, until docker compose down removes the containers. To read it again, for example only the bringup's:

1
docker compose logs bringup

ROS's log files

roslaunch and each node also write a log file. They go to ~/robot-data/log on the Raspberry Pi, with a folder for each start, and latest always points to the newest one. These files stay after docker compose down. To read them on your PC, copy them there, on the PC:

1
scp -r <user>@<robot-ip>:robot-data/log/latest robot-logs

All nodes' messages, live

Each node also sends its messages to the node rosout, which runs with the ROS master and collects them from the robot and the PC. With the master on your PC, rqt_console shows them there, live, with filters by node and severity. On the PC, in the dev container:

1
rqt_console

Comments

Comments are GitHub Discussions, shown with giscus. Loading them connects to giscus.app (hosted by Vercel, USA) and GitHub (USA); you need a GitHub account to comment.