-
Notifications
You must be signed in to change notification settings - Fork 671
Fix DCMotor equations to use freeCurrent #8395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,7 +68,7 @@ public DCMotor( | |
| this.rOhms = nominalVoltageVolts / this.stallCurrentAmps; | ||
| this.KvRadPerSecPerVolt = | ||
| freeSpeedRadPerSec / (nominalVoltageVolts - rOhms * this.freeCurrentAmps); | ||
| this.KtNMPerAmp = this.stallTorqueNewtonMeters / this.stallCurrentAmps; | ||
| this.KtNMPerAmp = this.stallTorqueNewtonMeters / (this.stallCurrentAmps - this.freeCurrentAmps); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -89,7 +89,7 @@ public double getCurrent(double speedRadiansPerSec, double voltageInputVolts) { | |
| * @return The current drawn by the motor. | ||
| */ | ||
| public double getCurrent(double torqueNm) { | ||
| return torqueNm / KtNMPerAmp; | ||
| return torqueNm / KtNMPerAmp + freeCurrentAmps; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -99,7 +99,7 @@ public double getCurrent(double torqueNm) { | |
| * @return The torque output. | ||
| */ | ||
| public double getTorque(double currentAmpere) { | ||
| return currentAmpere * KtNMPerAmp; | ||
| return (currentAmpere - freeCurrentAmps) * KtNMPerAmp; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -110,7 +110,7 @@ public double getTorque(double currentAmpere) { | |
| * @return The voltage of the motor. | ||
| */ | ||
| public double getVoltage(double torqueNm, double speedRadiansPerSec) { | ||
| return 1.0 / KvRadPerSecPerVolt * speedRadiansPerSec + 1.0 / KtNMPerAmp * rOhms * torqueNm; | ||
| return 1.0 / KvRadPerSecPerVolt * speedRadiansPerSec + 1.0 / KtNMPerAmp * rOhms * torqueNm + freeCurrentAmps * rOhms; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -122,7 +122,7 @@ public double getVoltage(double torqueNm, double speedRadiansPerSec) { | |
| */ | ||
| public double getSpeed(double torqueNm, double voltageInputVolts) { | ||
| return voltageInputVolts * KvRadPerSecPerVolt | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem right, since plugging in a torque and voltage of zero results in a nonzero speed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. free current scales with voltage right?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know. I was only ever taught about free current with respect to the free speed at the test voltage. I'm unable to find more info online either. |
||
| - 1.0 / KtNMPerAmp * torqueNm * rOhms * KvRadPerSecPerVolt; | ||
| - 1.0 / KtNMPerAmp * torqueNm * rOhms * KvRadPerSecPerVolt - KvRadPerSecPerVolt * freeCurrentAmps * rOhms; | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| // Copyright (c) FIRST and other WPILib contributors. | ||
| // Open Source Software; you can modify and/or share it under the terms of | ||
| // the WPILib BSD license file in the root directory of this project. | ||
|
|
||
| package edu.wpi.first.math.system.plant; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| import java.util.function.Supplier; | ||
| import java.util.stream.Stream; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.Arguments; | ||
| import org.junit.jupiter.params.provider.MethodSource; | ||
|
|
||
| class DCMotorTest { | ||
| private static final double kTolerance = 1e-12; | ||
|
|
||
| static Stream<Arguments> motors() { | ||
| return Stream.of( | ||
| Arguments.of("CIM", (Supplier<DCMotor>) () -> DCMotor.getCIM(1)), | ||
| Arguments.of("MiniCIM", (Supplier<DCMotor>) () -> DCMotor.getMiniCIM(1)), | ||
| Arguments.of("Bag", (Supplier<DCMotor>) () -> DCMotor.getBag(1)), | ||
| Arguments.of("Vex775Pro", (Supplier<DCMotor>) () -> DCMotor.getVex775Pro(1)), | ||
| Arguments.of("AndymarkRs775_125", (Supplier<DCMotor>) () -> DCMotor.getAndymarkRs775_125(1)), | ||
| Arguments.of("BanebotsRs775", (Supplier<DCMotor>) () -> DCMotor.getBanebotsRs775(1)), | ||
| Arguments.of("Andymark9015", (Supplier<DCMotor>) () -> DCMotor.getAndymark9015(1)), | ||
| Arguments.of("BanebotsRs550", (Supplier<DCMotor>) () -> DCMotor.getBanebotsRs550(1)), | ||
| Arguments.of("NEO", (Supplier<DCMotor>) () -> DCMotor.getNEO(1)), | ||
| Arguments.of("Neo550", (Supplier<DCMotor>) () -> DCMotor.getNeo550(1)), | ||
| Arguments.of("Falcon500", (Supplier<DCMotor>) () -> DCMotor.getFalcon500(1)), | ||
| Arguments.of("Falcon500Foc", (Supplier<DCMotor>) () -> DCMotor.getFalcon500Foc(1)), | ||
| Arguments.of("RomiBuiltIn", (Supplier<DCMotor>) () -> DCMotor.getRomiBuiltIn(1)), | ||
| Arguments.of("KrakenX60", (Supplier<DCMotor>) () -> DCMotor.getKrakenX60(1)), | ||
| Arguments.of("KrakenX60Foc", (Supplier<DCMotor>) () -> DCMotor.getKrakenX60Foc(1)), | ||
| Arguments.of("KrakenX44", (Supplier<DCMotor>) () -> DCMotor.getKrakenX44(1)), | ||
| Arguments.of("KrakenX44Foc", (Supplier<DCMotor>) () -> DCMotor.getKrakenX44Foc(1)), | ||
| Arguments.of("Minion", (Supplier<DCMotor>) () -> DCMotor.getMinion(1)), | ||
| Arguments.of("NeoVortex", (Supplier<DCMotor>) () -> DCMotor.getNeoVortex(1))); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testCurrentAtZeroSpeedAndNominalVoltageIsStallCurrent( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.stallCurrentAmps, | ||
| motor.getCurrent(0.0, motor.nominalVoltageVolts), | ||
| kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testCurrentAtFreeSpeedAndNominalVoltageIsFreeCurrent( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.freeCurrentAmps, | ||
| motor.getCurrent(motor.freeSpeedRadPerSec, motor.nominalVoltageVolts), | ||
| kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testCurrentAtStallTorqueIsStallCurrent(String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals(motor.stallCurrentAmps, motor.getCurrent(motor.stallTorqueNewtonMeters), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testCurrentAtZeroTorqueIsFreeCurrent(String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals(motor.freeCurrentAmps, motor.getCurrent(0.0), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testTorqueAtFreeCurrentIsZero(String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals(0.0, motor.getTorque(motor.freeCurrentAmps), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testTorqueAtStallCurrentIsStallTorque(String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.stallTorqueNewtonMeters, motor.getTorque(motor.stallCurrentAmps), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testVoltageAtStallTorqueAndZeroSpeedIsNominalVoltage( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.nominalVoltageVolts, | ||
| motor.getVoltage(motor.stallTorqueNewtonMeters, 0.0), | ||
| kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testVoltageAtZeroTorqueAndFreeSpeedIsNominalVoltage( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.nominalVoltageVolts, motor.getVoltage(0.0, motor.freeSpeedRadPerSec), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testSpeedAtStallTorqueAndNominalVoltageIsZero( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| 0.0, motor.getSpeed(motor.stallTorqueNewtonMeters, motor.nominalVoltageVolts), kTolerance); | ||
| } | ||
|
|
||
| @ParameterizedTest(name = "{0}") | ||
| @MethodSource("motors") | ||
| void testSpeedAtZeroTorqueAndNominalVoltageIsFreeSpeed( | ||
| String name, Supplier<DCMotor> motorFactory) { | ||
| var motor = motorFactory.get(); | ||
| assertEquals( | ||
| motor.freeSpeedRadPerSec, motor.getSpeed(0.0, motor.nominalVoltageVolts), kTolerance); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns a negative torque at 0 A, but at 0 velocity, 0 A actually corresponds to 0 torque. (This and
getSpeed()are what makes accounting for free current so difficult/annoying.)