SENSE
Read ball angle
& compass heading
→
DECIDE
Push, orbit,
or escape rear
→
This loop runs
every 10 ms
100 times per second
🔄
Omni-Wheel Drive
Four wheels mounted at 45° let the robot slide in any direction without turning its body — including diagonals and sideways.
- Motors M1–M4 driven by DRV8871 chips
- Two PWM signals per motor (IN1 / IN2)
- X-drive configuration — fast and agile
- Positive speed → IN1 = duty, IN2 = 0
- Negative speed → IN1 = 0, IN2 = duty
📡
IR Ball Sensor Ring
A ring of 12 infrared sensors encircles the robot and detects the IR-emitting ball, returning a precise angle every 10 ms.
- Ball angle: 0°–359° (0° = directly in front)
- Communicates via UART at 115 200 baud
- Pico receives on GP5 (UART1 RX)
- BALL_TIMEOUT discards stale readings
- Robot stops if no fresh signal arrives
🧭
IMU Compass (BNO055)
A 9-axis compass chip keeps the robot pointed at the goal even after bumps and collisions — no manual correction needed.
- Wired via I²C: SDA on GP0, SCL on GP1
- Records heading at startup as the target
- Calculates error 100× per second
- HEADING_KP controls correction strength
- MAX_ROTATION caps the turning output
🌀
Orbit & Push Behaviour
The robot circles around the ball to reach a position directly behind it before pushing towards the goal.
- FRONT_WINDOW: angle for "ball is in front"
- ORBIT_OFFSET: controls orbit path width
- ORBIT_POWER: speed while circling
- PUSH_POWER: speed when driving to goal
- REAR_ZONE: triggers special escape movement
🖥
Raspberry Pi Pico
The main controller runs MicroPython and coordinates all sensors, motors and timing with a tight 10 ms control loop.
- RP2040 dual-core processor at 133 MHz
- GP0/GP1 → IMU I²C (10 kHz)
- GP5 → Sensor ring UART RX
- GP10–GP19 → Motor PWM outputs
- Programmed and updated via Thonny
🔧
Tunable Constants
All behaviour values live in one file — settings.py. Change a value, save to the Pico, and the robot behaves differently.
- ORBIT_POWER = 24 000 (circling speed)
- PUSH_POWER = 32 000 (attack speed)
- ORBIT_OFFSET = 0.85 (orbit path size)
- HEADING_KP = 700 (heading correction)
- FRONT_WINDOW = 15° (push zone width)
5-File Modular Program
settings.py
Every tunable constant — the only file you need to change when tuning
drive.py
Motor class + OmniRobot class — converts angle & speed into wheel commands
imu.py
BNO055 reader — returns current compass heading from the chip
sensor_ring.py
UART reader — returns ball angle from the IR sensor ring
main.py
Main 10 ms loop — imports all modules and runs the sense→decide→act cycle