Navigation

Strategy: RC-First

The rulebook permits remote-controlled robots. RC mode is the primary competition mode; the autonomous FSM is a stretch goal demoed only if reliable.

Mode How to enter What it does
RC (primary) Hold BOOT button at power-on WiFi AP + phone joystick page; operator drives, samples, tags sectors
Autonomous (stretch) Normal power-on Wander pattern with zone auto-detection, 8-min hard cap

The WiFi AP and web server run in both modes so judges can always pull /data immediately after a run.


RC Run Procedure

  1. Power on with BOOT held → connect phone to RobotAP → open 192.168.4.1.
  2. Drive to a zone with the D-pad. Select the current sector (S1–S4) on the page.
  3. Stop next to the zone (never over a water slot). Press Sample Water or Sample Soil.
  4. The arm deploys, reads, retracts; the reading is logged with your sector tag and printed to serial.
  5. Repeat for all 12 zones. Press End Run to finalise results.json.

Position Estimation (and its limits)

The robot has no wheel encoders. Position is estimated as:

  • Heading — MPU6050 DMP absolute yaw, zeroed at power-on. Reliable.
  • Distance — commanded motor speed × time (MM_PER_SEC_AT_DRIVE, calibrated by timing a 1m drive). Rough.
// position.cpp — speed-model update, every 20ms
float v = (cmdL_mm_s + cmdR_mm_s) / 2.0f;   // commanded, not measured
pos.x_mm += v * dt * cosf(pos.heading_rad);
pos.y_mm += v * dt * sinf(pos.heading_rad);

The estimate feeds the path[] log for visualisation only. It is never used for safety decisions — zone detection (colour) and wall detection (ToF) are always live sensor reads.

If the robot gets stuck, officials place it at the arena centre. Heading survives (IMU is absolute); the position estimate does not. Samples and sector tags remain valid — the path plot is best-effort.


Autonomous FSM (stretch goal)

INIT
 │  Zero IMU heading · reset sample count · start 8-min timer
 ↓
SWEEP  ← wander with IMU heading hold
 │  isWaterZone()  (+ lockout) → POND_SAMPLE
 │  isSoilPatch()  (+ lockout) → MEASURE_SOIL
 │  ToF < WALL_STOP_MM         → bounce ~135° to new heading
 │  12 samples or 8 min        → COMPLETE
 ↓
POND_SAMPLE
 │  stop → arm 0° → settle → read NTU → arm 90° → log
 ↓
POND_BACKOFF
 │  REVERSE for POND_BACKOFF_MS — wheels never cross the recessed slot
 │  turn away → restart detection lockout → SWEEP
 ↓
MEASURE_SOIL
 │  stop → arm 180° → settle → read % → arm 90° → log → new heading → SWEEP
 ↓
COMPLETE
   stop · arm neutral · finalise results.json · LED blink
   web server stays alive — judges pull /data immediately

Key mechanisms

Mechanism Constant Why
8-minute hard cap RUN_TIME_LIMIT_MS Exceeding the run limit costs −5 pts
Re-sample lockout SAMPLE_LOCKOUT_MS No coordinates without encoders — a driving-time lockout prevents re-sampling the zone just measured
Pond backoff POND_BACKOFF_MS Water slots are recessed wheel traps; the robot reverses away after sampling, never drives over
Wall bounce WALL_STOP_MM VL53L0X stops the robot before the octagon wall; heading changes ~135°, alternating direction

Sector labels in autonomous mode

Without localization the FSM can only estimate sector by collection order (samples/3 + 1). Accurate sector labels come from RC mode, where the operator selects the sector before each sample. This is a deliberate tradeoff — and another reason RC is the primary mode.