001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.math.system.plant;
006
007import edu.wpi.first.math.system.plant.proto.DCMotorProto;
008import edu.wpi.first.math.system.plant.struct.DCMotorStruct;
009import edu.wpi.first.math.util.Units;
010
011/** Holds the constants for a DC motor. */
012public class DCMotor {
013  public final double nominalVoltageVolts;
014  public final double stallTorqueNewtonMeters;
015  public final double stallCurrentAmps;
016  public final double freeCurrentAmps;
017  public final double freeSpeedRadPerSec;
018  public final double rOhms;
019  public final double KvRadPerSecPerVolt;
020  public final double KtNMPerAmp;
021
022  public static final DCMotorProto proto = new DCMotorProto();
023  public static final DCMotorStruct struct = new DCMotorStruct();
024
025  /**
026   * Constructs a DC motor.
027   *
028   * @param nominalVoltageVolts Voltage at which the motor constants were measured.
029   * @param stallTorqueNewtonMeters Torque when stalled.
030   * @param stallCurrentAmps Current draw when stalled.
031   * @param freeCurrentAmps Current draw under no load.
032   * @param freeSpeedRadPerSec Angular velocity under no load.
033   * @param numMotors Number of motors in a gearbox.
034   */
035  public DCMotor(
036      double nominalVoltageVolts,
037      double stallTorqueNewtonMeters,
038      double stallCurrentAmps,
039      double freeCurrentAmps,
040      double freeSpeedRadPerSec,
041      int numMotors) {
042    this.nominalVoltageVolts = nominalVoltageVolts;
043    this.stallTorqueNewtonMeters = stallTorqueNewtonMeters * numMotors;
044    this.stallCurrentAmps = stallCurrentAmps * numMotors;
045    this.freeCurrentAmps = freeCurrentAmps * numMotors;
046    this.freeSpeedRadPerSec = freeSpeedRadPerSec;
047
048    this.rOhms = nominalVoltageVolts / this.stallCurrentAmps;
049    this.KvRadPerSecPerVolt =
050        freeSpeedRadPerSec / (nominalVoltageVolts - rOhms * this.freeCurrentAmps);
051    this.KtNMPerAmp = this.stallTorqueNewtonMeters / this.stallCurrentAmps;
052  }
053
054  /**
055   * Calculate current drawn by motor with given speed and input voltage.
056   *
057   * @param speedRadiansPerSec The current angular velocity of the motor.
058   * @param voltageInputVolts The voltage being applied to the motor.
059   * @return The estimated current.
060   */
061  public double getCurrent(double speedRadiansPerSec, double voltageInputVolts) {
062    return -1.0 / KvRadPerSecPerVolt / rOhms * speedRadiansPerSec + 1.0 / rOhms * voltageInputVolts;
063  }
064
065  /**
066   * Calculate torque produced by the motor with a given current.
067   *
068   * @param currentAmpere The current drawn by the motor.
069   * @return The torque output.
070   */
071  public double getTorque(double currentAmpere) {
072    return currentAmpere * KtNMPerAmp;
073  }
074
075  /**
076   * Calculate the voltage provided to the motor for a given torque and angular velocity.
077   *
078   * @param torqueNm The torque produced by the motor.
079   * @param speedRadiansPerSec The current angular velocity of the motor.
080   * @return The voltage of the motor.
081   */
082  public double getVoltage(double torqueNm, double speedRadiansPerSec) {
083    return 1.0 / KvRadPerSecPerVolt * speedRadiansPerSec + 1.0 / KtNMPerAmp * rOhms * torqueNm;
084  }
085
086  /**
087   * Calculates the angular speed produced by the motor at a given torque and input voltage.
088   *
089   * @param torqueNm The torque produced by the motor.
090   * @param voltageInputVolts The voltage applied to the motor.
091   * @return The angular speed of the motor.
092   */
093  public double getSpeed(double torqueNm, double voltageInputVolts) {
094    return voltageInputVolts * KvRadPerSecPerVolt
095        - 1.0 / KtNMPerAmp * torqueNm * rOhms * KvRadPerSecPerVolt;
096  }
097
098  /**
099   * Returns a copy of this motor with the given gearbox reduction applied.
100   *
101   * @param gearboxReduction The gearbox reduction.
102   * @return A motor with the gearbox reduction applied.
103   */
104  public DCMotor withReduction(double gearboxReduction) {
105    return new DCMotor(
106        nominalVoltageVolts,
107        stallTorqueNewtonMeters * gearboxReduction,
108        stallCurrentAmps,
109        freeCurrentAmps,
110        freeSpeedRadPerSec / gearboxReduction,
111        1);
112  }
113
114  /**
115   * Return a gearbox of CIM motors.
116   *
117   * @param numMotors Number of motors in the gearbox.
118   * @return A gearbox of CIM motors.
119   */
120  public static DCMotor getCIM(int numMotors) {
121    return new DCMotor(
122        12, 2.42, 133, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(5310), numMotors);
123  }
124
125  /**
126   * Return a gearbox of 775Pro motors.
127   *
128   * @param numMotors Number of motors in the gearbox.
129   * @return A gearbox of 775Pro motors.
130   */
131  public static DCMotor getVex775Pro(int numMotors) {
132    return new DCMotor(
133        12, 0.71, 134, 0.7, Units.rotationsPerMinuteToRadiansPerSecond(18730), numMotors);
134  }
135
136  /**
137   * Return a gearbox of NEO motors.
138   *
139   * @param numMotors Number of motors in the gearbox.
140   * @return A gearbox of NEO motors.
141   */
142  public static DCMotor getNEO(int numMotors) {
143    return new DCMotor(
144        12, 2.6, 105, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(5676), numMotors);
145  }
146
147  /**
148   * Return a gearbox of MiniCIM motors.
149   *
150   * @param numMotors Number of motors in the gearbox.
151   * @return A gearbox of MiniCIM motors.
152   */
153  public static DCMotor getMiniCIM(int numMotors) {
154    return new DCMotor(
155        12, 1.41, 89, 3, Units.rotationsPerMinuteToRadiansPerSecond(5840), numMotors);
156  }
157
158  /**
159   * Return a gearbox of Bag motors.
160   *
161   * @param numMotors Number of motors in the gearbox.
162   * @return A gearbox of Bag motors.
163   */
164  public static DCMotor getBag(int numMotors) {
165    return new DCMotor(
166        12, 0.43, 53, 1.8, Units.rotationsPerMinuteToRadiansPerSecond(13180), numMotors);
167  }
168
169  /**
170   * Return a gearbox of Andymark RS775-125 motors.
171   *
172   * @param numMotors Number of motors in the gearbox.
173   * @return A gearbox of Andymark RS775-125 motors.
174   */
175  public static DCMotor getAndymarkRs775_125(int numMotors) {
176    return new DCMotor(
177        12, 0.28, 18, 1.6, Units.rotationsPerMinuteToRadiansPerSecond(5800.0), numMotors);
178  }
179
180  /**
181   * Return a gearbox of Banebots RS775 motors.
182   *
183   * @param numMotors Number of motors in the gearbox.
184   * @return A gearbox of Banebots RS775 motors.
185   */
186  public static DCMotor getBanebotsRs775(int numMotors) {
187    return new DCMotor(
188        12, 0.72, 97, 2.7, Units.rotationsPerMinuteToRadiansPerSecond(13050.0), numMotors);
189  }
190
191  /**
192   * Return a gearbox of Andymark 9015 motors.
193   *
194   * @param numMotors Number of motors in the gearbox.
195   * @return A gearbox of Andymark 9015 motors.
196   */
197  public static DCMotor getAndymark9015(int numMotors) {
198    return new DCMotor(
199        12, 0.36, 71, 3.7, Units.rotationsPerMinuteToRadiansPerSecond(14270.0), numMotors);
200  }
201
202  /**
203   * Return a gearbox of Banebots RS 550 motors.
204   *
205   * @param numMotors Number of motors in the gearbox.
206   * @return A gearbox of Banebots RS 550 motors.
207   */
208  public static DCMotor getBanebotsRs550(int numMotors) {
209    return new DCMotor(
210        12, 0.38, 84, 0.4, Units.rotationsPerMinuteToRadiansPerSecond(19000.0), numMotors);
211  }
212
213  /**
214   * Return a gearbox of NEO 550 motors.
215   *
216   * @param numMotors Number of motors in the gearbox.
217   * @return A gearbox of NEO 550 motors.
218   */
219  public static DCMotor getNeo550(int numMotors) {
220    return new DCMotor(
221        12, 0.97, 100, 1.4, Units.rotationsPerMinuteToRadiansPerSecond(11000.0), numMotors);
222  }
223
224  /**
225   * Return a gearbox of Falcon 500 motors.
226   *
227   * @param numMotors Number of motors in the gearbox.
228   * @return A gearbox of Falcon 500 motors.
229   */
230  public static DCMotor getFalcon500(int numMotors) {
231    return new DCMotor(
232        12, 4.69, 257, 1.5, Units.rotationsPerMinuteToRadiansPerSecond(6380.0), numMotors);
233  }
234
235  /**
236   * Return a gearbox of Falcon 500 motors with FOC (Field-Oriented Control) enabled.
237   *
238   * @param numMotors Number of motors in the gearbox.
239   * @return A gearbox of Falcon 500 FOC enabled motors.
240   */
241  public static DCMotor getFalcon500Foc(int numMotors) {
242    // https://store.ctr-electronics.com/falcon-500-powered-by-talon-fx/
243    return new DCMotor(
244        12, 5.84, 304, 1.5, Units.rotationsPerMinuteToRadiansPerSecond(6080.0), numMotors);
245  }
246
247  /**
248   * Return a gearbox of Romi/TI_RSLK MAX motors.
249   *
250   * @param numMotors Number of motors in the gearbox.
251   * @return A gearbox of Romi/TI_RSLK MAX motors.
252   */
253  public static DCMotor getRomiBuiltIn(int numMotors) {
254    // From https://www.pololu.com/product/1520/specs
255    return new DCMotor(
256        4.5, 0.1765, 1.25, 0.13, Units.rotationsPerMinuteToRadiansPerSecond(150.0), numMotors);
257  }
258
259  /**
260   * Return a gearbox of Kraken X60 brushless motors.
261   *
262   * @param numMotors Number of motors in the gearbox.
263   * @return a gearbox of Kraken X60 motors.
264   */
265  public static DCMotor getKrakenX60(int numMotors) {
266    // From https://store.ctr-electronics.com/announcing-kraken-x60/
267    return new DCMotor(
268        12, 7.09, 366, 2, Units.rotationsPerMinuteToRadiansPerSecond(6000), numMotors);
269  }
270
271  /**
272   * Return a gearbox of Kraken X60 brushless motors with FOC (Field-Oriented Control) enabled.
273   *
274   * @param numMotors Number of motors in the gearbox.
275   * @return A gearbox of Kraken X60 FOC enabled motors.
276   */
277  public static DCMotor getKrakenX60Foc(int numMotors) {
278    // From https://store.ctr-electronics.com/announcing-kraken-x60/
279    return new DCMotor(
280        12, 9.37, 483, 2, Units.rotationsPerMinuteToRadiansPerSecond(5800), numMotors);
281  }
282
283  /**
284   * Return a gearbox of Neo Vortex brushless motors.
285   *
286   * @param numMotors Number of motors in the gearbox.
287   * @return a gearbox of Neo Vortex motors.
288   */
289  public static DCMotor getNeoVortex(int numMotors) {
290    // From https://www.revrobotics.com/next-generation-spark-neo/
291    return new DCMotor(
292        12, 3.60, 211, 3.6, Units.rotationsPerMinuteToRadiansPerSecond(6784), numMotors);
293  }
294}