Centralized graph navigation for two TurtleBot3 Waffle robots on a 6 m x 3 m table. A fleet service plans A* paths over graph.yaml, dispatches per-robot FollowPath goals, and exposes ROS services used by the CLI and web dashboard.
CLI / Web UI
|
| /fleet/move_to_node, /fleet/cancel_path, /fleet/rotate_robot
v
path_server
|
| FollowPath action goals
v
robot_executors
|
| /<robot>/cmd_vel, /<robot>/odom, /<robot>/path_status
v
Gazebo or real TurtleBot3s
Key pieces:
path_server: loads graph + robot config, owns fleet services, plans paths.robot_executors: one executor per robot; follows paths, handles stop/rotate commands, and applies obstacle settings.web-ui: rosbridge dashboard for live poses, drag-to-node dispatch, stop, and rotation.
- Docker + Docker Compose
- ROS Noetic environment from
docker/ - X server for Gazebo/RViz windows
- Real robots only: TurtleBot3 bringup installed and all machines on the same LAN
Allow GUI windows from Docker once per host session:
xhost +local:dockerUse one runtime mode at a time: simulation.launch for Gazebo, or robots.launch for physical robots.
Do not run both against the same ROS master.
cd docker
cp .env.example .env
# Set ROS_HOSTNAME to your laptop hostname.local or IP.
sudo docker compose up -d
sudo docker exec -it noetic zsh
catkin_make
source devel/setup.zshFor real robots, use mDNS or fixed IPs consistently. Each robot should reach the laptop ROS master before launching bringup.
source devel/setup.zsh
roslaunch pathfinder simulation.launchThis will start Gazebo, RViz, graph markers, and virtual robots based on robots.yaml.
Place robots at their configured start stations
On each TurtleBot3:
export ROS_MASTER_URI=http://<laptop-hostname>.local:11311
export ROS_HOSTNAME=$(hostname).local
rosrun pathfinder real_robot_bringup <tb3_01-or-tb3_05>If the pathfinder package is not available on the robot, run the equivalent
TurtleBot3 command directly:
export ROBOT_ID=<tb3_01-or-tb3_05>
export ROS_NAMESPACE=$ROBOT_ID
roslaunch turtlebot3_bringup turtlebot3_robot.launch /tf:=/$ROBOT_ID/raw_tf /tf_static:=/$ROBOT_ID/raw_tf_staticIn the laptop container, auto-detect connected robots and launch the stack:
source devel/setup.zsh
roslaunch pathfinder robots.launchThe ROS launch files start rosbridge on port 9090 by default.
cd web-ui
cp .env.example .env
cd ../docker/web-ui
docker compose upOpen http://localhost:5173.
The dashboard shows the graph, station nodes, robot poses, path state, robot config, stop control, and rotation control. Click a robot to select it, then drag it to a graph node to dispatch a move.
rosrun pathfinder client <robot_id> <target_node_id>
rosrun pathfinder client <robot_id> stop
rosrun pathfinder client <robot_id> turn_left 90
rosrun pathfinder client <robot_id> move_forward 0.2Robot IDs come from config/robots.yaml. Target node IDs come from config/graph.yaml.
- Click a robot on the map to select it (the robot icon gets a highlight box).
- Drag the selected robot to any graph node and release.
The right panel shows state: MOVING, the target node, and the current step count while the robot is in motion.
- Click a robot on the map to select it.
- Click the Stop button in the right panel.
- Click a robot on the map to select it.
- Click the Relocalize... button in the right panel.
- Drag on the map to set the desired heading and release to confirm (press ESC to cancel).
src/pathfinder/config/graph.yaml: graph nodes, edges, and top-level station entries.src/pathfinder/config/robots.yaml: robot IDs, Web UI display names,start_station, motion tuning, and obstacle tuning.
Robots can only start at station nodes. start_station must match a station number in graph.yaml.
Gazebo or RViz does not open:
xhost +local:dockerROS package is not found:
source devel/setup.zshRobot does not move:
rostopic hz /<robot_id>/odom
rosservice call /fleet/get_robotsWeb UI cannot connect:
rosnode list | grep rosbridge
echo $VITE_ROSBRIDGE_URL




