Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,18 @@ public static final class RobotConstants {
// Insert here the orientation (CCW == +) of the Rio and IMU from the robot
// An angle of "0." means the x-y-z markings on the device match the robot's intrinsic reference
// frame.
// NOTE: It is assumed that both the Rio and the IMU are mounted such that +Z is UP
public static final Rotation2d kRioOrientation =
public static final Rotation3d kRioOrientation =
switch (getRobot()) {
case COMPBOT -> Rotation2d.fromDegrees(-90.);
case DEVBOT -> Rotation2d.fromDegrees(0.);
default -> Rotation2d.fromDegrees(0.);
case COMPBOT -> new Rotation3d(0, 0, -90);
case DEVBOT -> Rotation3d.kZero;
default -> Rotation3d.kZero;
};
// IMU can be one of Pigeon2 or NavX
public static final Rotation2d kIMUOrientation =
public static final Rotation3d kIMUOrientation =
switch (getRobot()) {
case COMPBOT -> Rotation2d.fromDegrees(0.);
case DEVBOT -> Rotation2d.fromDegrees(0.);
default -> Rotation2d.fromDegrees(0.);
case COMPBOT -> Rotation3d.kZero;
case DEVBOT -> Rotation3d.kZero;
default -> Rotation3d.kZero;
};
}

Expand Down Expand Up @@ -324,6 +323,9 @@ public static final class DrivebaseConstants {
SwerveConstants.kDriveGearRatio / DCMotor.getKrakenX60Foc(1).KtNMPerAmp;
public static final double kSteerP = 400.0;
public static final double kSteerD = 20.0;

// Odometry-related constants
public static final double kHistorySize = 1.5; // seconds
}

