AIGP · VQ1
LIVE

Virtual Qualifier 1 · Status

Stack ready. Waiting on the binary.

AIGP launches VQ1 at the end of next week (week of May 25). Detector trained, PnP wired, PID tuned. Sim adapter is the last external dependency — it ships with the AIGP package.

Overall readiness On track
95 %
Done
5
Partial
1
Missing
0
Launch window

Late next week

week of May 25

Roster freeze

T − 24h

before launch

Run budget

8 min

per attempt · unlimited tries

Inference target

< 50 ms

YOLO11n on RTX 5080

01 · Stack

Component status

Gate detector

YOLO11n · 4-corner pose

Done

Trained on the synthetic gates dataset with corner keypoint labels. Inference well under budget.

weights
runs/detect/apex_yolo11n/weights/best.pt
size
5.3 MB · 150 epochs
trained
2026-05-17

PnP solver

4 corners → SE(3)

Done

SOLVEPNP_IPPE_SQUARE on known 1.5 m gate geometry — returns gate center in camera frame.

impl
vq1_completion_pilot.py:137
multi-gate
vision_enhancements.py:261
kalman variant
imu_gate_predictor.py:137

PID controller

Heading · Altitude · Pitch

Done

Conservative gains tuned for VQ1 completion. 30-frame lost-detection fallback → search behavior.

target speed
6.0 m/s
throttle hover
0.55
Kp (h/a/p)
0.8 / 0.6 / 0.5

Sim I/O bridge

UDP:5600 · MAVSDK telemetry

Partial

Schemas defined per VADR-TS-002. StubSimClient raises NotImplementedError — swap once the official adapter drops.

stub
vq1_completion_pilot.py:293
bridge
mavsdk_bridge.py
ETA
w/ sim drop

End-to-end pilot

vq1_completion_pilot.py

Dry-run

Detector → PnP → PID closed loop. CLI flags: --detector --intrinsics --dry-run.

entry
main() · L326
runbook
race/VQ1_RUNBOOK.md
dry-run
passes

Cockpit · launcher

PySide6 · overnight pipeline

Done

Native desktop monitor: NVML telemetry, phase status, live loss curves. Spawns detached overnight trainer.

cockpit
race/aigp_cockpit.py
launcher
race/launch_overnight.py
trainer
race/overnight_autotrainer.py

02 · Sequence

Critical path

  1. Now · Lock roster

    This weekend

    Roster freezes 24 h before launch. No changes during the qualifier phase. Physical Qualifier teams get another window later.

  2. Pre-flight dry-run

    ≈ 15 min

    Validate imports, weights paths, PnP geometry, and PID init without the sim.

    python race/vq1_completion_pilot.py --dry-run
  3. Detector validation

    target mAP > 0.85

    Re-benchmark on held-out synthetic set; eyeball val_batch0_pred.jpg.

    python race/benchmark_models.py
  4. Sim drop · adapter swap

    Blocked on AIGP

    Replace StubSimClient with the real adapter. Schemas pre-wired — estimated 2–4 hours once the binary lands.

  5. First live attempt

    8 min · unlimited tries

    Closed-loop run against AIGP sim. Log all attempts; iterate gains on whatever fails first.

  6. Submission snapshot

    submit_check.py

    Validate manifest and submission frame format before final upload.

    python submit_check.py

03 · Unknowns

What we learn from the sim drop

VADR-TS-002 pins most of the spec, but three items aren't real until the binary arrives.

Telemetry packet schema

VADR-TS-002 enumerates fields (attitude quaternion, body rates, accel, sim time). Real packet ordering, units, and rate need confirmation on first connect.

Control loop rate

Likely 100–500 Hz. PID is fine across that range, but the search-mode fallback timer is currently frame-indexed — re-tune if the sim ticks faster than vision.

Submission packaging

Unknown whether AIGP wants a Docker image, Python entry-point, or a standalone executable. Keep vq1_completion_pilot.py self-contained either way.

04 · Reference

Interface technical spec

The complete data contract between the AIGP sim and the pilot. What gets sent, in which direction, in what shape. Everything below is fixed by VADR-TS-002 except where marked otherwise.

4.1 · Architecture

Three independent UDP sockets on loopback. The pilot is a normal user-space process that can be killed and restarted without touching the sim — no shared memory, no privileged callbacks.

