Imported from frc461/Rowdy25 (
doc/dev/AGENTS.md). Install upstream withnpx skills add frc461/Rowdy25 --skill dev. Copyright stays with the author.
Rowdy 25 - AI Agent Guidelines
FRC 2025 robot codebase (Team 461 "Westside Robotics"). This document guides AI agents through the architecture, patterns, and workflows specific to this 2025 Reefscape robot.
Architecture Overview
Lifecycle & Entry Points
Main.java→Robot.java→RobotContainer.javaRobotBase.startRobot()launches the robot instanceRobotextendsTimedRobotwith periodic methods:robotPeriodic(),autonomousInit/Periodic(),teleopInit/Periodic()RobotContainerinitializes subsystems, commands, auto manager, and controller bindings (single entry point for all setup)
Core Subsystem Architecture: State Machines
RobotStates.java (~1050 lines) is the integrating superstructure:
- Enum
Statewith 22 states:STOW,L2_L3_L4_STOW,L1_CORAL,L2_CORAL,L3_CORAL,L4_CORAL,GROUND_CORAL,GROUND_ALGAE,LOW_REEF_ALGAE,HIGH_REEF_ALGAE,PROCESSOR,NET,CORAL_STATION,CORAL_STATION_OBSTRUCTED,PREPARE_CLIMB,CLIMB,MANUAL,OUTTAKE,OUTTAKE_ALGAE,OUTTAKE_L1,INTAKE_OUT - Manages coordinated transitions across the swerve, elevator, pivot, wrist, and intake subsystems
- Each subsystem has parallel state enums (e.g.,
Pivot.State.L2_CORAL_AT_BRANCH) - Uses the
Triggersystem for state-based automation:stowState.onTrue(...)chains commands orderedTransition()ensures safe non-conflicting movement (e.g., stow wrist before moving pivot through certain ranges); the elevator'sgoingDown()/goingThroughStow()predicates select the safe ordering
Subsystems (each has a paired *Telemetry.java for logging):
Swerve— Phoenix 6 swerve drivetrain withLocalADStarpathfinding and a 12-modeDriveModeenum (idle / translating / rotating / fast-rotating / six auto-heading modes); owns aLocalizerfor multi-camera localizationElevator,Pivot,Wrist— TalonFX Kraken motors with Motion Magic Expo, PID + gravity feedforward; pivot adds a servo-hub ratchet for mechanical holdIntake— Roller motor + CANandcolor proximity / color sensor + distance sensor for coral and algae detectionLights— LED strips (hardware disabled on the 2025 competition robot; code retained)
Key Data Flows
- State Transitions: Controller input →
RobotStates.toggle*State()→ state setter →TriggeronTrue →orderedTransition()→ subsystem position commands - Localization: Multiple cameras (Limelight, PhotonVision, QuestNav) →
Localizer→ pose estimation with vision-based trust filter - Autonomous:
AutoManager(chooser-based) →PathPlannerpaths →NamedCommandsevent markers trigger state changes - Telemetry:
DogLog+NetworkTablepublishers in each subsystem → SmartDashboard viaShuffleboard
Critical Developer Workflows
Build & Deploy
# Standard Gradle build (respects JAVA_HOME; build.gradle specifies Java 17)
./gradlew build
# If Gradle overrides Java version, force your JDK:
./gradlew -Dorg.gradle.java.home=/path/to/your/jdk build
# Deploy to RoboRIO (requires team number in .wpilib/wpilib_preferences.json)
./gradlew deploy
# Simulation with GUI:
./gradlew simulateJava
Testing & Tuning
- SysID:
SysID.javautility class for motor characterization (feedforward tuning) - SmartDashboard Choosers:
RobotStates.stateChooserallows manual state selection during disabled mode - Telemetry: DogLog logs all subsystem states; check
/media/logs/on roboRIO
Robot Identity & Constants
RobotIdentity.initializeConstants() (called from the Robot constructor) loads variant constants based on MAC address:
DefaultConstants— baseline values; also the fallback used for the alpha bot (no dedicated variant file)CompConstants— competition robot overridesSimConstants— simulation overridesTestConstants— test-bot overrides
Edit constants/variants/*.java for robot-specific PID gains, motor IDs, and presets.
Project-Specific Conventions
State Management Pattern
States represent physical robot positions + subsystem coordination intent:
STOW: Safe resting position, transitions toL2_L3_L4_STOWwhen holding coral for L2+ scoring- Coral scoring:
GROUND_CORAL(pickup) →L1_CORAL/L2_CORAL/L3_CORAL/L4_CORAL(aim) →OUTTAKE(score) - Algae scoring:
LOW_REEF_ALGAE/HIGH_REEF_ALGAE(pickup) →PROCESSOR/NET(score) - Camera trust toggle:
swerve.localizer.trustCamerasenables/disables vision-based positioning (fallback: intake-based outtake)
Coordinate System & Subsystem Positions
- Swerve: Field-centric (blue alliance = 0°, red alliance = 180°)
- Pivot/Wrist/Elevator: Motor rotations → degrees/inches via ratio constants in
Constants.java Localizer.javamanages April Tag-based pose + odometry + vision correctionsFieldUtil.javacontains reef branch positions and coral station locations (alliance-flip aware)
Command Composition Pattern
- Individual commands often wrap subsystem state setters:
pivot::setL2CoralState - Ordered sequences use
InstantCommand().andThen(waitUntil(...)).andThen(...) - Conditional logic via
ConditionalCommand(ifTrue, ifFalse, condition)or.onlyIf(boolean) - Parallel execution with
.alongWith()(e.g., intake intaking while pivot moves) - Interruption:
.until(condition)cancels command chain when condition becomes true
Telemetry & Logging
- DogLog: Deep logging of subsystem states, positions, command traces
- NetworkTable publishers: Real-time SmartDashboard updates (e.g.,
robotStatesPub.set(currentState.name())) - Servo Hub status: Tracks ratchet engagement (pivot safety mechanism)
- Vision debug: PhotonVision and Limelight targets logged per camera
Integration Points & External Dependencies
Vision Systems
- Limelight: April Tag pose estimation + alliance flip detection
- PhotonVision: Color-based coral/algae detection + object tracking
- QuestNav: Backup/alternate SLAM-based localization
- All mounted with specific offsets (
COLOR_FORWARD,LL_PITCH, etc.) in vision constants
PathPlanner Integration
- Path files:
src/main/deploy/pathplanner/paths/(auto-generated in Pathplanner UI) - Named Commands: Register via
NamedCommands.registerCommand(marker, command)inRobotContainer - Event markers: Paths trigger commands at specific waypoints (e.g.,
INTAKE_MARKER→setGroundCoralState()) - Pathfinding:
LocalADStarpathfinder warm-up on startup; avoids defined obstacles (reef zones, wall boundary)
Hardware Configuration (Constants)
- Motor IDs & CAN Bus:
ElevatorConstants.LEAD_ID,PivotConstants.ENCODER_ID, etc. - Sensor Ports: DIO ports for limit switches and proximity sensors
- Phoenix 6 Configs: Motor inversion, current limits, neutral modes (coast/brake)
- Servo Hub: Ratchet engagement channels (servo PWM control)
Patterns to Avoid
- Direct motor commands outside state machine: Always transition via
RobotStates.toggle*State()or subsystem state setters - Blocking waits: Use
WaitUntilCommand/WaitCommandwith command composition, notThread.sleep() - Modifying subsystem positions mid-state: State transitions should be atomic; use nested states if needed
- Ignoring elevator direction in transitions:
elevator.goingDown()determines safe transition path (callsorderedTransitionparameter) - Camera trust hardcode: Always reference
swerve.localizer.trustCamerasboolean for fallback logic
File Structure Quick Reference
src/main/java/io/github/frc461/rowdy25/
├── Main.java # Entry point
├── Robot.java # TimedRobot lifecycle
├── RobotContainer.java # Initialization hub
├── RobotStates.java # State machine superstructure
├── constants/
│ ├── Constants.java # Global + nested class constants
│ ├── RobotIdentity.java # Multi-robot selector
│ ├── RobotPoses.java # Field locations (reef, station)
│ └── variants/ # Robot-specific configs
├── subsystems/
│ ├── drivetrain/Swerve.java # Phoenix 6 swerve + localization
│ ├── elevator/Elevator.java # Linear extension
│ ├── pivot/Pivot.java # Base rotation (pitch)
│ ├── wrist/Wrist.java # Upper rotation (pitch) + gravity comp
│ ├── intake/Intake.java # Game piece grip motor + sensor
│ └── localizer/Localizer.java # Vision + odometry fusion
├── commands/
│ ├── *Command.java # Individual subsystem commands
│ ├── drive/ # Swerve-specific (pathfinding, auto-align)
│ └── auto/ # Autonomous-specific (search, follow)
├── autos/
│ └── AutoManager.java # Chooser-based auto builder
└── util/
├── FieldUtil.java # Reef pose calculations
├── vision/ # Limelight, PhotonVision utilities
└── DoubleTrueTrigger.java # Custom trigger logic
Tips for Code Changes
- Adding a new state: Add enum value to
RobotStates.State, create corresponding subsystem states, register trigger inconfigureToggleStateTriggers() - Tuning PID: Edit
constants/variants/values; use SysID for feedforward, tune P/I/D empirically on robot - Debugging state transitions: Check
orderedTransition()logic and subsystemgoingDown()/goingThroughStow()predicates - Vision changes: Update offsets in
Constants.VisionConstantsandLocalizer.javapose correction logic - New autonomous routine: Create path in PathPlanner, register event markers in
RobotContainer, test with auto mode disabled first