WPI Docs Interactive PID Tuning Example

Howdy folks!

There’s an open PR for some new pages in WPILib docs that need some “playtesting”.

Your mission, should you choose to accept it, is:

  1. Click here to go to the docs
  2. Follow the content on the page. Feel free to poke around to other pages too for more explanation
  3. Report back here, or on the github PR

The focused questions I’m curious about:

  1. Did the simulation and the visuals run smoothly on your PC/browser? If not, what’s your setup?
  2. If you’re already a “controls guru”, did the controls in the simulation act like you expect? Does the prose around it describe it well and correctly for FRC purposes?
  3. If you’re new controls stuff, is the additional content approachable, and helpful in ramping up your knowledge?
  4. Did you walk away with a better understanding of how PID controllers should behave in different FRC contexts?

Have fun, and all feedback is welcome! Speak your mind freely: Don’t hold back if you’re not sure of yourself on a topic, or worried it was already discussed, or worried our opinion might not be “correct”. I’m happy to filter and collate the conversations!


Very cool!

I think the units of the calculation might be off by a factor of 100 compared to the standard -1…1 range. For example at T=3 in the photo above, RPM = 868; (Set-point - RPM) * kP; (1000-868)*.45 = 59.4. I would expect the control effort to be 12v still because we are railed over a max of 1 but it is 6.2v.

1 Like

I think it might be a little clearer if the units and resolution were specified.


This is seriously amazing. This might be one of the most helpful things for students to understand how PID tuning works. Very well done!

Trying to implement the solution for Flywheel Tuning Step 2 and setting kV to 0.0075 as recommended you get the following error.

For the flywheel simulation It would be helpful to explicitly note the maximum set point value of the system. After some digging I can guess its around 1500 rpm because I can’t seem to get the system to reach any values beyond that (Even with wild PID constants).

I think it would also be helpful to draw the output line above all of the others on the graph. In the below picture you can not tell if the output is osculating or not because it is drawn behind the other lines.

1 Like

This is so awesome. Great work.

A few things:

Yes! It looks great.


A few things:
It would be nice to have parts of the graph appear as time goes on, not just show up all at once. This would be closer to what the students see while tuning a PID controller using glass or something like that and gives students a better idea of what is actually happening by being able to watch the rotational speed of the wheel and the graph.

Is the control effort line on the graph necessary? When I’ve done these things on our robot I just plot the output (ex. desired vs. actual rpm) and found that worked well enough. Is this a non-optimal way of doing that? I’m sure there is a valuable part of intuition that is gained from seeing that part on the graph, but I am not 100% sure what it is right now. It also kind of blocks the red and blue lines, in my opinion, those two should be the most dominant.

edit: After following the tuning solution, the green line makes a lot more sense. Some verbage about what the desired behavior of these lines would be helpful (or I missed them).

Flywheel Specific

In the flywheel example, it would be nice to have a marker on the graph as to when the gamepiece is interjected or just put the line about the gamepiece higher up in the paragraph so it is more prominent.


This is miniscule, but the arm likes to do a full 360 when trying to get to its next setpoint rather than just taking the closest path. I don’t know if it would affect tuning, but it is funny.

A line or section about why you need to or should be tuning your PID controllers in realistic conditions (ex. tuning swerve drive PID on blocks vs. the ground) would be good because I know that was lost on me when I was first starting.


Love the concept but the implementation doesn’t make sense to me. (Mechanical guy here…)

For a flywheel with feedforward only, why does the output vary with time?

What is the output disturbance at T=5?


1 Like

Gotcha. I concur something is smelly here. The underlying logic is done in a mix of revolutions and radians (RPM was purely for cosmetic display). Lemme do a walkthrough of the units and make sure things are internally consistent. At a minimum, while the system is overall ‘functional’, I would expect the thing you noticed to confuse a mathematically-inclined, detail-oriented student.

Yup that shouldn’t be there, will fix.

Can do - it’s a property of the underlying modeled motor and gearing (and is a good Segway into the “actuator saturation” common issue). Lemme do some thinking on how to handle this, whether it’s a “add more words” or just cap the text box input value.

Sweet, this is easy!

Makes sense, and I like this idea from the perspective that it would look more like what a student will actually see on a robot.

Would a moving cursor along the graph that’s time-synced with the animation fill the same purpose? Just thinking of alternates in case a full redraw is too resource-intensive for the average browser.

Got it. I can reorg a bit of the sections that talk about it in more detail.

Got it, seems easy enough to do.

can you screenshot the gain set and plots used to cause this? I’ll try to reproduce.

Excellent idea, will do.


Thank you! You are definitely in the target audience so the feedback is valuable!

So, at least in the nomenclature established in the WPILib docs, for the flywheel,

  • “Setpoint” is the desired, commanded speed of the flywheel
  • “Output” is the actual, measured speed of the flywheel
  • “control effort” is the voltage applied to the motor

