Spark Max PID Velocity control, Spark Max reaches set point and then

Hey! My team is trying to use two spark max motor controllers for our shooter using a velocity control PID loop. While tuning, each time the RPM reaches the set point the motor starts to go reverse which is shown as the spark max LEDs flash red and green. I can not figure out why this is happening. Any help would be greatly appreciated. Thank you.

Here is the code I am using. Thank you.

Hmmmm. Can you point to the exact file you’re using? The repo link provided doesn’t seem to contain robot code… at least not that I could find?

That being said, and making some assumptions about your mechanism and code…

The scenario you describe sounds like the P gain is very high. As the error becomes slightly positive, your P gain attempts to compensate by driving the motor full negative power. The wheel slows down, driving the error slightly negative, at which point the P gain compensates by driving the motor to full forward power. Repeat Ad infinitum.

Note - this is not… technically… wrong… other than the wear and tear (mechanically and electrically ) it puts on the motor. You’ve kinda created a Bang-Bang controller, which is a good way to control heavy rotating mass to a certain velocity.

Assuming you only want to run the motor one direction, you can use the spark max API’s to limit the output range to only drive forward. This will effectively be a true bang-bang controller. Alternatively, cut your P gain down by factors of two until the oscillatory behavior ceases.

As one sample point: Our 1:1 geared, two-NEO shooter has about ten pounds of rotating mass spread over 8-inch diameter wheels, and is tuned with a P gain of 0.0006, and an F gain of 0.0002. I don’t completely know how much you can extrapolate this, but if you told me you have a P gain of 350.0 , I’d definitely say “something’s wrong”.


Your code logic seems fair. Your P (1.0) and D (0.15) gains looks very high. They should be around your FF. Your PID is likely oscillating (a lot) around your setpoint, jumping from 1.0 to -1.0 output. I suggest you start with P around 0.0005, D of 0 and see what happens.

You can calculate the PID output by hand to give you a feel of the system response.
(Target-Current)*kP + Target*kFF = output

If your goal is at 3000 RPM and the wheel is currently at 2900 RPM, you will have an output of:
(3000-2900)*P[1.0] + (3000)*FF[0.000015] = 100 + 0.045 = 100.045 (much too high)
Else at 3100 RPM:
(3000-3100)*P[1.0] + (3000)*FF[0.000015] = -100 + 0.045 = -99.955 (much too low)

With P of 0.0005:
(3000-2900)*P[0.0005] + (3000)*FF[0.000015] = 100 + 0.045 = 0.095 (kinda low but the wheel is close to its target)

I suggest you plot the current velocity and percent output to the dashboard to ease debugging.

1 Like

Yup, sorry, I clicked three wrong things before I finally got the right code:

Concur, kP is very very very large. kD is also exceedingly large - kD = kP/10.0 is usually my rule-of-thumb starting point. Would recommend zeroing it out as well until kP is under control.


1 Like

Thank you very much! I will modify these values and hope it works. Thank you!