[wpimath] Replace Speeds with Velocities (#8479)

I left "free speed" alone since that's the technical term for it. In
general, velocity is a vector quantity, and speed is a magnitude (i.e.,
a strictly positive value).

This PR also replaces the speed verbiage in MotorController with duty
cycle.

Fixes #8423.
This commit is contained in:
Tyler Veness
2026-03-06 14:19:15 -08:00
committed by GitHub
parent 1e39f39128
commit 9bd9656871
594 changed files with 8073 additions and 7875 deletions

View File

@@ -92,10 +92,10 @@ ExpansionHubMotor::~ExpansionHubMotor() noexcept {
m_hub.UnreserveMotor(m_channel);
}
void ExpansionHubMotor::SetPercentagePower(double power) {
void ExpansionHubMotor::SetDutyCycle(double dutyCycle) {
SetEnabled(true);
m_modePublisher.Set(kPercentageMode);
m_setpointPublisher.Set(power);
m_setpointPublisher.Set(dutyCycle);
}
void ExpansionHubMotor::SetVoltage(wpi::units::volt_t voltage) {

View File

@@ -69,7 +69,7 @@ LEDPattern LEDPattern::OffsetBy(int offset) {
});
}
LEDPattern LEDPattern::ScrollAtRelativeSpeed(wpi::units::hertz_t velocity) {
LEDPattern LEDPattern::ScrollAtRelativeVelocity(wpi::units::hertz_t velocity) {
// velocity is in terms of LED lengths per second (1_hz = full cycle per
// second, 0.5_hz = half cycle per second, 2_hz = two cycles per second)
// Invert and multiply by 1,000,000 to get microseconds
@@ -88,7 +88,7 @@ LEDPattern LEDPattern::ScrollAtRelativeSpeed(wpi::units::hertz_t velocity) {
});
}
LEDPattern LEDPattern::ScrollAtAbsoluteSpeed(
LEDPattern LEDPattern::ScrollAtAbsoluteVelocity(
wpi::units::meters_per_second_t velocity, wpi::units::meter_t ledSpacing) {
// Velocity is in terms of meters per second
// Multiply by 1,000,000 to use microseconds instead of seconds

View File

@@ -8,7 +8,7 @@
using namespace wpi;
void MotorController::SetVoltage(wpi::units::volt_t output) {
void MotorController::SetVoltage(wpi::units::volt_t voltage) {
// NOLINTNEXTLINE(bugprone-integer-division)
Set(output / RobotController::GetBatteryVoltage());
SetDutyCycle(voltage / RobotController::GetBatteryVoltage());
}

View File

@@ -14,33 +14,28 @@
using namespace wpi;
void PWMMotorController::Set(double speed) {
void PWMMotorController::SetDutyCycle(double dutyCycle) {
if (m_isInverted) {
speed = -speed;
dutyCycle = -dutyCycle;
}
SetSpeed(speed);
SetDutyCycleInternal(dutyCycle);
for (auto& follower : m_nonowningFollowers) {
follower->Set(speed);
follower->SetDutyCycle(dutyCycle);
}
for (auto& follower : m_owningFollowers) {
follower->Set(speed);
follower->SetDutyCycle(dutyCycle);
}
Feed();
}
void PWMMotorController::SetVoltage(wpi::units::volt_t output) {
// NOLINTNEXTLINE(bugprone-integer-division)
Set(output / RobotController::GetBatteryVoltage());
}
double PWMMotorController::Get() const {
return GetSpeed() * (m_isInverted ? -1.0 : 1.0);
double PWMMotorController::GetDutyCycle() const {
return GetDutyCycleInternal() * (m_isInverted ? -1.0 : 1.0);
}
wpi::units::volt_t PWMMotorController::GetVoltage() const {
return Get() * RobotController::GetBatteryVoltage();
return GetDutyCycle() * RobotController::GetBatteryVoltage();
}
void PWMMotorController::SetInverted(bool isInverted) {
@@ -54,8 +49,8 @@ bool PWMMotorController::GetInverted() const {
void PWMMotorController::Disable() {
m_pwm.SetDisabled();
if (m_simSpeed) {
m_simSpeed.Set(0.0);
if (m_simDutyCycle) {
m_simDutyCycle.Set(0.0);
}
for (auto& follower : m_nonowningFollowers) {
@@ -94,7 +89,7 @@ PWMMotorController::PWMMotorController(std::string_view name, int channel)
m_simDevice = wpi::hal::SimDevice{"PWMMotorController", channel};
if (m_simDevice) {
m_simSpeed = m_simDevice.CreateDouble("Speed", true, 0.0);
m_simDutyCycle = m_simDevice.CreateDouble("DutyCycle", true, 0.0);
m_pwm.SetSimDevice(m_simDevice);
}
}
@@ -105,8 +100,8 @@ void PWMMotorController::InitSendable(wpi::util::SendableBuilder& builder) {
builder.SetSmartDashboardType("Motor Controller");
builder.SetActuator(true);
builder.AddDoubleProperty(
"Value", [=, this] { return Get(); },
[=, this](double value) { Set(value); });
"Value", [=, this] { return GetDutyCycle(); },
[=, this](double value) { SetDutyCycle(value); });
}
wpi::units::microsecond_t PWMMotorController::GetMinPositivePwm() const {
@@ -133,34 +128,34 @@ wpi::units::microsecond_t PWMMotorController::GetNegativeScaleFactor() const {
return GetMaxNegativePwm() - m_minPwm;
}
void PWMMotorController::SetSpeed(double speed) {
if (std::isfinite(speed)) {
speed = std::clamp(speed, -1.0, 1.0);
void PWMMotorController::SetDutyCycleInternal(double dutyCycle) {
if (std::isfinite(dutyCycle)) {
dutyCycle = std::clamp(dutyCycle, -1.0, 1.0);
} else {
speed = 0.0;
dutyCycle = 0.0;
}
if (m_simSpeed) {
m_simSpeed.Set(speed);
if (m_simDutyCycle) {
m_simDutyCycle.Set(dutyCycle);
}
wpi::units::microsecond_t rawValue;
if (speed == 0.0) {
if (dutyCycle == 0.0) {
rawValue = m_centerPwm;
} else if (speed > 0.0) {
rawValue = wpi::units::microsecond_t{static_cast<double>(
std::lround((speed * GetPositiveScaleFactor()).value()))} +
} else if (dutyCycle > 0.0) {
rawValue = wpi::units::microsecond_t{static_cast<double>(std::lround(
(dutyCycle * GetPositiveScaleFactor()).value()))} +
GetMinPositivePwm();
} else {
rawValue = wpi::units::microsecond_t{static_cast<double>(
std::lround((speed * GetNegativeScaleFactor()).value()))} +
rawValue = wpi::units::microsecond_t{static_cast<double>(std::lround(
(dutyCycle * GetNegativeScaleFactor()).value()))} +
GetMaxNegativePwm();
}
m_pwm.SetPulseTime(rawValue);
}
double PWMMotorController::GetSpeed() const {
double PWMMotorController::GetDutyCycleInternal() const {
wpi::units::microsecond_t rawValue = m_pwm.GetPulseTime();
if (rawValue == 0_us) {

View File

@@ -150,7 +150,8 @@ void Encoder::InitSendable(wpi::util::SendableBuilder& builder) {
builder.SetSmartDashboardType("Encoder");
}
builder.AddDoubleProperty("Speed", [=, this] { return GetRate(); }, nullptr);
builder.AddDoubleProperty(
"Velocity", [=, this] { return GetRate(); }, nullptr);
builder.AddDoubleProperty(
"Distance", [=, this] { return GetDistance(); }, nullptr);
builder.AddDoubleProperty(