I expect that with feedforward only, the voltage should step up to a constant value, and the actual speed of the flywheel should accelerate gradually (with, largely, exponential behavior).

So, with that in mind… does that help clarify what you’re seeing? If so, I can work to make sure those ideas are presented earlier rather than later.

It’s a gamepiece being injected into the flywheel. It’s mentioned in one sentence buried in the middle of other explanation, but it’s definitely less than obvious.

Based on multiple feedback comments on this, I’m actually thinking I might just expand the animation to show a ball making contact with the wheel and flying out. Would that help?

1 Like

Awesome… I second the idea of having the ball shown being shot and the corresponding slowdown.

Also, I found a hidden implication in this line:
" In this particular example, for a setpoint of 1000, values of Kp=2.0, Ki=0.0, and Kd=0.04 will produce somewhat reasonable results. It will get better or worse as you change the setpoint."

Does that imply the constants only work well for one setpoint? I changed the setpoint and see the off. I guess in the past I was under the impression the tuned values would work across a range of setpoints (ex different speeds for different distances from target). If we need different pid values for different setpoints how do we go about doing that? Can there be additional info on that?

1 Like

Loving it, must dig further…

1 Like

Yes-ish. The underlying idea this is hitting at: Without feedforward, the details of how your system acts will change a lot based on setpoint. This is somewhat obvious in the flywheel case, and very obvious in the vertical arm.

The reason for the setpoint-hedge-words is to point people to the next step - add feedforward to the control, then the system behavior becomes more consistent for many setpoints.

Lemme do some thinking on rewording though, to better communicate that intent. What you’re describing is definitely a valid controls strategy (“gain-scheduling”), but not what we’d be looking to have readers bite off at this point.

1 Like

Another controls outsider here. A definition of these terms early on in the doc (ie, before you start playing with the simulation) would be immensely helpful.

I had to go searching through the page to find hyperlinks to a glossary, and fully thought up until reading the quoted text from your post there, that “output” was the voltage applied to the motor, and was really lost on what “control effort” was (even after reading the definition in the glossary).

These terms/definitions weren’t overly clear on a first read through (not for me anyhow).


Setpoint of 7 with the recommended FF + PD values.
Since this is in radians, I think it is going all the way around (2pi) and then some to reach what I told it to do, which makes sense. Would be great if it could be optimized on the backend the same way that swerve module angles are since that is more intuitive (I would think). Would also be nice for it to be in degrees since teams will probably first think of degree setpoints first when putting in values for the setpoint (I did too before I read the axis titles).

1 Like

Sweet, thank you for the feedback! It’s definitely easy to add a summary to inject knowledge at just the right time.

For some perspective, a lot of times in software-land we tend to shy away from explaining things more than once. But, I think I agree, in this case especially, it’s worthwhile to make sure there’s a short and sweet summary to direct folks before they start digging into the details.

Bingo. Yup this is expected, the setpoint input is in radians of arm rotation, not final angular position.

What I’ll likely do - just cap the text box input at a -pi to pi range. It’s rare an arm can mechanically go all the way around like that anyway.

I’m also ok doing a cosmetic degrees display. It’s the way I think as well. It would better match pattern with how the flywheel is done.

1 Like

Ah ha… you expected me to read before I turned the knobs! I see game piece the explanation now. You could show it in the animation or just label the graph.

I’ve done a variety of control systems in my career dating back to proportional only mechanical devices or pneumatic PID - none of this fancy computer stuff. But I just wasn’t paying attention closely. Your “output” term is typically called the Process Variable. And I usually think of “output” as the output of the controller or in more classic terminology the Control Variable.

Excellent work though. Love it.




I was guessing this was probably the source of the confusion. For what it’s worth, I always learned it as “desired”, “actual”, and “control effort”, and that’s how most of my software ends up…

I’ll run it past some of the folks who set up the existing nomenclature pattern, but I can’t imagine it would be bad to have the alternate vocabulary listed somewhere. Given this is going to go out to all sorts of teams with all sorts of backgrounds, you have to funnel the nomenclature diversity together first before the consistency is meaningful.

1 Like

There’s potential confusion here between the inputs and outputs of the system, the inputs and outputs of the plant, and the inputs and outputs of the controller.

I think this is sufficiently confusing (especially for students) that we should have a section devoted to this nomenclature, complete with block diagrams.


This is great! I actually have used the examples on Wesley Aptekar-Cassels | Intro to Control Theory Part 1: PID to show how PIDs work. It’s the same sort of thing - just wanted to share as another example.

1 Like

Super neat to play with on my phone. Discrete buttons for “spin up”, “stop”, and “shoot ball” would be nice though. I’m pretty familiar with PID so I’ll have my less informed students take a look later.