Class Swerve
- All Implemented Interfaces:
AutoCloseable, Subsystem
SwerveDrivetrain for control and 250 Hz odometry,
with the robot pose owned by PoseFusion on the main loop so it can be replayed.
Where the pose comes from
CTRE's odometry thread still runs every module at 250 Hz. Its telemetry callback, on that
thread, only copies each sample into a bounded queue. Each robot loop periodic() drains
the queue into SwerveInputs, records it with AdvantageKit, and hands every sample to
PoseFusion, which is the pose everything on the robot reads (getRobotPose()).
Vision measurements go to PoseFusion too (see Vision). CTRE's internal estimate
is kept aligned with the fused pose (syncCtrePose()) because its field-centric requests
rotate by its own heading.
From the 2026 offseason branch
Per-module current and connection logging at 10 Hz, the SwerveAlignment encoder
publisher, skipping the bus optimisation on a dead bus (CanConfigBudget), and never doing
log work on CTRE's odometry thread. FM's own drive modes (pilot aim at target through ShotCalculator) are kept from main; the offseason bot's turret-pivot mode is not.
Simulation
maple-sim has no WPILib 2027 build, so the sim is CTRE's own updateSimState. To give
the vision comparison something to do, the sim keeps a separate perfect truth odometry
and feeds the robot code a version with wheel-radius and gyro-drift error (Swerve.SimErrors).
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classDeliberate odometry error in simulation, so the comparison between vision sources has something to correct.static enumstatic enumNested classes/interfaces inherited from class SwerveDrivetrain
SwerveDrivetrain.DeviceConstructor<DeviceT>, SwerveDrivetrain.OdometryThread, SwerveDrivetrain.SwerveControlParameters, SwerveDrivetrain.SwerveDriveState -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final doublestatic final doubleFields inherited from class SwerveDrivetrain
kNumConfigAttempts, m_drivetrainId, m_jni, m_telemetryJNI -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidCalled byRobotafter vision has been fused, so CTRE is re-aligned with the pose this loop's measurements produced.protected CommandbooleanfrontClosestToAngle(double angleDegrees) doubleFused heading minus the heading the aim request is holding, wrapped to (-pi, pi].protected doubleprotected StringRobot-relative chassis velocity measured from the modules this loop (a logged input).The gyro mount check, fed every loop, for the pre-match checks.getPoseAtTimestamp(double timestampSeconds) Get the robot's pose at a specific timestamp using interpolation.The robot pose and every per-source comparison track.The robot's fused pose: odometry plus every enabled vision source, integrated on the main loop from logged inputs.doublegetRotationDifference(double angle1, double angle2) Shortest absolute difference between two angles, degrees (0-180).doubleTruth pose in simulation, empty elsewhere.doublegetTilt()The Pigeon's tilt state this loop.doubleGyro yaw rate this loop, rad/s (a logged input).booleanWhether the Pigeon rebooted this loop, not counting Phoenix's report of the first contact after boot.inXzone(double minXmeter, double maxXmeter) inXzoneAlliance(double minXmeter, double maxXmeter) Whether the robot is in an X band of the field, flipped for red.inYzone(double minYmeter, double maxYmeter) inYzoneAlliance(double minYmeter, double maxYmeter) Whether the robot is in a Y band of the field, flipped for red.booleanisAiming()Whether the drivetrain is holding a heading on the shot solution this loop.booleanbooleanisAtDesiredRotation(double toleranceRadians) Whether the robot heading is within tolerance of the aim target.booleanisGoingTooFast(double thresholdSpeed) Returnstrueif the robot is moving faster than the threshold.booleanReturnstruewhen the robot is inside the opposing alliance's zone (pose X is flipped for red so the same rectangle works for both alliances).booleanReturnstruewhen the robot is inside the neutral zone.booleanisTilted()Whether the robot is tilted more thanTiltState.TILTED_DEG, e.g.booleanWhether the dashboard switch for tilt-scaled odometry is on (its default).protected voidReports drive and steer supply current to the battery logger every loop and logs per-module and summed currents at 10 Hz.booleanmoduleRebootedThisLoop(int module) Whether a module's drive motor rebooted this loop, not counting Phoenix's report of the first contact after boot.overSpeedTrigger(double thresholdSpeed) voidperiodic()protected Commandreorient(double angleDegrees) voidResets every pose track (and, in sim, the simulated robot) topose.voidsetRotationVelocityCoefficient(double rotationVelocityCoefficient) voidsetTeleopVelocityCoefficient(double teleopVelocityCoefficient) voidsetWantedState(Swerve.WantedState state) voidReads the drivetrain intoinputs, records them, and integrates this loop's odometry into the fused pose.booleanWhether the robot took a knock (collision, bump landing) in the last half second.Methods inherited from class SwerveDrivetrain
addVisionMeasurement, addVisionMeasurement, close, configNeutralMode, configNeutralMode, getKinematics, getModule, getModuleLocations, getModules, getOdometryFrequency, getOdometryFrequencyMeasure, getOdometryThread, getOperatorForwardDirection, getPigeon2, getRotation3d, getState, getStateCopy, isOdometryValid, isOnCANFD, optimizeBusUtilization, optimizeBusUtilization, optimizeBusUtilization, registerTelemetry, resetRotation, resetTranslation, samplePoseAt, seedFieldCentric, seedFieldCentric, setControl, setOperatorPerspectiveForward, setStateStdDevs, setVisionMeasurementStdDevs, tareEverything, updateSimStateMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface Subsystem
defer, getCurrentCommand, getDefaultCommand, getName, idle, register, removeDefaultCommand, run, runEnd, runOnce, setDefaultCommand, simulationPeriodic, startEnd, startRun
-
Field Details
-
TRANSLATION_ERROR_MARGIN_METERS
public static final double TRANSLATION_ERROR_MARGIN_METERS -
DRIVE_TO_POINT_STATIC_FRICTION_CONSTANT
public static final double DRIVE_TO_POINT_STATIC_FRICTION_CONSTANT- See Also:
-
-
Constructor Details
-
Swerve
Constructs a new Swerve drive subsystem.- Parameters:
config- drivetrain constants and module configurations
-
-
Method Details
-
isTiltScaledOdometry
public boolean isTiltScaledOdometry()Whether the dashboard switch for tilt-scaled odometry is on (its default). -
getMountCheck
The gyro mount check, fed every loop, for the pre-match checks. -
getTilt
The Pigeon's tilt state this loop. -
isTilted
public boolean isTilted()Whether the robot is tilted more thanTiltState.TILTED_DEG, e.g. on a bump. -
wasBumpedRecently
public boolean wasBumpedRecently()Whether the robot took a knock (collision, bump landing) in the last half second. -
updateInputs
public void updateInputs()Reads the drivetrain intoinputs, records them, and integrates this loop's odometry into the fused pose. Called byRobotat the top of every loop, before vision and before the scheduler, so everything this loop sees the same pose. -
moduleRebootedThisLoop
public boolean moduleRebootedThisLoop(int module) Whether a module's drive motor rebooted this loop, not counting Phoenix's report of the first contact after boot. Use this, not the rawModuleResetOccurredinput.- Parameters:
module- module index, inSwerveAlignment.MODULE_NAMESorder- Returns:
- true on the loop the reboot is seen
-
gyroRebootedThisLoop
public boolean gyroRebootedThisLoop()Whether the Pigeon rebooted this loop, not counting Phoenix's report of the first contact after boot. Use this, not the rawGyroResetOccurredinput.- Returns:
- true on the loop the reboot is seen
-
periodic
-
afterVision
public void afterVision()Called byRobotafter vision has been fused, so CTRE is re-aligned with the pose this loop's measurements produced. -
logBatteryUsage
protected void logBatteryUsage()Reports drive and steer supply current to the battery logger every loop and logs per-module and summed currents at 10 Hz. Diagnostic outputs only; nothing decides on them, so they are read straight from the signals rather than throughSwerveInputs. -
getCurrentCommandName
-
getRobotPose
The robot's fused pose: odometry plus every enabled vision source, integrated on the main loop from logged inputs.- Returns:
- the robot pose on the field
-
getPoseAtTimestamp
Get the robot's pose at a specific timestamp using interpolation.- Parameters:
timestampSeconds- the timestamp to sample at,Timer.getTimestamp()base- Returns:
- the interpolated pose, or current pose if the timestamp is not in the buffer
-
resetPose
-
inXzone
-
inYzone
-
inXzoneAlliance
Whether the robot is in an X band of the field, flipped for red.- Parameters:
minXmeter- the minimum X coordinate in metersmaxXmeter- the maximum X coordinate in meters- Returns:
- the Trigger
-
inYzoneAlliance
Whether the robot is in a Y band of the field, flipped for red.- Parameters:
minYmeter- the minimum Y coordinate in metersmaxYmeter- the maximum Y coordinate in meters- Returns:
- the Trigger
-
isInNeutralZone
public boolean isInNeutralZone()Returnstruewhen the robot is inside the neutral zone. -
isInEnemyAllianceZone
public boolean isInEnemyAllianceZone()Returnstruewhen the robot is inside the opposing alliance's zone (pose X is flipped for red so the same rectangle works for both alliances). -
inNeutralZone
-
inEnemyAllianceZone
-
inFieldRight
-
inFieldLeft
-
isGoingTooFast
public boolean isGoingTooFast(double thresholdSpeed) Returnstrueif the robot is moving faster than the threshold.- Parameters:
thresholdSpeed- the speed threshold in meters per second- Returns:
trueif the current linear speed exceeds the threshold
-
overSpeedTrigger
-
getCurrentRobotChassisSpeeds
Robot-relative chassis velocity measured from the modules this loop (a logged input).- Returns:
- the current robot chassis velocity
-
getYawRateRadPerSec
public double getYawRateRadPerSec()Gyro yaw rate this loop, rad/s (a logged input). -
reorient
-
reorientForward
-
reorientLeft
-
reorientBack
-
reorientRight
-
getClosestCardinal
protected double getClosestCardinal() -
cardinalReorient
-
frontClosestToAngle
public boolean frontClosestToAngle(double angleDegrees) -
getRotationDifference
public double getRotationDifference(double angle1, double angle2) Shortest absolute difference between two angles, degrees (0-180). -
setWantedState
-
getAimHeadingErrorRadians
public double getAimHeadingErrorRadians()Fused heading minus the heading the aim request is holding, wrapped to (-pi, pi]. Read from the fused pose, so it replays.- Returns:
- the heading error in radians, or NaN when the drivetrain is not aiming
-
isAiming
public boolean isAiming()Whether the drivetrain is holding a heading on the shot solution this loop. -
isAtDesiredRotation
public boolean isAtDesiredRotation() -
isAtDesiredRotation
public boolean isAtDesiredRotation(double toleranceRadians) Whether the robot heading is within tolerance of the aim target. Computed from the fused pose rather than CTRE's heading controller so it replays.- Parameters:
toleranceRadians- the allowed heading error in radians- Returns:
truewhile aiming and inside the tolerance
-
getSimTruthPose
-
getTeleopVelocityCoefficient
public double getTeleopVelocityCoefficient() -
setTeleopVelocityCoefficient
public void setTeleopVelocityCoefficient(double teleopVelocityCoefficient) -
getRotationVelocityCoefficient
public double getRotationVelocityCoefficient() -
setRotationVelocityCoefficient
public void setRotationVelocityCoefficient(double rotationVelocityCoefficient) -
getConfig
-
getInputs
-
getPoseFusion
The robot pose and every per-source comparison track.
-