NEO - Velocity PID does not hold velocity steady

We’re testing various ways to do a velocity PID of some kind.

We’re testing it with no load as a proof-of-concept.

When the motor has a power applied (e.g. via .set), the velocity holds very steady.

However, when we tried to run a velocity PID, it oscillates quite a bit around the required velocity, and we could not find a good PID parameter combination to make it work.

On the other hand, position PID was very easy to calibrate, and it works perfectly.

Any idea why?

All that testing was done with NEO internal encoders.

The method in question is below

The PID constants are the ones that work perfectly fine with position PID.

1 Like

Maybe add FF to make the velocity steadier?

I will try. This was a no-load test, and it fluctuated quite a bit. The test was to set it to 70 (with the conversion above) and it went between 120 and 40 or so.

AFAIK, constants for velocity and position PIDs are going to be different. What would you say is the range of the oscillation? There will be a tad of oscillation in velocity control but should be <1 rps over or under.

Otherwise, I would say tune down the P until you get rid of the oscillation. A good tuning step is turning up P until you see oscillation and then turning it down to get rid of the oscillation.

With it being a no-load test, I would expect to see a VERY SMALL P.

Yeah, the current constants are above, but I tried changing them. With P set to 0.005 the velocity never got above 60 or so, with the expected velocity set to 75.

Velocity PID in a low-inertia application (e.g. low mass flywheel shooters, no-load testing) with NEO/SparkMAX is limited in performance due to velocity signal filtering in the SparkMAX which introduces a significant effective delay into the feedback loop. There are quite a few posts on this topic. Here is one which references a number of the most important ones.

You are going to need feedforward to have any chance of your control loop being close to setpoint with the tiny proportional gains that are stable. Start with only kFF and increase it until your motor runs close to your setpoint in closed loop. You might find that values in the range of 1/5700 (max NEO rpm) get you in the ballpark for kFF.

Then add kP. Do not be surprised if stable kP values for low-inertia velocity loops have three leading zeros (e.g. 0.000x). For a completely unloaded test, you might even be at four leading zeros. Adjust kP until you get maybe a slight overshoot on a setpoint change, but no oscillation as the velocity settles to steady-state.

4 Likes

This thread had more detail as well about the filtering

1 Like

Thanks! I will try that

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