Tuning PID on a Flywheel

Our team is trying to tune PID on a flywheel and were having a problem with our current while the motor is oscillating back and forth along the setpoint. We’re using Falcon 500 for the shooter and I’ve made sure all of the RPM are converted to the ticks and vice versa. In the code, We’ve made sure to set the peak output maximum to 1 and minimum to 0 as well as adding a coerce to the input on the “set velocity” to make sure that the motor has no way of getting to a negative velocity, but when running our code and looking at the graph the motor somehow drops to negative current when trying to correct itself after overshooting. Unless I’m misunderstanding something electrical here, shouldn’t the current always be positive unless the motor spins in the opposing direction?

I think you will get negative current when the motor is acting as a brake even while it is continuing to spin in the same direction.

What kind of speed oscillations are you seeing (% above and below the set point)?

Same question as @wgorgen. If you have the code, we can also inspect for ancillary code issues (ie things unrelated to the tuning, but which may produce that behavior).

I can also offer this simulation and tuning walk-through guide as an example of how the PID tuning should look and act.

2 Likes

I don’t currently have the code with me and won’t be able to get it until our next meeting on Monday but from what I remember the motor was pretty good when I came to setting the kP at a lower value. Once it got high enough it would start to oscillate and I was able to tune kD and it would look almost perfect but the only problem was it would be 200 rpm under what we wanted. I then increase kP so it would oscillate at 3350 rpm and it would bounce anywhere from 3450 to 3250 with current rising and dropping to 50 to -50 amps. I have the motor in coast mode, which is set in both code and on the motor.

It seems kP alone will not enable you to reach your set point. This is because a proportional gain gets smaller and smaller as your error gets less. Once you’ve reached a sufficiently close value the error is small enough that the torque applied becomes steady state. If you increase kP beyond this so you reach your target you overshoot. If you are oscillating you may want to lower kP slightly.

To solve this problem you should use an integral gain, once you are sufficiently close the kI will close this gap for you by looking at the accumulation of error over time and correcting for it. You want to use a very small number for kI and I believe you can set the range for when you want the integral to start counting.

You likely don’t need kD for a flywheel, some doesn’t hurt though. kD helps to prevent overshoot by looking at the rate at which your approaching the target (rate of change of error) and reducing output if you are approaching the target too quickly. This is why kD is typically negative.

In summary:
kP increases output based on error, will cause steady state error and may barely oscillate when this is right.
kI resolves steady state error, but too high of a value becomes very unstable
kD reduces output if error is decreasing too quickly, helpful to prevent overshoot / reduce oscillation

You can definitely add some integral control as Mike mentioned, but I personally find integral control a little annoying to deal with, and haven’t really ever needed it on a flywheel.

One thing that might help is adding a feedforward term, which is just some amount of power based on what is expected to maintain the target RPM without considering the encoder feedback. This is really easy to figure out for a flywheel as motors speed linearly scales with voltage. If your flywheel is 1:1 with a Falcon, and the Falcon is 6380 RPM at 12V, then theoretically you just need 3350/6380=0.525 motor power to reach that RPM. You can then add the output of the P loop to this so that the P loop will make up for friction and all that sort of stuff. I believe there’s a feedforward built into the integrated PID on the Falcon 500 and it’s already multiplied by your target RPM, so you just need to input the motors speed constant (6380/12 RPM/volts, converted to the units the Falcon 500 software expects) as the value for that term.

Another tip is, as mentioned earlier, motor speed scales linearly with voltage, and setting motor power to .525 means you will send 52.5% percent of battery voltage to the motor. However, if we want this to be roughly 3350 RPM, this assumes that 100% is 12V, which is a dead battery. The Falcon 500 should have a mode you can turn on that compensates for this, so that you can send it a voltage directly (.525*12V = 6.3V) and it will figure out what percentage of present battery voltage it needs to get that, removing that source of inconsistency. It might do this by default if you’re running onboard PID, check the software documentation to be sure.

3 Likes

For flywheel, FF is better than Integral control.

5 Likes

I’ve tried to add an Integral value and it wouldn’t do anything. This could be because I did it when its at rest and I’m not too familiar with using the kI value.

I think you’re referring to the Izone? Like with the integral value I’m still not very familiar with this so if there is any that could explain this, I would be more than happy to read through it.

I think what we’re doing now is kinda the opposite of what your telling me. I tuned the the Feed Forward value so that the motor is just barely rotating and then decreased it by like .00001 so that the motor wouldn’t move. Then from there I was going to tune the kP value until it got to the set point as fast as possible. Then the plan was to use kD to tune any oscillating that may occur.

