Our season, explained with visuals.

Use this site while presenting: point to the pictures, show the iterations, and let the visuals carry the story.

IDENTIFY

Our Mission Analysis

One-glance takeaway: Push is dominant, Pull is limited, so we optimize push-first and keep one reliable pull attachment.

Sorted by Action Type: Push → Push/Pull → Pull → Lift → Drop

Mission 1
M1Drop
Mission 2
M2Push/Drop
Mission 3
M3Lift
Mission 4
M4Drop
Mission 5
M5Push
Mission 6
M6Push
Mission 7
M7Lift
Mission 8
M8Push
Mission 9
M9Pull
Mission 10
M10Push/Pull
Mission 11
M11Push
Mission 12
M12Push/Pull
Mission 13
M13Lift
Mission 14
M14Drop
Mission 15
M15Drop
DESIGN
Robot Redesign + Pinless Attachment System

Robot Evolution

Before: last year's base
Before
After: dual front motors
After: Dual Front Motors

Robot Iteration Timeline (6 Versions)

Robot iteration 1
Iteration 1
Initial base build
Robot iteration 2
Iteration 2
Front motor layout update
Robot iteration 3
Iteration 3
Stability + wheel tuning
Robot iteration 4
Iteration 4
Attachment interface rework
Robot iteration 5
Iteration 5
Reliability improvements
Robot iteration 6
Iteration 6
Final competition version
Robot iteration 6.2
Iteration 6.2
Final competition version

Pinless Attachment System

gravity holding it in place
Gears holding in place

Project Management & Team Organization

Mission Grouping Board (Main Center)

Mission grouping is the primary planning view. We grouped missions into runs by similar mechanics and attachment needs.

Run A • M5 M6 M7 M8

M5M5
M6M6
M7M7
M8M8

Run B • M9 M10

M9M9
M10M10

Run C • M1 M2

M1M1
M2M2

Run D • M3 M4

M3M3
M4M4

Run E • M11 M13

M11M11
M13M13

Run G • M15

M15M15

Two-Team Ownership Model

We split development ownership for faster iteration and clearer accountability.
Red Side Team
Kyle, Brian, Owen, Sam
Runs: A, C, D
Blue Side Team
Isabela, Jonathan, Anthony, Cailey, Julisa
Runs: B, E, G

Weekly Workflow

WEEKLY 90-MIN MEETING
Rough Draft: prove the run is possible.
ITERATION PHASE
Tune and debug alignment, drift, and consistency.
NEXT TRANSITION
Document attachment issues before reviewing each run problem.

Run Sequence Overview

Run A
Run B
Run C
Run D
Run E
Run G
RUNS
Iterations that made our runs reliable

Attachment System Upgrade: Color-Coordinated Across All Runs

Beyond improving each attachment, we color-coordinated all attachments by run so setup is faster, swaps are cleaner, and teammates can identify the correct tool instantly.

Run A: All Black Run B: Blue/Grey/Yellow Run C: Black/Yellow Run D: All Black Run E: All Blue
RUN A
All black pieces
RUN B
Blue, grey, and yellow pieces
RUN C
Black and yellow pieces
RUN D
All black pieces
RUN E
All blue pieces

Run A (M5,6,7,8)

Passive mechanism progression for cleaner trigger flow.

Final Result: Stable Cycle
Run A prototype version 1
PrototypeBase Fit
Run A improvement version
ImprovementWider Intake
Run A refinement version
RefinementAdded Support
Run A final version
Final VersionFinal Tuned

Run B (M9,10)

Tip control evolution for repeatable pan contact.

Final Result: Cleaner Release
Run B prototype version 1
PrototypeEarly Reach
Run B improvement version
ImprovementBetter Angle
Run B refinement version
RefinementLower Friction
Run B final version
Final VersionFinal Tuned

Run C (M1,2)

Pickup geometry tuned for more reliable retrieval.

Final Result: Better Alignment
Run C prototype version 1
PrototypeFirst Grip
Run C improvement version
ImprovementAdded Support
Run C refinement version
RefinementCleaner Contact
Run C final version
Final VersionFinal Tuned

Run D (M3,4)

Lift geometry evolved toward stable drop positioning.

Final Result: Locked Geometry
Run D prototype version 1
PrototypeBase Lift
Run D improvement pass
ImprovementAngle Test
Run D refinement version
RefinementAdded Support
Run D final version
Final VersionFinal Tuned

Run E (M11,13)

Underside approach refined for faster transitions.

Final Result: Faster Swap
Run E prototype version 1
PrototypeInitial Pass
Run E improvement version
ImprovementLower Friction
Run E refinement version
RefinementUnderside Guide
Run E final version
Final VersionCleaner Release
CREATE
Python + PID (data-driven accuracy)
SPIKE Prime Results (100 Runs)
Y-Axis Range
-13 to 13
Runs Plotted
100
Drive Straight Test: Yaw Stability (100 Runs)
Average Yaw Error
0.087°
Best Run
0.00°
Worst Run
1.214°
Consistency
94.2% ✓

