Skip to content

Bring-up, calibration and test plan

Do these in order. Each step has a pass condition. Do not move on until it passes: a problem found at step 3 costs ten minutes, the same problem found at the contest costs the title.

0. Tools

pip install platformio numpy matplotlib pytest schemdraw
cd firmware
pio test -e native        # maze logic on your PC, must pass before flashing
pio run -e esp32 -t upload
pio device monitor -b 115200

1. Power, no motors connected

  • Buck output 5.00 V +-0.1 V with the ESP32 disconnected.
  • ESP32 boots, serial shows the banner. battery reading within 0.1 V of a multimeter on the pack. If not, check R6/R7 and their ratio in hal.cpp.

2. Sensors (mode "sensor test", press MODE twice)

Serial prints at 10 Hz.

Check Pass
ToF mask in the boot banner 0xF (all four answered). 0x7 means the right sensor failed: check its XSHUT wire
Hand at 50 mm in front of each sensor that sensor reads 40 to 60 mm, the others do not change
Robot still gyro reads within +-0.3 deg/s
Rotate the robot by hand to the left gyro positive. If negative, flip the sign in imuYawRate()
Push the robot forward by hand 18 cm odometry x or y grows by 0.18 +- 0.01 m. If it goes negative, swap that encoder's A/B

3. Motors, robot on a stand (wheels in the air)

  • In setup(), temporarily call hal::motorsEnable(true); hal::motorsSetVolts(2, 2, hal::batteryVolts());. Both wheels must spin forward. If one spins backward, swap its motor wires (not the code).
  • Encoder counts must increase for forward rotation on both sides.
  • Measure no-load wheel speed at 2 V and 4 V from the encoder counts. k_w = u / omega_w. Compare with MOTOR_K * GEAR in config.h and correct it.

4. Calibrate (on the practice maze)

Mode Setup Result
calibrate ToF robot centred in a cell with walls left, right and front four offsets, saved to flash. Typical: under 15 mm
calibrate wheel cell centre, facing a wall exactly 4 cells ahead wheel radius, saved. Expect 15.5 to 16.5 mm
calibrate track anywhere with room to spin track width from 5 gyro-measured turns, saved
calibrate gyro scale cell centre, wall in front spins 1, 4, then 20 turns and reads the leftover angle on the front wall; scale saved. Expect within 3 % of 1

Repeat the wheel calibration three times: the three results should agree within 0.5 %. Repeat the gyro calibration three times: they should agree within 0.03 % (the simulator gets within 0.063 % of the truth from a 3 % error, python -m sim.calibrate). Diagonal runs need about 0.15 % (DESIGN 14). Serial c prints every stored calibration.

5. Closed-loop motion

Add a temporary test mode or use the serial console:

Test Pass
Forward 1 cell, 10 times, each from a cell centre stops within 5 mm of the centre every time
Pivot 90 degrees left 4 times ends within 2 degrees of the start heading
Pivot 180, 10 times no wall contact, ends within 2 degrees
Forward 6 cells in a corridor, start 10 mm off-centre ends centred within 5 mm, no wall touch
Forward 6 cells in an open area (no side walls) ends within 10 mm laterally: the gyro heading term at work

If moves oscillate: lower WN_FWD / WN_ROT. If they are sluggish or stop short: check MOTOR_K and mass, the feedforward is probably wrong. If the robot weaves in corridors: lower STEER_WN to 6.

6. Search on the practice maze

  • Mode "clear maze", then "search". Robot must reach the goal and return to start. Serial m prints the learned map: compare with the real maze.
  • Power-cycle and press m again: the map must still be there (flash persistence).
  • Unplug the battery in the middle of a search, reconnect, search again: it continues with what it already knew.

7. Fast run

Bring the three fast-run modes up in this order; each one only after the previous one passes.

  1. Pivots (v1), mode "fast run (pivots)". Start at FAST_V = 0.6. Ten clean runs in a row before raising it by 0.2.
  2. Smooth turns, mode "fast run (smooth turns)". Serial v until the preset is safe, p prints the plan and its planned time. After every run, l dumps the flight log: capture it (pio device monitor | tee run.txt) and compare with the simulator on the same maze:
python -m sim.run drive --maze mymaze.txt --mode smooth --preset safe --log sim.csv
python tools/plot_log.py run.txt --sim sim.csv
Check in the log Pass
cross_mm (path-following error) within +-5 mm on straights, +-8 mm in turns
w follows w_ref through every turn no lag of more than about 20 ms
measured run time vs p within 5 %
gyro bias printed after the run below 0.005 rad/s; larger means the board heats up or the IMU moves

Ten clean runs at safe, then normal, then fast. 3. Diagonals, mode "fast run (diagonals)": only with the gyro scale calibrated (step 4) and ten clean smooth runs at the same preset. In simulation these are the least reliable runs (README results).

Log the times. The best competition setting is the fastest mode and preset with ten clean runs out of ten, then one step slower for the contest.

8. Before every contest

  • [ ] Rulebook read: maze size, cell size, goal location, number of runs, time limit, how touching the robot is penalised, whether the maze is known before the run
  • [ ] MAZE_W, MAZE_H, GOALS, CELL match the rulebook
  • [ ] Three packs charged and labelled
  • [ ] Spare wheels, motors, one spare ToF, spare ESP32 with firmware already flashed
  • [ ] Laptop with PlatformIO working offline (dependencies already downloaded)
  • [ ] ToF calibration redone on the contest maze during practice time: wall paint and lighting differ
  • [ ] Tyres cleaned (tape or alcohol) before every run