Running pid loops in a separate thread.

I was wondering if anyone ran their pid loops separately from the main code in a different thread so as to get a higher refresh frequency. I fact, is multithreading even possible on the crio? I know that you can run separate loops in labview but I have read that the context switches eat the CPU. Is it possible in java?

Multithreading is possible on the cRIO, and in fact, multiple teams have utilized multithreading in their code. I know in C++ you can use pthreads to perform multithreading. I believe in the java api, you either have your class extend runnable or Threads. I’m not 100% sure on that, but you can check out the api to see what you can use. Just be careful with your stack and the memory. In Java, dealing with the stack and memory when multithreading is much simpler than in C, but you still have all of the usual caveats. In C++ you had to make sure certain variables were locked and unlocked when needed unless they were mutexed.

In Java at least, threads are actually pretty easy to use. I usually prefer using a TimerTask than an explicit Thread though. In terms of PID, if you look at PIDController’s source, that is exactly what it does – it’s already threaded.

The WPILIB implementation for java already uses threads for each PID controller. (See PIDCommand). However, the threads still have to lock internally with the Squawk JVM, so that field communication can occur. I don’t know that you can improve your sampling rate. Can you clarify why you think you need a higher sampling/control rate? Are you having a stability issue? Your parameter tuning likely needs to be adjusted, but no change to sampling rate should be necessary.

The cRIO has a PowerPC processor and does run a real time operating system. So threads do exist for this configuration. Context switching is too low level to consider for FRC robotics – the overhead is insignificant. This is not the cause of your issues with the PID controller.

As stated above fully possible. Team 3946 used it in 2013 for our RPi (RPi was doing image processing/goal tracking).

All of our code is available here: UltimateAscent

The specific classes you would probably want to look at are ThreadedPi, ThreadedBerryPi under Subsystems, and PrintThreadPiData under Commands.

Just came back here after working on some home projects. Thanks for all the help. I was hoping to get a higher sampling rate so that I could arc the robot’s path in autonomous if i need to. The way things are right now, PID does not work for moving setpoints.

If you are a high school student and considering trajectory-following control, good work!

This statement is vague and hard to assist without more information. How often are you changing the setpoint? My assumption is too often. A rule of thumb in control is 4-10X faster system convergence than control signal changes. Since you are limited to a ~200 Hz update rate, your setpoint should be updated only a few times a second.

To help you understand this more, I refer to the top figure on the PID Controller page. In a stable PID Controller design, the coefficients Kp, Ki, Kd are chosen (“tuned”) for the system dynamics. In general most people just guess and check until something works.

When looking at that figure, what you are doing is changing r(t). This introduces new dynamics into the e(t) signal. Thus, the given set of Kp, Ki, Kd parameters may not lead to a stable controller (because they worked with the original dynamics, and not the combination of original and new). I think this is what you are experiencing based on the “PID does not work for moving setpoints” comment. In general, PID controllers do allow for changing set points (this is why that diagram shows r(t) as a function of time and not just a constant-value r). One way is to change the three coefficients, but in your use here this isn’t desirable (you can explore this more in college).

Another approach is to change the nature of the dynamics added, by which I mean to change r(t) less often. Remember the first goal of a control system is stability, not time-optimal control. Thus, introducing changes to r(t) at a slower rate should help you maintain stability and allow for trajectory following.

If you still have more stability issues, then you can also try to slow down the motor speeds. I know this is less desirable to you than faster sampling, but as you prove to yourself you can do it at slower speeds, you might then try for to increase the speed later.

…that sounds like bad news for my pre-season programming project… I’ve been working on creating my own PID library to use for concurrently maintaining and changing the speed of the mecanum wheels on our practice drive-train during teleop, but based on what you’re saying, constantly changing the setpoint won’t work… (It was the original intention of the library, but if it fails (which it looks like it should), it hasn’t necessarily outlived it’s functionality :smiley: From what I hear, PID loops have lots of other potential uses).