Skip to content
Getting Started with FRC·Lesson 17 of 28

Project 4 — Build a Fuel Launcher for REBUILT

Add a single-motor flywheel launcher subsystem that shoots the 2026 'Fuel' foam balls into the Hub on a button press.

Sign in to track progress, earn XP, and save lessons.

The 2026 game, REBUILT presented by Haas, is built around scoring foam balls called Fuel into a Hub goal, with a Tower to climb in endgame. The simplest scoring mechanism is a flywheel launcher — exactly the kind of mechanism the official KitBot and the AndyMark Everybot iterate toward. We will add one as a clean subsystem.

Hardware: one launcher wheel driven by a NEO on a SPARK MAX (CAN ID 5). A flywheel works by spinning fast, then transferring momentum to the ball on contact.

LauncherSubsystem.java:

package frc.robot.subsystems;

import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.config.SparkMaxConfig;
import com.revrobotics.spark.config.SparkBaseConfig.IdleMode;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;

public class LauncherSubsystem extends SubsystemBase {
  private final SparkMax m_launch = new SparkMax(5, MotorType.kBrushless);

  public LauncherSubsystem() {
    SparkMaxConfig cfg = new SparkMaxConfig();
    cfg.idleMode(IdleMode.kCoast)        // let the wheel spin down freely
       .smartCurrentLimit(40);            // protect the motor and battery
    m_launch.configure(cfg,
        ResetMode.kResetSafeParameters,
        PersistMode.kPersistParameters);
  }

  public Command shoot() {
    return startEnd(() -> m_launch.set(0.85),  // spin up to 85%
                    () -> m_launch.set(0.0));  // stop on release
  }
}

The configure(...) call with ResetMode.kResetSafeParameters and PersistMode.kPersistParameters is the REVLib 2025+ pattern for applying and saving a config. The startEnd factory returns a command that runs the first lambda when scheduled and the second when it ends — perfect for 'hold to shoot'. The smartCurrentLimit(40) call matters: a flywheel pulls a large inrush current when spinning up, and capping it helps keep you from tripping a breaker or browning out the roboRIO.

Bind it in RobotContainer:

private final LauncherSubsystem m_launcher = new LauncherSubsystem();
// inside configureBindings():
m_ctrl.rightTrigger().whileTrue(m_launcher.shoot());

Tuning the shot: start at 85% and adjust. Too slow and the Fuel arcs short of the Hub; too fast and it bounces out. Real teams later replace the open-loop set() with a velocity PID + feedforward so the wheel recovers to target RPM between shots — that consistency is what helps you reach the Energized (100 Fuel) and Supercharged (360 Fuel) ranking-point thresholds. For now, open-loop is a perfect first launcher. Give the wheel a moment to spin up before feeding a ball, and use coast idle so it does not jerk to a stop.

Key takeaways

  • A flywheel launcher transfers momentum to the Fuel ball; startEnd() gives you a clean hold-to-shoot command
  • smartCurrentLimit(40) on the launcher reduces the spin-up inrush that can brown out the robot
  • Open-loop set(0.85) is fine to start; velocity PID+feedforward later gives the consistent shots needed for the Energized/Supercharged ranking points

Lesson quiz

Required

Answer all 3 questions correctly to complete this lesson.

1.In the 2026 FRC game REBUILT, what are the foam-ball game pieces that a launcher shoots called?

2.Why can't a pure PID (feedback-only) controller reliably hold a launcher flywheel at a target velocity?

3.Compared with feedforward-plus-PID, what is the main trait of a simple bang-bang controller on a flywheel?

Answer every question to submit.