/************************************************************************* */
Expand Down Expand Up @@ -416,6 +418,16 @@ public static final class AutoConstants {
/** Vision Constants (Assuming PhotonVision) ***************************** */
public static class VisionConstants {

public static final java.util.Set<Integer> kTrustedTags =
java.util.Set.of(2, 3, 4, 5, 8, 9, 10, 11, 18, 19, 20, 21, 24, 25, 26, 27); // HUB AprilTags

// Noise scaling factors (lower = more trusted)
public static final double kTrustedTagStdDevScale = 0.6; // 40% more weight
public static final double kUntrustedTagStdDevScale = 1.3; // 30% less weight

// Optional: if true, reject observations that contain no trusted tags
public static final boolean kRequireTrustedTag = false;

// AprilTag Identification Constants
public static final double kAmbiguityThreshold = 0.4;
public static final double kTargetLogTimeSecs = 0.1;
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.revrobotics.util.StatusLogger;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import edu.wpi.first.wpilibj.Threads;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj2.command.Command;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class Robot extends LoggedRobot {
private Command m_autoCommandPathPlanner;
private RobotContainer m_robotContainer;
private Timer m_disabledTimer;
private static boolean isBlueAlliance = false;

// Define simulation fields here
private VisionSystemSim visionSim;
Expand Down Expand Up @@ -135,9 +137,13 @@ public Robot() {
/** TESTING VERSION OF ROBOTPERIODIC FOR OVERRUN SOURCES */
@Override
public void robotPeriodic() {

isBlueAlliance = DriverStation.getAlliance().orElse(Alliance.Blue) == Alliance.Blue;

final long t0 = System.nanoTime();

if (isReal()) {
// Switch thread to high priority to improve loop timing
Threads.setCurrentThreadPriority(true, 99);
}
final long t1 = System.nanoTime();
Expand Down Expand Up @@ -186,6 +192,7 @@ public void autonomousInit() {
CommandScheduler.getInstance().cancelAll();
m_robotContainer.getDrivebase().setMotorBrake(true);
m_robotContainer.getDrivebase().resetHeadingController();
m_robotContainer.getVision().resetPoseGate(Timer.getFPGATimestamp());

// TODO: Make sure Gyro inits here with whatever is in the path planning thingie
switch (Constants.getAutoType()) {
Expand Down Expand Up @@ -315,4 +322,13 @@ public void simulationPeriodic() {
// Update sim each sim tick
visionSim.update(m_robotContainer.getDrivebase().getPose());
}

// Helper method to simplify checking if the robot is blue or red alliance
public static boolean isBlue() {
return isBlueAlliance;
}

public static boolean isRed() {
return !isBlue();
}
}
106 changes: 62 additions & 44 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
// 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.
//
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
Expand Down Expand Up @@ -75,6 +81,9 @@
/** This is the location for defining robot hardware, commands, and controller button bindings. */
public class RobotContainer {

private static final boolean USE_MAPLESIM = true;
public static final boolean MAPLESIM = USE_MAPLESIM && Robot.isSimulation();

/** Define the Driver and, optionally, the Operator/Co-Driver Controllers */
// Replace with ``CommandPS4Controller`` or ``CommandJoystick`` if needed
final CommandXboxController driverController = new CommandXboxController(0); // Main Driver
Expand All @@ -96,16 +105,14 @@ public class RobotContainer {

// These are "Virtual Subsystems" that report information but have no motors
private final Imu m_imu;
private final Vision m_vision;

@SuppressWarnings("unused")
private final Accelerometer m_accel;

@SuppressWarnings("unused")
private final RBSIPowerMonitor m_power;

@SuppressWarnings("unused")
private final Vision m_vision;

@SuppressWarnings("unused")
private List<RBSICANHealth> canHealth;

Expand All @@ -128,36 +135,7 @@ public class RobotContainer {
// Alerts
private final Alert aprilTagLayoutAlert = new Alert("", AlertType.INFO);

// Vision Factories
private VisionIO[] buildVisionIOsReal(Drive drive) {
return switch (Constants.getVisionType()) {
case PHOTON ->
Arrays.stream(Cameras.ALL)
.map(c -> (VisionIO) new VisionIOPhotonVision(c.name(), c.robotToCamera()))
.toArray(VisionIO[]::new);

case LIMELIGHT ->
Arrays.stream(Cameras.ALL)
.map(c -> (VisionIO) new VisionIOLimelight(c.name(), drive::getHeading))
.toArray(VisionIO[]::new);

case NONE -> new VisionIO[] {new VisionIO() {}};
};
}

private static VisionIO[] buildVisionIOsSim(Drive drive) {
var cams = Constants.Cameras.ALL;
VisionIO[] ios = new VisionIO[cams.length];
for (int i = 0; i < cams.length; i++) {
var cfg = cams[i];
ios[i] = new VisionIOPhotonVisionSim(cfg.name(), cfg.robotToCamera(), drive::getPose);
}
return ios;
}

private VisionIO[] buildVisionIOsReplay() {
return new VisionIO[] {new VisionIO() {}};
}
public static RobotContainer instance;

/**
* Constructor for the Robot Container. This container holds subsystems, opertator interface
Expand All @@ -179,7 +157,9 @@ public RobotContainer() {

m_drivebase = new Drive(m_imu);
m_flywheel = new Flywheel(new FlywheelIOSim()); // new Flywheel(new FlywheelIOTalonFX());
m_vision = new Vision(m_drivebase::addVisionMeasurement, buildVisionIOsReal(m_drivebase));
m_vision =
new Vision(
m_drivebase, m_drivebase::addVisionMeasurement, buildVisionIOsReal(m_drivebase));
m_accel = new Accelerometer(m_imu);
sweep = null;
break;
Expand All @@ -192,12 +172,10 @@ public RobotContainer() {
m_flywheel = new Flywheel(new FlywheelIOSim());

// ---------------- Vision IOs (robot code) ----------------
var cams = frc.robot.Constants.Cameras.ALL;

// If you keep Vision expecting exactly two cameras:
VisionIO[] visionIOs = buildVisionIOsSim(m_drivebase);
m_vision = new Vision(m_drivebase::addVisionMeasurement, visionIOs);

var cams = Cameras.ALL;
m_vision =
new Vision(
m_drivebase, m_drivebase::addVisionMeasurement, buildVisionIOsSim(m_drivebase));
m_accel = new Accelerometer(m_imu);

// ---------------- CameraSweepEvaluator (sim-only analysis) ----------------
Expand Down Expand Up @@ -231,7 +209,8 @@ public RobotContainer() {
m_imu = new Imu(new ImuIOSim() {});
m_drivebase = new Drive(m_imu);
m_flywheel = new Flywheel(new FlywheelIO() {});
m_vision = new Vision(m_drivebase::addVisionMeasurement, buildVisionIOsReplay());
m_vision =
new Vision(m_drivebase, m_drivebase::addVisionMeasurement, buildVisionIOsReplay());
m_accel = new Accelerometer(m_imu);
sweep = null;
break;
Expand Down Expand Up @@ -493,6 +472,11 @@ public Drive getDrivebase() {
return m_drivebase;
}

/** Vision getter method for use with Robot.java */
public Vision getVision() {
return m_vision;
}

/**
* Set up the SysID routines from AdvantageKit
*
Expand Down Expand Up @@ -536,6 +520,40 @@ private void definesysIdRoutines() {
}
}

// Vision Factories
// Vision Factories (REAL)
private VisionIO[] buildVisionIOsReal(Drive drive) {
return switch (Constants.getVisionType()) {
case PHOTON ->
java.util.Arrays.stream(Constants.Cameras.ALL)
.map(c -> (VisionIO) new VisionIOPhotonVision(c.name(), c.robotToCamera()))
.toArray(VisionIO[]::new);

case LIMELIGHT ->
java.util.Arrays.stream(Constants.Cameras.ALL)
.map(c -> (VisionIO) new VisionIOLimelight(c.name(), drive::getHeading))
.toArray(VisionIO[]::new);

case NONE -> new VisionIO[] {}; // recommended: no cameras
};
}

// Vision Factories (SIM)
private VisionIO[] buildVisionIOsSim(Drive drive) {
var cams = Constants.Cameras.ALL;
VisionIO[] ios = new VisionIO[cams.length];
for (int i = 0; i < cams.length; i++) {
var cfg = cams[i];
ios[i] = new VisionIOPhotonVisionSim(cfg.name(), cfg.robotToCamera(), drive::getPose);
}
return ios;
}

// Vision Factories (REPLAY)
private VisionIO[] buildVisionIOsReplay() {
return new VisionIO[] {}; // simplest: Vision does nothing during replay
}

/**
* Example Choreo auto command
*
Expand Down
Loading