diff --git a/src/main/java/swervelib/SwerveDrive.java b/src/main/java/swervelib/SwerveDrive.java index 6c25baa..2a4839f 100644 --- a/src/main/java/swervelib/SwerveDrive.java +++ b/src/main/java/swervelib/SwerveDrive.java @@ -28,6 +28,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import swervelib.imu.SwerveIMU; import swervelib.math.SwerveMath; import swervelib.parser.SwerveControllerConfiguration; @@ -47,6 +49,10 @@ public class SwerveDrive { public final SwerveDrivePoseEstimator swerveDrivePoseEstimator; /** Swerve modules. */ private final SwerveModule[] swerveModules; + /** WPILib {@link Notifier} to keep odometry up to date. */ + private final Notifier odometryThread; + /** Odometry lock to ensure thread safety. */ + private final Lock odometryLock = new ReentrantLock(); /** Field object. */ public Field2d field = new Field2d(); /** Swerve controller for controlling heading of the robot. */ @@ -76,8 +82,6 @@ public class SwerveDrive { private int moduleSynchronizationCounter = 0; /** The last heading set in radians. */ private double lastHeadingRadians = 0; - /** WPILib {@link Notifier} to keep odometry up to date. */ - private final Notifier odometryThread; /** * Creates a new swerve drivebase subsystem. Robot is controlled via the {@link SwerveDrive#drive} @@ -644,6 +648,7 @@ public void replaceSwerveModuleFeedforward(SimpleMotorFeedforward feedforward) { * SmartDashboard with module encoder readings and states. */ public void updateOdometry() { + odometryLock.lock(); // Update odometry swerveDrivePoseEstimator.update(getYaw(), getModulePositions()); @@ -697,6 +702,7 @@ public void updateOdometry() { if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.HIGH.ordinal()) { SwerveDriveTelemetry.updateData(); } + odometryLock.unlock(); } /** Synchronize angle motor integrated encoders with data from absolute encoders. */ diff --git a/src/main/java/swervelib/encoders/CANCoderSwerve.java b/src/main/java/swervelib/encoders/CANCoderSwerve.java index 03f30cb..e8fbddc 100644 --- a/src/main/java/swervelib/encoders/CANCoderSwerve.java +++ b/src/main/java/swervelib/encoders/CANCoderSwerve.java @@ -90,8 +90,7 @@ public double getAbsolutePosition() { // Source: // https://github.com/democat3457/swerve-lib/blob/7c03126b8c22f23a501b2c2742f9d173a5bcbc40/src/main/java/com/swervedrivespecialties/swervelib/ctre/CanCoderFactoryBuilder.java#L51-L74 ErrorCode code = encoder.getLastError(); - int ATTEMPTS = 3; - for (int i = 0; i < ATTEMPTS; i++) { + for (int i = 0; i < maximumRetries; i++) { if (code == ErrorCode.OK) { break; } diff --git a/src/main/java/swervelib/encoders/SparkMaxEncoderSwerve.java b/src/main/java/swervelib/encoders/SparkMaxEncoderSwerve.java index d962dfc..c72c63f 100644 --- a/src/main/java/swervelib/encoders/SparkMaxEncoderSwerve.java +++ b/src/main/java/swervelib/encoders/SparkMaxEncoderSwerve.java @@ -2,7 +2,10 @@ import com.revrobotics.AbsoluteEncoder; import com.revrobotics.CANSparkMax; +import com.revrobotics.REVLibError; import com.revrobotics.SparkMaxAbsoluteEncoder.Type; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.function.Supplier; import swervelib.motors.SwerveMotor; /** SparkMax absolute encoder, attached through the data port. */ @@ -20,13 +23,27 @@ public class SparkMaxEncoderSwerve extends SwerveAbsoluteEncoder { public SparkMaxEncoderSwerve(SwerveMotor motor, int conversionFactor) { if (motor.getMotor() instanceof CANSparkMax) { encoder = ((CANSparkMax) motor.getMotor()).getAbsoluteEncoder(Type.kDutyCycle); - encoder.setVelocityConversionFactor(conversionFactor); - encoder.setPositionConversionFactor(conversionFactor); + configureSparkMax(() -> encoder.setVelocityConversionFactor(conversionFactor)); + configureSparkMax(() -> encoder.setPositionConversionFactor(conversionFactor)); } else { throw new RuntimeException("Motor given to instantiate SparkMaxEncoder is not a CANSparkMax"); } } + /** + * Run the configuration until it succeeds or times out. + * + * @param config Lambda supplier returning the error state. + */ + private void configureSparkMax(Supplier config) { + for (int i = 0; i < maximumRetries; i++) { + if (config.get() == REVLibError.kOk) { + return; + } + } + DriverStation.reportWarning("Failure configuring encoder", true); + } + /** Reset the encoder to factory defaults. */ @Override public void factoryDefault() { diff --git a/src/main/java/swervelib/encoders/SwerveAbsoluteEncoder.java b/src/main/java/swervelib/encoders/SwerveAbsoluteEncoder.java index 364dc92..825ec44 100644 --- a/src/main/java/swervelib/encoders/SwerveAbsoluteEncoder.java +++ b/src/main/java/swervelib/encoders/SwerveAbsoluteEncoder.java @@ -6,6 +6,11 @@ */ public abstract class SwerveAbsoluteEncoder { + /** + * The maximum amount of times the swerve encoder will attempt to configure itself if failures + * occur. + */ + public final int maximumRetries = 5; /** Last angle reading was faulty. */ public boolean readingError = false; diff --git a/src/main/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java b/src/main/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java index 9d28eac..233af6d 100644 --- a/src/main/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java +++ b/src/main/java/swervelib/motors/SparkMaxBrushedMotorSwerve.java @@ -6,13 +6,14 @@ import com.revrobotics.CANSparkMax.IdleMode; import com.revrobotics.CANSparkMaxLowLevel.MotorType; import com.revrobotics.CANSparkMaxLowLevel.PeriodicFrame; +import com.revrobotics.REVLibError; import com.revrobotics.RelativeEncoder; import com.revrobotics.SparkMaxAlternateEncoder; import com.revrobotics.SparkMaxPIDController; import com.revrobotics.SparkMaxRelativeEncoder.Type; import edu.wpi.first.wpilibj.DriverStation; +import java.util.function.Supplier; import swervelib.encoders.SwerveAbsoluteEncoder; -import swervelib.motors.SparkMaxSwerve.SparkMAX_slotIdx; import swervelib.parser.PIDFConfig; /** Brushed motor control with SparkMax. */ @@ -77,10 +78,11 @@ public SparkMaxBrushedMotorSwerve( : motor.getEncoder(encoderType, countsPerRevolution); // Configure feedback of the PID controller as the integrated encoder. - pid.setFeedbackDevice(encoder); + configureSparkMax(() -> pid.setFeedbackDevice(encoder)); } - motor.setCANTimeout(0); // Spin off configurations in a different thread. + configureSparkMax( + () -> motor.setCANTimeout(0)); // Spin off configurations in a different thread. } /** @@ -108,6 +110,20 @@ public SparkMaxBrushedMotorSwerve( useDataPortQuadEncoder); } + /** + * Run the configuration until it succeeds or times out. + * + * @param config Lambda supplier returning the error state. + */ + private void configureSparkMax(Supplier config) { + for (int i = 0; i < maximumRetries; i++) { + if (config.get() == REVLibError.kOk) { + return; + } + } + DriverStation.reportWarning("Failure configuring motor " + motor.getDeviceId(), true); + } + /** * Set the voltage compensation for the swerve module motor. * @@ -115,7 +131,7 @@ public SparkMaxBrushedMotorSwerve( */ @Override public void setVoltageCompensation(double nominalVoltage) { - motor.enableVoltageCompensation(nominalVoltage); + configureSparkMax(() -> motor.enableVoltageCompensation(nominalVoltage)); } /** @@ -126,7 +142,7 @@ public void setVoltageCompensation(double nominalVoltage) { */ @Override public void setCurrentLimit(int currentLimit) { - motor.setSmartCurrentLimit(currentLimit); + configureSparkMax(() -> motor.setSmartCurrentLimit(currentLimit)); } /** @@ -136,8 +152,8 @@ public void setCurrentLimit(int currentLimit) { */ @Override public void setLoopRampRate(double rampRate) { - motor.setOpenLoopRampRate(rampRate); - motor.setClosedLoopRampRate(rampRate); + configureSparkMax(() -> motor.setOpenLoopRampRate(rampRate)); + configureSparkMax(() -> motor.setClosedLoopRampRate(rampRate)); } /** @@ -164,7 +180,7 @@ public boolean isAttachedAbsoluteEncoder() { @Override public void factoryDefaults() { if (!factoryDefaultOccurred) { - motor.restoreFactoryDefaults(); + configureSparkMax(motor::restoreFactoryDefaults); factoryDefaultOccurred = true; } } @@ -172,7 +188,7 @@ public void factoryDefaults() { /** Clear the sticky faults on the motor controller. */ @Override public void clearStickyFaults() { - motor.clearFaults(); + configureSparkMax(motor::clearFaults); } /** @@ -185,7 +201,7 @@ public void clearStickyFaults() { public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) { if (encoder.getAbsoluteEncoder() instanceof AbsoluteEncoder) { absoluteEncoder = (AbsoluteEncoder) encoder.getAbsoluteEncoder(); - pid.setFeedbackDevice(absoluteEncoder); + configureSparkMax(() -> pid.setFeedbackDevice(absoluteEncoder)); } if (absoluteEncoder == null && this.encoder == null) { DriverStation.reportError("An encoder MUST be defined to work with a SparkMAX", true); @@ -203,15 +219,17 @@ public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) { @Override public void configureIntegratedEncoder(double positionConversionFactor) { if (absoluteEncoder == null) { - encoder.setPositionConversionFactor(positionConversionFactor); - encoder.setVelocityConversionFactor(positionConversionFactor / 60); + configureSparkMax(() -> encoder.setPositionConversionFactor(positionConversionFactor)); + configureSparkMax(() -> encoder.setVelocityConversionFactor(positionConversionFactor / 60)); // Taken from // https://github.com/frc3512/SwerveBot-2022/blob/9d31afd05df6c630d5acb4ec2cf5d734c9093bf8/src/main/java/frc/lib/util/CANSparkMaxUtil.java#L67 configureCANStatusFrames(10, 20, 20, 500, 500); } else { - absoluteEncoder.setPositionConversionFactor(positionConversionFactor); - absoluteEncoder.setVelocityConversionFactor(positionConversionFactor / 60); + configureSparkMax( + () -> absoluteEncoder.setPositionConversionFactor(positionConversionFactor)); + configureSparkMax( + () -> absoluteEncoder.setVelocityConversionFactor(positionConversionFactor / 60)); } } @@ -222,14 +240,17 @@ public void configureIntegratedEncoder(double positionConversionFactor) { */ @Override public void configurePIDF(PIDFConfig config) { - int pidSlot = - isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : SparkMAX_slotIdx.Position.ordinal(); - pid.setP(config.p, pidSlot); - pid.setI(config.i, pidSlot); - pid.setD(config.d, pidSlot); - pid.setFF(config.f, pidSlot); - pid.setIZone(config.iz, pidSlot); - pid.setOutputRange(config.output.min, config.output.max, pidSlot); + // int pidSlot = + // isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : + // SparkMAX_slotIdx.Position.ordinal(); + int pidSlot = 0; + + configureSparkMax(() -> pid.setP(config.p, pidSlot)); + configureSparkMax(() -> pid.setI(config.i, pidSlot)); + configureSparkMax(() -> pid.setD(config.d, pidSlot)); + configureSparkMax(() -> pid.setFF(config.f, pidSlot)); + configureSparkMax(() -> pid.setIZone(config.iz, pidSlot)); + configureSparkMax(() -> pid.setOutputRange(config.output.min, config.output.max, pidSlot)); } /** @@ -240,9 +261,9 @@ public void configurePIDF(PIDFConfig config) { */ @Override public void configurePIDWrapping(double minInput, double maxInput) { - pid.setPositionPIDWrappingEnabled(true); - pid.setPositionPIDWrappingMinInput(minInput); - pid.setPositionPIDWrappingMaxInput(maxInput); + configureSparkMax(() -> pid.setPositionPIDWrappingEnabled(true)); + configureSparkMax(() -> pid.setPositionPIDWrappingMinInput(minInput)); + configureSparkMax(() -> pid.setPositionPIDWrappingMaxInput(maxInput)); } /** @@ -256,11 +277,11 @@ public void configurePIDWrapping(double minInput, double maxInput) { */ public void configureCANStatusFrames( int CANStatus0, int CANStatus1, int CANStatus2, int CANStatus3, int CANStatus4) { - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus0, CANStatus0); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus1, CANStatus1); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus2, CANStatus2); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus3, CANStatus3); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus4, CANStatus4); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus0, CANStatus0)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus1, CANStatus1)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus2, CANStatus2)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus3, CANStatus3)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus4, CANStatus4)); // TODO: Configure Status Frame 5 and 6 if necessary // https://docs.revrobotics.com/sparkmax/operating-modes/control-interfaces } @@ -272,7 +293,7 @@ public void configureCANStatusFrames( */ @Override public void setMotorBrake(boolean isBrakeMode) { - motor.setIdleMode(isBrakeMode ? IdleMode.kBrake : IdleMode.kCoast); + configureSparkMax(() -> motor.setIdleMode(isBrakeMode ? IdleMode.kBrake : IdleMode.kCoast)); } /** @@ -288,7 +309,7 @@ public void setInverted(boolean inverted) { /** Save the configurations from flash to EEPROM. */ @Override public void burnFlash() { - motor.burnFlash(); + configureSparkMax(() -> motor.burnFlash()); } /** @@ -309,13 +330,17 @@ public void set(double percentOutput) { */ @Override public void setReference(double setpoint, double feedforward) { - int pidSlot = - isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : SparkMAX_slotIdx.Position.ordinal(); - pid.setReference( - setpoint, - isDriveMotor ? ControlType.kVelocity : ControlType.kPosition, - pidSlot, - feedforward); + // int pidSlot = + // isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : + // SparkMAX_slotIdx.Position.ordinal(); + int pidSlot = 0; + configureSparkMax( + () -> + pid.setReference( + setpoint, + isDriveMotor ? ControlType.kVelocity : ControlType.kPosition, + pidSlot, + feedforward)); } /** @@ -358,7 +383,7 @@ public double getPosition() { @Override public void setPosition(double position) { if (absoluteEncoder == null) { - encoder.setPosition(position); + configureSparkMax(() -> encoder.setPosition(position)); } } } diff --git a/src/main/java/swervelib/motors/SparkMaxSwerve.java b/src/main/java/swervelib/motors/SparkMaxSwerve.java index 9d374ad..308ab9b 100644 --- a/src/main/java/swervelib/motors/SparkMaxSwerve.java +++ b/src/main/java/swervelib/motors/SparkMaxSwerve.java @@ -6,8 +6,11 @@ import com.revrobotics.CANSparkMax.IdleMode; import com.revrobotics.CANSparkMaxLowLevel.MotorType; import com.revrobotics.CANSparkMaxLowLevel.PeriodicFrame; +import com.revrobotics.REVLibError; import com.revrobotics.RelativeEncoder; import com.revrobotics.SparkMaxPIDController; +import edu.wpi.first.wpilibj.DriverStation; +import java.util.function.Supplier; import swervelib.encoders.SwerveAbsoluteEncoder; import swervelib.parser.PIDFConfig; @@ -42,7 +45,8 @@ public SparkMaxSwerve(CANSparkMax motor, boolean isDriveMotor) { pid.setFeedbackDevice( encoder); // Configure feedback of the PID controller as the integrated encoder. - motor.setCANTimeout(0); // Spin off configurations in a different thread. + // Spin off configurations in a different thread. + configureSparkMax(() -> motor.setCANTimeout(0)); } /** @@ -55,6 +59,20 @@ public SparkMaxSwerve(int id, boolean isDriveMotor) { this(new CANSparkMax(id, MotorType.kBrushless), isDriveMotor); } + /** + * Run the configuration until it succeeds or times out. + * + * @param config Lambda supplier returning the error state. + */ + private void configureSparkMax(Supplier config) { + for (int i = 0; i < maximumRetries; i++) { + if (config.get() == REVLibError.kOk) { + return; + } + } + DriverStation.reportWarning("Failure configuring motor " + motor.getDeviceId(), true); + } + /** * Set the voltage compensation for the swerve module motor. * @@ -62,7 +80,7 @@ public SparkMaxSwerve(int id, boolean isDriveMotor) { */ @Override public void setVoltageCompensation(double nominalVoltage) { - motor.enableVoltageCompensation(nominalVoltage); + configureSparkMax(() -> motor.enableVoltageCompensation(nominalVoltage)); } /** @@ -73,7 +91,7 @@ public void setVoltageCompensation(double nominalVoltage) { */ @Override public void setCurrentLimit(int currentLimit) { - motor.setSmartCurrentLimit(currentLimit); + configureSparkMax(() -> motor.setSmartCurrentLimit(currentLimit)); } /** @@ -83,8 +101,8 @@ public void setCurrentLimit(int currentLimit) { */ @Override public void setLoopRampRate(double rampRate) { - motor.setOpenLoopRampRate(rampRate); - motor.setClosedLoopRampRate(rampRate); + configureSparkMax(() -> motor.setOpenLoopRampRate(rampRate)); + configureSparkMax(() -> motor.setClosedLoopRampRate(rampRate)); } /** @@ -111,7 +129,7 @@ public boolean isAttachedAbsoluteEncoder() { @Override public void factoryDefaults() { if (!factoryDefaultOccurred) { - motor.restoreFactoryDefaults(); + configureSparkMax(motor::restoreFactoryDefaults); factoryDefaultOccurred = true; } } @@ -119,7 +137,7 @@ public void factoryDefaults() { /** Clear the sticky faults on the motor controller. */ @Override public void clearStickyFaults() { - motor.clearFaults(); + configureSparkMax(motor::clearFaults); } /** @@ -132,7 +150,7 @@ public void clearStickyFaults() { public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) { if (encoder.getAbsoluteEncoder() instanceof AbsoluteEncoder) { absoluteEncoder = (AbsoluteEncoder) encoder.getAbsoluteEncoder(); - pid.setFeedbackDevice(absoluteEncoder); + configureSparkMax(() -> pid.setFeedbackDevice(absoluteEncoder)); } return this; } @@ -146,15 +164,17 @@ public SwerveMotor setAbsoluteEncoder(SwerveAbsoluteEncoder encoder) { @Override public void configureIntegratedEncoder(double positionConversionFactor) { if (absoluteEncoder == null) { - encoder.setPositionConversionFactor(positionConversionFactor); - encoder.setVelocityConversionFactor(positionConversionFactor / 60); + configureSparkMax(() -> encoder.setPositionConversionFactor(positionConversionFactor)); + configureSparkMax(() -> encoder.setVelocityConversionFactor(positionConversionFactor / 60)); // Taken from // https://github.com/frc3512/SwerveBot-2022/blob/9d31afd05df6c630d5acb4ec2cf5d734c9093bf8/src/main/java/frc/lib/util/CANSparkMaxUtil.java#L67 configureCANStatusFrames(10, 20, 20, 500, 500); } else { - absoluteEncoder.setPositionConversionFactor(positionConversionFactor); - absoluteEncoder.setVelocityConversionFactor(positionConversionFactor / 60); + configureSparkMax( + () -> absoluteEncoder.setPositionConversionFactor(positionConversionFactor)); + configureSparkMax( + () -> absoluteEncoder.setVelocityConversionFactor(positionConversionFactor / 60)); } } @@ -165,15 +185,16 @@ public void configureIntegratedEncoder(double positionConversionFactor) { */ @Override public void configurePIDF(PIDFConfig config) { - int pidSlot = - isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : SparkMAX_slotIdx.Position.ordinal(); - pidSlot = 0; - pid.setP(config.p, pidSlot); - pid.setI(config.i, pidSlot); - pid.setD(config.d, pidSlot); - pid.setFF(config.f, pidSlot); - pid.setIZone(config.iz, pidSlot); - pid.setOutputRange(config.output.min, config.output.max, pidSlot); + // int pidSlot = + // isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : + // SparkMAX_slotIdx.Position.ordinal(); + int pidSlot = 0; + configureSparkMax(() -> pid.setP(config.p, pidSlot)); + configureSparkMax(() -> pid.setI(config.i, pidSlot)); + configureSparkMax(() -> pid.setD(config.d, pidSlot)); + configureSparkMax(() -> pid.setFF(config.f, pidSlot)); + configureSparkMax(() -> pid.setIZone(config.iz, pidSlot)); + configureSparkMax(() -> pid.setOutputRange(config.output.min, config.output.max, pidSlot)); } /** @@ -184,9 +205,9 @@ public void configurePIDF(PIDFConfig config) { */ @Override public void configurePIDWrapping(double minInput, double maxInput) { - pid.setPositionPIDWrappingEnabled(true); - pid.setPositionPIDWrappingMinInput(minInput); - pid.setPositionPIDWrappingMaxInput(maxInput); + configureSparkMax(() -> pid.setPositionPIDWrappingEnabled(true)); + configureSparkMax(() -> pid.setPositionPIDWrappingMinInput(minInput)); + configureSparkMax(() -> pid.setPositionPIDWrappingMaxInput(maxInput)); } /** @@ -200,11 +221,11 @@ public void configurePIDWrapping(double minInput, double maxInput) { */ public void configureCANStatusFrames( int CANStatus0, int CANStatus1, int CANStatus2, int CANStatus3, int CANStatus4) { - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus0, CANStatus0); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus1, CANStatus1); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus2, CANStatus2); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus3, CANStatus3); - motor.setPeriodicFramePeriod(PeriodicFrame.kStatus4, CANStatus4); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus0, CANStatus0)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus1, CANStatus1)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus2, CANStatus2)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus3, CANStatus3)); + configureSparkMax(() -> motor.setPeriodicFramePeriod(PeriodicFrame.kStatus4, CANStatus4)); // TODO: Configure Status Frame 5 and 6 if necessary // https://docs.revrobotics.com/sparkmax/operating-modes/control-interfaces } @@ -216,7 +237,7 @@ public void configureCANStatusFrames( */ @Override public void setMotorBrake(boolean isBrakeMode) { - motor.setIdleMode(isBrakeMode ? IdleMode.kBrake : IdleMode.kCoast); + configureSparkMax(() -> motor.setIdleMode(isBrakeMode ? IdleMode.kBrake : IdleMode.kCoast)); } /** @@ -236,7 +257,7 @@ public void burnFlash() { Thread.sleep(200); } catch (Exception e) { } - motor.burnFlash(); + configureSparkMax(() -> motor.burnFlash()); } /** @@ -258,14 +279,17 @@ public void set(double percentOutput) { @Override public void setReference(double setpoint, double feedforward) { boolean possibleBurnOutIssue = true; - int pidSlot = - isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : SparkMAX_slotIdx.Position.ordinal(); - pidSlot = 0; + // int pidSlot = + // isDriveMotor ? SparkMAX_slotIdx.Velocity.ordinal() : + // SparkMAX_slotIdx.Position.ordinal(); + int pidSlot = 0; if (isDriveMotor) { - pid.setReference(setpoint, ControlType.kVelocity, pidSlot, feedforward); + configureSparkMax( + () -> pid.setReference(setpoint, ControlType.kVelocity, pidSlot, feedforward)); } else { - pid.setReference(setpoint, ControlType.kPosition, pidSlot, feedforward); + configureSparkMax( + () -> pid.setReference(setpoint, ControlType.kPosition, pidSlot, feedforward)); } } @@ -309,7 +333,7 @@ public double getPosition() { @Override public void setPosition(double position) { if (absoluteEncoder == null) { - encoder.setPosition(position); + configureSparkMax(() -> encoder.setPosition(position)); } } diff --git a/src/main/java/swervelib/motors/SwerveMotor.java b/src/main/java/swervelib/motors/SwerveMotor.java index 99365b7..569cd95 100644 --- a/src/main/java/swervelib/motors/SwerveMotor.java +++ b/src/main/java/swervelib/motors/SwerveMotor.java @@ -8,6 +8,11 @@ */ public abstract class SwerveMotor { + /** + * The maximum amount of times the swerve motor will attempt to configure a motor if failures + * occur. + */ + public final int maximumRetries = 5; /** Whether the swerve motor is a drive motor. */ protected boolean isDriveMotor; diff --git a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml index 2e6e475..903bea2 100644 --- a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml +++ b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml @@ -8,6 +8,6 @@ 2023.0.6 - 20230830020321 + 20230830025709 diff --git a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.md5 b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.md5 index 4a9deda..6a40962 100644 --- a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.md5 +++ b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.md5 @@ -1 +1 @@ -cf13497a4123468f14b7796490b317ae \ No newline at end of file +af45abc8a3fd6fdf8b1d4a6ad5cd3953 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha1 b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha1 index d9c08ad..674e595 100644 --- a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha1 +++ b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha1 @@ -1 +1 @@ -97d526d890ab4f8733fc89d6af08df048a8283b5 \ No newline at end of file +081b5a5bfc3916c09035bc05d4dbd15821e32131 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha256 b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha256 index afb1250..da110e5 100644 --- a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha256 +++ b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha256 @@ -1 +1 @@ -9ebfeea7bfb21e49f23bd80e4c2b2e404e5ec53d711a3bdec5b7887503419613 \ No newline at end of file +5178d7973cd079217fbc37677ac1101f93ca5fcd9d9333e28076d8e9f9555668 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha512 b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha512 index 8273b8d..3426e9c 100644 --- a/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha512 +++ b/yagsl/repos/swervelib/YAGSL-cpp/maven-metadata.xml.sha512 @@ -1 +1 @@ -9affbfe564f7ae266d551e651b240f297345b89de42f4eb2fb7300d1a4922bc0f18622aec82e79a7780c8a78000a5a4db661c674ccd707c5172a14d55944f272 \ No newline at end of file +1b28591f76f1042a8885b24e251227c55ea0a63fa135af00c48d006d7d1316ca53d4018c8bf72644749d2c5b86ec787d25aaed1f76ecc87da08b1a5fb120369e \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar index 6c1c7a8..2756475 100644 Binary files a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar and b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar differ diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.md5 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.md5 index 08350eb..8a019a6 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.md5 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.md5 @@ -1 +1 @@ -c373d7c3767f717c9a6d3fe91050807a \ No newline at end of file +c42d0787b015598645c01e7e67fdd2ed \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha1 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha1 index 066fd90..38dbb60 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha1 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha1 @@ -1 +1 @@ -880393f4eb863edf432fd79a375c11b6ba4638d6 \ No newline at end of file +ae08ed1d5fe08c94b0416108a3c984eb122edc32 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha256 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha256 index 07e3055..225eeaa 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha256 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha256 @@ -1 +1 @@ -6d92e82b8eb353d560634dda046d2cb1f162d9fd1a2d44a002f6acc452bbe0c6 \ No newline at end of file +99121689ad1b076d6cc126a6dfc92de66a692c03cbfad72af7034bf0ffb4a704 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha512 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha512 index e2819f4..7f65364 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha512 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-javadoc.jar.sha512 @@ -1 +1 @@ -148af091a0e53bc201ec289b492065f2c207e3305b81a849bdd96d5a44d4890c53ff990c0fcebbe0ebd481eaf8ffb25eb143efa5b208d4dd45308285698162e3 \ No newline at end of file +fd95e96124867d038ceaadfc8d4be1c1efac0e8fc3430babcd8898750786a734c4250b9467648d3f002390a3f959c61dd4c75ca04433848354596e81cb41afa3 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar index 41dc73f..d5dd6ac 100644 Binary files a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar and b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar differ diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.md5 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.md5 index a6429b6..b767bb8 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.md5 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.md5 @@ -1 +1 @@ -54501890061fa04c79ac085841bc8d04 \ No newline at end of file +d8d8b7f928c4df193ff1f2d418a16472 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha1 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha1 index 89677ab..6acdec4 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha1 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha1 @@ -1 +1 @@ -bf1fb019812d2b2812dd51a15529381d4192a781 \ No newline at end of file +b9255d677764b8c7da30b2ae334b1caf804a341c \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha256 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha256 index 89c1f15..b2996d4 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha256 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha256 @@ -1 +1 @@ -7e111d0c2ff87546023ff645841f54ae79bc2ab385d9f525abca13a9dc95d749 \ No newline at end of file +d82a1b7006fdfbfda62d27f7b0c102a4318d65191d7a6d88a1df69ebe0a90d79 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha512 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha512 index 8b14efa..451a0c9 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha512 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6-sources.jar.sha512 @@ -1 +1 @@ -aec7b073f2f59764282c48aed123535b78890cb6721292d5b9e5df1b56bf82dfa382fc55d158f44293b1784ec9a70afdb7aa7a6f2d1e5b1f41db40165c86751e \ No newline at end of file +0d4a57b804106ac6efbb1be366965decb6d02f9d2822478da48e4f835c399708c0520df149896c615ea278a7ab724296256dc7eea0e37674fe246495fc0e185e \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar index 060678f..16740cd 100644 Binary files a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar and b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar differ diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.md5 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.md5 index c31f4d0..bce1abf 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.md5 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.md5 @@ -1 +1 @@ -93febeed8db5c3bbbdfb7530cd496c2c \ No newline at end of file +da3b6ac71ddbd08a32e06162c54322ef \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha1 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha1 index de7bd37..2b3ac72 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha1 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha1 @@ -1 +1 @@ -3e06db5e67ad59785dd509cda4766a22d67486cf \ No newline at end of file +b4dd958d11e23a8a4774b4e3f7a0cf4ac0a18bb1 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha256 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha256 index fc53858..c5a52bd 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha256 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha256 @@ -1 +1 @@ -e9a4967a3f0f77e747193cff00af30499c687e2356e7fde34b6a85a084f26277 \ No newline at end of file +fe05f10da153cd1fc876e54ff404cbda419853b6dd57868ccc737e66450999bb \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha512 b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha512 index b264030..345d187 100644 --- a/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha512 +++ b/yagsl/repos/swervelib/YAGSL-java/2023.0.6/YAGSL-java-2023.0.6.jar.sha512 @@ -1 +1 @@ -3d541baee00aaeb8e75e45d192857d1f78bc5fd57a1da1e9fd18363f2f127a4a5e806cb80f510b89667c30245d24ed5846dc9e0bafda67ea086888320c9139cd \ No newline at end of file +2dbad654dfb29fe5f79d78685a30d156ee0b1c9debead0626aafbe3e7eb4b801b9de4de27f82c149bd22460e736a69e8942c4d22d7a343a3b05e22ed6b5c106c \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml index 66aa289..d8e5e38 100644 --- a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml +++ b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml @@ -8,6 +8,6 @@ 2023.0.6 - 20230830020324 + 20230830025712 diff --git a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.md5 b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.md5 index 717268f..5070215 100644 --- a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.md5 +++ b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.md5 @@ -1 +1 @@ -e8659340158e2c81a780aec5b3ae6073 \ No newline at end of file +0bfb37afda5eeab7c40bb7b722de7e55 \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha1 b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha1 index e742f3c..4785720 100644 --- a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha1 +++ b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha1 @@ -1 +1 @@ -f2094f5e62943ae4cc4ee5dc0ece686ab3b27efd \ No newline at end of file +201702ce94d0931400d8ce7386baddec2b9bd14e \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha256 b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha256 index a82e02b..bccf7b7 100644 --- a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha256 +++ b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha256 @@ -1 +1 @@ -dd14256aeb99ba852b2a4f6b9914a01b914006509ef10cf4fb4ae380cc477a02 \ No newline at end of file +2c8af8b0cc0ca24061cb4a26c9175b078821f39d388476758f9872cf1faf5fec \ No newline at end of file diff --git a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha512 b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha512 index daabe8d..c4c0d16 100644 --- a/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha512 +++ b/yagsl/repos/swervelib/YAGSL-java/maven-metadata.xml.sha512 @@ -1 +1 @@ -c0adfc7ed0a517ab5c6f40202a929e55be5ebdf496c66c3cff63288365e8ba4719c83e98cecdab86c101e480dc05ac65330cca27e0ba751084ae5949b03e01bd \ No newline at end of file +8da8c83075d203f7b3ee768aec031fac56361bdc3308ddbc4012214b5370ef9c8f22b7b336233118d488a3691aa86d0bdb7ff98f35444c7fe4feba45dea42028 \ No newline at end of file