SparkMAX Velocity Closed Loop Example Code Doesn't Work Properly

So we’re having trouble getting the PIDController in the SparkMAX to work properly. We are trying to control to output RPM and the built-in pid controller is controlling to a too low speed. It is typically about a factor of 3 wrong; but the factor seems to depend on the PID coefficients.

As a test, we went back to the REVRobotics Example code from https://github.com/REVrobotics/SPARK-MAX-Examples/Java/Velocity Closed Loop Control . After changing only the CANID, the output on the SmartDashboard shows a set point of 5700 RPM; but the actual output is 1862. This is the exact same symptom we were seeing with our code.

We’re at the latest firmware and we did a factory reset. We’re at a loss at what to try next. Any ideas?

Thanks
MA
Mentor Team 281

I assume this is for a shooter? Do you have a gearbox or other reduction (e.g. chain/belt) in the system?

Do you have an Integral term?

The value of the input to the motor is going to be Kp*(E)+FF. Let’s ignore the FF for just a moment, so KP*E.

Now, giving your numbers, E=(5700-1862)=3838. Now, what value of input is required to get to 1872. Obviously, it depends on how much weight and friction, and what gear ratio, etc, is needed, so I’m going to make up a number. In order to reach 1872, you have to provide an input of .2.

Now, what is your gain on KP. I’ll just make up a number (not really) of 5.211x10-5.

Say, isn’t 5 x 10-5 the example given by RevRobotics? Hmmm…

So, now, suppose you start your loop, and the motor isn’t spinning. That means the input to the motor will be Kp * E, and E is 5700, so it will apply 5700 * .00005211=.29, and the motor will start moving.

Now, it will be getting a little bit closer to the set point, so the error will drop. What happens when it reaches 1872? In that case, the value will be equal to 0.2, which is exactly the speed required to spin it at 1872. So the control loop will tell it to apply 0.2, and that is enough to spin it at 1872, and there it will sit.

To get it moving, you have to provide an I term. Now, as it sits at 1872, the error will accumulate, and push it forward.

Note that a D term won’t do any good. Once it hits the steady state value at 1872, the value of D will drop to zero, so no matter what the value of KD is, the D term won’t provide any input.

You can shift the point where it stops by providing a FF term, but all that does is shift the point. It doesn’t fix the problem. There will be some point where KP*E+FF will be exactly what is required to spin the motor at that speed, and that will be the steady state value. Put in an I term.

ETA: (But see Oblarg’s reply below. I was being very theoretical, knowing that there will always be a steady state error unless there is an I term, but in terms of practical performance, if you measure what it takes to get to your setpoint, and then use that as an FF term, your performance may very well be better than trying to achieve zero steady state error with an I term.)

In practice, if your feedforward is good enough, the steady-state error is negligible, even if it’s technically nonzero. Integral gain shouldn’t be needed in such a case, and will generally make your system perform worse due to added instability unless you do a fair bit of practical hacking to deal with windup.

True. (Although I hadn’t thought about it. I was being a bit too theoretical in my head.)

Question answers: No gearboxes. Just a NEO attached to the SparkMAX.
Their code has P and F (no I or D). I know we can add this stuff; but It should settle at the demand speed. If fact, we see the overshoot and settling at the wrong speed. That shouldn’t happen unless the error term goes negative, so internally we think it’s targetting the wrong speed. We just don’t understand why.

OK I think we found our problem. We assumed the example code worked with constants that made the motor turn at roughly the desired RPM. After taking the example code and tuning the PIDs we ended up an order of magnitude or two higher than the example constants.

Thanks Everyone.

All these suggestions and solutions are correct and the rule is don’t naively use someone else’s tuning unless your complete mechanism is known to be very similar.

An extreme example to demonstrate why there are variations in orders of magnitude in constants: a small change in voltage to a motor not attached to anything will vary hundreds of RPM (and thus be hard or nearly impossible to control). A small change in voltage to a motor attached to 150 pounds of robot will do nothing.

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