From 393a1f3b77376c4148c8c86cdc904a8583afad7a Mon Sep 17 00:00:00 2001 From: rkris28 Date: Wed, 8 Oct 2025 20:34:44 -0400 Subject: [PATCH 1/5] Shooting Testing Shooting Testing --- src/main/java/frc/robot/Orchestrator.java | 2 +- src/main/java/frc/robot/RobotContainer.java | 29 +++++++++++------ .../frc/robot/subsystems/shooter/Shooter.java | 31 +++++++++++++++++-- .../subsystems/shooter/ShooterConstants.java | 4 +-- 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/main/java/frc/robot/Orchestrator.java b/src/main/java/frc/robot/Orchestrator.java index f1d1b2d..9d0c90f 100644 --- a/src/main/java/frc/robot/Orchestrator.java +++ b/src/main/java/frc/robot/Orchestrator.java @@ -21,7 +21,7 @@ public Orchestrator(Indexer indexer, Shooter shooter) { public Command spinUp(BooleanSupplier fastMode) { return Commands.either( shooter.fullSpeed(), - shooter.speedUp(), + shooter.speedUp_80Percent(), fastMode); } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 5274408..428e94d 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -17,7 +17,6 @@ import frc.robot.subsystems.shooter.Shooter; import frc.robot.subsystems.shooter.ShooterIOSparkMax; import frc.robot.subsystems.vision.Vision; -import frc.robot.subsystems.vision.VisionIO; import frc.robot.subsystems.vision.VisionIOPhotonVision; @@ -31,7 +30,6 @@ public class RobotContainer { // The robot's subsystems and commands are defined here... private final Drive drive; // The robot's subsystems and commands are defined here... - private final Vision vision; private final Indexer indexer = new Indexer(new IndexerIOSparkMax()); private final Shooter shooter = new Shooter(new ShooterIOSparkMax()); private final Orchestrator orchestrator = new Orchestrator(indexer, shooter); @@ -44,7 +42,6 @@ public class RobotContainer { public RobotContainer() { // Configure the trigger bindings drive = new Drive(new DriveIOSparkMax()); - vision = new Vision(new VisionIOPhotonVision("VGA_USB_Camera"){}); configureBindings(); } @@ -75,16 +72,30 @@ private void configureBindings() { .rightTrigger() .whileTrue(orchestrator.shootCycle(() -> fastMode)) .onFalse(orchestrator.stopAll()); - driverController.y().whileTrue(shooter.speedUp()).onFalse(shooter.stop()); - driverController - .leftTrigger() - .whileTrue(orchestrator.reverseAll()) - .onFalse(orchestrator.stopAll()); - + driverController .rightBumper() .onTrue(orchestrator.shootOnce(() -> fastMode)) .onFalse(orchestrator.stopAll()); + + driverController.x().whileTrue(shooter.speedUp_20Percent()).onFalse(shooter.stop()); + + driverController.b().whileTrue(shooter.speedUp_40Percent()).onFalse(shooter.stop()); + + driverController.start().whileTrue(shooter.speedUp_60Percent()).onFalse(shooter.stop()); + + driverController.leftTrigger().onTrue(indexer.indexUntilSwitch()); + + driverController.y().onTrue(indexer.indexIntoShooter()); + + + driverController + .leftBumper() + .whileTrue(orchestrator.reverseAll()) + .onFalse(orchestrator.stopAll()); + + + } /** diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index 52e56b4..4542335 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -37,10 +37,37 @@ public Command reverse() { } - public Command speedUp() { + public Command speedUp_60Percent() { return Commands.run( () -> { - io.setPercent(ShooterConstants.SPEED); + io.setPercent(0.6); + }, + this + ); + } + + public Command speedUp_80Percent() { + return Commands.run( + () -> { + io.setPercent(0.8); + }, + this + ); + } + + public Command speedUp_40Percent() { + return Commands.run( + () -> { + io.setPercent(0.4); + }, + this + ); + } + + public Command speedUp_20Percent() { + return Commands.run( + () -> { + io.setPercent(0.2); }, this ); diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java index de81527..2b28620 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java @@ -2,8 +2,6 @@ public class ShooterConstants { - public static final double SPEED = 0.8; - public static final double REVERSE_SHOOTER_PERCENT = -0.5; public static final int SHOOTER_MOTOR_ID = 8; @@ -12,5 +10,5 @@ public class ShooterConstants { public static final double ENCODER_VELOCITY_CONVERSION = 1.0; - public static final double SPINUP_SECONDS = 0.1; + public static final double SPINUP_SECONDS = 0.6; } \ No newline at end of file From 9e62d5ef89270ba5b5611714a2bd12fd56166cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ShayanH=C3=A1sHackedThis?= Date: Wed, 8 Oct 2025 20:50:48 -0400 Subject: [PATCH 2/5] regression line --- src/main/java/frc/robot/RobotContainer.java | 2 +- .../java/frc/robot/subsystems/shooter/Shooter.java | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index 428e94d..f096a95 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -78,7 +78,7 @@ private void configureBindings() { .onTrue(orchestrator.shootOnce(() -> fastMode)) .onFalse(orchestrator.stopAll()); - driverController.x().whileTrue(shooter.speedUp_20Percent()).onFalse(shooter.stop()); + driverController.x().whileTrue(shooter.speedUp_Distance(300.0)).onFalse(shooter.stop()); driverController.b().whileTrue(shooter.speedUp_40Percent()).onFalse(shooter.stop()); diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index 4542335..56e13b7 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -36,7 +36,15 @@ public Command reverse() { ); } - + public Command speedUp_Distance(Double distance) { + return Commands.run( + () -> { + double percent = (8.331 * Math.pow(10,-5)*Math.pow(distance,2) - 0.0734*distance + 15.709)/100; + io.setPercent(percent); + }, + this + ); + } public Command speedUp_60Percent() { return Commands.run( () -> { From 6ce40c4a4678c2d3ed613e87a20aa539e4358a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ShayanH=C3=A1sHackedThis?= Date: Wed, 15 Oct 2025 22:05:24 -0400 Subject: [PATCH 3/5] fixed regression line, implemented shooting functions --- src/main/java/frc/robot/Orchestrator.java | 22 +++++++- src/main/java/frc/robot/RobotContainer.java | 6 +-- .../frc/robot/subsystems/shooter/Shooter.java | 51 +++---------------- 3 files changed, 28 insertions(+), 51 deletions(-) diff --git a/src/main/java/frc/robot/Orchestrator.java b/src/main/java/frc/robot/Orchestrator.java index 9d0c90f..14cc9bb 100644 --- a/src/main/java/frc/robot/Orchestrator.java +++ b/src/main/java/frc/robot/Orchestrator.java @@ -7,21 +7,41 @@ import frc.robot.subsystems.indexer.Indexer; import frc.robot.subsystems.shooter.Shooter; import frc.robot.subsystems.shooter.ShooterConstants; +import org.littletonrobotics.junction.AutoLogOutput; +import org.littletonrobotics.junction.Logger; public class Orchestrator { private final Indexer indexer; private final Shooter shooter; + @AutoLogOutput + private double Distance = 300.0; + @AutoLogOutput private double shootingPower = 0.0; public Orchestrator(Indexer indexer, Shooter shooter) { this.indexer = indexer; this.shooter = shooter; } + public Command spinUpDistance(Double distance) { + Distance = distance; + double percent = (8.331 * Math.pow(10, -5) * Math.pow(distance, 2) + 0.0734 * distance + 15.709) / 100; + Logger.recordOutput("Shooter/Percent", percent); + return shooter.runPercent(percent); + } + public Command shootCycleDistance() { + return Commands.parallel( + spinUpDistance(420.0), + Commands.sequence( + intakeIfNeeded(), + Commands.waitSeconds(ShooterConstants.SPINUP_SECONDS), + indexer.indexIntoShooter()) + .repeatedly()); + } public Command spinUp(BooleanSupplier fastMode) { return Commands.either( shooter.fullSpeed(), - shooter.speedUp_80Percent(), + shooter.runPercent(0.8), fastMode); } diff --git a/src/main/java/frc/robot/RobotContainer.java b/src/main/java/frc/robot/RobotContainer.java index f096a95..720d12d 100644 --- a/src/main/java/frc/robot/RobotContainer.java +++ b/src/main/java/frc/robot/RobotContainer.java @@ -78,11 +78,7 @@ private void configureBindings() { .onTrue(orchestrator.shootOnce(() -> fastMode)) .onFalse(orchestrator.stopAll()); - driverController.x().whileTrue(shooter.speedUp_Distance(300.0)).onFalse(shooter.stop()); - - driverController.b().whileTrue(shooter.speedUp_40Percent()).onFalse(shooter.stop()); - - driverController.start().whileTrue(shooter.speedUp_60Percent()).onFalse(shooter.stop()); + driverController.x().whileTrue(orchestrator.shootCycleDistance()).onFalse(shooter.stop()); driverController.leftTrigger().onTrue(indexer.indexUntilSwitch()); diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index 56e13b7..93fe0ff 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -36,51 +36,6 @@ public Command reverse() { ); } - public Command speedUp_Distance(Double distance) { - return Commands.run( - () -> { - double percent = (8.331 * Math.pow(10,-5)*Math.pow(distance,2) - 0.0734*distance + 15.709)/100; - io.setPercent(percent); - }, - this - ); - } - public Command speedUp_60Percent() { - return Commands.run( - () -> { - io.setPercent(0.6); - }, - this - ); - } - - public Command speedUp_80Percent() { - return Commands.run( - () -> { - io.setPercent(0.8); - }, - this - ); - } - - public Command speedUp_40Percent() { - return Commands.run( - () -> { - io.setPercent(0.4); - }, - this - ); - } - - public Command speedUp_20Percent() { - return Commands.run( - () -> { - io.setPercent(0.2); - }, - this - ); - } - public Command fullSpeed() { return Commands.run( () -> { @@ -89,6 +44,12 @@ public Command fullSpeed() { this ); } + public Command runPercent(double percent){ + return Commands.run(() -> { + io.setPercent(percent); + }, + this); + } } From ebe72069fa97f728a0592668033cfabe7710bbcf Mon Sep 17 00:00:00 2001 From: Ronit Sharma Date: Mon, 20 Oct 2025 20:25:56 -0400 Subject: [PATCH 4/5] Pushing Tasked Files - Not Fully Finished --- .gitignore | 2 +- src/main/java/frc/robot/Orchestrator.java | 1 - .../frc/robot/lib/utils/TunableNumber.java | 115 ++++++++++++++++++ .../frc/robot/subsystems/shooter/Shooter.java | 7 +- .../subsystems/shooter/ShooterConstants.java | 43 ++++++- .../robot/subsystems/shooter/ShooterIO.java | 7 +- .../subsystems/shooter/ShooterIOSparkMax.java | 51 ++++++-- 7 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 src/main/java/frc/robot/lib/utils/TunableNumber.java diff --git a/.gitignore b/.gitignore index 9a9ca7b..1055d0a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ *.lai *.la *.a -*.lib +*.frc.robot.lib # Executables *.exe diff --git a/src/main/java/frc/robot/Orchestrator.java b/src/main/java/frc/robot/Orchestrator.java index 14cc9bb..01db1b9 100644 --- a/src/main/java/frc/robot/Orchestrator.java +++ b/src/main/java/frc/robot/Orchestrator.java @@ -40,7 +40,6 @@ public Command shootCycleDistance() { public Command spinUp(BooleanSupplier fastMode) { return Commands.either( - shooter.fullSpeed(), shooter.runPercent(0.8), fastMode); } diff --git a/src/main/java/frc/robot/lib/utils/TunableNumber.java b/src/main/java/frc/robot/lib/utils/TunableNumber.java new file mode 100644 index 0000000..1d61c2d --- /dev/null +++ b/src/main/java/frc/robot/lib/utils/TunableNumber.java @@ -0,0 +1,115 @@ +package frc.lib.utils; + +import frc.robot.Constants; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.DoubleSupplier; +import org.littletonrobotics.junction.networktables.LoggedNetworkNumber; + +/** + * Class for a tunable number. Gets value from dashboard in tuning mode, returns default if not or + * value not in dashboard. + */ +public class TunableNumber implements DoubleSupplier { + private static final String tableKey = "/Tuning"; + + private final String key; + private boolean hasDefault = false; + private double defaultValue; + private LoggedNetworkNumber dashboardNumber; + private Map lastHasChangedValues = new HashMap<>(); + + /** + * Create a new LoggedTunableNumber + * + * @param dashboardKey Key on dashboard + */ + public TunableNumber(String dashboardKey) { + this.key = tableKey + "/" + dashboardKey; + } + + /** + * Create a new LoggedTunableNumber with the default value + * + * @param dashboardKey Key on dashboard + * @param defaultValue Default value + */ + public TunableNumber(String dashboardKey, double defaultValue) { + this(dashboardKey); + initDefault(defaultValue); + } + + /** + * Set the default value of the number. The default value can only be set once. + * + * @param defaultValue The default value + */ + public void initDefault(double defaultValue) { + if (!hasDefault) { + hasDefault = true; + this.defaultValue = defaultValue; + if (Constants.tuningMode) { + dashboardNumber = new LoggedNetworkNumber(key, defaultValue); + } + } + } + + /** + * Get the current value, from dashboard if available and in tuning mode. + * + * @return The current value + */ + public double get() { + if (!hasDefault) { + return 0.0; + } else { + return Constants.tuningMode ? dashboardNumber.get() : defaultValue; + } + } + + /** + * Checks whether the number has changed since our last check + * + * @param id Unique identifier for the caller to avoid conflicts when shared between multiple + * objects. Recommended approach is to pass the result of "hashCode()" + * @return True if the number has changed since the last time this method was called, false + * otherwise. + */ + public boolean hasChanged(int id) { + double currentValue = get(); + Double lastValue = lastHasChangedValues.get(id); + if (lastValue == null || currentValue != lastValue) { + lastHasChangedValues.put(id, currentValue); + return true; + } + + return false; + } + + /** + * Runs action if any of the tunableNumbers have changed + * + * @param id Unique identifier for the caller to avoid conflicts when shared between multiple * + * objects. Recommended approach is to pass the result of "hashCode()" + * @param action Callback to run when any of the tunable numbers have changed. Access tunable + * numbers in order inputted in method + * @param tunableNumbers All tunable numbers to check + */ + public static void ifChanged(int id, Consumer action, TunableNumber... tunableNumbers) { + if (Arrays.stream(tunableNumbers).anyMatch(tunableNumber -> tunableNumber.hasChanged(id))) { + action.accept(Arrays.stream(tunableNumbers).mapToDouble(TunableNumber::get).toArray()); + } + } + + /** Runs action if any of the tunableNumbers have changed */ + public static void ifChanged(int id, Runnable action, TunableNumber... tunableNumbers) { + ifChanged(id, values -> action.run(), tunableNumbers); + } + + @Override + public double getAsDouble() { + return get(); + } +} diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index 93fe0ff..3df65ae 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -36,11 +36,10 @@ public Command reverse() { ); } - public Command fullSpeed() { + + public Command toVelocity(double velocity) { return Commands.run( - () -> { - io.setPercent(1); - }, + () -> io.setVelocity(velocity), this ); } diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java index 2b28620..4aa5a9a 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java @@ -1,14 +1,49 @@ package frc.robot.subsystems.shooter; +import frc.robot.Constants; +import frc.lib.utils.TunableNumber; + public class ShooterConstants { + public static final TunableNumber KS; + public static final TunableNumber KV; + public static final TunableNumber KP; + public static final TunableNumber KI; + public static final TunableNumber KD; - public static final double REVERSE_SHOOTER_PERCENT = -0.5; + public static final double TOLERANCE; + public static final double ENCODER_POSITION_CONVERSION_FACTOR; + public static final double ENCODER_VELOCITY_CONVERSION_FACTOR; + + public static final double REVERSE_SHOOTER_PERCENT = -0.5; public static final int SHOOTER_MOTOR_ID = 8; + public static final double SPINUP_SECONDS = 0.6; - public static final double ENCODER_POSITION_CONVERSION = 1.0; - public static final double ENCODER_VELOCITY_CONVERSION = 1.0; + static { + switch (Constants.getRobot()) { + case PARADE_DAY -> { + KS = new TunableNumber("Shooter/KS", 0.0); + KV = new TunableNumber("Shooter/KV", 0.0); + KP = new TunableNumber("Shooter/KP", 0.0001); + KI = new TunableNumber("Shooter/KI", 0.0); + KD = new TunableNumber("Shooter/KD", 0.0); - public static final double SPINUP_SECONDS = 0.6; + TOLERANCE = 0.0; + ENCODER_POSITION_CONVERSION_FACTOR = 1.0; + ENCODER_VELOCITY_CONVERSION_FACTOR = 1.0; // Already in RPM + } + default -> { + KS = new TunableNumber("Shooter/KS", 0.0); + KV = new TunableNumber("Shooter/KV", 0.0); + KP = new TunableNumber("Shooter/KP", 0.0); + KI = new TunableNumber("Shooter/KI", 0.0); + KD = new TunableNumber("Shooter/KD", 0.0); + + TOLERANCE = 0.0; + ENCODER_POSITION_CONVERSION_FACTOR = 0.0; + ENCODER_VELOCITY_CONVERSION_FACTOR = 0.0; + } + } + } } \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java b/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java index 2a6a301..07a3fe7 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java @@ -7,15 +7,10 @@ public interface ShooterIO { @AutoLog class ShooterIOInputs { - public double velocity; - public double appliedVolts; - public double currentAmps; - public double temperature; - public boolean readyToShoot = false; } @@ -23,6 +18,8 @@ default void updateInputs(ShooterIOInputs inputs) {} default void setPercent(double percent) {} + default void setVelocity(double velocity) {} + default void setVoltage(double voltage) {} default void stop() {} diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java b/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java index 70c2267..5a9666c 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java @@ -3,12 +3,12 @@ import static frc.robot.subsystems.shooter.ShooterConstants.*; import com.revrobotics.RelativeEncoder; +import com.revrobotics.spark.*; +import com.revrobotics.spark.SparkBase.ControlType; import com.revrobotics.spark.SparkBase.PersistMode; import com.revrobotics.spark.SparkBase.ResetMode; -import com.revrobotics.spark.SparkLimitSwitch; import com.revrobotics.spark.SparkLowLevel.MotorType; -import com.revrobotics.spark.SparkMax; -import com.revrobotics.spark.config.EncoderConfig; +import com.revrobotics.spark.config.ClosedLoopConfig; import com.revrobotics.spark.config.SparkBaseConfig.IdleMode; import com.revrobotics.spark.config.SparkMaxConfig; @@ -16,25 +16,37 @@ public class ShooterIOSparkMax implements ShooterIO { private final SparkMax motor; private final RelativeEncoder encoder; + private final SparkClosedLoopController controller; + + private double targetVelocityRPM = 0.0; public ShooterIOSparkMax() { motor = new SparkMax(SHOOTER_MOTOR_ID, MotorType.kBrushless); + encoder = motor.getEncoder(); + controller = motor.getClosedLoopController(); var config = new SparkMaxConfig(); config.inverted(false) - .idleMode(IdleMode.kBrake) + .idleMode(IdleMode.kCoast) // Coast mode for flywheels .voltageCompensation(12) .smartCurrentLimit(30); - EncoderConfig enc = new EncoderConfig(); - enc.positionConversionFactor(ENCODER_POSITION_CONVERSION); - enc.velocityConversionFactor(ENCODER_VELOCITY_CONVERSION); - config.apply(enc); + config.encoder + .positionConversionFactor(ENCODER_POSITION_CONVERSION_FACTOR) + .velocityConversionFactor(ENCODER_VELOCITY_CONVERSION_FACTOR); - motor.configure(config, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); + config.closedLoop + .feedbackSensor(ClosedLoopConfig.FeedbackSensor.kPrimaryEncoder) + .pidf(0.0001, 0.0, 0.0, 0.0); // Start with small P for velocity control - encoder = motor.getEncoder(); + config.signals + .primaryEncoderVelocityAlwaysOn(true) + .primaryEncoderVelocityPeriodMs(20) + .appliedOutputPeriodMs(20) + .busVoltagePeriodMs(20) + .outputCurrentPeriodMs(20); + motor.configure(config, ResetMode.kResetSafeParameters, PersistMode.kPersistParameters); } @Override @@ -43,17 +55,34 @@ public void updateInputs(ShooterIOInputs inputs) { inputs.appliedVolts = motor.getBusVoltage() * motor.getAppliedOutput(); inputs.currentAmps = motor.getOutputCurrent(); inputs.velocity = encoder.getVelocity(); + inputs.targetVelocityRPM = targetVelocityRPM; + + inputs.atTargetVelocity = + targetVelocityRPM > 0 && + Math.abs(targetVelocityRPM - inputs.velocity) < TOLERANCE; } + @Override public void setPercent(double percent) { + targetVelocityRPM = 0.0; // Not using velocity control motor.set(percent); } + @Override + public void setVelocity(double velocityRPM) { + this.targetVelocityRPM = velocityRPM; + controller.setReference(velocityRPM, ControlType.kVelocity); + } + + @Override public void setVoltage(double volts) { + targetVelocityRPM = 0.0; // Not using velocity control motor.setVoltage(volts); } + @Override public void stop() { + targetVelocityRPM = 0.0; motor.set(0); } -} +} \ No newline at end of file From d90421bcf365e90fc5117604e62202ab63e91931 Mon Sep 17 00:00:00 2001 From: Ronit Sharma Date: Tue, 21 Oct 2025 12:41:12 -0400 Subject: [PATCH 5/5] Cleaning up code and fixing minor errors Deleted the TunableNumber utility and removed all shooter tuning parameters from ShooterConstants. Shooter subsystem and IO classes were updated to use static constants and simplified velocity handling. Added fullSpeed command to Shooter and updated Orchestrator to use it for fastMode. --- src/main/java/frc/robot/Orchestrator.java | 5 +- .../frc/robot/lib/utils/TunableNumber.java | 115 ------------------ .../frc/robot/subsystems/shooter/Shooter.java | 13 +- .../subsystems/shooter/ShooterConstants.java | 43 +------ .../robot/subsystems/shooter/ShooterIO.java | 7 +- .../subsystems/shooter/ShooterIOSparkMax.java | 19 +-- 6 files changed, 30 insertions(+), 172 deletions(-) delete mode 100644 src/main/java/frc/robot/lib/utils/TunableNumber.java diff --git a/src/main/java/frc/robot/Orchestrator.java b/src/main/java/frc/robot/Orchestrator.java index 01db1b9..96b0550 100644 --- a/src/main/java/frc/robot/Orchestrator.java +++ b/src/main/java/frc/robot/Orchestrator.java @@ -40,8 +40,9 @@ public Command shootCycleDistance() { public Command spinUp(BooleanSupplier fastMode) { return Commands.either( + shooter.fullSpeed(), shooter.runPercent(0.8), - fastMode); + fastMode); } public Command intakeIfNeeded() { @@ -77,4 +78,4 @@ public Command reverseAll() { public Command stopAll() { return Commands.parallel(shooter.stop(), indexer.stop()); } -} +} \ No newline at end of file diff --git a/src/main/java/frc/robot/lib/utils/TunableNumber.java b/src/main/java/frc/robot/lib/utils/TunableNumber.java deleted file mode 100644 index 1d61c2d..0000000 --- a/src/main/java/frc/robot/lib/utils/TunableNumber.java +++ /dev/null @@ -1,115 +0,0 @@ -package frc.lib.utils; - -import frc.robot.Constants; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.DoubleSupplier; -import org.littletonrobotics.junction.networktables.LoggedNetworkNumber; - -/** - * Class for a tunable number. Gets value from dashboard in tuning mode, returns default if not or - * value not in dashboard. - */ -public class TunableNumber implements DoubleSupplier { - private static final String tableKey = "/Tuning"; - - private final String key; - private boolean hasDefault = false; - private double defaultValue; - private LoggedNetworkNumber dashboardNumber; - private Map lastHasChangedValues = new HashMap<>(); - - /** - * Create a new LoggedTunableNumber - * - * @param dashboardKey Key on dashboard - */ - public TunableNumber(String dashboardKey) { - this.key = tableKey + "/" + dashboardKey; - } - - /** - * Create a new LoggedTunableNumber with the default value - * - * @param dashboardKey Key on dashboard - * @param defaultValue Default value - */ - public TunableNumber(String dashboardKey, double defaultValue) { - this(dashboardKey); - initDefault(defaultValue); - } - - /** - * Set the default value of the number. The default value can only be set once. - * - * @param defaultValue The default value - */ - public void initDefault(double defaultValue) { - if (!hasDefault) { - hasDefault = true; - this.defaultValue = defaultValue; - if (Constants.tuningMode) { - dashboardNumber = new LoggedNetworkNumber(key, defaultValue); - } - } - } - - /** - * Get the current value, from dashboard if available and in tuning mode. - * - * @return The current value - */ - public double get() { - if (!hasDefault) { - return 0.0; - } else { - return Constants.tuningMode ? dashboardNumber.get() : defaultValue; - } - } - - /** - * Checks whether the number has changed since our last check - * - * @param id Unique identifier for the caller to avoid conflicts when shared between multiple - * objects. Recommended approach is to pass the result of "hashCode()" - * @return True if the number has changed since the last time this method was called, false - * otherwise. - */ - public boolean hasChanged(int id) { - double currentValue = get(); - Double lastValue = lastHasChangedValues.get(id); - if (lastValue == null || currentValue != lastValue) { - lastHasChangedValues.put(id, currentValue); - return true; - } - - return false; - } - - /** - * Runs action if any of the tunableNumbers have changed - * - * @param id Unique identifier for the caller to avoid conflicts when shared between multiple * - * objects. Recommended approach is to pass the result of "hashCode()" - * @param action Callback to run when any of the tunable numbers have changed. Access tunable - * numbers in order inputted in method - * @param tunableNumbers All tunable numbers to check - */ - public static void ifChanged(int id, Consumer action, TunableNumber... tunableNumbers) { - if (Arrays.stream(tunableNumbers).anyMatch(tunableNumber -> tunableNumber.hasChanged(id))) { - action.accept(Arrays.stream(tunableNumbers).mapToDouble(TunableNumber::get).toArray()); - } - } - - /** Runs action if any of the tunableNumbers have changed */ - public static void ifChanged(int id, Runnable action, TunableNumber... tunableNumbers) { - ifChanged(id, values -> action.run(), tunableNumbers); - } - - @Override - public double getAsDouble() { - return get(); - } -} diff --git a/src/main/java/frc/robot/subsystems/shooter/Shooter.java b/src/main/java/frc/robot/subsystems/shooter/Shooter.java index 3df65ae..75d752c 100644 --- a/src/main/java/frc/robot/subsystems/shooter/Shooter.java +++ b/src/main/java/frc/robot/subsystems/shooter/Shooter.java @@ -37,9 +37,17 @@ public Command reverse() { } - public Command toVelocity(double velocity) { + public Command toVelocity(double velocityRPM) { return Commands.run( - () -> io.setVelocity(velocity), + () -> io.setVelocity(velocityRPM), + this + ); + } + public Command fullSpeed() { + return Commands.run( + () -> { + io.setPercent(1); + }, this ); } @@ -50,5 +58,4 @@ public Command runPercent(double percent){ this); } - } diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java index 4aa5a9a..a44339a 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterConstants.java @@ -1,49 +1,12 @@ package frc.robot.subsystems.shooter; -import frc.robot.Constants; -import frc.lib.utils.TunableNumber; - public class ShooterConstants { - public static final TunableNumber KS; - public static final TunableNumber KV; - public static final TunableNumber KP; - public static final TunableNumber KI; - public static final TunableNumber KD; - - public static final double TOLERANCE; - - public static final double ENCODER_POSITION_CONVERSION_FACTOR; - public static final double ENCODER_VELOCITY_CONVERSION_FACTOR; + public static final double TOLERANCE = 0.0; + public static final double ENCODER_POSITION_CONVERSION_FACTOR = 1.0; + public static final double ENCODER_VELOCITY_CONVERSION_FACTOR = 1.0; public static final double REVERSE_SHOOTER_PERCENT = -0.5; public static final int SHOOTER_MOTOR_ID = 8; public static final double SPINUP_SECONDS = 0.6; - - static { - switch (Constants.getRobot()) { - case PARADE_DAY -> { - KS = new TunableNumber("Shooter/KS", 0.0); - KV = new TunableNumber("Shooter/KV", 0.0); - KP = new TunableNumber("Shooter/KP", 0.0001); - KI = new TunableNumber("Shooter/KI", 0.0); - KD = new TunableNumber("Shooter/KD", 0.0); - - TOLERANCE = 0.0; - ENCODER_POSITION_CONVERSION_FACTOR = 1.0; - ENCODER_VELOCITY_CONVERSION_FACTOR = 1.0; // Already in RPM - } - default -> { - KS = new TunableNumber("Shooter/KS", 0.0); - KV = new TunableNumber("Shooter/KV", 0.0); - KP = new TunableNumber("Shooter/KP", 0.0); - KI = new TunableNumber("Shooter/KI", 0.0); - KD = new TunableNumber("Shooter/KD", 0.0); - - TOLERANCE = 0.0; - ENCODER_POSITION_CONVERSION_FACTOR = 0.0; - ENCODER_VELOCITY_CONVERSION_FACTOR = 0.0; - } - } - } } \ No newline at end of file diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java b/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java index 07a3fe7..185f43b 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterIO.java @@ -1,16 +1,17 @@ package frc.robot.subsystems.shooter; -import org.ejml.dense.row.factory.DecompositionFactory_CDRM; import org.littletonrobotics.junction.AutoLog; public interface ShooterIO { @AutoLog class ShooterIOInputs { - public double velocity; + public double velocityRPM; public double appliedVolts; public double currentAmps; public double temperature; + public double targetVelocityRPM = 0.0; + public boolean atTargetVelocity; public boolean readyToShoot = false; } @@ -18,7 +19,7 @@ default void updateInputs(ShooterIOInputs inputs) {} default void setPercent(double percent) {} - default void setVelocity(double velocity) {} + default void setVelocity(double velocityRPM) {} default void setVoltage(double voltage) {} diff --git a/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java b/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java index 5a9666c..22825de 100644 --- a/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java +++ b/src/main/java/frc/robot/subsystems/shooter/ShooterIOSparkMax.java @@ -27,19 +27,22 @@ public ShooterIOSparkMax() { var config = new SparkMaxConfig(); config.inverted(false) - .idleMode(IdleMode.kCoast) // Coast mode for flywheels + .idleMode(IdleMode.kCoast) .voltageCompensation(12) .smartCurrentLimit(30); - config.encoder + config + .encoder .positionConversionFactor(ENCODER_POSITION_CONVERSION_FACTOR) .velocityConversionFactor(ENCODER_VELOCITY_CONVERSION_FACTOR); - config.closedLoop + config + .closedLoop .feedbackSensor(ClosedLoopConfig.FeedbackSensor.kPrimaryEncoder) - .pidf(0.0001, 0.0, 0.0, 0.0); // Start with small P for velocity control + .pidf(0.0001, 0.0, 0.0, 0.0); - config.signals + config + .signals .primaryEncoderVelocityAlwaysOn(true) .primaryEncoderVelocityPeriodMs(20) .appliedOutputPeriodMs(20) @@ -54,17 +57,16 @@ public void updateInputs(ShooterIOInputs inputs) { inputs.temperature = motor.getMotorTemperature(); inputs.appliedVolts = motor.getBusVoltage() * motor.getAppliedOutput(); inputs.currentAmps = motor.getOutputCurrent(); - inputs.velocity = encoder.getVelocity(); + inputs.velocityRPM = encoder.getVelocity(); inputs.targetVelocityRPM = targetVelocityRPM; inputs.atTargetVelocity = targetVelocityRPM > 0 && - Math.abs(targetVelocityRPM - inputs.velocity) < TOLERANCE; + Math.abs(targetVelocityRPM - inputs.velocityRPM) < TOLERANCE; } @Override public void setPercent(double percent) { - targetVelocityRPM = 0.0; // Not using velocity control motor.set(percent); } @@ -76,7 +78,6 @@ public void setVelocity(double velocityRPM) { @Override public void setVoltage(double volts) { - targetVelocityRPM = 0.0; // Not using velocity control motor.setVoltage(volts); }