|
| 1 | +package org.team5499.monkeyLib.math.physics |
| 2 | + |
| 3 | +/** |
| 4 | + * Model of a DC motor rotating a shaft. All parameters refer to the output (e.g. should already consider gearing |
| 5 | + * and efficiency losses). The motor is assumed to be symmetric forward/reverse. |
| 6 | + * |
| 7 | + * @property speedPerVolt kV, or rad/s per V (no load) |
| 8 | + * @property torquePerVolt N•m per V (stall) |
| 9 | + * @property frictionVoltage the voltage needed to overcome static |
| 10 | + */ |
| 11 | +class DCMotorTransmission( |
| 12 | + val speedPerVolt: Double, |
| 13 | + val torquePerVolt: Double, |
| 14 | + val frictionVoltage: Double |
| 15 | +) { |
| 16 | + // TODO add electrical constants? (e.g. current) |
| 17 | + |
| 18 | + /** |
| 19 | + * Returns the idle speed of the motor at this voltage |
| 20 | + * |
| 21 | + * @param voltage The voltage across the motor |
| 22 | + * @return The theoretical speed in rad/s |
| 23 | + */ |
| 24 | + @Suppress("ReturnCount") |
| 25 | + fun freeSpeedAtVoltage(voltage: Double): Double { |
| 26 | + if (voltage > 0.0) { |
| 27 | + return Math.max(0.0, voltage - frictionVoltage) * speedPerVolt |
| 28 | + } else if (0.0 > voltage) { |
| 29 | + return Math.min(0.0, voltage + frictionVoltage) * speedPerVolt |
| 30 | + } else { |
| 31 | + return 0.0 |
| 32 | + } |
| 33 | + } |
| 34 | + |
| 35 | + /** |
| 36 | + * Get the theoretical torque applied by the motor at a given speed and voltage |
| 37 | + * |
| 38 | + * @param outputSpeed The speed of the motor in rad/s |
| 39 | + * @param voltage The voltage across the motor |
| 40 | + * @return The theoretical torque in N•m |
| 41 | + */ |
| 42 | + fun getTorqueForVoltage(outputSpeed: Double, voltage: Double): Double { |
| 43 | + var effectiveVoltage = voltage |
| 44 | + if (outputSpeed > 0.0) { |
| 45 | + // Forward motion, rolling friction. |
| 46 | + effectiveVoltage -= frictionVoltage |
| 47 | + } else if (0.0 > outputSpeed) { |
| 48 | + // Reverse motion, rolling friction. |
| 49 | + effectiveVoltage += frictionVoltage |
| 50 | + } else if (voltage > 0.0) { |
| 51 | + // System is static, forward torque. |
| 52 | + effectiveVoltage = Math.max(0.0, voltage - frictionVoltage) |
| 53 | + } else if (0.0 > voltage) { |
| 54 | + // System is static, reverse torque. |
| 55 | + effectiveVoltage = Math.min(0.0, voltage + frictionVoltage) |
| 56 | + } else { |
| 57 | + // System is idle. |
| 58 | + return 0.0 |
| 59 | + } |
| 60 | + return torquePerVolt * (-outputSpeed / speedPerVolt + effectiveVoltage) |
| 61 | + } |
| 62 | + |
| 63 | + /** |
| 64 | + * Get the required voltage for the requested torque at a speed. |
| 65 | + * |
| 66 | + * @param outputSpeed The output speed of the motor in rad/s |
| 67 | + * @param torque The output torque of the motor in N•m |
| 68 | + * @return The theoretical voltage for the requested torque and speed |
| 69 | + */ |
| 70 | + fun getVoltageForTorque(outputSpeed: Double, torque: Double): Double { |
| 71 | + var modifiedFrictionVoltage: Double = 0.0 |
| 72 | + if (outputSpeed > 0.0) { |
| 73 | + // Forward motion, rolling friction. |
| 74 | + modifiedFrictionVoltage = frictionVoltage |
| 75 | + } else if (0.0 > outputSpeed) { |
| 76 | + // Reverse motion, rolling friction. |
| 77 | + modifiedFrictionVoltage = -frictionVoltage |
| 78 | + } else if (torque > 0.0) { |
| 79 | + // System is static, forward torque. |
| 80 | + modifiedFrictionVoltage = frictionVoltage |
| 81 | + } else if (0.0 > torque) { |
| 82 | + // System is static, reverse torque. |
| 83 | + modifiedFrictionVoltage = -frictionVoltage |
| 84 | + } else { |
| 85 | + // System is idle. |
| 86 | + return 0.0 |
| 87 | + } |
| 88 | + return torque / torquePerVolt + outputSpeed / speedPerVolt + modifiedFrictionVoltage |
| 89 | + } |
| 90 | +} |
0 commit comments