Skip to content
2 changes: 1 addition & 1 deletion .wpilib/wpilib_preferences.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"enableCppIntellisense": false,
"currentLanguage": "java",
"projectYear": "2026beta",
"projectYear": "2026",
"teamNumber": 0
}
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2026.1.1-beta-1"
id "edu.wpi.first.GradleRIO" version "2026.1.1"
id "com.peterabeles.gversion" version "1.10.3"
id "com.diffplug.spotless" version "8.0.+"
id "io.freefair.lombok" version "9.1.+"
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import edu.wpi.first.units.measure.Mass;
import edu.wpi.first.wpilibj.PowerDistribution;
import edu.wpi.first.wpilibj.RobotBase;
import frc.robot.AprilTagLayout.AprilTagLayoutType;
import frc.robot.FieldConstants.AprilTagLayoutType;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.drive.SwerveConstants;
import frc.robot.util.Alert;
Expand Down Expand Up @@ -487,6 +487,6 @@ public static CTREPro getPhoenixPro() {

/** Get the current AprilTag layout type. */
public static AprilTagLayoutType getAprilTagLayoutType() {
return AprilTagLayout.defaultAprilTagType;
return FieldConstants.defaultAprilTagType;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright (c) 2024-2026 Az-FIRST
// http://github.com/AZ-First
// Copyright (c) 2025-2026 Littleton Robotics
// http://github.com/Mechanical-Advantage
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -28,12 +30,21 @@
import java.nio.file.Path;
import lombok.Getter;

public class AprilTagLayout {
/**
* Contains various field dimensions and useful reference points. All units are in meters and poses
* have a blue alliance origin.
*/
public class FieldConstants {

/** AprilTag Field Layout ************************************************ */
public static final double aprilTagWidth = Inches.of(6.50).in(Meters);

public static final String aprilTagFamily = "36h11";

public static final double fieldLength = AprilTagLayoutType.OFFICIAL.getLayout().getFieldLength();
public static final double fieldWidth = AprilTagLayoutType.OFFICIAL.getLayout().getFieldWidth();

public static final int aprilTagCount = AprilTagLayoutType.OFFICIAL.getLayout().getTags().size();
public static final AprilTagLayoutType defaultAprilTagType = AprilTagLayoutType.OFFICIAL;

public static final AprilTagFieldLayout aprilTagLayout =
Expand All @@ -42,34 +53,26 @@ public class AprilTagLayout {
@Getter
public enum AprilTagLayoutType {
OFFICIAL("2026-official"),

NONE("2026-none"),
REEFSCAPE("2025-official");

// SPEAKERS_ONLY("2024-speakers"),
// AMPS_ONLY("2024-amps"),
// WPI("2024-wpi");

private AprilTagLayoutType(String name) {
if (Constants.disableHAL) {
layout = null;
} else {
try {
layout =
new AprilTagFieldLayout(
Path.of(Filesystem.getDeployDirectory().getPath(), "apriltags", name + ".json"));
} catch (IOException e) {
throw new RuntimeException(e);
}
AprilTagLayoutType(String name) {
try {
layout =
new AprilTagFieldLayout(
Constants.disableHAL
? Path.of("src", "main", "deploy", "apriltags", name + ".json")
: Path.of(
Filesystem.getDeployDirectory().getPath(), "apriltags", name + ".json"));
} catch (IOException e) {
throw new RuntimeException(e);
}
if (layout == null) {
layoutString = "";
} else {
try {
layoutString = new ObjectMapper().writeValueAsString(layout);
} catch (JsonProcessingException e) {
throw new RuntimeException(
"Failed to serialize AprilTag layout JSON " + toString() + "for PhotonVision");
}

try {
layoutString = new ObjectMapper().writeValueAsString(layout);
} catch (JsonProcessingException e) {
throw new RuntimeException(
"Failed to serialize AprilTag layout JSON " + toString() + "for PhotonVision");
}
}

Expand Down
24 changes: 16 additions & 8 deletions src/main/java/frc/robot/README
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ robot. The files that should exist in this directory are listed below, along
with a brief description of their contents and which files MUST be edited to
include information about the specific robot being controlled.

AprilTagLayout.java
The year-specific AprilTag and field layout file. Teams may modify this
file to include additional information specific for their needs.

BuildConstants.java
Not tracked by git, used by the build system to record information about
the latest build of the code. This file should NOT be altered, and will be
Expand All @@ -22,12 +18,24 @@ Constants.java
importing only the constants needed for a particular software module. This
file MUST be modified to include the proper robot constants in the code.

FieldConstants.java
The year-specific AprilTag and field layout file. Teams may modify the
file to include additional information specific for their needs.

FieldState.java
For 2026 - REBUILT, the field produces information that affects gameplay,
namely which HUB is active at different times during the match. The file
converts data from the FMS into data that can be used by teams for scoring
control.

Main.java
This is the file run by the RoboRIO virtual machine. Do NOT alter this
file.
The file run by the RoboRIO virtual machine. Do NOT alter this file.

README
This file.

Robot.java
This file is called by ``Main.java`` and directs the operation of the robot
The file called by ``Main.java`` and which directs the operation of the robot
according to the currently commanded mode (disabled, autonomous, teleop,
test, and simulation). Care must be taken when modifying this module to
ensure proper operation of the robot. One section that would be useful to
Expand Down Expand Up @@ -76,4 +84,4 @@ util/


--------------------
Last Modified: 06 Jan 2026, TPEB
Last Modified: 12 Jan 2026, TPEB
2 changes: 0 additions & 2 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ public Robot() {
// Initialize URCL
Logger.registerURCL(URCL.startExternal());
StatusLogger.disableAutoLogging(); // Disable REVLib's built-in logging

// TODO: Uncomment this upon next release of AKit
// LoggedPowerDistribution.getInstance(PowerConstants.kPDMCANid, PowerConstants.kPDMType);

// Start AdvantageKit logger
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.robot.AprilTagLayout.AprilTagLayoutType;
import frc.robot.Constants.OperatorConstants;
import frc.robot.FieldConstants.AprilTagLayoutType;
import frc.robot.commands.AutopilotCommands;
import frc.robot.commands.DriveCommands;
import frc.robot.subsystems.accelerometer.Accelerometer;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/frc/robot/subsystems/drive/ModuleIOBlended.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
import com.ctre.phoenix6.swerve.SwerveModuleConstants;
import com.ctre.phoenix6.swerve.SwerveModuleConstants.ClosedLoopOutputType;
import com.ctre.phoenix6.swerve.SwerveModuleConstantsFactory;
import com.revrobotics.PersistMode;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.SparkBase;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkLowLevel.MotorType;
import com.revrobotics.spark.SparkMax;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/frc/robot/subsystems/drive/ModuleIOSpark.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import static frc.robot.subsystems.drive.SwerveConstants.*;

import com.revrobotics.AbsoluteEncoder;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.SparkBase;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkClosedLoopController.ArbFFUnits;
import com.revrobotics.spark.SparkFlex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
import com.ctre.phoenix6.BaseStatusSignal;
import com.ctre.phoenix6.StatusSignal;
import com.ctre.phoenix6.hardware.CANcoder;
import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.SparkBase;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkClosedLoopController.ArbFFUnits;
import com.revrobotics.spark.SparkFlex;
Expand Down
16 changes: 7 additions & 9 deletions src/main/java/frc/robot/subsystems/drive/README
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
The hardware-specific IO files included here are a baseline for what we expect
teams to use. If, however, you are using a different combination of hardware,
you will need to create a new ``ModuleIO*.java`` or ``GyroIO*.java`` file. We
encourage you to submit a PR to the Az-RBSI repositiory with your new hardware
file if you feel other teams may benefit from its inclusion. Additionally, the
instantiation logic in ``Drive.java`` will need to be extended to include the
new module type.
you will need to create a new ``ModuleIO*.java`` file. We encourage you to
submit a PR to the Az-RBSI repositiory with your new hardware file if you feel
other teams may benefit from its inclusion. Additionally, the instantiation
logic in ``Drive.java`` will need to be extended to include the new module
type.

Existing IO files:

- ``GyroIOPigeon2.java``: CTRE Pigeon2 as the swerve IMU
- ``GyroIONavX.java``: NavX as the swerve IMU, connected via SPI

- ``ModuleIOTalonFX.java``: 2x TalonFX motors + CANcoder
- ``ModuleIOTalonFXS.java``: 2x TalonFXS motors + CANcoder
- ``ModuleIOSpark.java``: 2x Rev NEO motors + analog absolute encoder connected to the RIO
- ``ModuleIOSparkCANcoder.java``: 2x Rv NEO motors + CANcoder
- ``ModuleIOBlended.java``: TalonFX drive, Rev NEO steer motors + CANcoder


--------------------
Last Modified: 2 Jan 2025, TPEB
Last Modified: 12 Jan 2026, TPEB
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@
// Copyright (c) 2021-2026 Littleton Robotics
// http://github.com/Mechanical-Advantage
//
// Use of this source code is governed by a BSD
// license that can be found in the AdvantageKit-License.md file
// at the root directory of this project.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 3 as published by the Free Software Foundation or
// available in the root directory of this project.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

package frc.robot.subsystems.flywheel_example;

import static frc.robot.Constants.FlywheelConstants.*;
import static frc.robot.Constants.RobotDevices.*;

import com.revrobotics.PersistMode;
import com.revrobotics.RelativeEncoder;
import com.revrobotics.ResetMode;
import com.revrobotics.spark.ClosedLoopSlot;
import com.revrobotics.spark.FeedbackSensor;
import com.revrobotics.spark.SparkBase;
import com.revrobotics.spark.SparkBase.ControlType;
import com.revrobotics.spark.SparkBase.PersistMode;
import com.revrobotics.spark.SparkBase.ResetMode;
import com.revrobotics.spark.SparkClosedLoopController;
import com.revrobotics.spark.SparkClosedLoopController.ArbFFUnits;
import com.revrobotics.spark.SparkLowLevel.MotorType;
Expand All @@ -30,18 +35,19 @@
import frc.robot.Constants.DrivebaseConstants;
import frc.robot.subsystems.drive.SwerveConstants;
import frc.robot.util.SparkUtil;
import org.littletonrobotics.junction.Logger;

/**
* NOTE: To use the Spark Flex / NEO Vortex, replace all instances of "CANSparkMax" with
* "CANSparkFlex".
*/
public class FlywheelIOSpark implements FlywheelIO {

// Define the leader / follower motors from the Ports section of RobotContainer
private final SparkBase leader =
new SparkMax(FLYWHEEL_LEADER.getDeviceNumber(), MotorType.kBrushless);
private final SparkBase follower =
// Define the leader / follower motors from the RobotDevices section of RobotContainer
private final SparkMax leader =
new SparkMax(FLYWHEEL_LEADER.getDeviceNumber(), MotorType.kBrushless);
private final SparkMax follower =
new SparkMax(FLYWHEEL_FOLLOWER.getDeviceNumber(), MotorType.kBrushless);
private final RelativeEncoder encoder = leader.getEncoder();
private final SparkClosedLoopController pid = leader.getClosedLoopController();
// IMPORTANT: Include here all devices listed above that are part of this mechanism!
Expand Down Expand Up @@ -97,6 +103,13 @@ public void updateInputs(FlywheelIOInputs inputs) {
Units.rotationsPerMinuteToRadiansPerSecond(encoder.getVelocity() / kFlywheelGearRatio);
inputs.appliedVolts = leader.getAppliedOutput() * leader.getBusVoltage();
inputs.currentAmps = new double[] {leader.getOutputCurrent(), follower.getOutputCurrent()};

// AdvantageKit logging
Logger.recordOutput("Flywheel/PositionRad", inputs.positionRad);
Logger.recordOutput("Flywheel/VelocityRadPerSec", inputs.velocityRadPerSec);
Logger.recordOutput("Flywheel/AppliedVolts", inputs.appliedVolts);
Logger.recordOutput("Flywheel/LeaderCurrent", inputs.currentAmps[0]);
Logger.recordOutput("Flywheel/FollowerCurrent", inputs.currentAmps[1]);
}

@Override
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/frc/robot/subsystems/imu/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
The hardware-specific IO files included here are a baseline for what we expect
teams to use. If, however, you are using a different combination of hardware,
you will need to create a new ``GyroIO*.java`` file. We encourage you to
submit a PR to the Az-RBSI repositiory with your new hardware file if you feel
other teams may benefit from its inclusion.

Existing IO files:

- ``GyroIOPigeon2.java``: CTRE Pigeon2 as the swerve IMU
- ``GyroIONavX.java``: NavX as the swerve IMU, connected via SPI


--------------------
Last Modified: 12 Jan 2026, TPEB
8 changes: 4 additions & 4 deletions src/main/java/frc/robot/subsystems/vision/Vision.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import edu.wpi.first.wpilibj.Alert;
import edu.wpi.first.wpilibj.Alert.AlertType;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.AprilTagLayout;
import frc.robot.FieldConstants;
import frc.robot.subsystems.vision.VisionIO.PoseObservationType;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -90,7 +90,7 @@ public void periodic() {

// Add tag poses
for (int tagId : inputs[cameraIndex].tagIds) {
var tagPose = AprilTagLayout.aprilTagLayout.getTagPose(tagId);
var tagPose = FieldConstants.aprilTagLayout.getTagPose(tagId);
if (tagPose.isPresent()) {
tagPoses.add(tagPose.get());
}
Expand All @@ -108,9 +108,9 @@ public void periodic() {

// Must be within the field boundaries
|| observation.pose().getX() < 0.0
|| observation.pose().getX() > AprilTagLayout.aprilTagLayout.getFieldLength()
|| observation.pose().getX() > FieldConstants.aprilTagLayout.getFieldLength()
|| observation.pose().getY() < 0.0
|| observation.pose().getY() > AprilTagLayout.aprilTagLayout.getFieldWidth();
|| observation.pose().getY() > FieldConstants.aprilTagLayout.getFieldWidth();

// Add pose to log
robotPoses.add(observation.pose());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

package frc.robot.subsystems.vision;

import static frc.robot.AprilTagLayout.*;
import static frc.robot.FieldConstants.*;

import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation2d;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Transform3d;
import frc.robot.AprilTagLayout;
import frc.robot.FieldConstants;
import java.util.function.Supplier;
import org.photonvision.simulation.PhotonCameraSim;
import org.photonvision.simulation.SimCameraProperties;
Expand All @@ -38,7 +38,7 @@ public VisionIOPhotonVisionSim(
// Initialize vision sim
if (visionSim == null) {
visionSim = new VisionSystemSim("main");
visionSim.addAprilTags(AprilTagLayout.aprilTagLayout);
visionSim.addAprilTags(FieldConstants.aprilTagLayout);
}

// Add sim camera
Expand Down
Loading