mirror of
https://github.com/BroncBotz3481/YAGSL
synced 2026-06-19 06:21:40 +00:00
199 lines
6.8 KiB
Java
199 lines
6.8 KiB
Java
package swervelib;
|
|
|
|
import edu.wpi.first.math.geometry.Rotation2d;
|
|
import edu.wpi.first.math.kinematics.SwerveModuleState;
|
|
import edu.wpi.first.wpilibj.DriverStation;
|
|
import edu.wpi.first.wpilibj.Timer;
|
|
import swervelib.encoders.SwerveAbsoluteEncoder;
|
|
|
|
/**
|
|
* Class to perform tests on the swerve drive.
|
|
*/
|
|
public class SwerveDriveTest
|
|
{
|
|
|
|
/**
|
|
* Set the angle of the modules to a given {@link Rotation2d}
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to use.
|
|
* @param moduleAngle {@link Rotation2d} to set every module to.
|
|
*/
|
|
public static void angleModules(SwerveDrive swerveDrive, Rotation2d moduleAngle)
|
|
{
|
|
for (SwerveModule swerveModule : swerveDrive.getModules())
|
|
{
|
|
swerveModule.setDesiredState(new SwerveModuleState(0, moduleAngle), false, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Power the drive motors for the swerve drive to a set duty cycle percentage.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to control.
|
|
* @param percentage Duty cycle percentage of voltage to send to drive motors.
|
|
*/
|
|
public static void powerDriveMotorsDutyCycle(SwerveDrive swerveDrive, double percentage)
|
|
{
|
|
for (SwerveModule swerveModule : swerveDrive.getModules())
|
|
{
|
|
swerveModule.getDriveMotor().set(percentage);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Power the angle motors for the swerve drive to a set percentage.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to control.
|
|
* @param percentage DutyCycle percentage to send to angle motors.
|
|
*/
|
|
public static void powerAngleMotors(SwerveDrive swerveDrive, double percentage)
|
|
{
|
|
for (SwerveModule swerveModule : swerveDrive.getModules())
|
|
{
|
|
swerveModule.getAngleMotor().set(percentage);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Power the drive motors for the swerve drive to a set voltage.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to control.
|
|
* @param volts DutyCycle percentage of voltage to send to drive motors.
|
|
*/
|
|
public static void powerDriveMotorsVoltage(SwerveDrive swerveDrive, double volts)
|
|
{
|
|
for (SwerveModule swerveModule : swerveDrive.getModules())
|
|
{
|
|
swerveModule.getDriveMotor().setVoltage(volts);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Power the angle motors for the swerve drive to a set voltage.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to control.
|
|
* @param volts Voltage to send to angle motors.
|
|
*/
|
|
public static void powerAngleMotorsVoltage(SwerveDrive swerveDrive, double volts)
|
|
{
|
|
for (SwerveModule swerveModule : swerveDrive.getModules())
|
|
{
|
|
swerveModule.getAngleMotor().setVoltage(volts);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the modules to center to 0.
|
|
*
|
|
* @param swerveDrive Swerve Drive to control.
|
|
*/
|
|
public static void centerModules(SwerveDrive swerveDrive)
|
|
{
|
|
angleModules(swerveDrive, Rotation2d.fromDegrees(0));
|
|
}
|
|
|
|
/**
|
|
* Find the minimum amount of power required to move the swerve drive motors.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to control.
|
|
* @param minMovement Minimum amount of movement to drive motors.
|
|
* @param testDelaySeconds Time in seconds for the motor to move.
|
|
* @param maxVolts The maximum voltage to send to drive motors.
|
|
* @return minimum voltage required.
|
|
*/
|
|
public static double findDriveMotorKV(SwerveDrive swerveDrive, double minMovement, double testDelaySeconds,
|
|
double maxVolts)
|
|
{
|
|
double[] startingEncoders = new double[4];
|
|
double kV = 0;
|
|
|
|
SwerveDriveTest.powerDriveMotorsVoltage(swerveDrive, 0);
|
|
SwerveModule[] modules = swerveDrive.getModules();
|
|
for (int i = 0; i < modules.length; i++)
|
|
{
|
|
startingEncoders[i] = Math.abs(modules[i].getDriveMotor().getPosition());
|
|
}
|
|
|
|
for (double kV_new = 0; kV_new < maxVolts; kV_new += 0.0001)
|
|
{
|
|
|
|
SwerveDriveTest.powerDriveMotorsVoltage(swerveDrive, kV);
|
|
boolean foundkV = false;
|
|
double startTimeSeconds = Timer.getFPGATimestamp();
|
|
while ((Timer.getFPGATimestamp() - startTimeSeconds) < testDelaySeconds && !foundkV)
|
|
{
|
|
for (int i = 0; i < modules.length; i++)
|
|
{
|
|
if ((modules[i].getDriveMotor().getPosition() - startingEncoders[i]) > minMovement)
|
|
{
|
|
foundkV = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (foundkV)
|
|
{
|
|
SwerveDriveTest.powerDriveMotorsVoltage(swerveDrive, 0);
|
|
kV = kV_new;
|
|
}
|
|
}
|
|
return kV;
|
|
}
|
|
|
|
/**
|
|
* Find the coupling ratio for all modules.
|
|
*
|
|
* @param swerveDrive {@link SwerveDrive} to operate with.
|
|
* @param volts Voltage to send to angle motors to spin.
|
|
* @param automatic Attempt to automatically spin the modules.
|
|
* @return Average coupling ratio.
|
|
*/
|
|
public static double findCouplingRatio(SwerveDrive swerveDrive, double volts, boolean automatic)
|
|
{
|
|
System.out.println("Stopping the Swerve Drive.");
|
|
SwerveDriveTest.powerDriveMotorsVoltage(swerveDrive, 0);
|
|
SwerveDriveTest.powerAngleMotorsVoltage(swerveDrive, 0);
|
|
Timer.delay(1);
|
|
double couplingRatioSum = 0;
|
|
for (SwerveModule module : swerveDrive.getModules())
|
|
{
|
|
if (module.getAbsoluteEncoder() == null)
|
|
{
|
|
throw new RuntimeException("Absolute encoders are required to find the coupling ratio.");
|
|
}
|
|
SwerveAbsoluteEncoder absoluteEncoder = module.getAbsoluteEncoder();
|
|
if (absoluteEncoder.readingError)
|
|
{
|
|
throw new RuntimeException("Absolute encoder encountered a reading error please debug.");
|
|
}
|
|
System.out.println("Fetching the current absolute encoder and drive encoder position.");
|
|
module.getAngleMotor().setVoltage(0);
|
|
Timer.delay(1);
|
|
Rotation2d startingAbsoluteEncoderPosition = Rotation2d.fromDegrees(absoluteEncoder.getAbsolutePosition());
|
|
double driveEncoderPositionRotations = module.getDriveMotor().getPosition() /
|
|
module.configuration.conversionFactors.drive;
|
|
if (automatic)
|
|
{
|
|
module.getAngleMotor().setVoltage(volts);
|
|
Timer.delay(0.01);
|
|
System.out.println("Rotating the module 360 degrees");
|
|
while (!Rotation2d.fromDegrees(absoluteEncoder.getAbsolutePosition()).equals(startingAbsoluteEncoderPosition))
|
|
;
|
|
module.getAngleMotor().setVoltage(0);
|
|
} else
|
|
{
|
|
DriverStation.reportWarning(
|
|
"Spin the " + module.configuration.name + " module 360 degrees now, you have 1 minute.\n",
|
|
false);
|
|
Timer.delay(60);
|
|
}
|
|
double couplingRatio = (module.getDriveMotor().getPosition() / module.configuration.conversionFactors.drive) -
|
|
driveEncoderPositionRotations;
|
|
DriverStation.reportWarning(module.configuration.name + " Coupling Ratio: " + couplingRatio, false);
|
|
couplingRatioSum += couplingRatio;
|
|
}
|
|
DriverStation.reportWarning("Average Coupling Ratio: " + (couplingRatioSum / 4.0), false);
|
|
return (couplingRatioSum / 4.0);
|
|
}
|
|
}
|