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.
batteryreading within 0.1 V of a multimeter on the pack. If not, check R6/R7 and their ratio inhal.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 callhal::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 * GEARinconfig.hand 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
mprints the learned map: compare with the real maze. - Power-cycle and press
magain: 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.
- Pivots (v1), mode "fast run (pivots)". Start at
FAST_V = 0.6. Ten clean runs in a row before raising it by 0.2. - Smooth turns, mode "fast run (smooth turns)". Serial
vuntil the preset is safe,pprints the plan and its planned time. After every run,ldumps 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,CELLmatch 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