Files
YAGSL/swervelib/encoders/SparkMaxEncoderSwerve.java

223 lines
6.4 KiB
Java
Raw Normal View History

2023-02-13 17:21:24 -06:00
package swervelib.encoders;
2023-02-13 14:37:05 -06:00
import com.revrobotics.AbsoluteEncoder;
import com.revrobotics.REVLibError;
2024-12-09 23:26:04 +00:00
import com.revrobotics.spark.SparkAbsoluteEncoder;
import com.revrobotics.spark.SparkMax;
2025-02-22 06:15:56 +00:00
import com.revrobotics.spark.config.ClosedLoopConfig.FeedbackSensor;
2024-12-09 23:26:04 +00:00
import com.revrobotics.spark.config.SparkMaxConfig;
import edu.wpi.first.wpilibj.Alert;
import edu.wpi.first.wpilibj.Alert.AlertType;
import java.util.function.Supplier;
2024-12-09 23:26:04 +00:00
import swervelib.motors.SparkMaxBrushedMotorSwerve;
import swervelib.motors.SparkMaxSwerve;
2023-02-13 17:21:24 -06:00
import swervelib.motors.SwerveMotor;
2023-02-13 14:37:05 -06:00
/**
* SparkMax absolute encoder, attached through the data port.
*/
public class SparkMaxEncoderSwerve extends SwerveAbsoluteEncoder
{
/**
* The {@link AbsoluteEncoder} representing the duty cycle encoder attached to the SparkMax.
*/
2024-12-09 23:26:04 +00:00
public SparkAbsoluteEncoder encoder;
2024-01-17 09:17:39 -06:00
/**
* An {@link Alert} for if there is a failure configuring the encoder.
*/
2024-12-09 23:26:04 +00:00
private Alert failureConfiguring;
2024-01-17 09:17:39 -06:00
/**
* An {@link Alert} for if there is a failure configuring the encoder offset.
*/
2024-12-09 23:26:04 +00:00
private Alert offsetFailure;
/**
* {@link SparkMaxBrushedMotorSwerve} or {@link SparkMaxSwerve} instance.
*/
private SwerveMotor sparkMax;
2023-02-13 14:37:05 -06:00
/**
2024-12-09 23:26:04 +00:00
* Create the {@link SparkMaxEncoderSwerve} object as a duty cycle from the {@link com.revrobotics.spark.SparkMax}
* motor.
2023-02-13 14:37:05 -06:00
*
2023-08-09 15:05:33 -05:00
* @param motor Motor to create the encoder from.
* @param conversionFactor The conversion factor to set if the output is not from 0 to 360.
2023-02-13 14:37:05 -06:00
*/
2023-08-09 15:05:33 -05:00
public SparkMaxEncoderSwerve(SwerveMotor motor, int conversionFactor)
2023-02-13 14:37:05 -06:00
{
2024-02-12 18:59:40 -06:00
failureConfiguring = new Alert(
"Encoders",
2025-02-22 06:15:56 +00:00
"Failure configuring SparkMax Absolute Encoder",
2024-12-09 23:26:04 +00:00
AlertType.kWarning);
2024-02-12 18:59:40 -06:00
offsetFailure = new Alert(
"Encoders",
"Failure to set Absolute Encoder Offset",
2024-12-09 23:26:04 +00:00
AlertType.kWarning);
if (motor.getMotor() instanceof SparkMax)
2023-02-13 14:37:05 -06:00
{
2024-12-09 23:26:04 +00:00
sparkMax = motor;
encoder = ((SparkMax) motor.getMotor()).getAbsoluteEncoder();
2025-02-22 06:15:56 +00:00
setConversionFactor(conversionFactor);
2023-02-13 14:37:05 -06:00
} else
{
throw new RuntimeException("Motor given to instantiate SparkMaxEncoder is not a CANSparkMax");
}
}
2025-02-22 06:15:56 +00:00
@Override
public void close()
{
// SPARK MAX encoder gets closed with the motor
// I don't think an encoder getting closed should
// close the entire motor so i will keep this empty
// sparkFlex.close();
}
/**
* Run the configuration until it succeeds or times out.
*
* @param config Lambda supplier returning the error state.
*/
private void configureSparkMax(Supplier<REVLibError> config)
{
for (int i = 0; i < maximumRetries; i++)
{
if (config.get() == REVLibError.kOk)
{
return;
}
}
2024-01-17 09:17:39 -06:00
failureConfiguring.set(true);
}
2023-02-13 14:37:05 -06:00
/**
* Reset the encoder to factory defaults.
*/
@Override
public void factoryDefault()
{
// Do nothing
}
/**
* Clear sticky faults on the encoder.
*/
@Override
public void clearStickyFaults()
{
// Do nothing
}
/**
* Configure the absolute encoder to read from [0, 360) per second.
*
* @param inverted Whether the encoder is inverted.
*/
@Override
public void configure(boolean inverted)
{
2024-12-09 23:26:04 +00:00
if (sparkMax instanceof SparkMaxSwerve)
{
SparkMaxConfig cfg = ((SparkMaxSwerve) sparkMax).getConfig();
2025-02-22 06:15:56 +00:00
cfg.absoluteEncoder.inverted(inverted);
2024-12-09 23:26:04 +00:00
((SparkMaxSwerve) sparkMax).updateConfig(cfg);
} else if (sparkMax instanceof SparkMaxBrushedMotorSwerve)
{
SparkMaxConfig cfg = ((SparkMaxBrushedMotorSwerve) sparkMax).getConfig();
2025-02-22 06:15:56 +00:00
cfg.absoluteEncoder.inverted(inverted);
2024-12-09 23:26:04 +00:00
((SparkMaxBrushedMotorSwerve) sparkMax).updateConfig(cfg);
}
2023-02-13 14:37:05 -06:00
}
2025-02-22 06:15:56 +00:00
/**
* Set the conversion factor of the {@link SparkMaxEncoderSwerve}.
*
* @param conversionFactor Position conversion factor from ticks to unit.
*/
public void setConversionFactor(double conversionFactor)
{
// By default the SparkMax relays the info from the duty cycle encoder to the roborio every 200ms on CAN frame 5
// This needs to be set to 20ms or under to properly update the swerve module position for odometry
// Configuration taken from 3005, the team who helped develop the Max Swerve:
// https://github.com/FRC3005/Charged-Up-2023-Public/blob/2b6a7c695e23edebafa27a76cf639a00f6e8a3a6/src/main/java/frc/robot/subsystems/drive/REVSwerveModule.java#L227-L244
// Some of the frames can probably be adjusted to decrease CAN utilization, with 65535 being the max.
// From testing, 20ms on frame 5 sometimes returns the same value while constantly powering the azimuth but 8ms may be overkill,
// with limited testing 19ms did not return the same value while the module was constatntly rotating.
SparkMaxConfig cfg = null;
if (sparkMax instanceof SparkMaxSwerve)
{
cfg = ((SparkMaxSwerve) sparkMax).getConfig();
} else if (sparkMax instanceof SparkMaxBrushedMotorSwerve)
{
cfg = ((SparkMaxBrushedMotorSwerve) sparkMax).getConfig();
}
if (cfg != null)
{
cfg.signals
.absoluteEncoderPositionAlwaysOn(true)
.absoluteEncoderPositionPeriodMs(20);
cfg.absoluteEncoder
.positionConversionFactor(conversionFactor)
.velocityConversionFactor(conversionFactor / 60);
}
if (sparkMax instanceof SparkMaxSwerve)
{
((SparkMaxSwerve) sparkMax).updateConfig(cfg);
} else if (sparkMax instanceof SparkMaxBrushedMotorSwerve)
{
((SparkMaxBrushedMotorSwerve) sparkMax).updateConfig(cfg);
}
}
2023-02-13 14:37:05 -06:00
/**
* Get the absolute position of the encoder.
*
* @return Absolute position in degrees from [0, 360).
*/
@Override
public double getAbsolutePosition()
{
return encoder.getPosition();
}
/**
* Get the instantiated absolute encoder Object.
*
* @return Absolute encoder object.
*/
@Override
public Object getAbsoluteEncoder()
{
return encoder;
}
/**
* Sets the Absolute Encoder Offset inside of the SparkMax's Memory.
*
* @param offset the offset the Absolute Encoder uses as the zero point.
* @return if setting Absolute Encoder Offset was successful or not.
*/
@Override
public boolean setAbsoluteEncoderOffset(double offset)
{
return false;
}
/**
* Get the velocity in degrees/sec.
*
* @return velocity in degrees/sec.
*/
@Override
public double getVelocity()
{
return encoder.getVelocity();
}
2023-02-13 14:37:05 -06:00
}