Complete robotics control system for FIRST LEGO League SUBMERGED / UNEARTHED 2025 season, featuring autonomous missions, teleoperation, and deployment tooling for LEGO SPIKE Prime with PyBricks.
This repository contains two main components:
- Robot Mission System - Autonomous mission programs with on-hub menu selection
- Teleoperation System - Xbox controller support for manual robot control with recording/playback
Both systems are designed for the LEGO SPIKE Prime hub running PyBricks firmware, providing advanced features like PID control, smart navigation, and battery monitoring.
- On-hub mission menu - Slot-based
@mission("slot")decorator system for easy mission management - Smart PID navigation - Closed-loop drive and turn routines for precise, repeatable movements
- Battery safety - Low-voltage alerts and monitoring to prevent brownouts during competition
- Attachment control - Manual jog mode for testing and positioning attachments
- Multiple mission support - 7+ pre-programmed missions ready for competition
- Xbox controller support - Tank drive controls with auxiliary motor management
- Recording & playback - Record teleop runs and generate hub-deployable replay scripts
- Real-time streaming - BLE-based controller input streaming to the hub
- Auto-generation - Recorded runs automatically convert to standalone Python programs
-
Flash the robot program to your SPIKE Prime hub:
- Open
src/robot/main.pyin the PyBricks IDE - Connect to your hub and click "Download and Run"
- Open
-
On the hub display:
- Use left/right buttons to select a mission number (1-7, T, M)
- Press center button to start the mission
- Robot backs up slightly and resets gyro before each run
-
Mission slots:
1-7- Competition missions (see mission code in src/robot/main.py for attachment requirements)T- Test mission (drive square pattern)M- Manual attachment mode (left/right buttons jog motors)
-
Install dependencies:
pip install pybricksdev evdev
-
Connect Xbox controller to your computer via USB or Bluetooth
-
Deploy and run teleop:
cd src/robot python deploy_teleop.py --hub "YourHubName"
-
Controls:
- Left stick Y-axis → Left drive motor
- Right stick Y-axis → Right drive motor
- Left trigger → Left aux motor (forward)
- Right trigger → Right aux motor (forward)
- Left bumper + trigger → Reverse left aux
- Right bumper + trigger → Reverse right aux
- B button → Start/stop recording
- A button → Replay last recording
FLL-Lebob-Unearthed/
├── src/
│ ├── robot/ # Main robot control system
│ │ ├── main.py # Competition missions (deploy to hub)
│ │ ├── aaron_main.py # Alternate mission configuration
│ │ ├── teleop_hub.py # Teleop receiver (runs on hub)
│ │ ├── deploy.py # Simple deployment script
│ │ └── deploy_teleop.py # Xbox controller teleop system
│ └── innovations/ # Innovation project code
│ └── main.py
├── resources/ # Field maps and path visualizations
│ ├── Map.pdf # Competition field map
│ └── PathV*.png # Mission path diagrams (V1-V5)
├── out/ # Generated outputs and recordings
│ ├── teleop-recording-*.csv # Teleop recording data
│ └── teleop-recording-*.py # Auto-generated replay scripts
├── AGENTS.md # Contributor guidelines and coding standards
├── LICENSE # Apache 2.0 License
└── README.md # This file
- LEGO SPIKE Prime Hub (Robot Inventor hub also compatible)
- PyBricks firmware v3.4 or later installed on hub
- 4 motors: 2 drive motors (ports C, D) + 2 aux motors (ports E, F)
- Xbox controller (for teleop mode only)
- Python 3.8+ for development scripts
- PyBricks IDE or pybricksdev CLI for deployment
- evdev (Linux) for Xbox controller support in teleop mode
pip install pybricksdev evdev- Open PyBricks IDE or SPIKE Prime app
- Load
src/robot/main.py - Connect to hub and click "Download and Run"
Using the included deployment script:
cd src/robot
python deploy.pyOr manually with pybricksdev:
pybricksdev run ble --name "FatSean" src/robot/main.pyDeploy teleop and stream Xbox controller input:
cd src/robot
python deploy_teleop.py --hub "FatSean" --debugOptions:
--hub NAME- Hub Bluetooth name (default: "FatSean")--device PATH- Specific input device (e.g.,/dev/input/event18)--deadband VALUE- Controller deadzone (default: 0.05)--debug- Show detailed connection and input data--no-record- Disable recording features--record-out PATH- Custom recording output path
- Start recording: Press B button during teleop
- Stop recording: Press B button again
- Replay last: Press A button
Recordings are saved to out/teleop-recording-TIMESTAMP.csv and auto-converted to deployable Python scripts in out/teleop-recording-TIMESTAMP.py.
To replay a recording on the hub:
pybricksdev run ble --name "FatSean" out/teleop-recording-TIMESTAMP.py- Drive base: 2 motors (left: Port D, right: Port C), 62.4mm diameter wheels, 150mm axle track
- Left aux motor: Port F (attachment arm)
- Right aux motor: Port E (attachment arm)
- Gyro/IMU: Built-in hub IMU for heading control
- Mission 1: Coral reef mission with precise positioning
- Mission 2: Complex curve navigation with stall detection
- Mission 3: Shipwreck mission with lever pulling mechanism
- Mission 4: Platform flip with raising bucket
- Mission 5: Statue lifting and transport
- Mission 6: High-speed attachment spinning
- Mission 7: Attachment test routine
- Mission T: Test pattern (drive square)
- Mission M: Manual attachment control mode
See src/robot/main.py for detailed mission code and sequencing.
The robot includes a custom PID controller for:
- Smart driving: Gyro-corrected straight line movement
- Smart turning: Precise angle control with overshoot prevention
- Battery compensation: Adjusts for voltage drop during runs
Configure PID constants in the Robot class initialization.
Competition field maps and path planning diagrams are stored in resources/:
Map.pdf- Official FLL Unearthed field layoutPathV1.pngthroughPathV5.png- Documented mission paths and strategies
Use these resources for:
- Planning new missions
- Documenting successful runs
- Team strategy discussions
- Driver training
The robot monitors battery voltage and provides visual feedback:
- High voltage (>8.4V): Green indicator
- Medium voltage (7.2V-8.4V): Orange indicator
- Low voltage (<7.2V): Red warning, recommend recharge
Each mission displays battery status before running. The system includes LOW_VOLTAGE protection to prevent brownouts during critical movements.
We welcome contributions from team members! Please follow these guidelines:
- Follow PEP 8 conventions (4-space indentation,
snake_casefunctions) - Use descriptive variable names
- Add comments for complex mission logic
- Keep
src/robot/main.pyhub-friendly (minimal imports, single file)
- Test missions thoroughly on the competition table
- Document attachment requirements
- Note battery voltage during testing
- Update path diagrams in
resources/if routes change - Use the
@mission("slot")decorator for new missions
- Use conventional commit format:
feat:,fix:,docs:, etc. - Describe mission changes and required attachments
- Include field test results
- Reference related issues
See AGENTS.md for detailed contributor guidelines.
- Ensure PyBricks firmware is installed (not LEGO firmware)
- Check Bluetooth is enabled
- Verify hub name matches deployment script (default: "FatSean")
- Try restarting the hub
- Check battery voltage (should be >7.5V for consistent performance)
- Verify attachments are properly installed
- Reset gyro by restarting the mission or hub
- Ensure starting position is correct
- Verify Xbox controller is connected:
ls /dev/input/event* - Check controller batteries
- Try
--debugflag to see connection details - Ensure no other programs are using the controller
- Check
out/directory exists and is writable - Ensure recording wasn't disabled with
--no-record - Verify there's disk space available
- Look for error messages in debug output
This project is licensed under the Apache License 2.0.
Copyright © 2025 Team LEBOB - FLL Unearthed
You are free to use, modify, and distribute this code. See the LICENSE file for full terms and conditions.
Team LEBOB - FIRST LEGO League Unearthed Season 2025
For questions, issues, or contributions, please open an issue on GitHub or contact the team.
Good luck at competition! 🏆