Trouble tuning Flywheel PID

Hey, so I’m trying to tune a Flywheel PID loop. It uses two Falcons with no gear reductions. I’m trying to tune the P value until it gets to approximately the right value, then use Ziegler-Nichols to get the I and D values. I’m trying to get the encoder velocity to 10000. The problem is, past a P value of 0.00002, it oscillates violiently, but at that value the encoder velocity only moves to 2000. One thing I tried doing was using the Phoenix Ramping feature to make sure it wouldn’t immediately shoot super fast, but it did little to abate the oscillation. How do I go from here?

I and D are currently 0 btw.

Follow the steps in CTRE documentation first.
You’ll want to start by calculating a Feedforward gain value first. Not to be confused with arbitrary feed forward.

Very strange. Definitely concur, start with CTRE documentation. With just a simple flywheel and motor, I’d expect the tune order should be F, then P, then some form of I/D/Ramping if needed (but not before getting F and P good).

If you haven’t done this tuning before, here’s a runthrough of how it’s supposed work and look.

Note the tiny values may be legit. It all just depends on the units being used. We’re using REV, and our gains are legitimately in the 10^-3 and 10^-4 range.

1 Like

For what it’s worth, it’s really just easier to do I and D manually by tweaking and observing the loop. I don’t know anyone in FRC who actually uses the differential equations.

I agree that a P value that tiny seems absurdly suspect. Are you sure the encoder velocity is in the units you expect it to be? Just to sanity check, observe the velocity when you just run the motor at 100% power full on. Many functions return things like ticks per 100ms rather than revolutions per minute which you could be expecting…

Definitely follow the advice of setting a feedforward - you do not want P to be responsible for bringing the loop to speed from rest alone. This forces P to do far more work than it has to be doing, making it harder to properly tune. With a proper feed forward, P only has to account for the error caused by inefficiencies, voltage drops, and the like. I am not sure this will solve your problem but it is a good practice.

Another good practice that also won’t solve your problem is to ensure the speed controller is set such that it will not command the motor with a negative value. This makes the oscillations inherently less violent.


Great advice, never thought of that. Thanks.


just a side note, PID’s you use in frc usually don’t require I term. Just doing F, P, and D should give you what you need, especially for flywheel.
Also that p does not look right at all. For comparison, I am running my team’s flywheel P at 0.9 for 775 pros.
Just like everyone has been suggesting, you need get rid of P and start with F. Also at this point in time I suggest you remove the ramping feature, it might just get in the way of you trying to tune PID. Make sure that your code actually states “velocity” for the controlmode. I would also suggest that you make one of the motors as followers and only follow one encoder.

1 Like

We have the exact same setup (although our wheel may be built differently). The Ziegler-Nichols method did not work for us. Our speeds are in RPS, and our PIDF is 0.0084 0.000017 0.85 0.01.

Yep, this was what worked! I was trying to tune P first, then I and D, and that was not correct. After about half an hour doing it your way I got it more or less running perfectly as I want it to. Thanks so much :slight_smile:

For anyone else who comes across this and are trying to tune flywheel PIDF, start by setting P, I, and D to 0, and set F to 0.0001. Increment or decrement as necessary, then tune PID. Of course, YMMV depending on your application but in general this should work.


I created a simple robot project to tune Spark Max/NEO based flywheels. I documented all the best practiced for tuning the PIDF closed loop control. Everything is controllable from SmartDashboard, so tuning is very quick. Hopefully others find this useful.

1 Like

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