[wpimath] Make swerve and differential kinematics functions immutable (#8274)

Originally started with just swerve, but expanded to diff and mecanum
(docs only) for parity across the drivetrains. Return value checks are
applied when possible to make migration easier and to error loudly if
people forget.

---------

Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
This commit is contained in:
Gold856
2026-04-17 00:23:32 -04:00
committed by GitHub
parent 8c80cdcf28
commit 056d7bcbbe
34 changed files with 396 additions and 394 deletions

View File

@@ -15,10 +15,8 @@ void Drivetrain::Drive(wpi::units::meters_per_second_t xVelocity,
}
chassisVelocities = chassisVelocities.Discretize(period);
auto states = m_kinematics.ToSwerveModuleVelocities(chassisVelocities);
m_kinematics.DesaturateWheelVelocities(&states, kMaxVelocity);
auto [fl, fr, bl, br] = states;
auto [fl, fr, bl, br] = m_kinematics.DesaturateWheelVelocities(
m_kinematics.ToSwerveModuleVelocities(chassisVelocities), kMaxVelocity);
m_frontLeft.SetDesiredVelocity(fl);
m_frontRight.SetDesiredVelocity(fr);
m_backLeft.SetDesiredVelocity(bl);

View File

@@ -52,25 +52,23 @@ void SwerveModule::SetDesiredVelocity(
wpi::math::Rotation2d encoderRotation{
wpi::units::radian_t{m_turningEncoder.GetDistance()}};
// Optimize the desired velocity to avoid spinning further than 90 degrees
desiredVelocity.Optimize(encoderRotation);
// Scale velocity by cosine of angle error. This scales down movement
// Optimize the desired velocity to avoid spinning further than 90 degrees,
// then scale velocity 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.
desiredVelocity.CosineScale(encoderRotation);
auto velocity =
desiredVelocity.Optimize(encoderRotation).CosineScale(encoderRotation);
// Calculate the drive output from the drive PID controller.
const auto driveOutput = m_drivePIDController.Calculate(
m_driveEncoder.GetRate(), desiredVelocity.velocity.value());
m_driveEncoder.GetRate(), velocity.velocity.value());
const auto driveFeedforward =
m_driveFeedforward.Calculate(desiredVelocity.velocity);
const auto driveFeedforward = m_driveFeedforward.Calculate(velocity.velocity);
// Calculate the turning motor output from the turning PID controller.
const auto turnOutput = m_turningPIDController.Calculate(
wpi::units::radian_t{m_turningEncoder.GetDistance()},
desiredVelocity.angle.Radians());
velocity.angle.Radians());
const auto turnFeedforward = m_turnFeedforward.Calculate(
m_turningPIDController.GetSetpoint().velocity);

View File

@@ -18,10 +18,8 @@ void Drivetrain::Drive(wpi::units::meters_per_second_t xVelocity,
}
chassisVelocities = chassisVelocities.Discretize(period);
auto states = m_kinematics.ToSwerveModuleVelocities(chassisVelocities);
m_kinematics.DesaturateWheelVelocities(&states, kMaxVelocity);
auto [fl, fr, bl, br] = states;
auto [fl, fr, bl, br] = m_kinematics.DesaturateWheelVelocities(
m_kinematics.ToSwerveModuleVelocities(chassisVelocities), kMaxVelocity);
m_frontLeft.SetDesiredVelocity(fl);
m_frontRight.SetDesiredVelocity(fr);
m_backLeft.SetDesiredVelocity(bl);

View File

@@ -52,25 +52,23 @@ void SwerveModule::SetDesiredVelocity(
wpi::math::Rotation2d encoderRotation{
wpi::units::radian_t{m_turningEncoder.GetDistance()}};
// Optimize the desired velocity to avoid spinning further than 90 degrees
desiredVelocity.Optimize(encoderRotation);
// Scale velocity by cosine of angle error. This scales down movement
// Optimize the desired velocity to avoid spinning further than 90 degrees,
// then scale velocity 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.
desiredVelocity.CosineScale(encoderRotation);
auto velocity =
desiredVelocity.Optimize(encoderRotation).CosineScale(encoderRotation);
// Calculate the drive output from the drive PID controller.
const auto driveOutput = m_drivePIDController.Calculate(
m_driveEncoder.GetRate(), desiredVelocity.velocity.value());
m_driveEncoder.GetRate(), velocity.velocity.value());
const auto driveFeedforward =
m_driveFeedforward.Calculate(desiredVelocity.velocity);
const auto driveFeedforward = m_driveFeedforward.Calculate(velocity.velocity);
// Calculate the turning motor output from the turning PID controller.
const auto turnOutput = m_turningPIDController.Calculate(
wpi::units::radian_t{m_turningEncoder.GetDistance()},
desiredVelocity.angle.Radians());
velocity.angle.Radians());
const auto turnFeedforward = m_turnFeedforward.Calculate(
m_turningPIDController.GetSetpoint().velocity);