diff --git a/src/main/deploy/pathplanner/paths/Test Path.path b/src/main/deploy/pathplanner/paths/Test Path.path index f0bbff3..93cb9a9 100644 --- a/src/main/deploy/pathplanner/paths/Test Path.path +++ b/src/main/deploy/pathplanner/paths/Test Path.path @@ -3,13 +3,13 @@ "waypoints": [ { "anchor": { - "x": 2.0, - "y": 7.0 + "x": 4.884468124673432, + "y": 3.3034818122181178 }, "prevControl": null, "nextControl": { - "x": 3.0, - "y": 7.0 + "x": 5.8844681246734325, + "y": 3.3034818122181178 }, "isLocked": false, "linkedName": null diff --git a/src/main/java/frc/robot/Commands/TeleopCommands/PathfindingCommands.java b/src/main/java/frc/robot/Commands/TeleopCommands/PathfindingCommands.java index d61b54c..26d7fcb 100644 --- a/src/main/java/frc/robot/Commands/TeleopCommands/PathfindingCommands.java +++ b/src/main/java/frc/robot/Commands/TeleopCommands/PathfindingCommands.java @@ -3,13 +3,16 @@ import com.pathplanner.lib.auto.AutoBuilder; import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.math.util.Units; import edu.wpi.first.wpilibj2.command.Command; -import edu.wpi.first.wpilibj2.command.PrintCommand; +import edu.wpi.first.wpilibj2.command.Commands; import frc.robot.Constants.FieldConstants; import frc.robot.Constants.PathPlannerConstants; +import frc.robot.Subsystems.Drive.Drive; import frc.robot.Subsystems.Drive.DriveConstants; import frc.robot.Subsystems.Vision.Vision; import frc.robot.Subsystems.Vision.VisionConstants; +import java.util.function.BooleanSupplier; import java.util.function.DoubleSupplier; import java.util.function.IntSupplier; @@ -18,81 +21,256 @@ public class PathfindingCommands { /** * Generates a trajectory for the robot to follow to the best AprilTag seen. If no AprilTag is * seen, a message will be printed repeatedly to the console advising to change the robot mode to - * move again. + * move again. The trajectory will automatically be rotated to the Red alliance. * - * @param vision Vision subsystem - * @param distanceFromTagMeters Distance in front of the AprilTag for the robot to end up - * @return Command that makes the robot follow a trajectory to in front of the AprilTag + *

Since a new trajectory is meant to be generated upon every button press, all the code must + * be inside of the return. This is done by returning a {@code Commands.run()} with a block of + * code inside of the lambda function for the {@link Runnable} parameter. + * + * @param drive {@link Drive} subsystem + * @param vision {@link Vision} subsystem + * @param distanceFromTagMeters Distance in front of the AprilTag for the robot to end up. + * @param stopTrigger {@link BooleanSupplier} with the condition to end the Pathfinding command. + * @return {@link Command} that makes the robot follow a trajectory to in front of the AprilTag. */ - public static Command pathfindToCurrentTag(Vision vision, DoubleSupplier distanceFromTagMeters) { - /** - * Get ID of AprilTag currently seen by the front camera, if any. If an invalid ID is given the - * apriltagPose Optional will be empty - */ - var apriltagPose = - FieldConstants.APRILTAG_FIELD_LAYOUT.getTagPose( - vision.getTagID(VisionConstants.CAMERA.FRONT.CAMERA_INDEX)); + public static Command pathfindToCurrentTag( + Drive drive, + Vision vision, + DoubleSupplier distanceFromTagMeters, + BooleanSupplier stopTrigger) { + return Commands.run( + () -> { + /* + * Get ID of AprilTag currently seen by the front camera, if any. If an invalid ID is + * given the apriltagPose Optional will be empty + */ + var apriltagPose = + FieldConstants.APRILTAG_FIELD_LAYOUT.getTagPose( + vision.getTagID(VisionConstants.CAMERA.FRONT.CAMERA_INDEX)); - // If no valid tag returned then return a print messsage instead - if (apriltagPose.isEmpty()) return new PrintCommand("Invalid Tag ID"); + // If no valid tag returned then return a print messsage instead + if (apriltagPose.isEmpty()) { + Commands.print("Invalid AprilTag ID").until(stopTrigger).schedule(); + } else { - // Turn 3d AprilTag pose into a 2d pose - var apriltagPose2d = apriltagPose.get().toPose2d(); + // Turn 3d AprilTag pose into a 2d pose + var apriltagPose2d = apriltagPose.get().toPose2d(); - /** - * The goal pose is the end position for the center of the robot. Transforming by half the track - * width will leave the robot right up against the tag and any additional distance can be added - */ - var goalPose = - new Pose2d( - /** - * Multiply the x by cos and y by sin of the tag angle so that the hypot (tag to robot) - * is the desired distance away from the tag + /* + * The goal pose is the end position for the center of the robot. Transforming by half + * the track width will leave the robot right up against the tag and any additional + * distance can be added */ - apriltagPose2d.getX() - + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) - * apriltagPose2d.getRotation().getCos(), - apriltagPose2d.getY() - + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) - * apriltagPose2d.getRotation().getSin(), - apriltagPose2d.getRotation().plus(Rotation2d.k180deg)); + var goalPose = + new Pose2d( + /* + * Multiply the x by cos and y by sin of the tag angle so that the hypot (tag to + * robot) is the desired distance away from the tag + */ + apriltagPose2d.getX() + + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) + * apriltagPose2d.getRotation().getCos(), + apriltagPose2d.getY() + + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) + * apriltagPose2d.getRotation().getSin(), + apriltagPose2d.getRotation().plus(Rotation2d.k180deg)); - // Rotate by 180 as the AprilTag angles are rotated 180 degrees relative to the robot - return AutoBuilder.pathfindToPose(goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0); + // Rotate by 180 as the AprilTag angles are rotated 180 degrees relative to the robot + AutoBuilder.pathfindToPoseFlipped( + goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0) + .until(stopTrigger) + .schedule(); + } + }, + drive); } /** * Generates a trajectory for the robot to follow to the AprilTag corresponding to the ID inputed - * with an additional distance translation + * with an additional distance translation. The trajectory will automatically be rotated to the + * red alliance. * - * @param tagID AprilTag ID of the desired AprilTag to align to - * @param distanceFromTagMeters Distance in front of the AprilTag for the robot to end up - * @return Command that makes the robot follow a trajectory to in front of the AprilTag + * @param tagID AprilTag ID of the desired AprilTag to align to. + * @param wallDistanceMeters Distance in front of the AprilTag for the robot to end up. + * @return {@link Command} that makes the robot follow a trajectory to in front of the AprilTag. */ - public static Command pathfindToAprilTag( - IntSupplier tagID, DoubleSupplier distanceFromTagMeters) { + public static Command pathfindToAprilTag(IntSupplier tagID, DoubleSupplier wallDistanceMeters) { // Get the 2d pose of the AprilTag associated with the inputed ID var apriltagPose = FieldConstants.APRILTAG_FIELD_LAYOUT.getTagPose(tagID.getAsInt()).get().toPose2d(); - /** + /* * The goal pose is the end position for the center of the robot. Transforming by half the track * width will leave the robot right up against the tag and any additional distance can be added */ var goalPose = new Pose2d( - /** + /* * Multiply the x by cos and y by sin of the tag angle so that the hypot (tag to robot) * is the desired distance away from the tag */ apriltagPose.getX() - + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) + + ((DriveConstants.TRACK_WIDTH_M / 2) + wallDistanceMeters.getAsDouble()) * apriltagPose.getRotation().getCos(), apriltagPose.getY() - + ((DriveConstants.TRACK_WIDTH_M / 2) + distanceFromTagMeters.getAsDouble()) + + ((DriveConstants.TRACK_WIDTH_M / 2) + wallDistanceMeters.getAsDouble()) * apriltagPose.getRotation().getSin(), // Rotate by 180 as the AprilTag angles are rotated 180 degrees relative to the robot apriltagPose.getRotation().plus(Rotation2d.k180deg)); - return AutoBuilder.pathfindToPose(goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0); + return AutoBuilder.pathfindToPoseFlipped( + goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0); + } + + /** + * Generates a trajectory for the robot to follow to a specified REEF BRANCH with an additional + * distance translation. The trajectory will automatically be rotated to the red alliance. + * + * @param branchLetter Letter corresponding to BRANCH to pathfind to. + * @param wallDistanceMeters Distance from the REEF wall in meters. + * @return {@link Command} that makes the robot follow a trajectory to in front of the BRANCH. + */ + public static Command pathfindToBranch(String branchLetter, DoubleSupplier wallDistanceMeters) { + // Position of BRANCH corresponding to zone the robot is in + var branchPose = FieldConstants.BRANCH_POSES.get(branchLetter); + + // Translated pose to send to Pathfinder, so that robot isn't commanded to go directly on top of + // the BRANCH + var goalPose = + new Pose2d( + // Multiply the x by cos and y by sin of the tag angle so that the hypot (tag to robot) + // is the desired distance away from the tag + branchPose.getX() + + ((DriveConstants.TRACK_WIDTH_M / 2) + + FieldConstants.BRANCH_TO_WALL_X_M + + wallDistanceMeters.getAsDouble()) + * branchPose.getRotation().getCos(), + branchPose.getY() + + ((DriveConstants.TRACK_WIDTH_M / 2) + + FieldConstants.BRANCH_TO_WALL_X_M + + wallDistanceMeters.getAsDouble()) + * branchPose.getRotation().getSin(), + // Rotate by 180 as the AprilTag angles are rotated 180 degrees relative to the robot + branchPose.getRotation().plus(Rotation2d.k180deg)); + + return AutoBuilder.pathfindToPoseFlipped( + goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0); + } + + /** + * Generates a trajectory for the robot to follow to the nearest BRANCH. The trajectory will + * automatically be rotated to the Red alliance. + * + *

Since a new trajectory is meant to be generated upon every button press, all the code must + * be inside of the return. This is done by returning a {@code Commands.run()} with a block of + * code inside of the lambda function for the {@link Runnable} parameter. + * + * @param drive {@link Drive} subsystem + * @param wallDistanceMeters Distance from the REEF wall in meters. + * @param stopTrigger {@link BooleanSupplier} with the condition to end the Pathfinding command. + * @return {@link Command} that makes the robot follow a trajectory to in front of the nearest + * BRANCH. + */ + public static Command pathfindToClosestReef( + Drive drive, DoubleSupplier wallDistanceMeters, BooleanSupplier stopTrigger) { + return Commands.run( + () -> { + var currentPose = drive.getCurrentPose2d(); + // Angle from REEF to robot + double thetaDeg = + Units.radiansToDegrees( + Math.atan2( + currentPose.getY() - FieldConstants.REEF_CENTER_TRANSLATION.getY(), + currentPose.getX() - FieldConstants.REEF_CENTER_TRANSLATION.getX())); + // Letter corresponding to BRANCH to pathfind to + String branchLetter; + + // Decide which BRANCH to pathfind to + if (thetaDeg > 150) { + // BRANCH A (left) + branchLetter = "A"; + } else if (thetaDeg < -150) { + // BRANCH B (right) + branchLetter = "B"; + } else if (thetaDeg < -90 && thetaDeg > -150) { + // REEF zone CD + if (thetaDeg < -120) { + // BRANCH C (left) + branchLetter = "C"; + } else { + // BRANCH D (right) + branchLetter = "D"; + } + } else if (thetaDeg < -30 && thetaDeg > -90) { + // REEF zone EF + if (thetaDeg < -60) { + // BRANCH E (left) + branchLetter = "E"; + } else { + // BRANCH F (right) + branchLetter = "F"; + } + } else if (thetaDeg < 30 && thetaDeg > -30) { + // REEF zone GH + if (thetaDeg < 0) { + // BRANCH G (left) + branchLetter = "G"; + } else { + // BRANCH H (right) + branchLetter = "H"; + } + } else if (thetaDeg < 90 && thetaDeg > 30) { + // REEF zone IJ + if (thetaDeg < 60) { + // BRANCH I (left) + branchLetter = "I"; + } else { + // BRANCH J (right) + branchLetter = "J"; + } + } else { + // REEF zone KL + if (thetaDeg < 120) { + // BRANCH K (left) + branchLetter = "K"; + } else { + // BRANCH L (right) + branchLetter = "L"; + } + } + // Position of BRANCH corresponding to zone the robot is in + var branchPose = FieldConstants.BRANCH_POSES.get(branchLetter); + /* + * Translated pose to send to Pathfinder, so that robot isn't commanded to go directly on + * top of the BRANCH + */ + var goalPose = + new Pose2d( + /* + * Multiply the x by cos and y by sin of the tag angle so that the hypot (tag to + * robot) is the desired distance away from the tag + */ + branchPose.getX() + + ((DriveConstants.TRACK_WIDTH_M / 2) + + FieldConstants.BRANCH_TO_WALL_X_M + + wallDistanceMeters.getAsDouble()) + * branchPose.getRotation().getCos(), + branchPose.getY() + + ((DriveConstants.TRACK_WIDTH_M / 2) + + FieldConstants.BRANCH_TO_WALL_X_M + + wallDistanceMeters.getAsDouble()) + * branchPose.getRotation().getSin(), + /* + * Rotate by 180 as the AprilTag angles are rotated 180 degrees relative to the + * robot + */ + branchPose.getRotation().plus(Rotation2d.k180deg)); + + // Create and follow the trajectory to the goal pose + AutoBuilder.pathfindToPoseFlipped( + goalPose, PathPlannerConstants.DEFAULT_PATH_CONSTRAINTS, 0) + .until(stopTrigger) + .schedule(); + }, + drive); } } diff --git a/src/main/java/frc/robot/Constants.java b/src/main/java/frc/robot/Constants.java index 6312952..96e75f6 100644 --- a/src/main/java/frc/robot/Constants.java +++ b/src/main/java/frc/robot/Constants.java @@ -18,13 +18,17 @@ import com.pathplanner.lib.path.PathConstraints; import edu.wpi.first.apriltag.AprilTagFieldLayout; import edu.wpi.first.apriltag.AprilTagFields; +import edu.wpi.first.math.geometry.Pose2d; import edu.wpi.first.math.geometry.Pose3d; +import edu.wpi.first.math.geometry.Translation2d; import edu.wpi.first.math.system.plant.DCMotor; import edu.wpi.first.math.util.Units; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.DriverStation.Alliance; import edu.wpi.first.wpilibj.RobotBase; import frc.robot.Subsystems.Drive.DriveConstants; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; /** @@ -68,6 +72,12 @@ public static Optional getAlliance() { return DriverStation.getAlliance(); } + /** Whether or not the robot is on the Red Alliance */ + public static boolean isRed() { + return RobotStateConstants.getAlliance().isPresent() + && RobotStateConstants.getAlliance().get() == DriverStation.Alliance.Red; + } + /** After 500 seconds, the CAN times out */ public static final int CAN_CONFIG_TIMEOUT_SEC = 500; @@ -129,6 +139,79 @@ public final class FieldConstants { public static Optional getAprilTagPose(int ID) { return APRILTAG_FIELD_LAYOUT.getTagPose(ID); } + + /** + * Translation of the center of the REEF from the origin point (bottom left corner) of the + * field. Measured in meters + */ + public static final Translation2d REEF_CENTER_TRANSLATION = + new Translation2d(Units.inchesToMeters(176.746), FIELD_WIDTH / 2.0); + + /** A Map that links the BRANCH letter to its position on the field as a {@link Pose2d} */ + public static final Map BRANCH_POSES = new HashMap<>(); + /** + * The center of each face of the REEF, aka where the AprilTag is located. Definded starting at + * the inner face (facing towards opposite alliance side) in clockwise order + */ + public static final Pose2d[] CENTER_FACES = new Pose2d[6]; + /** Distance from the BRANCH to the REEF face wall in meters */ + public static final double BRANCH_TO_WALL_X_M = Units.inchesToMeters(7); + + static { + // Initialize faces starting from inner face and in clockwise order + CENTER_FACES[0] = getAprilTagPose(21).get().toPose2d(); + CENTER_FACES[1] = getAprilTagPose(22).get().toPose2d(); + CENTER_FACES[2] = getAprilTagPose(17).get().toPose2d(); + CENTER_FACES[3] = getAprilTagPose(18).get().toPose2d(); + CENTER_FACES[4] = getAprilTagPose(19).get().toPose2d(); + CENTER_FACES[5] = getAprilTagPose(20).get().toPose2d(); + /** + * Letters of BRANCHES in same order as faces, first 6 are left BRANCHES, last 6 are right + * BRANCHES + */ + String BRANCH_LETTERS = "GECAKIHFDBLJ"; + /** Hypotenuse from AprilTag to BRANCH */ + double ARPILTAG_TO_BRANCH_HYPOT_M = Units.inchesToMeters(13); + /** Angle from AprilTag to BRANCH that the hypotenuse makes */ + double ARPILTAG_TO_BRANCH_ANGLE_RAD = Units.degreesToRadians(30); + + // Initialize BRANCH poses + for (int i = 0; i < 6; i++) { + // Left BRANCH of REEF face + var leftBranch = + new Pose2d( + CENTER_FACES[i].getX() + + (-ARPILTAG_TO_BRANCH_HYPOT_M + * Math.cos( + ARPILTAG_TO_BRANCH_ANGLE_RAD + + CENTER_FACES[i].getRotation().getRadians())), + CENTER_FACES[i].getY() + + (-ARPILTAG_TO_BRANCH_HYPOT_M + * Math.sin( + ARPILTAG_TO_BRANCH_ANGLE_RAD + + CENTER_FACES[i].getRotation().getRadians())), + CENTER_FACES[i].getRotation()); + + // Right BRANCH of REEF face + var rightBranch = + new Pose2d( + CENTER_FACES[i].getX() + + (-ARPILTAG_TO_BRANCH_HYPOT_M + * Math.cos( + -ARPILTAG_TO_BRANCH_ANGLE_RAD + + CENTER_FACES[i].getRotation().getRadians())), + CENTER_FACES[i].getY() + + (-ARPILTAG_TO_BRANCH_HYPOT_M + * Math.sin( + -ARPILTAG_TO_BRANCH_ANGLE_RAD + + CENTER_FACES[i].getRotation().getRadians())), + CENTER_FACES[i].getRotation()); + + // Map poses to corresponding BRANCH letter + BRANCH_POSES.put(BRANCH_LETTERS.substring(i, i + 1), leftBranch); + BRANCH_POSES.put(BRANCH_LETTERS.substring(i + 6, i + 7), rightBranch); + } + } } /** Constants for PathPlanner configurations and Pathfinding */ @@ -162,8 +245,9 @@ public final class PathPlannerConstants { /* Pathfinding */ /** Max translational and rotational velocity and acceleration used for Pathfinding */ public static final PathConstraints DEFAULT_PATH_CONSTRAINTS = - new PathConstraints(3, 3, Units.degreesToRadians(515.65), Units.degreesToRadians(262.82)); - /** Default distnace away from an AprilTag the robot should be when Pathfinding to it */ - public static final double DEFAULT_APRILTAG_DISTANCE_M = Units.inchesToMeters(8); + new PathConstraints( + 5.2, 5.2, Units.degreesToRadians(515.65), Units.degreesToRadians(262.82)); + /** Default distance away from any wall when the robot is Pathfinding towards one */ + public static final double DEFAULT_WALL_DISTANCE_M = Units.inchesToMeters(6); } } diff --git a/src/main/java/frc/robot/Robot.java b/src/main/java/frc/robot/Robot.java index cbf97b6..a29ec10 100644 --- a/src/main/java/frc/robot/Robot.java +++ b/src/main/java/frc/robot/Robot.java @@ -86,7 +86,7 @@ public Robot() { * 3: Commit number (of this branch), * 4: Functionality: 0 = working, 1 = WIP, 2 = doesn't work */ - SmartDashboard.putString("Version Number", "23.0.23.0"); + SmartDashboard.putString("Version Number", "24.0.24.0"); SmartDashboard.putString("Last Deployed: ", BuildConstants.BUILD_DATE); // Run a warmup command for the Pathfinder because the first command can potentially have a diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index fc53831..f417d04 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -273,36 +273,39 @@ private void driverControllerBindings() { .x() .onTrue( PathfindingCommands.pathfindToCurrentTag( - m_visionSubsystem, () -> PathPlannerConstants.DEFAULT_APRILTAG_DISTANCE_M) - .until(m_driverController.x().negate())); + m_driveSubsystem, + m_visionSubsystem, + () -> PathPlannerConstants.DEFAULT_WALL_DISTANCE_M, + m_driverController.x().negate())); // AprilTag 18 - REEF m_driverController .leftTrigger() .onTrue( PathfindingCommands.pathfindToAprilTag( - () -> 18, () -> PathPlannerConstants.DEFAULT_APRILTAG_DISTANCE_M) + () -> 18, () -> PathPlannerConstants.DEFAULT_WALL_DISTANCE_M) .until(m_driverController.leftTrigger().negate())); // AprilTag 17 - REEF m_driverController .leftBumper() .onTrue( PathfindingCommands.pathfindToAprilTag( - () -> 17, () -> PathPlannerConstants.DEFAULT_APRILTAG_DISTANCE_M) + () -> 17, () -> PathPlannerConstants.DEFAULT_WALL_DISTANCE_M) .until(m_driverController.leftBumper().negate())); // AprilTag 19 - REEF m_driverController .rightTrigger() .onTrue( PathfindingCommands.pathfindToAprilTag( - () -> 19, () -> PathPlannerConstants.DEFAULT_APRILTAG_DISTANCE_M) + () -> 19, () -> PathPlannerConstants.DEFAULT_WALL_DISTANCE_M) .until(m_driverController.rightTrigger().negate())); - // AprilTag 14 - BARGE Net + // Closest REEF BRANCH m_driverController .rightBumper() .onTrue( - PathfindingCommands.pathfindToAprilTag( - () -> 14, () -> PathPlannerConstants.DEFAULT_APRILTAG_DISTANCE_M) - .until(m_driverController.rightBumper().negate())); + PathfindingCommands.pathfindToClosestReef( + m_driveSubsystem, + () -> PathPlannerConstants.DEFAULT_WALL_DISTANCE_M, + m_driverController.rightBumper().negate())); } /** Aux Controls */ @@ -362,6 +365,7 @@ public void auxControllerBindings() { Commands.run( () -> { m_funnelSubsystem.enablePID(true); + m_funnelSubsystem.setSetpoint(Units.rotationsPerMinuteToRadiansPerSecond(1000)); }, m_funnelSubsystem)) @@ -436,14 +440,15 @@ public Command getAutonomousCommand() { /** * Sets all mechanisms to brake mode, intended for use when the robot is disabled. * - * @param enable - True to set brake mode, False to set coast mode + * @param enable {@code true} to enable brake mode, {@code false} to enable coast mode. */ public void allMechanismsBrakeMode(boolean enable) { m_driveSubsystem.enableBrakeModeAll(enable); - m_climberSubsystem.enableBrakeMode(enable); - m_AEESubsystem.enableBrakeMode(enable); m_algaePivotSubsystem.enableBrakeMode(enable); - m_funnelSubsystem.enableBrakeMode(enable); m_periscopeSubsystem.enableBrakeMode(enable); + m_climberSubsystem.enableBrakeMode(enable); + m_funnelSubsystem.enableBrakeMode(enable); + m_AEESubsystem.enableBrakeMode(enable); + m_CEESubsystem.enableBrakeMode(enable); } } diff --git a/src/main/java/frc/robot/Subsystems/Vision/Vision.java b/src/main/java/frc/robot/Subsystems/Vision/Vision.java index e4afb8f..4f8c1b1 100644 --- a/src/main/java/frc/robot/Subsystems/Vision/Vision.java +++ b/src/main/java/frc/robot/Subsystems/Vision/Vision.java @@ -79,7 +79,7 @@ public void periodic() { var target = currentResult.getBestTarget(); if (target.getFiducialId() >= 1 && target.getFiducialId() <= 22 - && target.getPoseAmbiguity() > 0.0 + && target.getPoseAmbiguity() >= 0.0 && target.getPoseAmbiguity() <= 0.2) { var estimatedPose = m_photonPoseEstimators[i].update(currentResult); if (estimatedPose.isEmpty()) diff --git a/src/main/java/frc/robot/Subsystems/Vision/VisionConstants.java b/src/main/java/frc/robot/Subsystems/Vision/VisionConstants.java index b5082f3..69c10d1 100644 --- a/src/main/java/frc/robot/Subsystems/Vision/VisionConstants.java +++ b/src/main/java/frc/robot/Subsystems/Vision/VisionConstants.java @@ -28,13 +28,16 @@ public enum CAMERA { /** 3d offset of the center of the robot to the Front camera */ private static final Transform3d FRONT_CAMERA_ROBOT_OFFSET = new Transform3d( - new Translation3d(Units.inchesToMeters(13.5), 0, Units.inchesToMeters(3.5)), - new Rotation3d(0, 0, 0)); + new Translation3d( + Units.inchesToMeters(13.75), + Units.inchesToMeters(-5.5), + Units.inchesToMeters(5.375)), // measured extremely accurately + new Rotation3d(Math.PI / 2, Units.degreesToRadians(-25), 0)); /** 3d offset of the center of the robot to the Back camera */ private static final Transform3d BACK_CAMERA_ROBOT_OFFSET = new Transform3d( new Translation3d(Units.inchesToMeters(-13.5), 0, Units.inchesToMeters(3.5)), - new Rotation3d(0, Units.degreesToRadians(35), Math.PI)); + new Rotation3d(0, Units.degreesToRadians(-25), Math.PI)); /** Array of 3d transformations from the center of the robot to each camera location */ public static final Transform3d[] CAMERA_ROBOT_OFFSETS = { FRONT_CAMERA_ROBOT_OFFSET, BACK_CAMERA_ROBOT_OFFSET