Pybricks PID Drive Straight Implementation

#!/usr/bin/env pybricks-micropython
  """
  FLL Season PID Drive Straight Module
  Maintains accurate heading using gyro feedback and proportional correction.
  """

  from pybricks.hubs import EV3Brick
  from pybricks.ev3devices import Motor, GyroSensor
  from pybricks.parameters import Port, Direction
  from pybricks.tools import wait

  # Initialize hardware
  ev3_brick = EV3Brick()
  gyro_sensor = GyroSensor(Port.S3)
  left_motor = Motor(Port.B, positive_direction=Direction.FORWARD)
  right_motor = Motor(Port.C, positive_direction=Direction.FORWARD)

  # PID Configuration Constants
  TARGET_HEADING_DEGREES = 0  # Maintain straight line (0° yaw)
  KP_GAIN = 1.2  # Proportional gain: higher = stronger correction
  MOTOR_BASE_SPEED_DPS = 360  # Base drive speed in degrees per second

  # Drive Parameters
  DRIVE_DISTANCE_MM = 1000  # Distance to drive straight
  WHEEL_DIAMETER_MM = 55.0  # FLL standard wheel size
  GEAR_RATIO = 1.0  # Direct drive (adjust if geared)

  def calculate_wheel_rotation_degrees(distance_mm):
    """Convert linear distance to motor rotation in degrees."""
    wheel_circumference = WHEEL_DIAMETER_MM * 3.14159
    full_rotations = distance_mm / wheel_circumference
    return full_rotations * 360

  def pid_drive_straight(distance_mm, base_speed_dps):
    """
    Drive straight using PID feedback from gyro sensor.
    
    Args:
      distance_mm: Distance to drive in millimeters
      base_speed_dps: Base motor speed in degrees per second
    """
    
    # Reset gyro heading to establish reference
    gyro_sensor.reset_angle(0)
    
    # Calculate target motor rotation
    target_rotation_degrees = calculate_wheel_rotation_degrees(distance_mm)
    
    # Motor position tracking
    left_start_angle = left_motor.angle()
    right_start_angle = right_motor.angle()
    
    # PID error tracking for diagnostics
    yaw_errors = []
    
    # Main drive loop
    while True:
      # Calculate distance traveled (average of both motors)
      left_current_angle = left_motor.angle()
      right_current_angle = right_motor.angle()
      average_rotation = (left_current_angle + right_current_angle) / 2
      distance_traveled = average_rotation - (left_start_angle + right_start_angle) / 2
      
      # Check if target distance reached
      if distance_traveled >= target_rotation_degrees:
        left_motor.stop()
        right_motor.stop()
        ev3_brick.speaker.beep(frequency=1000, duration=50)
        break
      
      # Read current heading from gyro
      current_heading = gyro_sensor.angle()
      
      # Calculate heading error (deviation from target)
      heading_error = current_heading - TARGET_HEADING_DEGREES
      
      # Store error for analysis
      yaw_errors.append(heading_error)
      
      # PID Correction: proportional only (P-controller)
      # Negative error = heading right, positive = heading left
      correction_speed = -1 * KP_GAIN * heading_error
      
      # Apply correction by differential motor speed
      left_motor_speed = base_speed_dps + correction_speed
      right_motor_speed = base_speed_dps - correction_speed
      
      # Send commands to motors
      left_motor.run(left_motor_speed)
      right_motor.run(right_motor_speed)
      
      # Small delay for sensor reading cycle
      wait(10)
    
    # Calculate and log performance metrics
    average_error = sum(yaw_errors) / len(yaw_errors) if yaw_errors else 0
    max_error = max(yaw_errors) if yaw_errors else 0
    
    ev3_brick.speaker.say(f"Drive complete. Avg error: {average_error:.2f} degrees")
    
    return {
      "average_yaw_error": average_error,
      "max_yaw_error": max_error,
      "trials": len(yaw_errors)
    }

  # Main execution
  if __name__ == "__main__":
    ev3_brick.speaker.beep()
    
    # Run drive straight test
    results = pid_drive_straight(
      distance_mm=DRIVE_DISTANCE_MM,
      base_speed_dps=MOTOR_BASE_SPEED_DPS
    )
    
    ev3_brick.speaker.say(f"Complete")
  

Key Tuning Parameters

KP_GAIN
1.2 (increase for faster response)
Base Speed
360 dps (motor degrees/sec)
Gyro Feedback
10ms loop cycle

Pybricks + PID correction achieved 94.2% consistency by continuously adjusting motor power based on gyro heading feedback.

SHARE
Coopertition: sharing designs, code, and tutorials

Community Resources

Shared Folder + Tutorials
Follow on TikTok
Check out our latest builds and quick tutorials.
Visit TikTok
Subscribe on YouTube
Deep dives into our design process and strategies.
Visit YouTube
Follow on Instagram
Behind-the-scenes content and team updates.
Visit Instagram