AIGP SIM · *.exe Physics @ 500 Hz Renderer @ ~30 Hz Camera (640×360 fwd) IMU sample Course scorer Control receiver internet ↻ anti-cheat parallel instances OK PILOT · python JPEG decode YOLO11n · 4 corners PnP → gate pose PID controller Command emitter Frame logger (opt) vq1_completion_pilot.py stateless across runs UDP:5600 JPEG video ≈30 Hz UDP:? telemetry ≥100 Hz UDP:? (T, R, P, Y) per-frame three independent sockets · loopback only · no shared memory · no privileged callback
Fig 4.1  Block diagram. Same architectural pattern as PX4 SITL, AirSim, Gazebo — any language with a UDP socket and JPEG decoder can implement a pilot.

4.2 · One render tick

Wall-clock time flows top to bottom. Telemetry streams continuously; vision drives the control output. One frame in, one control packet out.

SIM PILOT t_sim = N JPEG frame (~25 KB) → recvfrom() on :5600 telemetry packets (3+ during frame interval) → decode YOLO11n PnP transform → body PID step ≈17 ms total ← ControlCmd (16 bytes) sendto() — throttle, roll, pitch, yaw t_sim = N + Δ
Fig 4.2  One tick. Pilot is frame-driven — telemetry between frames buffers and consumes on the next vision tick.

4.3 · Video frame anatomy

JPEG-encoded 640×360 RGB frame over UDP:5600 at ≈30 Hz. Below: an annotated decode showing detector output, principal point, and the 20° tilt offset.

image y-center · y = 180px · (camera tilted +20° up · true horizon below) (cx, cy) = (320, 180) TL TR BR BL u_g=473 v_g=210 → PnP gate 0.94 gate 0.62 (filtered) (0, 0) (640, 0) (0, 360) (640, 360) detector → (bbox, 4 kpts, conf) per gate · pilot picks largest-area gate above conf 0.5
Fig 4.3  Annotated decoded frame. Bbox and four corner keypoints per gate. Far gate detected but ignored until the near gate is cleared.

4.4 · Telemetry packet

Best-guess wire layout: 48 bytes, little-endian, four fields. VADR-TS-002 fixes the field set; byte order confirmed on first recvfrom().

TELEMETRY DATAGRAM · 48 bytes · little-endian 0 4 8 12 16 20 24 28 …48 q.w q.x q.y q.z attitude_q : 16B ω.x ω.y ω.z body_rates : 12B a.x a.y a.z body_accel : 12B t_sim (float64) t_sim : 8B struct.unpack('<4f 3f 3f d', payload)
Fig 4.4  48-byte telemetry datagram. Quaternion (16B) + body rates (12B) + body accel (12B) + sim time (8B). If real packet ordering differs, only the unpack format string changes.

4.5 · Coordinate frames

Three frames. PnP measures in the camera frame; we transform to body, combine with telemetry, then issue body-frame commands. World frame is conceptual — no absolute position in VQ1.

WORLD · NED N (X) E (Y) D (Z) conceptual only — no abs pos in VQ1 BODY · NED +X fwd +Y right +Z down attitude_q rotates body → world CAMERA · OPTICAL +Z optical −Y up (img) +X right (img) tilted +20° up about body Y axis R_world←body (attitude_q) R_body←cam (fixed +20° pitch)
Fig 4.5  Three frames and the rotations between them.

4.6 · Throttle envelope

Max thrust is roughly 2·m·g — hover sits at throttle = 0.55, not 0.5. A PID biased around 0.5 will slowly sink. Set the hover offset, add the controller delta on top.

THROTTLE → THRUST · SIMDRONE ENVELOPE 0.0 0.25 0.50 0.75 1.0 throttle command 0 m·g 2 m·g hover = m·g hover = 0.55 descent aggressive climb
Fig 4.6  Throttle-to-thrust map. Hover sits well above 0.5 because max thrust is ~2·m·g.

4.7 · Per-frame timing budget

≈17 ms typical · 50 ms hard cap. Vision dominates; PnP and PID are nearly free. Headroom absorbs GPU contention and logging jitter.

0 ms 25 ms 50 ms PER-FRAME PIPELINE · ≈17 ms typical · 50 ms hard cap recv + decode 5 ms YOLO11n 8 ms kpt 1ms PnP PID ≈17 ms · typical headroom · GPU contention · logging 33 ms 50 ms · cap (next frame arrives in ~33 ms @ 30 Hz)
Fig 4.7  Per-frame compute on RTX 5080. YOLO is the long pole; everything else is <1 ms.

4.8 · Pilot state machine

Two states. TRACK is the happy path. SEARCH is a graceful fallback that buys ~1 second of fresh observation angles when detection fails.

TRACK PnP → PID toward gate target speed 6 m/s heading · altitude · pitch PIDs SEARCH slow yaw rotation hover-altitude hold until next detection 30 frames w/o detection any detection · conf > 0.5 start
Fig 4.8  Two-state pilot. TRACK on detection, SEARCH after 30 lost frames (≈1 s).