001/** 002 * ********************** PROJECT RON ************************ 003 */ 004/* Copyright (c) 2026 StuyPulse Robotics. All rights reserved. */ 005/* Use of this source code is governed by an MIT-style license */ 006/* that can be found in the repository LICENSE file. */ 007/** 008 * *********************************************************** 009 */ 010package com.stuypulse.robot.constants; 011 012import static edu.wpi.first.units.Units.*; 013import edu.wpi.first.math.VecBuilder; 014import edu.wpi.first.math.Vector; 015import edu.wpi.first.math.geometry.Pose2d; 016import edu.wpi.first.math.geometry.Rotation2d; 017import edu.wpi.first.math.numbers.N3; 018import edu.wpi.first.math.util.Units; 019import edu.wpi.first.networktables.BooleanSubscriber; 020import edu.wpi.first.networktables.DoubleSubscriber; 021import edu.wpi.first.units.*; 022import edu.wpi.first.units.measure.*; 023import edu.wpi.first.wpilibj.LEDPattern; 024import edu.wpi.first.wpilibj.simulation.SingleJointedArmSim; 025import edu.wpi.first.wpilibj.util.Color; 026import com.ctre.phoenix6.CANBus; 027import dev.doglog.DogLog; 028 029import com.pathplanner.lib.path.PathConstraints; 030 031/*- 032 * File containing tunable settings for every subsystem on the robot. 033 * 034 * We use DogLog's tunables in order to have tunable 035 * values that we can edit on whatever dashboard we 036 * are using. 037 */ 038public interface Settings { 039 040 Time DT = Seconds.of(0.020); 041 042 boolean DEBUG_MODE = true; 043 044 CANBus CANBUS = new CANBus("rio"); 045 046 public interface EnabledSubsystems { 047 048 BooleanSubscriber FEEDER = DogLog.tunable("Enabled Subsystems/Feeder", true); 049 050 BooleanSubscriber INTAKE = DogLog.tunable("Enabled Subsystems/Intake", true); 051 052 // BooleanSubscriber INTAKE_ROLLERS = DogLog.tunable("Enabled Subsystems/Intake/Rollers", true); 053 054 // BooleanSubscriber INTAKE_PIVOT = DogLog.tunable("Enabled Subsystems/Intake/Pivot", true); 055 056 BooleanSubscriber LED = DogLog.tunable("Enabled Subsystems/LED", false); 057 058 BooleanSubscriber HANDOFF = DogLog.tunable("Enabled Subsystems/Handoff", true); 059 060 BooleanSubscriber SHOOTER = DogLog.tunable("Enabled Subsystems/Shooter", true); 061 062 BooleanSubscriber VISION = DogLog.tunable("Enabled Subsystems/Vision", true); 063 064 BooleanSubscriber SWERVE = DogLog.tunable("Enabled Subsystems/Swerve", true); 065 } 066 067 public interface Vision { 068 069 // TODO: These numbers are temporary, may need testing 070 public final Vector<N3> MT1_STDEVS = VecBuilder.fill(0.5, 0.5, 1.0); 071 072 public final Vector<N3> MT2_STDEVS = VecBuilder.fill(0.7, 0.7, 694694.0); 073 074 public final Pose2d INVALID_POSITION = Pose2d.kZero; 075 076 public final double MAX_ANGULAR_VELOCITY_RAD_SEC = 2 * Math.PI; 077 } 078 079 public interface Intake { 080 081 public interface Pivot { 082 083 // state angles 084 // TODO:Get new pivot angles 085 Angle INITIAL_ANGLE = Degrees.of(-102); 086 087 Angle STOW_ANGLE = Degrees.of(-102); 088 089 Angle DEPLOY_ANGLE = Degrees.of(-22); 090 091 Angle AGITATE_UP_ANGLE = Degrees.of(-62); 092 093 Angle DIGEST_ANGLE = Degrees.of(-92); 094 095 Angle AGITATE_DOWN_ANGLE = Degrees.of(-22); 096 097 // misc 098 Angle ANGLE_TOLERANCE = Degrees.of(0.5); 099 100 Angle PUSHDOWN_THRESHOLD = Degrees.of(-30); 101 102 DoubleSubscriber PUSHDOWN_CURRENT = DogLog.tunable("Intake/Pivot/Pushdown Current Tuning Amps", 13.0); 103 104 // amps 105 Current STALL_CURRENT = Amps.of(25); 106 107 // TODO: set this up? 108 Time STALL_DEBOUNCE_SEC = Seconds.of(0.0); 109 110 Voltage HOMING_DOWN_VOLTAGE = Volts.of(3); 111 112 // sysid 113 Velocity<VoltageUnit> RAMP_RATE = Volts.of(1).per(Second); 114 115 Voltage STEP_VOLTAGE = Volts.of(1); 116 117 // sim 118 Angle MIN_ANGLE = Degrees.of(0); 119 120 Angle MAX_ANGLE = Degrees.of(-102.0); 121 122 double GEAR_RATIO = 60.0; 123 124 Distance PIVOT_ARM_LENGTH = Meters.of(0.1439822); 125 126 // mass in kg 127 MomentOfInertia MOI = KilogramSquareMeters.of(SingleJointedArmSim.estimateMOI(PIVOT_ARM_LENGTH.in(Meters), 1)); 128 } 129 130 public interface Roller { 131 132 Current STALL_CURRENT = Amps.of(50); 133 134 Time STALL_DEBOUNCE_SEC = Seconds.of(0.1); 135 136 double GEAR_RATIO = 16.0 / 27.0; 137 138 MomentOfInertia J = KilogramSquareMeters.of(0.001); 139 140 double IDLE_DUTY_CYCLE = 0; 141 142 double INTAKE_DUTY_CYCLE = 1; 143 144 double OUTTAKE_DUTY_CYCLE = -1; 145 } 146 } 147 148 public interface Feeder { 149 150 Voltage REVERSE_VOLTAGE = Volts.of(-10.0); // TODO: get 151 DoubleSubscriber REVERSE_TIME_BEFORE_SHOOT = DogLog.tunable("Feeder/Seconds To Reverse Before Shooting", 0.75); 152 153 Voltage FORWARD_VOLTAGE = Volts.of(10.0); 154 155 // TODO: get from mec 156 double GEAR_RATIO = 34/14; // (34/14) : 1 157 158 MomentOfInertia J = KilogramSquareMeters.of(0.001); 159 } 160 161 public interface LED { 162 163 // TODO: Get actual length of led, along with length of individual sections 164 int LED_LENGTH = 80; 165 166 // Buffer Views {Starting Index, Ending Index} 167 int[] SHOOTER_BUFFER = { 0, 19 }; 168 169 int[] FEEDER_BUFFER = { 20, 39 }; 170 171 int[] INTAKE_BUFFER = { 40, 59 }; 172 173 int[] HANDOFF_BUFFER = { 60, 79 }; 174 175 // shooter 176 LEDPattern SHOOTING = LEDPattern.solid(Color.kOrange); 177 178 LEDPattern FERRYING = LEDPattern.solid(Color.kPurple); 179 180 LEDPattern MANUAL = LEDPattern.solid(Color.kPeru); 181 182 // feeder 183 LEDPattern FEEDER_FORWARD = LEDPattern.solid(Color.kBlue); 184 185 LEDPattern FEEDER_REVERSE = LEDPattern.solid(Color.kRed); 186 187 // intake 188 LEDPattern INTAKING = LEDPattern.solid(Color.kYellow); 189 190 LEDPattern OUTTAKING = LEDPattern.solid(Color.kGreen); 191 192 LEDPattern HOMING_DOWN = LEDPattern.solid(Color.kGainsboro); 193 194 LEDPattern AGITATING = LEDPattern.solid(Color.kCyan); 195 196 // handoff 197 LEDPattern HANDOFF_FORWARD = LEDPattern.solid(Color.kDarkOrange); 198 199 // mmm papaya whip 200 LEDPattern HANDOFF_REVERSE = LEDPattern.solid(Color.kPapayaWhip); 201 202 // states 203 LEDPattern DISABLED = LEDPattern.solid(Color.kGray); 204 } 205 206 public interface Handoff { 207 Voltage IDLE_VOLTAGE = Volts.of(0.0); 208 209 Voltage FORWARD_VOLTAGE = Volts.of(12.0); 210 211 Voltage REVERSE_VOLTAGE = Volts.of(-10.0); 212 213 double STALL_CURRENT = 67; 214 215 // TODO: get and maybe convert to wpilib units 216 double STALL_DEBOUNCE = 67; 217 218 double J_KG_METERS_SQUARED = 1; 219 220 double GEAR_RATIO = 1.0 / 3.0; // 1:3 221 } 222 223 public interface Shooter { 224 DoubleSubscriber FIRST_SHOT_BONUS = DogLog.tunable("Shooter/First_shot_bonus_RPM", 250.0); 225 Time FIRST_SHOT_DEBOUNCE = Seconds.of(6.7); 226 227 Time SHOOT_TIME_AUTO = Seconds.of(1.5); 228 229 Velocity<VoltageUnit> RAMP_RATE = Volts.of(1).per(Second); 230 231 Voltage STEP_VOLTAGE = Volts.of(7); 232 233 Distance WHEEL_RADIUS = Inches.of(4); 234 235 // Sim 236 MomentOfInertia J = KilogramSquareMeters.of(0.1); 237 238 double GEAR_RATIO = 0.1; 239 240 // TODO: get 241 Distance FLYWHEEL_RADIUS = Inches.of(3); 242 243 // TODO: Test for manual shooting RPM 244 DoubleSubscriber MANUAL_HUB_RPM = DogLog.tunable("Shooter/Manual Shot Tuning RPM", 3650.0); 245 246 AngularVelocity MIN_SHOOTER_VELOCITY = RPM.of(1740); 247 248 DoubleSubscriber SHOOT_TUNING_RPM = DogLog.tunable("Shooter/Shoot Tuning RPM", 0.0); 249 DoubleSubscriber FERRY_TUNING_RPM = DogLog.tunable("Shooter/Ferry Tuning RPM", 0.0); 250 251 AngularVelocity SHOOTER_SPUN_UP_TOLERANCE = RPM.of(100); 252 public interface RPMInterpolation { 253 254 double[][] distanceRPMInterpolationValues = { 255 {1.46, 2600}, 256 {2.07, 3150}, 257 {3.13, 3700}, 258 {3.45, 3933}, 259 {4.13, 4200} 260 //TODO: These numbers don't make sense 261 // { 4.895367348608047, 3250.0 }, 262 // { 6.1322461808798705, 3487.0 } 263 }; 264 } 265 266 // These values are placeholders and should be replaced with actual data from testing 267 public interface TOFInterpolation { 268 269 double[][] distanceTOFInterpolationValues = { 270 { 1.0, 0.5 }, 271 { 2.0, 0.75 }, 272 { 3.0, 1.0 }, 273 { 4.0, 1.25 }, 274 { 5.0, 1.5 } }; 275 } 276 277 // These values are placeholders and should be replaced with actual data from testing 278 public interface FerryRPMInterpolation { 279 280 double[][] ferryDistanceRPMInterpolation = { 281 { 1.0, 2300.0 }, 282 { 2.0, 2800.0 }, 283 { 3.0, 3300.0 }, 284 { 4.0, 3800.0 }, 285 { 5.0, 5500.0 } }; 286 } 287 288 // These values are placeholders and should be replaced with actual data from testing 289 public interface FerryTOFInterpolation { 290 291 double[][] FerryTOFInterpolationInterpolation = { 292 { 1.0, 0.5 }, 293 { 2.0, 0.75 }, 294 { 3.0, 1.0 }, 295 { 4.0, 1.25 }, 296 { 5.0, 1.5 } }; 297 } 298 // These values are placeholders and should be replaced with actual data from testing 299 } 300 301 public interface Swerve { 302 303 double MODULE_VELOCITY_DEADBAND_M_PER_S = 0.1; 304 305 double ROTATIONAL_DEADBAND_RAD_PER_S = 0.1; 306 307 public interface Constraints { 308 309 double MAX_VELOCITY_M_PER_S = 4.3; 310 311 // TODO: revert to 15.0 312 double MAX_ACCEL_M_PER_S_SQUARED = 20.0; 313 314 double MAX_ANGULAR_VEL_RAD_PER_S = Units.degreesToRadians(400.0); 315 316 // TODO: revert to 900 317 double MAX_ANGULAR_ACCEL_RAD_PER_S = Units.degreesToRadians(300.0); 318 319 PathConstraints DEFAULT_CONSTRAINTS = new PathConstraints(MAX_VELOCITY_M_PER_S, MAX_ACCEL_M_PER_S_SQUARED, MAX_ANGULAR_VEL_RAD_PER_S, MAX_ANGULAR_ACCEL_RAD_PER_S); 320 } 321 322 public interface Alignment { 323 324 public interface Constraints { 325 326 double DEFAULT_MAX_VELOCITY = 4.3; 327 328 double DEFAULT_MAX_ACCELERATION = 15.0; 329 330 double DEFAULT_MAX_ANGULAR_VELOCITY = Units.degreesToRadians(400.0); 331 332 double DEFAULT_MAX_ANGULAR_ACCELERATION = Units.degreesToRadians(900.0); 333 } 334 335 public interface Tolerances { 336 337 Distance X_TOLERANCE = Inches.of(2.0); 338 339 Distance Y_TOLERANCE = Inches.of(2.0); 340 341 Rotation2d THETA_TOLERANCE = Rotation2d.fromDegrees(8); 342 343 Pose2d POSE_TOLERANCE = new Pose2d(X_TOLERANCE.in(Meters), Y_TOLERANCE.in(Meters), THETA_TOLERANCE); 344 345 LinearVelocity MAX_VELOCITY_WHEN_ALIGNED = MetersPerSecond.of(0.15); 346 347 Time ALIGNMENT_DEBOUNCE = Seconds.of(0.15); 348 } 349 350 public interface Targets { 351 352 // TODO: Get actual angle 353 Rotation2d HUB_LEFT_CORNER = Rotation2d.fromDegrees(45); 354 355 Rotation2d HUB_RIGHT_CORNER = Rotation2d.fromDegrees(-45); 356 } 357 } 358 } 359 360 public interface Driver { 361 362 double BUZZ_TIME = 1.0; 363 364 double BUZZ_INTENSITY = 1.0; 365 366 public interface Drive { 367 368 double DEADBAND = 0.05; 369 370 double RC = 0.05; 371 372 double POWER = 2.0; 373 } 374 375 public interface Turn { 376 377 double DEADBAND = 0.07; 378 379 double RC = 0.05; 380 381 double POWER = 2.0; 382 } 383 } 384}