I’ll try that feedforward method on Monday and keep this post updated with any trouble I run into.

So, what you’re doing is the type of feedforward you’d use to counteract gravity on an elevator (we usually call this kG or something) – for a shooter where your feedforward gets you mostly up to speed, you’d use a velocity feedforward, which is just a gain that’s applied to your setpoint (kV * setpoint) to get your motor spinning up to most of the target velocity

3 Likes

I’d recommend going back to the kP value before you were oscillating, set your Izone to about double the steady state error you are seeing (400 rpm) and slowly ramp up kI until your steady state error goes away. Try starting with a value of 0.001, if it seems to have no effect, bump the kI value up, if it starts to oscillate while you are increasing kI but did not oscillate with just kP, you’ve gone too far.

Feedforward definitely works too as Rahul said. You may still end up with steady state error though.

For education, reasons are better than statements.

2 Likes

For posterity, explanation is better than snappy one-liners (unless you’re a politician).

2 Likes

Sure, we can go deeper.

For the sake of discussion, I am considering the flywheel, its motor and motor controller, and any sensors as the “system” under control. The controller is software or configuration applied by the user from the roboRIO.

Basic Expected System Behavior

As a general statement, if you want your flywheel to spin at a constant speed, you need to be giving it some non-zero control effort (voltage, motor command, what have you). Friction and Back-EMF have varying roles in this effect, but regardless of how the physics plays out, the end result is the same: To keep it going at a certain speed, you need to be injecting non-zero control effort.

P alone is Insufficient

P control by itself won’t do this: When you’re at your desired speed, error goes to zero, which makes your control effort zero. This will cause the shooter wheel to slow down. Then you get more error, P gets bigger, control effort comes back, and the system speeds up again. Generally, it won’t be able to maintain that speed.

You need something else.

I can help

Integral term is one way to fix this. By accumulating error over time, in steady state, it will provide that constant offset component of the control effort. However, this comes at a risk: Integrators exhibit “windup” behavior, where during periods of time of large error their value becomes quite large. As your actual speed approaches your desired speed, they continue to “keep their foot on the gas pedal” and push you past your setpoint. This tends to increase the time it takes for the flywheel to “settle down” at the target speed or, worse, cause it to oscillate even more than it already was. So, while in many cases it will “work”, I wouldn’t sign up to say it’s a generally applicable solution.

The Alternate

To paint with very broad brush strokes: All good control systems derive their control effort value from two main components:

  1. What you expect the control effort to need to be, given what you’re trying to get the system to do.
  2. Extra additions or subtractions to account for error in the system.

Error, in general, would be anything that 1 doesn’t directly account for. It has to be measured by a sensor, since it can’t be (or purposefully hasn’t been) predicted.

To make a control system work better, you can either improve the precision with which you calculate 1, or pull some fancy tricks with 2 to make it act “better”.

When moving from P to PI, you’re saying 1 is equal to zero, and trying to get fancier with 2 to account for more diverse forms of error. The alternate of “Feed-Forward” makes 1 better.

A very simple model of a flywheel is to assume that it achieves its maximum velocity at battery voltage (~12.5V). Any velocity less than that will be achieved by applying a voltage proportional to that velocity. IE:

V_{FF} = \omega_{des} \frac{12.5}{\omega_{max}}

This discounts a chunk of the physics involved (and relies on 2 to take care of the discrepancy). But, for flywheels I’ve found so far, it takes care of the vast majority of the constant-control-effort needed to keep the wheel moving at a certain speed.

Using this strategy, you very well may be able to get by with just a simple P control for 2. I or D may come into play if you have specific requirements on how you “reject disturbances” - IE, transition from off to on, or deal with a ball getting injected.

To get a hands on feel for the difference, Try running the tuning exercise as written - using FF prior to attempting any P/I/D. Then, restart, and run it with using only P/I/D. Especially if you vary the setpoint across the full range, I believe you’ll find results get more consistent using the feed-forward method.

@Mike_Schreiber apologies if it appears my initial line was targeted at shooting down your recommendation - it was not intended as such. I do believe FF will get OP further than adding I control with fewer pitfalls (as outlined above). I also do like to provide more info than less, but have been criticized more than once recently for providing too much info - I’ve not yet found the right balance between explaining everything, and leading students with the “just-in-time” right set of information.

FWIW I have used I control on flywheels before, especially with the various I-zone windup integration strategies. These also can work, and are what I would put in the category of “Making 2 fancier”. My proposal is to spend a bit of time attacking 1 before investing lots of time into getting 2 fancier - I suspect OP may find their answer more quickly that way.

4 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.