Omni Soccer Robot

Raspberry Pi Pico · MicroPython · 5-File Modular Program
Omni-wheel drive IR ball tracking Heading hold Tunable constants Modular Python
SENSE
Read ball angle
& compass heading
DECIDE
Push, orbit,
or escape rear
ACT
Send motor
commands
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

Key Formulas

Heading correction:
error = target − current
rotation = error × HEADING_KP
Max rotation cap:
if rotation > MAX_ROTATION:
    rotation = MAX_ROTATION
Ball timeout:
BALL_TIMEOUT = 500 ms
= 0.5 s before stale data rejected