This repository contains the probation task for autonomous gate navigation using ROS2 and a Unity simulation.
You should NOT clone this repository directly from the Mecatron GitHub organisation.
Instead, fork this repository to your own GitHub account and clone from it. (Please ask ChatGPT how to fork a github repository if you are unsure). After cloning, ensure you are on the
probation/taskbranch:git checkout probation/taskImplement your solution in this branch
probation/taskin either Python or C++ and send us the link to your forked repository once completed.
We use
ROS2 Jazzy + Ubuntu 24.04for all development. The environment is fully Dockerized (Native installation is not encouraged).
See docs/GETTING_STARTED.md for the full step-by-step setup guide (Ubuntu 24.04 via WSL2 → Git → Docker → Build).
Prerequisites to Download (Installed & Run on Windows Host):
- Unity Simulation — the simulation environment (
UnitySim.exe), downloaded and run on Windows. - Foxglove Studio — for monitoring vehicle state and topics visually. See docs/FOXGLOVE_SETUP.md for connection and layout import instructions.
Task Goal: Navigate an Autonomous Underwater Vehicle (AUV) through a gate in a simulated underwater environment.
Learning Objectives:
- Working with a robot simulator using ROS2
- Processing object detection data to extract meaningful information
- Developing autonomous decision-making and control algorithms
- Managing a project with multiple concurrent processes and nodes
Success Criteria:
- The vehicle navigates autonomously through the gate 3 times, at 3 different random initial positions.
probation_ws/
├── src/
│ ├── ROS-TCP-Endpoint/ # Unity-ROS2 communication bridge
│ ├── probation_bringup/ # Launch, config, and your solution scripts
│ │ ├── launch/
│ │ │ └── probation.launch.py # <-- Main launch file for the simulation
│ │ └── scripts/
│ │ └── solution_template.py # <-- Start here: implement your solution
│ └── vision/
│ └── vision_msgs/ # Custom message definitions for bounding boxes
Start the container (once) and enter it (every time you open a new Ubuntu terminal):
cd ~/probation_ws
docker compose up -d dev-core
docker compose exec dev-core bashInside your Docker container (or native terminal), run:
ros2 launch probation_bringup probation.launch.pyThis starts two processes:
- ROS-TCP-Endpoint on port
10000— the Unity simulation connects to this. - Foxglove Bridge on port
8765— open Foxglove Studio, connect tows://localhost:8765, and import docs/probation_foxglove_layout.json (see docs/FOXGLOVE_SETUP.md).
Launch UnitySim.exe on your Windows host. Once it connects, you will see topics appear in ROS2.
In a second terminal inside the container:
# Check that simulation topics are visible
ros2 topic list
# Verify vehicle state is being published
ros2 topic echo /mavros/stateTip: If
ros2 topic listshows nothing (or is missing topics you expect), the ROS2 daemon may be stale. Restart it and try again:ros2 daemon stop ros2 daemon start
Open a second Ubuntu terminal:
cd ~/probation_ws
docker compose exec dev-core bashThen run:
ros2 run probation_bringup solution_template.pyTip: If you create new Python scripts in
src/probation_bringup/scripts/, ensure they have executable permissions:chmod +x src/probation_bringup/scripts/<script_name>.py
Use these commands to explore any topic yourself:
ros2 topic info <topic> # See the message type
ros2 interface show <message_type> # See all fields of a message type
ros2 topic echo <topic> # Print live data| Topic | Message Type | Description |
|---|---|---|
/main_camera/detection/bounding_boxes |
vision_msgs/BoundingBoxArray |
Gate detection from the front camera |
/mavros/global_position/compass_hdg |
std_msgs/Float64 |
Current heading in degrees (0–360) |
/mavros/global_position/rel_alt |
std_msgs/Float64 |
Current depth/altitude in meters |
/mavros/setpoint_velocity/cmd_vel_unstamped |
geometry_msgs/Twist |
Send velocity commands to move the vehicle |
/mavros/state |
mavros_msgs/State |
Vehicle armed/mode status |
The camera publishes all detected objects as a BoundingBoxArray. Each BoundingBox contains:
| Field | Type | Description |
|---|---|---|
x |
float | Horizontal center (0.0 = left edge, 0.5 = center, 1.0 = right edge) |
y |
float | Vertical center (0.0 = top edge, 0.5 = center, 1.0 = bottom edge) |
w |
float | Width of bounding box (normalized 0.0–1.0) |
h |
float | Height of bounding box (normalized 0.0–1.0) |
conf |
float | Detection confidence (0.0–1.0) |
label_id |
int | Numeric class ID of the detected object |
label_name |
string | String class name of the detected object |
To move the vehicle, publish a geometry_msgs/Twist message:
linear.x — forward (+) / backward (−) [m/s]
linear.y — strafe left (+) / right (−) [m/s]
linear.z — up (+) / down (−) [m/s]
angular.z — yaw left/CCW (+) / right/CW (−)[rad/s]
- Random Initial Position: The vehicle spawns at a random location and orientation on each run.
- Imperfect Detection: The object detector does not detect the gate 100% of the time. Your solution should handle frames where no detection is received.
- GUIDED Mode Required: The vehicle must be in
GUIDEDflight mode to accept velocity commands from ROS2. Without this, all published commands are ignored.
Open src/probation_bringup/scripts/solution_template.py.
It contains a clean ROS2 node skeleton to start building your solution.
Reference ROS2 code examples (publishers, subscribers, clients, services) are available under
docs/help/.
Suggested progression:
- Set the vehicle to
GUIDEDmode via the service client. - Subscribe to sensor topics and log what you receive.
- Send a simple constant velocity and watch the vehicle move.
- Implement closed-loop control using sensor feedback to navigate through the gate.
Refer to Section 8 for useful commands and links.
One possible approach — there are many valid solutions:
- Set vehicle to
GUIDEDmode - Descend to a depth where the gate is likely visible
- Implement a search pattern to find the gate
- Align laterally and in heading with the gate center
- Drive forward through the gate
The gate area contains an orange flare that may appear as an obstacle. If the vehicle's initial position faces this obstacle:
- You may implement obstacle avoidance for bonus points (not required).
- Alternatively, you may reset the simulation and try a new spawn.
Focus on the gate navigation first. Obstacle avoidance is optional.
# Check available topics and services
ros2 topic list
ros2 service list
# Restart the ROS2 daemon if topics/services are missing or stale
ros2 daemon stop
ros2 daemon start
# Inspect message types
ros2 interface show vision_msgs/msg/BoundingBox
ros2 interface show geometry_msgs/msg/Twist
ros2 interface show mavros_msgs/srv/SetMode
# Monitor live data
ros2 topic echo /main_camera/detection/bounding_boxes
ros2 topic echo /mavros/global_position/compass_hdg
ros2 topic echo /mavros/global_position/rel_alt
# Set vehicle mode manually (useful for testing)
ros2 service call /mavros/set_mode mavros_msgs/srv/SetMode "{base_mode: 0, custom_mode: 'GUIDED'}"
# Switch back to manual keyboard control
ros2 service call /mavros/set_mode mavros_msgs/srv/SetMode "{base_mode: 0, custom_mode: 'ALT_HOLD'}"
# Verify your velocity commands are being published
ros2 topic echo /mavros/setpoint_velocity/cmd_vel_unstamped
ros2 topic hz /mavros/setpoint_velocity/cmd_vel_unstampedGood luck! The key is building a system that handles imperfect sensing robustly. Start simple, iterate, and test frequently.
