Redefining PID values in code


Anyone know if and how to change the PID values of a loop within code, for example during a match? The same loop, just like a different P or any of the others. Using C++ btw. From WPILIB, it seems possible, but not sure how to go about doing it.



You can use the setPID() function to set the gains of the P, I, D, (and optional F) gains while the controller is running if I’m understanding the documentation correctly, or just use the setP(), setI(), setD(), or setF() function. How you go about implementing that could be a button press, pulling a number off the SmartDashboard, or some other more clever way.



Failing this you could just set the PID(f) values to a variable such as P = pVar

and somewhere else in your teleop loop do

 if(ControllerButton1.get() == true){
      pVar = 1
      pVar = 2


For the case of SmartDashboard, it is a lot simpler to put a PIDController object on SmartDashboard, which will call SetP etc. for you. Useful for tuning.

1 Like


OP -yes, you can do what you describe.

Things to consider:

  1. If you are adjusting the gains on a CAN-based controller, there is delay in sending the change. Some of these calls can be slow (depends on the year, API, language, controller, etc…). SRX’s and Spark Max’s support the concept of “slots” where you can pre-program the set of gains you will use into different slots, and then swap the slot in use at runtime.

  2. The technique you are describing is more generally known as “Gain Scheduling” in the controls world. It is useful, but does come with some caveats. Namely, when you change gains, you have to be careful about the state of the system. For example, consider if gain set 1 has I = 0.001 and gain set 2 has I = 50.0. If you happen to swap from gain set 1 to 2 at a time when the integrator is “spun up”, it will go from having minimal impact on the control effort to a very large impact. This step change in the control output may not be desirable.

If you like, could you provide more info about your physical setup, and the behavior you’re looking to control/induce? It’s possible that there may be an alternate solution (F, perhaps?) which suits the situation better -folks here could help you discern that if you want.



I would also recommend having the PID values on smartdashboard, they save you a lot of time from having to not re-deploy when you are tuning values