Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

final_task — RoboGames 2026 Final Round Drone Stack

Self-contained onboard autonomy for the simplified final-round arena. The drone follows a yellow path, identifies airports via AprilTags, and lands once at the country-2 airport. No retakeoff is required.

All runtime paths are relative so this directory can be moved into a new repository without code changes.

Final-round task summary

The overall flow is the same as the semi-final task — follow the yellow path, decode AprilTags, land on the requested country — but the rules are simplified for the final arena:

Aspect Semi-final Final round
Arena layout Multi-loop course Simplified path (per arena image)
Required landings One per requested country Exactly one — at a country 2 airport
Retakeoff after landing Yes, to find the next country No — mission ends after landing
Takeoff pad marker None AprilTag 302 placed on the takeoff pad

How AprilTag IDs are decoded

A 3-digit ID XYZ encodes:

  • X (hundreds) — country code
  • Y (tens) — airport status: 1 = safe, 0 = unsafe
  • Z (ones) — reachable airports (informational)

Examples:

Tag ID Country Status Meaning
213 2 safe Valid landing target
212 2 safe Valid landing target
202 2 unsafe Skipped
115 1 safe Wrong country — skipped
302 3 unsafe Takeoff pad — filtered out before mission logic

Tag 302 (takeoff pad)

Tag 302 sits on the takeoff pad and is provided to help the autopilot stabilise during the initial climb. Teams are not required to modify it. This stack lists 302 in apriltag.ignore_tag_ids so the perception layer drops it before it can ever influence the mission FSM:

  • It is never added to the airport graph.
  • It never triggers visual servo or landing.
  • The mission only acts on tags that pass the country/status check.

If your local arena uses a different takeoff-pad ID, override apriltag.ignore_tag_ids in your config/local.json.

Mission state machine

INIT → FOLLOW_LINE ⇄ VISUAL_SERVO → LAND_WAIT → COMPLETE
                                     ↓
                  (any state) → FAILSAFE on timeout / land timeout

There is no RETAKEOFF state in the final-round runner — the mission is complete the moment the country-2 landing succeeds.

What is included

  • src/ — modular onboard autonomy stack
  • config/ — tunable JSON parameters
  • scripts/ — startup and diagnostics utilities
  • tests/ — host-runnable tests (no MAVLink/camera hardware needed)
  • requirements.txt — Python dependencies
  • .gitignore — Python and Raspberry Pi development ignore rules

Target Platform

  • Raspberry Pi 5
  • Alpine Linux
  • MAVLink endpoint on UDP port 14550
  • Camera stream on TCP port 9000 (raw RGB frames)

1. Connect over SSH

From your host machine:

ssh root@localhost -p 2222

After login, move to the project directory on the Pi:

cd /path/to/final_task

2. Install system packages (Alpine apk)

apk add --no-cache \
  python3 \
  py3-pip \
  python3-dev \
  gcc \
  g++ \
  make \
  musl-dev \
  linux-headers

3. Create and activate virtual environment

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt

For SSH/headless operation on Raspberry Pi this project uses opencv-contrib-python-headless by default, so GUI/X11 libraries are not required for mission runtime.

If you previously installed GUI OpenCV wheels, clean them first to avoid mixed-wheel conflicts such as ImportError: libxcb.so.1:

python3 -m pip uninstall -y \
  opencv-python \
  opencv-contrib-python \
  opencv-python-headless \
  opencv-contrib-python-headless
python3 -m pip install -r requirements.txt

4. Configure mission parameters

Default config lives at config/defaults.json. The default mission.requested_countries is [2], matching the final-round single-landing requirement.

For real hardware tuning:

  1. Copy config/hardware.example.json to config/local.json
  2. Adjust camera, HSV thresholds, PID gains, and landing tolerances
  3. Run mission with the override file
cp config/hardware.example.json config/local.json
python3 -m src.mission --config config/local.json --debug

If config/local.json is missing, mission startup fails with a hint that includes the exact cp command above.

You can override the country at the command line (rarely needed for the final round):

python3 -m src.mission --config config/local.json --countries 2

5. Start onboard mission

Option A — Startup script (recommended)

sh scripts/start.sh config/defaults.json

With country override:

COUNTRIES=2 sh scripts/start.sh config/local.json

Option B — Run mission directly

python3 -m src.mission --config config/defaults.json

6. Hardware test flow (SSH session)

Run these checks in order before live flight:

  1. Validate config and camera socket reachability:

    python3 scripts/diagnostics.py
  2. Confirm MAVLink heartbeat and telemetry access:

    python3 scripts/test_mavlink.py
  3. Preview camera and detection overlays (q to quit, requires GUI):

    python3 scripts/camera_preview.py
  4. Run mission with conservative speeds first:

    python3 -m src.mission --config config/local.json --debug

7. Host-side automated tests

The tests/ folder contains hardware-free tests. They verify:

  • AprilTag metadata decoding (country / status / reachable digits)
  • Tag 302 filtering (takeoff pad must never trigger landing)
  • Mission FSM behaviour: country-2 safe airport → land → COMPLETE
  • Country-mismatch and unsafe-status tags do not trigger landing
  • Single-landing flow (no arm/takeoff calls happen after land)

Run them all with:

python3 tests/run_all.py

Or individually:

python3 tests/test_apriltag_decode.py
python3 tests/test_mission_flow.py

These tests need only numpy, opencv-contrib-python-headless, and pymavlink installed (the same as requirements.txt); they replace MAVLink and the camera with in-process fakes.

Module overview

  • src/mavlink_client.py — MAVLink connection and arm / takeoff / velocity / land commands
  • src/camera_stream.py — TCP frame ingestion from port 9000
  • src/apriltag_detector.py — AprilTag detection + ignore_tag_ids filter for takeoff pad
  • src/line_follower.py — Adaptive yellow-path detection
  • src/landing_controller.py — Landing command fusion (tag alignment + line assist)
  • src/mission.py — Simplified single-landing FSM

Performance notes for Raspberry Pi 5 + Alpine

  • Frame buffering is intentionally small to reduce control lag.
  • Vision uses simple morphology and contour logic to limit CPU usage.
  • Avoid running extra GUI tools during flight unless needed for diagnostics.
  • Keep camera resolution moderate (for example 640x480) if CPU load is high.

Camera stream expectations and troubleshooting

  • The mission TCP camera client expects raw RGB frames at 640x480 by default.
  • If dimensions differ from the configured expected size, that frame is dropped to prevent OpenCV crashes from malformed payloads.
  • If you intentionally use a different camera size, override camera.expected_width and camera.expected_height in your local config.

Portability notes

  • No hardcoded absolute paths.
  • Config and script paths are relative to the project root.
  • This folder can be copied into a new repository and run as-is after dependency installation.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages