Im trying to get PIDF set up on our robot (PID is already set up and Im waiting for the robot to finish so I can tune). Would anyone happen to know the mathematical model I need to use for the F controller? I am using a position based PID Control and know that F is dependent on the velocity.
The easy way to get F is to run your mechanism at several throttle settings (say 0.25, 0.5, 0.75, and 1.0) and measure the speed, then interpolate back from the speed you want to the throttle to use. For a shooter/intake, measure the final equilibrium speed. For a drivetrain, measure the speed at somewhere about half to two thirds of your anticipated normal sprint distance.
The slightly more time consuming way is to use the characterization utility which depends on you application.
Yet another way to do it is based on the type of motor you’re using and the gear ratio! By Kirchoff’s law, the voltage V=IR + Kw w where I is the current, R is the effective resistance, Kw is the motor’s back-emf constant, and w is the angular velocity in rad/s. The total torque on the motor T=Kt*I-bw where Kt is the torque constant and b is viscous friction. At steady state, there is no torque so I=bw/Kt. Plugging into the first equation gives V=(bw/Kt)R + Kw w = (bR/kT + Kw) w. So the feedforward in volts/(rad/s) is (bR/kT + Kw). You’ll have to convert into whatever units you want, such as (% of average battery voltage)/(ticks/100ms) (or if you’re using some sort of voltage compensation, % of max saturation voltage). And keep in mind if there’s a gearing between the motor and the encoder you’ll have to adjust this constant (if geared up, decrease it by the gear ratio for example) Finding the actual constants is a bit tricky but luckily all you need are the motor curves. I’ve found this link explains it well. It uses only two points on the motor curves (stall and free) but if you download the spreadsheets and do some sort of linear regression you can get slightly more accurate values. It might be wiser to go with the above stated empirical methods because they’re easier (a lot of math gets you same result lol) and just in case there’s some sort of unmodeled dynamics, but I’ve found at least for the Falcon500’s it’s pretty accurate, haven’t tested with other motors
EDIT: Now that I finally saw OP’s question was about “position”, not “drivetrain velocity”, making some quick changes…
Every time I’ve actually done it on a robot, I’ve used velocity profiling, or bang-bang. Depends on how fast the mechanism needed to move.
Building it up from first principles is a fun exercise too - aprxlycalculus is definitely going the right direction.
My mental model is always:
- Motor controller applies a voltage to the motor
- Based on motor constants, the motor’s current speed, and the applied voltage, you can calculate the motor’s output shaft torque
- This torque is transmitted through gearboxes and chain with losses and ratios, to the mechanism.
- Apply \sum F=ma on the mechanism to calculate the change in mechanism’s position.
- Mechanism position is transferred back up through chain/gearboxes to the motors, changing the motor speed.
- Repeat with new motor speed
Note that any first-principles analysis will inevitably not be accurate. Friction is everywhere, datasheets have tolerances… This error is “soaked up” by the P/I/D portions of your closed loop control, and usually pretty well.
The fairly simplistic approach of just making F proportional to setpoint may or may not work. It only works when you can roughly map motor voltage to some function of measurable quatities (like mechanism position). Maybe the function is “pulse at the beginning”, maybe it’s “zero”, maybe it’s “constant times cosine of measured angle”… all just depends on the mechanism being controlled.
The dynamics of this playing out on an arm affected by gravity are simulated here.
TL;DR tuning with simple feed forward models is probably your best bet for quick wins… But building up a first-principles understanding is more healthy for your brain in the long run.
Don’t forget that after all that tweaking, the optimization can be different from the beginning to the end of a match due to battery voltage decreasing. With the right tuning, your I-ntegrator term should be able to compensate for that.
Yup! Another one for the “unmodeled factors” bucket. I and (if it’s bad enough) P should help take care of it.
Integral gain is very much the wrong way to deal with battery voltage drop. The WPILib SpeedController
interface has a setVoltage
method which compensates for battery voltage, and most “smart motor controllers” have built-in voltage compensation that can be enabled through their API.
I strongly recommend avoiding integral gain at all costs; it is almost never necessary in FRC, and causes many problems with stability and repeatability.
Gotcha. I think I’m mostly on board with you… to clarify…
I do believe integration terms have usage in a handful of contexts, but almost always with a range limiter on ensuring there’s a small enough error before integration happens. Definitely agreed there are tons of stability issues when used without care.
From John’s comment, and my FRC experience - my mental model of the world led me to a scenario where motor RPM did something like this:
With small enough steady state error to not allow P to have meaningful impact. After P gives out, I may be useful to help close the gap further… if closing the gap is needed. Agreed that a more nuanced feed forward model would help more directly, especially since the behavior of motor RPM & torque is fairly predictable with decaying battery capacity.
If you did choose to use I gain in a case like this though, you definitely need to be switching gains, (or using IZone features to automatically disable integration) when you’re to the left of that green dotted line. Without care, you’ll have so much integrator windup that you very well may never converge.
Additionally… this constant-velocity-setpoint is probably unrealistic for most drivetrain applications.
I very well might be missing something else… and all of this is probably beyond the scope of what OP was suggesting…
EDIT: And, OP asked about position, not velocity.
What I’ll definitely say, to make sure no one misunderstands - if your issue is “battery voltage drops change our drivetrain’s closed loop behavior”, the answer is definitely not “crank up I”. A more subtle analysis is needed.
Am I missing something here? It’s a position based controller.
Unless it is holding a position against a force, the answer is the feedforward ought to be zero.
If you are using it for a climber, where you want to climb to a certain height, then the feedforward value should be the value required to maintain the height you want against gravity. Other posters have provided some different ways to work on that, but I’ll offer one more. Don’t use pid.
I’ll elaborate if requested.
errrp. Too much robots, too little sleep.
Nope, I was missing something this whole time. I’d read OP’s post a few times, missed the word “position” every time, and went ahead assuming drivetrain.
Position control can have feed-forward terms, but the trivial “proportional to setpoint” will almost never work.
Off to do some edits…
Oops, I missed position control. My comments are much more applicable to velocity control.
I like gerthworm’s chart. That’s correct, the shape on the left is pretty close to the ideal response and more I-term won’t help there. The remaining error on the right is what more I-term can resolve.
I can’t speak to how smart the firmware is. We’ve had good luck tuning for 12V to 10V this year with PIDF. I believe we can do the same with PID, so we’ll probably experiment more with that after our Week 1 competition.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.