Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7ee8cf4
Linear Slide IO
SCool62 Jan 30, 2026
90c641a
Linear slide io sim
SCool62 Jan 30, 2026
1322331
Base impl of lintake subsystem
SCool62 Jan 30, 2026
28aad47
Spotless
SCool62 Jan 30, 2026
fd5840d
Constants from CAD
SCool62 Jan 30, 2026
9ebf40b
Rack talon config
SCool62 Jan 30, 2026
1cb3361
Rename slide to rack
SCool62 Jan 30, 2026
5b11938
Linear rack sim constants from CAD
SCool62 Jan 30, 2026
6d65339
Roller config
SCool62 Jan 30, 2026
35529d8
Spotless
SCool62 Jan 30, 2026
aca4771
Instantiate new lintake in constructor
SCool62 Jan 30, 2026
5a00e24
CAN range
SCool62 Jan 30, 2026
e848cd4
Merge branch 'main' into subsystem/lintake
SCool62 Feb 4, 2026
0d29155
Turret works hood sort of
SCool62 Feb 7, 2026
d85fcc6
Comments
SCool62 Feb 8, 2026
9580ae8
Intake viz
SCool62 Feb 8, 2026
5fc55a5
Climber viz
SCool62 Feb 8, 2026
ed03d74
Cleanup and comments
SCool62 Feb 8, 2026
9c29ea4
Make constants constants
SCool62 Feb 8, 2026
6d1e3f1
Make zeroed mech and robot poses sim only
SCool62 Feb 8, 2026
34e0b99
Merge branch 'main' into subsystem/lintake
SCool62 Feb 8, 2026
65759a3
Can ids
SCool62 Feb 8, 2026
6652844
Impl beambreak method
SCool62 Feb 8, 2026
c3bacc8
Remove unused method in intake subsystem
SCool62 Feb 8, 2026
befbd92
Merge branch 'main' into feature/mechanism-viz
SCool62 Feb 8, 2026
6b3861d
Climber position from hardware
SCool62 Feb 8, 2026
c5a9a4b
Make sure all climber stuff uses correct units
SCool62 Feb 8, 2026
761a7ea
Log climber setpoint
SCool62 Feb 8, 2026
3921e2a
Osciliate when outtaking
SCool62 Feb 9, 2026
f4a5e67
Scale oscilation to be reasonable
SCool62 Feb 9, 2026
a799802
Spotless
SCool62 Feb 9, 2026
08bfa82
Add current zeroing
SCool62 Feb 10, 2026
c818d0f
Actually zero rack by extending
SCool62 Feb 10, 2026
f73c8d9
Spotless
SCool62 Feb 10, 2026
c9c9877
Merge branch 'subsystem/lintake' into feature/mechanism-viz
SCool62 Feb 10, 2026
7e2485d
Add back intake rotation lol
SCool62 Feb 10, 2026
26557ec
Fix direction
SCool62 Feb 11, 2026
e7dca4b
Add lintake viz
SCool62 Feb 11, 2026
f93f118
Spotless
SCool62 Feb 11, 2026
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
119 changes: 115 additions & 4 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import com.ctre.phoenix6.SignalLogger;
import com.ctre.phoenix6.sim.TalonFXSimState.MotorType;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.geometry.Translation3d;
import edu.wpi.first.math.kinematics.ChassisSpeeds;
import edu.wpi.first.math.system.plant.DCMotor;
import edu.wpi.first.math.system.plant.LinearSystemId;
Expand All @@ -29,6 +34,7 @@
import edu.wpi.first.wpilibj2.command.button.RobotModeTriggers;
import edu.wpi.first.wpilibj2.command.button.Trigger;
import frc.robot.Superstructure.SuperState;
import frc.robot.components.canrange.CANrangeIOReal;
import frc.robot.components.rollers.RollerIO;
import frc.robot.components.rollers.RollerIOSim;
import frc.robot.subsystems.climber.ClimberIO;
Expand All @@ -39,6 +45,8 @@
import frc.robot.subsystems.indexer.SpindexerSubsystem;
import frc.robot.subsystems.intake.FintakeSubsystem;
import frc.robot.subsystems.intake.Intake;
import frc.robot.subsystems.intake.LinearRackIO;
import frc.robot.subsystems.intake.LinearRackIOSim;
import frc.robot.subsystems.intake.LintakeSubsystem;
import frc.robot.subsystems.led.LEDIOReal;
import frc.robot.subsystems.led.LEDSubsystem;
Expand All @@ -52,6 +60,7 @@
import frc.robot.subsystems.swerve.SwerveSubsystem;
import frc.robot.subsystems.swerve.odometry.PhoenixOdometryThread;
import frc.robot.utils.CommandXboxControllerSubsystem;
import frc.robot.utils.LoggedTunableNumber;
import java.util.Optional;
import java.util.Set;
import org.ironmaple.simulation.SimulatedArena;
Expand Down Expand Up @@ -171,6 +180,8 @@ public enum RobotEdition {
private final LEDSubsystem leds;
private final ClimberSubsystem climber;

private Intake intake = null;

// climber only exists for the comp bot - this is accounted for later

private final Superstructure superstructure;
Expand Down Expand Up @@ -216,7 +227,6 @@ public Robot() {
// break
// granted this would never actually happen but
Indexer indexer = null;
Intake intake = null;
Shooter shooter = null;

// this looks at the ROBOT_EDITION variable and decides which version of each subsystem to
Expand Down Expand Up @@ -312,7 +322,27 @@ public Robot() {
DCMotor.getKrakenX44Foc(1)),
MotorType.KrakenX44,
canivore));
intake = new LintakeSubsystem();
// TODO: FOVs
intake =
(ROBOT_MODE == RobotMode.REAL)
? new LintakeSubsystem(
new LinearRackIO(14, canivore, LintakeSubsystem.getRackMotorConfig()),
new RollerIO(8, LintakeSubsystem.getRollerMotorConfig(), canivore),
new CANrangeIOReal(0, canivore, 10))
: new LintakeSubsystem(
new LinearRackIOSim(14, canivore, LintakeSubsystem.getRackMotorConfig()),
new RollerIOSim(
8,
LintakeSubsystem.getRollerMotorConfig(),
new DCMotorSim(
LinearSystemId.createDCMotorSystem(
DCMotor.getKrakenX44Foc(1),
0.001,
LintakeSubsystem.ROLLER_GEAR_RATIO),
DCMotor.getKrakenX44Foc(1)),
MotorType.KrakenX44,
canivore),
new CANrangeIOReal(0, canivore, 10));
shooter =
new TurretSubsystem(
ROBOT_MODE == RobotMode.REAL
Expand Down Expand Up @@ -564,13 +594,80 @@ private void addAutos() {
// autoChooser.addOption("Intake Roller Sysid", intake.runRollerSysid());
// autoChooser.addOption("Flywheel Sysid", shooter.runFlywheelSysid());

private LoggedTunableNumber turretAngle = new LoggedTunableNumber("Turret Angle Rads", 0);
private LoggedTunableNumber hoodAngle = new LoggedTunableNumber("Hood angle rads", 0);
private LoggedTunableNumber intakeExtension = new LoggedTunableNumber("Intake extension", 0);

@Override
public void robotPeriodic() {
CommandScheduler.getInstance().run();

superstructure.periodic();

// TODO Log mechanism poses
// TODO: YAW VALUE FROM HARDWARE
Pose3d turretPose =
new Pose3d(
new Translation3d(-0.177413, -0.111702, 0.350341),
new Rotation3d(0, 0, turretAngle.getAsDouble()));

// TODO: USE MEASURED EXTENSIONS AND ANGLES
Logger.recordOutput(
"Robot/Mechanism Poses",
new Pose3d[] {
// Turret
turretPose,
// Hood
turretPose
// First transform the hood out to the hood pivot, and rotate by the amount needed
.transformBy(
new Transform3d(
new Translation3d(-0.095638, 0, 0.095123),
new Rotation3d(0, hoodAngle.getAsDouble() * -1, 0)))
// Then, transform the hood back to the correct location relative to the turret
.transformBy(
new Transform3d(
new Translation3d(-0.095638, 0, 0.095123).times(-1), Rotation3d.kZero)),
// Intake
new Pose3d(
intake.getExtensionMeters() * LintakeSubsystem.INTAKE_ROTATION.getCos(),
0,
-(intake.getExtensionMeters() * LintakeSubsystem.INTAKE_ROTATION.getSin()),
Rotation3d.kZero),
// Climber
new Pose3d(0, 0, climber.getClimberExtensionMeters(), Rotation3d.kZero)
});

// TODO: ACTUAL SETPOINT
Pose3d turretSetpoint =
new Pose3d(
new Translation3d(-0.177413, -0.111702, 0.350341),
new Rotation3d(0, 0, turretAngle.getAsDouble()));
// TODO: ACTUAL SETPOINTS
Logger.recordOutput(
"Robot/Mechanism Setpoints",
new Pose3d[] {
// Turret
turretSetpoint,
// Hood
turretSetpoint
// First transform the hood out to the hood pivot, and rotate by the amount needed
.transformBy(
new Transform3d(
new Translation3d(-0.095638, 0, 0.095123),
new Rotation3d(0, hoodAngle.getAsDouble() * -1, 0)))
// Then, transform the hood back to the correct location relative to the turret
.transformBy(
new Transform3d(
new Translation3d(-0.095638, 0, 0.095123).times(-1), Rotation3d.kZero)),
// Intake
new Pose3d(
intake.getExtensionSetpointMeters() * LintakeSubsystem.INTAKE_ROTATION.getCos(),
0,
-(intake.getExtensionSetpointMeters() * LintakeSubsystem.INTAKE_ROTATION.getSin()),
Rotation3d.kZero),
// Climber
new Pose3d(0, 0, climber.getClimberSetpointMeters(), Rotation3d.kZero)
});

updateAlerts();
}
Expand Down Expand Up @@ -634,7 +731,21 @@ public void simulationInit() {
}

@Override
public void simulationPeriodic() {}
public void simulationPeriodic() {
// Log zeroed poses for mechs and robot for debugging in sim
Logger.recordOutput(
"Robot/Zeroed Mechanism Poses",
new Pose3d[] {
// Turret
new Pose3d(),
// Hood
new Pose3d(),
new Pose3d(),
new Pose3d()
});

Logger.recordOutput("Robot/Zero Position", new Pose2d());
}

@Override
public void disabledInit() {}
Expand Down
34 changes: 20 additions & 14 deletions src/main/java/frc/robot/subsystems/climber/ClimberIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@
import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.signals.InvertedValue;
import com.ctre.phoenix6.signals.NeutralModeValue;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.units.measure.Angle;
import edu.wpi.first.units.measure.AngularVelocity;
import edu.wpi.first.units.measure.Current;
import edu.wpi.first.units.measure.Temperature;
import edu.wpi.first.units.measure.Voltage;
import org.littletonrobotics.junction.AutoLog;
import org.littletonrobotics.junction.AutoLogOutput;

public class ClimberIO {

@AutoLog
public static class ClimberIOInputs {
public Rotation2d motorPositionRotations = new Rotation2d();
public double motorPositionMeters = 0.0;
public double motorVelocityMetersPerSec = 0.0;
public double motorStatorCurrentAmps = 0.0;
public double motorSupplyCurrentAmps = 0.0;
Expand All @@ -32,8 +32,9 @@ public static class ClimberIOInputs {

protected final TalonFX climberMotor;

private final StatusSignal<Angle> motorPositionRotations;
private final StatusSignal<AngularVelocity> angularVelocityRotsPerSec;
// Rotation -> linear conversion happens in sensor to mech ratio
private final StatusSignal<Angle> motorPositionMeters;
private final StatusSignal<AngularVelocity> velocityMetersPerSec;
private final StatusSignal<Current> statorCurrentAmps;
private final StatusSignal<Current> supplyCurrentAmps;
private final StatusSignal<Voltage> motorVoltage;
Expand All @@ -50,21 +51,21 @@ public ClimberIO(CANBus canBus) {
climberMotor = new TalonFX(30, canBus);
climberMotor.getConfigurator().apply(ClimberIO.getClimberConfiguration());

angularVelocityRotsPerSec = climberMotor.getVelocity();
velocityMetersPerSec = climberMotor.getVelocity();
supplyCurrentAmps = climberMotor.getSupplyCurrent();
motorVoltage = climberMotor.getMotorVoltage();
statorCurrentAmps = climberMotor.getStatorCurrent();
motorTemp = climberMotor.getDeviceTemp();
motorPositionRotations = climberMotor.getPosition();
motorPositionMeters = climberMotor.getPosition();

BaseStatusSignal.setUpdateFrequencyForAll(
50.0,
angularVelocityRotsPerSec,
velocityMetersPerSec,
supplyCurrentAmps,
motorVoltage,
statorCurrentAmps,
motorTemp,
motorPositionRotations);
motorPositionMeters);
climberMotor.optimizeBusUtilization();
}

Expand All @@ -76,7 +77,8 @@ public static TalonFXConfiguration getClimberConfiguration() {
config.MotorOutput.Inverted = InvertedValue.Clockwise_Positive;

// todo: find and make climber gear ratio variable
config.Feedback.SensorToMechanismRatio = ClimberSubsystem.GEAR_RATIO;
config.Feedback.SensorToMechanismRatio =
ClimberSubsystem.GEAR_RATIO * (Math.PI * ClimberSubsystem.SPOOL_DIAMETER_METERS);

// todo: tune
config.Slot0.kS = 0.0;
Expand Down Expand Up @@ -108,19 +110,23 @@ public void setClimberVelocity(double climberVelocity) {

public void updateInputs(ClimberIOInputs inputs) {
BaseStatusSignal.refreshAll(
motorPositionRotations,
angularVelocityRotsPerSec,
motorPositionMeters,
velocityMetersPerSec,
statorCurrentAmps,
supplyCurrentAmps,
motorVoltage,
motorTemp);

inputs.motorPositionRotations =
Rotation2d.fromRotations(motorPositionRotations.getValueAsDouble());
inputs.motorPositionMeters = motorPositionMeters.getValueAsDouble();
inputs.motorVoltage = motorVoltage.getValueAsDouble();
inputs.motorTempC = motorTemp.getValueAsDouble();
inputs.motorSupplyCurrentAmps = supplyCurrentAmps.getValueAsDouble();
inputs.motorStatorCurrentAmps = statorCurrentAmps.getValueAsDouble();
inputs.motorVelocityMetersPerSec = angularVelocityRotsPerSec.getValueAsDouble();
inputs.motorVelocityMetersPerSec = velocityMetersPerSec.getValueAsDouble();
}

@AutoLogOutput(key = "Climber/Setpoint Meters")
public double getClimberSetpointMeters() {
return climberSetpoint;
}
}
11 changes: 11 additions & 0 deletions src/main/java/frc/robot/subsystems/climber/ClimberSubsystem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package frc.robot.subsystems.climber;

import edu.wpi.first.math.util.Units;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import org.littletonrobotics.junction.Logger;
Expand All @@ -8,6 +9,7 @@ public class ClimberSubsystem extends SubsystemBase {
// todo: find actual constants
public static double GEAR_RATIO = (45.0 / 1.0);
public static double MAX_EXTENSION_METERS = 0.2413;
public static double SPOOL_DIAMETER_METERS = Units.inchesToMeters(0.668898);
public static double MAX_ACCELERATION = 10.0;
public static double MAX_VELOCITY = 2.0;

Expand Down Expand Up @@ -39,4 +41,13 @@ public Command retractClimber() {
climberIO.setClimberPosition(0.0);
});
}

public double getClimberExtensionMeters() {
// Convert rotations into linear motion
return climberInputs.motorPositionMeters;
}

public double getClimberSetpointMeters() {
return climberIO.getClimberSetpointMeters();
}
}
10 changes: 10 additions & 0 deletions src/main/java/frc/robot/subsystems/intake/FintakeSubsystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,14 @@ public static TalonFXConfiguration getIntakeConfig() {
public boolean beambreak() {
return canrangeInputs.isDetected;
}

@Override
public double getExtensionMeters() {
return 0;
}

@Override
public double getExtensionSetpointMeters() {
return 0;
}
}
4 changes: 4 additions & 0 deletions src/main/java/frc/robot/subsystems/intake/Intake.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ public interface Intake {

/** for controller rumble */
public boolean beambreak();

public double getExtensionMeters();

public double getExtensionSetpointMeters();
}
Loading