Two fully autonomous robots — an attacker and a defender — for the
RoboCupJunior Soccer Infrared (formerly Lightweight) league.
Firmware(C++) · multi-board electronics (KiCad) · mechanical design (Fusion 360).
The five boards — Main 2.0 · IR ring · Line ring · Power · Ultrasonic (KiCad renders; build photos in Docs/Images/Electronics)
## How it plays — design choices vs. the game Everything here is built around what actually wins (and loses) a RoboCupJunior Soccer match: - **Score in the goal.** The IR ring gives the ball's bearing; the main board chases it with an omni-wheel drive held straight by a BNO055 heading PID. Once the ball is captured, the OpenMV camera finds the goal, picks the **open corner** (dodging the keeper), and the chassis turns in place until that corner is dead ahead before the solenoid fires. Aiming the open corner instead of the goal centre is how you beat a keeper. - **Never cross the line (the expensive mistake).** Touching a wall *or* driving fully into the marked penalty area is an **out-of-bounds penalty** — the robot is removed for a minute, and any goal scored while it's penalised is wiped. The attacker therefore treats a side as the field boundary **only when the line ring and the ultrasonics agree** (white line seen *and* wall within 300 mm), then flees away from it. Two independent sensors must concur, so one noisy reading can't make the robot dart out of bounds. - **Keep the keeper on its line, not inside the box.** No robot may be *fully* inside the penalty area (that's out of bounds), so the defender uses the line ring to ride the **edge of the goal area ("the D")** — staying on the line rather than crossing it — while tracking the ball laterally and clearing it on contact. - **Stay legal in the Infrared league.** IR-emitting rangefinders (ToF, LiDAR, IR distance sensors) are **banned** in the Infrared league because they'd swamp other robots' IR ball sensors — which is exactly why walls are ranged with **ultrasonic** HC-SR04s here, not IR. The reflectance line sensors face **down at the floor** and are shrouded so their light can't be mistaken for the orange ball by other teams' cameras. - **Power within the rules.** The rules cap robot power at **48 V DC**; the solenoid kicker runs from a 48 V boost converter — right at the legal ceiling for the hardest legal kick — while logic and motors run from 3.3 V / 5 V / 12 V rails. - **Referee start/stop.** The main board reads the RoboCupJunior **Communication Module** GO/STOP lines, so a referee can start and halt the robot as the rules require at the international competition. ## Folder structure ``` RoboCup Internationals 2025-26/ ├─ README.md ← you are here ├─ Docs/ │ ├─ HOW_IT_WORKS.md ← full technical deep-dive │ ├─ MAPPING.md ← original → new file/folder mapping │ ├─ TDP.md ← Team Description Paper (Markdown) │ ├─ TDP_images/ ← images embedded in TDP.md │ ├─ RoboCup_Internationals_Poster.png │ ├─ VVS_Ballers_GroupInterview_Deck.pptx │ ├─ VVS_Ballers_BOM.xlsx ← bill of materials │ ├─ VVS_Ballers_Electronics_Block_Diagram.png │ └─ Images/ ← gallery: Robots · Electronics · Mechanical · Diagrams · Team ├─ Firmware/ ← all microcontroller code │ ├─ Attacker/ ← main-board attacker (current: …_Line) │ ├─ Defender/ ← main-board goalkeeper (Defender_Full) │ ├─ IR_Ball_Sensor/ ← IR ring (Code2_Calibrated = flight build) │ ├─ Line_Sensor/ ← QTR line ring (Detect / Baseline / Raw) │ ├─ Ultrasonic/ ← Nano Every HC-SR04 board + main-board parser │ ├─ Camera/ ← OpenMV H7 goal vision (MicroPython) │ ├─ Motor_Current/ ← optional over-current watchdog │ └─ README.md ├─ PCB/ ← KiCad sources, Gerbers, wiring PDFs, fab zips │ ├─ Main/ IR/ Line/ Ultrasonic/ Power/ │ ├─ Wiring/ ← human-readable wiring per board (PDF) │ ├─ Fabrication/ ← ready-to-order Gerber zips │ └─ README.md ├─ CAD/ ← Fusion 360 sources + printable STLs │ ├─ Fusion/ Printable/{Chassis, Drive, Ball_Capture, Sensor_Mounts} │ └─ README.md └─ Legacy/ ← superseded designs, kept for history (see Legacy/README.md) ``` ## Build & flash All boards build in the **Arduino IDE** (each sketch folder is named to match its `.ino`); the Teensy/Nano sketches also build under **PlatformIO** via the `platformio.ini` in each folder. | Target | Board setting | Libraries / notes | |---|---|---| | Main board (attacker/defender) | Teensy 4.1, USB Type *Serial* | Adafruit BNO055 + Adafruit Unified Sensor (Defender OLED option also needs SSD1306 + GFX) | | IR ring | Teensy 4.1 | none (core `analogRead`) — flash `Code2_Calibrated` | | Line ring | Teensy 4.1 | none | | Ultrasonic | Arduino Nano Every (megaAVR) | none; *Registers emulation → None (ATMEGA4809)* | | Motor-current | Arduino Nano Every | none | | Camera | OpenMV H7 | save `Goal_Cam.py` to the H7 flash as `main.py` | PlatformIO example: `pio run -e teensy41 -t upload` (Teensy) or `pio run -e nano_every -t upload` (Nano). ## Inter-board links (summary) Three of the four links are short binary frames with a 2-byte sync and an identical **CRC-8 (poly 0x07)**, so the main board can reject any corrupted frame; the IR link is plain delimited ASCII: - **IR → Main** (Serial4): ASCII `"