WPILib PIDController Period

Looking at the WPILib PIDController (java). I see the period is fixed during construction, not calculated – using this value to calculate the “velocity error” given the amount of clock jitter I am seeing, I am wonder if it would not be better to calculate the real period (using something like Timer.getFPGATimestamp()?

Still (always) learning, but this seems like a possible source of error.


To answer the “how” first:

Here’s a java PID implementation we created a number of years ago that does what you describe, along with its underlying integration and derivative calculation classes.

To answer the “why”:

This question hits at two related topics:

  1. What’s the “best” way to take integrals and derivatives in discrete time?
  2. How much does (or should) periodic loop jitter matter?

The answer to both lies in a tradeoff of computational and implementation complexity, and how bad making assumptions about what the underlying analog signal makes the error.

Most academic theory on this work tends to assume fixed timestep, and most industry controllers I’ve seen assume the same. I attribute this to a few facts:

  1. Given a certain fixed sample rate, it’s hard to make generally-true assumptions about what the underlying analog signal is, in a way that is helpful to computation.
  2. Given any underlying analog signal, and are having issues with your math on the signal, increasing the sample rate will almost always make the results “better”.

Sometimes marginally better, sometimes only a bit better, but in very very few cases worse.

Academically speaking, there’s this thing called the Nyquist rate that defines what sample rate is needed for a particular underlying analog signal. In a horribly over-simplified nutshell, Nyquist says “if you meet this sample rate, all this other math will just work at a fixed sample rate”.

As a result: most embedded design patters would say that if jitter is causing you to miss the Nyquist rate for your signal processing, you fix the jitter problem before you get “creative” with your math.

Side reason, that’s important to the software-y folks: single-step debugging through code that has lots of TImer.getFPGATimestamp() calls means the code’s behavior will change based on whether you’re debugging or not. For this reason alone, those libraries linked above haven’t seen use on a robot in multiple years.

How much jitter are you seeing? Are you using the wpilibj.PIDController or the wpilibj.controller.PIDController?

It is; we’re thinking of adding a calculate overload that takes a period measurement for teams that want to do it with greater precision. For most cases, it shouldn’t matter.

We are using edu.wpi.first.wpilibj.controller.PIDController I don’t have the logs in front of me, and there is no doubt that our loop timing is significantly improved over last year; however, it is still not rock solid like a loop interval on an Arduino or a “real” real time os would be.

This code is part of a prototype flywheel, we will be using NEO/SparkMax’s on the final bot, so we will almost certainly use the REV API and offload this activity, but it is a good opportunity to teach, so I was walking a student through the code when the question occurred to me (right as I was explaining about the “noise” from taking a double derivative on a position sensor).

Thanks to everyone who spends so much time improving WPILib and supporting the teams here.

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