I am working on programming a motor simulator for FRC motors, which allows a user to input a set of motors, a gear reduction, and an attachment in the form of a moment of inertia.
The simulator should calculate the angle, angular velocity, and angular acceleration of the attachment at any time.
Currently, I calculate the angular acceleration (alpha) of the attachment, then add alpha(*dt) to the angular velocity (omega), and omega to the position (theta).
I had determined the following formula for torque of the motor, given voltage and current speed: stallTorque * (percentVoltage - (omega / freeSpeed)
and I know from physics that: alpha=torque/moment.
This does not work as expected, and I think it’s because my formula for torque is wrong, and I don’t fully understand DC motors.
How are speed and torque related? by most explanations, speed should have an inverse relationship with torque, but this system would indicate that it does not. Am I making a false assumption?
You are correct that the torque formula isn’t correct.
The angular momentum does not play into the torque calculation (though it will be part of the angular acceleration). Torque is (modeled as) proportional to current, not speed.
Torque = stallTorque * (current - freeCurrent)/(stallCurrent-freeCurrent)
At stall, current is proportional to inputVoltage (V=IR):
if (speed==0) current = inputVoltage * stallCurrent / nominalVoltage
By spinning, the motor generates a backVoltage proportional to speed:
backVoltage = speed * freeBackVoltage / freeSpeed
Free back voltage is calculated from the residual voltage at free speed and V=IR (R being calculated from stall):
freeBackVoltage = nominalVoltage * (1- freeCurrent / stallCurrent)
and finally, current at speed is again calculated from V=IR, using the residual voltage (applied - back):
current = (inputVoltage - backVoltage) * stallCurrent / nominalVoltage
I leave rolling all this back up into your calculation to you.
https://github.com/RobotCasserole1736/RoboSim/blob/master/Octave/lib/motor_CIM.m might be of some help.
https://github.com/RobotCasserole1736/RoboSim/blob/master/Octave/lib_test/motor_model_test.m will give some context to how that above code can be used.
Torque vs speed at the spec voltage is commonly modeled as a straight line connecting the stall point (stall torque @ zero speed) at the spec voltage to the free speed point (zero torque @ free speed) at the spec voltage.
So the equation of that line would be:
T = T[sub]s[/sub]*(1-N/N[sub]f[/sub])
… where T is torque, T[sub]s[/sub] is stall torque at the spec voltage, N is speed, and N[sub]f[/sub] is free speed at the spec voltage.
Values for Stall Torque and Free Speed of FRC-legal motors are published every year.
Let’s say the spec voltage is 12 volts (it is for most FRC motors).
If the applied voltage “V” is not equal to 12 volts, the equation can be generalized by using the approximation:
T=T[sub]s[/sub]*(V/12-N/N[sub]f[/sub])
I added the red part.
This is called Euler integration. Given all the other tolerances in the model, it’s probably adequate for what you are doing. But for students who may be interested in learning about it, the Midpoint Method is a better way to do numerical integration that is quite easy to implement in Excel. You can find a discussion thread here.
Hi Ari,
I love how you think, your instincts are spot on. The devil’s in the details as they say, and you just need to scale the right terms. I started out 30 years ago as a brushless DC motor guy, and it’s all too easy (for me) to recite equations but I really struggle to explain DC motors in a clear and understandable way.
If you assume that the motor torque when stalled is the “stall torque” (given a full input command) then when the motor reaches the no-load speed the torque reaches zero (hence max speed with no torque). Look at the factor (no-load speed - speed)/no-load speed and you’ll get a term that starts at 1 and linearly goes to 0 at the no-load speed. let torque = stall_torque*(no-load speed - speed)/no-load speed and you’ve got it.
let alpha = torque/inertia, and velocity = velocity + alphadeltatime, and your done. BTW, if you’re using a motor command of let’s say: cmd = k, where k is between + and - 1, torque becomes = stall_torque(cmd*no-load speed - speed)/no-load speed.
If you publish what you have, we have about 17 hours before build season starts to sort it out:)
Sincerely,
Steve Spoldi.
Less whatever time we will spend banking sleep and cooking (and otherwise preparing) for kickoff, of course!