diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp index 0f9e27ede1..380f8cb593 100644 --- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp +++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp @@ -48,9 +48,17 @@ frc::SwerveModulePosition SwerveModule::GetPosition() const { void SwerveModule::SetDesiredState( const frc::SwerveModuleState& referenceState) { + frc::Rotation2d encoderRotation{ + units::radian_t{m_turningEncoder.GetDistance()}}; + // Optimize the reference state to avoid spinning further than 90 degrees - const auto state = frc::SwerveModuleState::Optimize( - referenceState, units::radian_t{m_turningEncoder.GetDistance()}); + auto state = + frc::SwerveModuleState::Optimize(referenceState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement + // perpendicular to the desired direction of travel that can occur when + // modules change directions. This results in smoother driving. + state.speed *= (state.angle - encoderRotation).Cos(); // Calculate the drive output from the drive PID controller. const auto driveOutput = m_drivePIDController.Calculate( diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp index d4ee6ae6a9..dc1cdb0bc4 100644 --- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp +++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp @@ -55,9 +55,17 @@ frc::SwerveModulePosition SwerveModule::GetPosition() { void SwerveModule::SetDesiredState( const frc::SwerveModuleState& referenceState) { + frc::Rotation2d encoderRotation{ + units::radian_t{m_turningEncoder.GetDistance()}}; + // Optimize the reference state to avoid spinning further than 90 degrees - const auto state = frc::SwerveModuleState::Optimize( - referenceState, units::radian_t{m_turningEncoder.GetDistance()}); + auto state = + frc::SwerveModuleState::Optimize(referenceState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement + // perpendicular to the desired direction of travel that can occur when + // modules change directions. This results in smoother driving. + state.speed *= (state.angle - encoderRotation).Cos(); // Calculate the drive output from the drive PID controller. const auto driveOutput = m_drivePIDController.Calculate( diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp index c5a0839650..2afaf55844 100644 --- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp +++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp @@ -48,9 +48,17 @@ frc::SwerveModulePosition SwerveModule::GetPosition() const { void SwerveModule::SetDesiredState( const frc::SwerveModuleState& referenceState) { + frc::Rotation2d encoderRotation{ + units::radian_t{m_turningEncoder.GetDistance()}}; + // Optimize the reference state to avoid spinning further than 90 degrees - const auto state = frc::SwerveModuleState::Optimize( - referenceState, units::radian_t{m_turningEncoder.GetDistance()}); + auto state = + frc::SwerveModuleState::Optimize(referenceState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement + // perpendicular to the desired direction of travel that can occur when + // modules change directions. This results in smoother driving. + state.speed *= (state.angle - encoderRotation).Cos(); // Calculate the drive output from the drive PID controller. const auto driveOutput = m_drivePIDController.Calculate( diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervebot/SwerveModule.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervebot/SwerveModule.java index 27ea37f46d..65089f973d 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervebot/SwerveModule.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervebot/SwerveModule.java @@ -109,9 +109,15 @@ public class SwerveModule { * @param desiredState Desired state with speed and angle. */ public void setDesiredState(SwerveModuleState desiredState) { + var encoderRotation = new Rotation2d(m_turningEncoder.getDistance()); + // Optimize the reference state to avoid spinning further than 90 degrees - SwerveModuleState state = - SwerveModuleState.optimize(desiredState, new Rotation2d(m_turningEncoder.getDistance())); + SwerveModuleState state = SwerveModuleState.optimize(desiredState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement perpendicular to the desired + // direction of travel that can occur when modules change directions. This results in smoother + // driving. + state.speedMetersPerSecond *= state.angle.minus(encoderRotation).getCos(); // Calculate the drive output from the drive PID controller. final double driveOutput = diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/subsystems/SwerveModule.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/subsystems/SwerveModule.java index 46825b2deb..27e800c649 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/subsystems/SwerveModule.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/subsystems/SwerveModule.java @@ -105,9 +105,15 @@ public class SwerveModule { * @param desiredState Desired state with speed and angle. */ public void setDesiredState(SwerveModuleState desiredState) { + var encoderRotation = new Rotation2d(m_turningEncoder.getDistance()); + // Optimize the reference state to avoid spinning further than 90 degrees - SwerveModuleState state = - SwerveModuleState.optimize(desiredState, new Rotation2d(m_turningEncoder.getDistance())); + SwerveModuleState state = SwerveModuleState.optimize(desiredState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement perpendicular to the desired + // direction of travel that can occur when modules change directions. This results in smoother + // driving. + state.speedMetersPerSecond *= state.angle.minus(encoderRotation).getCos(); // Calculate the drive output from the drive PID controller. final double driveOutput = diff --git a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervedriveposeestimator/SwerveModule.java b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervedriveposeestimator/SwerveModule.java index afd74893c3..938b6c8f3c 100644 --- a/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervedriveposeestimator/SwerveModule.java +++ b/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervedriveposeestimator/SwerveModule.java @@ -109,9 +109,15 @@ public class SwerveModule { * @param desiredState Desired state with speed and angle. */ public void setDesiredState(SwerveModuleState desiredState) { + var encoderRotation = new Rotation2d(m_turningEncoder.getDistance()); + // Optimize the reference state to avoid spinning further than 90 degrees - SwerveModuleState state = - SwerveModuleState.optimize(desiredState, new Rotation2d(m_turningEncoder.getDistance())); + SwerveModuleState state = SwerveModuleState.optimize(desiredState, encoderRotation); + + // Scale speed by cosine of angle error. This scales down movement perpendicular to the desired + // direction of travel that can occur when modules change directions. This results in smoother + // driving. + state.speedMetersPerSecond *= state.angle.minus(encoderRotation).getCos(); // Calculate the drive output from the drive PID controller. final double driveOutput =