generated from StuyPulse/Phil
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from StuyPulse/se/swerve
Add Swerve subsystem
- Loading branch information
Showing
11 changed files
with
541 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/main/java/com/stuypulse/robot/subsystems/swerve/AbstractSwerveDrive.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.stuypulse.robot.subsystems.swerve; | ||
import com.stuypulse.stuylib.math.Vector2D; | ||
|
||
import edu.wpi.first.math.geometry.Translation2d; | ||
import edu.wpi.first.math.kinematics.ChassisSpeeds; | ||
import edu.wpi.first.math.kinematics.SwerveModuleState; | ||
import edu.wpi.first.wpilibj.smartdashboard.Field2d; | ||
import edu.wpi.first.wpilibj2.command.SubsystemBase; | ||
|
||
public abstract class AbstractSwerveDrive extends SubsystemBase { | ||
public abstract void initFieldObject(Field2d field); | ||
public abstract SwerveModuleState[] getModuleStates(); | ||
public abstract Translation2d[] getModulePositions(); | ||
public abstract void setChassisSpeed(ChassisSpeeds speeds); | ||
public abstract void setModuleStates(SwerveModuleState[] states); | ||
public abstract void drive(Vector2D velocity, double Rotation2D); | ||
public abstract void stop(double Rotation2D); | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/com/stuypulse/robot/subsystems/swerve/AbstractSwerveModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.stuypulse.robot.subsystems.swerve; | ||
|
||
import edu.wpi.first.math.geometry.Rotation2d; | ||
|
||
import edu.wpi.first.math.geometry.Translation2d; | ||
import edu.wpi.first.math.kinematics.SwerveModuleState; | ||
import edu.wpi.first.wpilibj2.command.SubsystemBase; | ||
|
||
public abstract class AbstractSwerveModule extends SubsystemBase { | ||
public abstract SwerveModuleState getState(); | ||
public abstract double getVelocity(); | ||
public abstract Rotation2d getAngle(); | ||
public abstract String getId(); | ||
public abstract Translation2d getModulePosition(); | ||
public abstract void setState(SwerveModuleState state); | ||
public abstract void periodic(); | ||
public Object getRotation2d() { | ||
// TODO Auto-generated method stub | ||
throw new UnsupportedOperationException("Unimplemented method 'getRotation2d'"); | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
} | ||
|
194 changes: 194 additions & 0 deletions
194
src/main/java/com/stuypulse/robot/subsystems/swerve/SwerveDrive.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
package com.stuypulse.robot.subsystems.swerve; | ||
|
||
import com.ctre.phoenix6.mechanisms.swerve.SwerveDrivetrain.SwerveDriveState; | ||
import com.ctre.phoenix6.sim.ChassisReference; | ||
import com.kauailabs.navx.frc.AHRS; | ||
import com.stuypulse.robot.constants.Settings; | ||
import com.stuypulse.stuylib.math.Vector2D; | ||
|
||
import edu.wpi.first.math.geometry.Pose2d; | ||
import edu.wpi.first.math.geometry.Rotation2d; | ||
import edu.wpi.first.math.geometry.Translation2d; | ||
import edu.wpi.first.math.geometry.Twist2d; | ||
import edu.wpi.first.math.kinematics.ChassisSpeeds; | ||
import edu.wpi.first.math.kinematics.SwerveDriveKinematics; | ||
import edu.wpi.first.math.kinematics.SwerveModuleState; | ||
import edu.wpi.first.wpilibj.SPI; | ||
import edu.wpi.first.wpilibj.smartdashboard.Field2d; | ||
import edu.wpi.first.wpilibj.smartdashboard.FieldObject2d; | ||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; | ||
|
||
/* | ||
* Fields: | ||
* - swerveModules: AbstractSwerveModule... | ||
* - kinematics: SwerveDriveKinematics | ||
* - gyro: AHRS | ||
* - modules2D: FieldObject2D[] | ||
* | ||
* Tasks: | ||
* - drive | ||
* - followDrive | ||
* - trackingDrive | ||
* - aligning (Trap, Speaker, Amp) | ||
* - GTADrive (shooting while driving) | ||
* | ||
* Methods: | ||
* + singleton | ||
* + initFieldObject(Field2D field): void | ||
* + getModulePositions(): Translation2D[] | ||
* + getModuleStates(): SwerveModuleStates[] | ||
* + getModuleOffsets(): Rotation2D[] | ||
* + getChassisSpeeds(): ChassisSpeed[] | ||
* + setModuleStates(SwerveModuleState... states): void | ||
* + setChassisSpeed(ChassisSpeed): void | ||
* + drive(double, Rotation2D) | ||
* + stop(double, Rotation2D) | ||
* | ||
* SwerveDrive.java | ||
* Methods: | ||
* - getGyroAngle(): Rotation2D | ||
* - getGyroYaw(): Rotation2D | ||
* - getGyroPitch(): Rotation2D | ||
* - getGyroRoll(): Rotation2D | ||
* - getKinematics(): SwerveDriveKinematics | ||
* + periodic(): void | ||
* | ||
* | ||
*/ | ||
public class SwerveDrive extends AbstractSwerveDrive { | ||
|
||
private AbstractSwerveModule[] modules; | ||
private SwerveDriveKinematics kinematics; | ||
private AHRS gyro; | ||
private FieldObject2d[] modules2D; | ||
|
||
public SwerveDrive(AbstractSwerveModule[] modules){ | ||
this.modules = modules; | ||
this.kinematics = new SwerveDriveKinematics(getModulePositions()); | ||
this.gyro = new AHRS(SPI.Port.kMXP); | ||
this.modules2D = new FieldObject2d[modules.length]; | ||
} | ||
|
||
@Override | ||
public void initFieldObject(Field2d field) { | ||
for (int i = 0; i < modules.length; i++){ | ||
modules2D[i] = field.getObject(modules[i].getId() + "-2d"); | ||
} | ||
} | ||
|
||
public SwerveDriveKinematics getKinematics() { | ||
return kinematics; | ||
} | ||
|
||
@Override | ||
public SwerveModuleState[] getModuleStates() { | ||
SwerveModuleState[] states = new SwerveModuleState[modules.length]; | ||
for (int i = 0; i< modules.length; i++){ | ||
states[i] = modules[i].getState(); | ||
} | ||
return states; | ||
} | ||
|
||
@Override | ||
public Translation2d[] getModulePositions() { | ||
Translation2d[] offsets = new Translation2d[modules.length]; | ||
for (int i = 0; i < modules.length; i++){ | ||
offsets[i] = modules[i].getModulePosition(); | ||
} | ||
return offsets; | ||
} | ||
|
||
public ChassisSpeeds getChassisSpeed() { | ||
return getKinematics().toChassisSpeeds(getModuleStates()); | ||
} | ||
|
||
/*Setters */ | ||
|
||
private static SwerveModuleState filterModuleState(SwerveModuleState state) { | ||
if (Math.abs(state.speedMetersPerSecond) > Settings.Swerve.MODULE_VELOCITY_DEADBAND.get()) | ||
return state; | ||
|
||
return new SwerveModuleState(0, state.angle); | ||
} | ||
|
||
@Override | ||
public void setModuleStates(SwerveModuleState[] states) { | ||
if (states.length != modules.length) { | ||
throw new IllegalArgumentException("Provided incorrect number of states for swerve drive modules"); | ||
} | ||
|
||
SwerveDriveKinematics.desaturateWheelSpeeds(states, Settings.Swerve.MAX_MODULE_SPEED.get()); | ||
|
||
for (int i = 0; i < modules.length; i++){ | ||
modules[i].setState(filterModuleState(states[i])); | ||
} | ||
} | ||
|
||
@Override | ||
public void setChassisSpeed(ChassisSpeeds robotSpeeds) { | ||
setModuleStates(kinematics.toSwerveModuleStates(robotSpeeds)); | ||
} | ||
|
||
@Override | ||
public void drive(Vector2D velocity, double rotation) { | ||
ChassisSpeeds speeds = ChassisSpeeds.fromFieldRelativeSpeeds( | ||
velocity.x, -velocity.y, | ||
rotation, | ||
getGyroAngle() | ||
); | ||
|
||
Pose2d pose = new Pose2d( | ||
Settings.DT * speeds.vxMetersPerSecond, | ||
Settings.DT * speeds.vyMetersPerSecond, | ||
Rotation2d.fromDegrees(Settings.DT * speeds.omegaRadiansPerSecond) | ||
); | ||
|
||
Twist2d twistVel = new Pose2d().log(pose); | ||
|
||
setChassisSpeed( new ChassisSpeeds( | ||
twistVel.dx / Settings.DT, | ||
twistVel.dy / Settings.DT, | ||
twistVel.dtheta / Settings.DT | ||
)); | ||
} | ||
|
||
@Override | ||
public void stop(double Rotation2D) { | ||
setChassisSpeed(new ChassisSpeeds()); | ||
} | ||
|
||
/*Gyro */ | ||
public Rotation2d getGyroPitch() { | ||
return Rotation2d.fromDegrees(gyro.getPitch()); | ||
} | ||
|
||
public Rotation2d getGyroAngle() { | ||
return gyro.getRotation2d(); | ||
} | ||
|
||
public Rotation2d getGyroRoll() { | ||
return Rotation2d.fromDegrees(gyro.getRoll()); | ||
} | ||
|
||
public Rotation2d getGyroYaw() { | ||
return Rotation2d.fromDegrees(gyro.getYaw()); | ||
} | ||
|
||
public double getForwardAccelerationGs() { | ||
return gyro.getWorldLinearAccelY(); | ||
} | ||
|
||
@Override | ||
public void periodic() { | ||
/*XXX: WAITING FOR ODOMETRY TO WRITE PERIODIC */ | ||
|
||
SmartDashboard.putNumber("Swerve/Gyro Angle (deg)", getGyroAngle().getDegrees()); | ||
SmartDashboard.putNumber("Swerve/Gyro Pitch", getGyroPitch().getDegrees()); | ||
SmartDashboard.putNumber("Swerve/Gyro Roll", getGyroRoll().getDegrees()); | ||
|
||
SmartDashboard.putNumber("Swerve/Forward Acceleration (Gs)", getForwardAccelerationGs()); | ||
SmartDashboard.putNumber("Swerve/X Acceleration (Gs)", gyro.getWorldLinearAccelX()); | ||
SmartDashboard.putNumber("Swerve/Y Acceleration (Gs)", gyro.getWorldLinearAccelY()); | ||
SmartDashboard.putNumber("Swerve/Z Acceleration (Gs)", gyro.getWorldLinearAccelZ()); | ||
} | ||
} |
Oops, something went wrong.