Skip to content

Commit bc5df67

Browse files
committed
New DriveSubsystem
1 parent 9b98109 commit bc5df67

1 file changed

Lines changed: 80 additions & 7 deletions

File tree

src/main/java/frc/robot/subsystems/DriveSubsystem.java

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@
44

55
package frc.robot.subsystems;
66

7+
import edu.wpi.first.math.filter.SlewRateLimiter;
78
import edu.wpi.first.math.geometry.Pose2d;
89
import edu.wpi.first.math.geometry.Rotation2d;
910
import edu.wpi.first.math.kinematics.ChassisSpeeds;
1011
import edu.wpi.first.math.kinematics.SwerveDriveKinematics;
1112
import edu.wpi.first.math.kinematics.SwerveDriveOdometry;
1213
import edu.wpi.first.math.kinematics.SwerveModulePosition;
1314
import edu.wpi.first.math.kinematics.SwerveModuleState;
15+
import edu.wpi.first.util.WPIUtilJNI;
1416
import edu.wpi.first.wpilibj.ADIS16470_IMU;
1517
import frc.robot.Constants.DriveConstants;
18+
import frc.robot.Constants.OIConstants;
19+
import frc.utils.SwerveUtils;
1620
import edu.wpi.first.wpilibj2.command.SubsystemBase;
1721

1822
public class DriveSubsystem extends SubsystemBase {
@@ -40,6 +44,15 @@ public class DriveSubsystem extends SubsystemBase {
4044
// The gyro sensor
4145
private final ADIS16470_IMU m_gyro = new ADIS16470_IMU();
4246

47+
// Slew rate filter variables for controlling lateral acceleration
48+
private double currentRotation = 0.0;
49+
private double currentTranslationDir = 0.0;
50+
private double currentTranslationMag = 0.0;
51+
52+
private SlewRateLimiter magLimiter = new SlewRateLimiter(OIConstants.kMagnitudeSlewRate);
53+
private SlewRateLimiter rotLimiter = new SlewRateLimiter(OIConstants.kRotationalSlewRate);
54+
double prevTime = WPIUtilJNI.now() * 1e-6;
55+
4356
// Odometry class for tracking robot pose
4457
SwerveDriveOdometry m_odometry = new SwerveDriveOdometry(
4558
DriveConstants.kDriveKinematics,
@@ -103,16 +116,68 @@ public void resetOdometry(Pose2d pose) {
103116
* @param fieldRelative Whether the provided x and y speeds are relative to the
104117
* field.
105118
*/
106-
public void drive(double xSpeed, double ySpeed, double rot, boolean fieldRelative) {
107-
// Adjust input based on max speed
108-
xSpeed *= DriveConstants.kMaxSpeedMetersPerSecond;
109-
ySpeed *= DriveConstants.kMaxSpeedMetersPerSecond;
110-
rot *= DriveConstants.kMaxAngularSpeed;
119+
public void drive(double xSpeed, double ySpeed, double rot, boolean fieldRelative, boolean rateLimit) {
120+
121+
double xSpeedCommanded;
122+
double ySpeedCommanded;
123+
124+
if (rateLimit) {
125+
// Convert XY to polar for rate limiting
126+
double inputTranslationDir = Math.atan2(ySpeed, xSpeed);
127+
double inputTranslationMag = Math.sqrt(Math.pow(xSpeed, 2) + Math.pow(ySpeed, 2));
128+
129+
// Calculate the direction slew rate based on an estimate of the lateral acceleration
130+
double directionSlewRate;
131+
if (currentTranslationMag != 0.0) {
132+
directionSlewRate = Math.abs(OIConstants.kDirectionSlewRate / currentTranslationMag);
133+
} else {
134+
directionSlewRate = 500.0; //some high number that means the slew rate is effectively instantaneous
135+
}
136+
137+
138+
double currentTime = WPIUtilJNI.now() * 1e-6;
139+
double elapsedTime = currentTime - prevTime;
140+
double angleDif = SwerveUtils.AngleDifference(inputTranslationDir, currentTranslationDir);
141+
if (angleDif < 0.45*Math.PI) {
142+
currentTranslationDir = SwerveUtils.StepTowardsCircular(currentTranslationDir, inputTranslationDir, directionSlewRate * elapsedTime);
143+
currentTranslationMag = magLimiter.calculate(inputTranslationMag);
144+
}
145+
else if (angleDif > 0.85*Math.PI) {
146+
if (currentTranslationMag > 1e-4) { //some small number to avoid floating-point errors with equality checking
147+
// keep currentTranslationDir unchanged
148+
currentTranslationMag = magLimiter.calculate(0.0);
149+
}
150+
else {
151+
currentTranslationDir = SwerveUtils.WrapAngle(currentTranslationDir + Math.PI);
152+
currentTranslationMag = magLimiter.calculate(inputTranslationMag);
153+
}
154+
}
155+
else {
156+
currentTranslationDir = SwerveUtils.StepTowardsCircular(currentTranslationDir, inputTranslationDir, directionSlewRate * elapsedTime);
157+
currentTranslationMag = magLimiter.calculate(0.0);
158+
}
159+
prevTime = currentTime;
160+
161+
xSpeedCommanded = currentTranslationMag * Math.cos(currentTranslationDir);
162+
ySpeedCommanded = currentTranslationMag * Math.sin(currentTranslationDir);
163+
currentRotation = rotLimiter.calculate(rot);
164+
165+
166+
} else {
167+
xSpeedCommanded = xSpeed;
168+
ySpeedCommanded = ySpeed;
169+
currentRotation = rot;
170+
}
171+
172+
// Convert the commanded speeds into the correct units for the drivetrain
173+
double xSpeedDelivered = xSpeedCommanded * DriveConstants.kMaxSpeedMetersPerSecond;
174+
double ySpeedDelivered = ySpeedCommanded * DriveConstants.kMaxSpeedMetersPerSecond;
175+
double rotDelivered = currentRotation * DriveConstants.kMaxAngularSpeed;
111176

112177
var swerveModuleStates = DriveConstants.kDriveKinematics.toSwerveModuleStates(
113178
fieldRelative
114-
? ChassisSpeeds.fromFieldRelativeSpeeds(xSpeed, ySpeed, rot, Rotation2d.fromDegrees(m_gyro.getAngle()))
115-
: new ChassisSpeeds(xSpeed, ySpeed, rot));
179+
? ChassisSpeeds.fromFieldRelativeSpeeds(xSpeedDelivered, ySpeedDelivered, rotDelivered, Rotation2d.fromDegrees(m_gyro.getAngle()))
180+
: new ChassisSpeeds(xSpeedDelivered, ySpeedDelivered, rotDelivered));
116181
SwerveDriveKinematics.desaturateWheelSpeeds(
117182
swerveModuleStates, DriveConstants.kMaxSpeedMetersPerSecond);
118183
m_frontLeft.setDesiredState(swerveModuleStates[0]);
@@ -175,4 +240,12 @@ public double getHeading() {
175240
public double getTurnRate() {
176241
return m_gyro.getRate() * (DriveConstants.kGyroReversed ? -1.0 : 1.0);
177242
}
243+
244+
/*@Override
245+
public void initSendable(SendableBuilder builder) {
246+
super.initSendable(builder);
247+
builder.addDoubleProperty("Magnitude Commanded", () -> magCommanded, null);
248+
//builder.addBooleanProperty("At Setpoint", () -> atSetpoint(), null);
249+
//addChild("Controller", m_controller);
250+
}*/
178251
}

0 commit comments

Comments
 (0)