Tune values while the robot is enabled

I wonder what’s the easiest way to implement a way of tuning values, for example PID constants, while the robot is enabled, that instead of disabling the robot, changing the values in the code and then redeploying.


There are many on here more knowledgable than I in this department, as we are just beginning to implement PID on our team. However, it seems there are two paradigms.

  1. Use the tests feature and livewindow. This seems to be setup automatically when you create a PID subsystem.

  2. Create a variable that holds your constant that reads from and writes to the smartdashboard. Update it durring your chosen robot mode (teleop, auto, or tests). Then, when all is said and done you could actually use it as a constant. Obviously you have to have the value be variable (ie. Non-static) while tuning.

The latter is what we found to work best. It allowed us to vendor-agnostically use this technique on CTRE and REV motor controllers for motor-controller side PID. Was really handy

1 Like

If you are using Java or C++, I highly recommend the Preferences system: Setting Robot Preferences — FIRST Robotics Competition documentation. It does everything you want - lets you read/write values in code while also displaying them on the SmartDashboard/Shuffleboard, and will save values between robot reboots.


SmartDashboard with PIDController can work well.

If you are doing this to config values onboard a can motor controller like a talon srx or a falcon, you should do something like this to prevent constantly setting the config every single loop (setting configs makes the can util spike a lot), and to instead only set it when you actually change the variable:

double newKP = SmartDashboard.getNumber("kP", 0.0);
if (newKP != previousKP){
    leftMaster.config_kP(0, newKP);   
    previousKP = newKP;     
1 Like

This approach has also worked really well for us. We wrote a helper class (TunableNumber.java) that automatically switches between a constant value and a NetworkTables value. Our constants file includes a line to switch into “tuning mode,” which allows every TunableNumber to be changed. We then update the default values in code so that they behave like normal constants while tuning mode is disabled.


I do prefer this approach over preferences - I want a “one safe source” for my “correct” calibration numbers, which is highly visible and hard to mess up. Usually, software source code is the place for this. Using something other than the one-safe-source should take active effort ( like toggling a switch). It should reset on power cycle. The goal is to ensure I know exactly what gains were running on a robot when we see it do bad behavior X out on the field, so we can start debugging it.

One additional note - for certain systems (occasionally PID), changing gains in the middle of motion can cause some wonky transient behavior.

We prefer to do tuning in a slower but more rigorous cycle:

  1. Pick a test to exercise some motion of the robot.
  2. Disable the robot
  3. Pick a new guess at controller gains
  4. Enable and run the test, recording data
  5. Disable the robot
  6. Analyze data. If it looks good, STOP. Else, GOTO 3

This ensures each test is “fair” - each started from the same initial state.

Once we get good gains from that process, if needed, we validate those gains against a set of different initial states. However, since your gain set needs to work at all times during robot operation, this time is more “test/issue-discovery” rather than “tuning”.


I generally opt for #2, but I keep running into something. To get a value to ‘stick’ in Glass, I seem to have to hit ‘Enter’. Doing that disables the robot.

Is there a way around this?

+1 to the CTRE Phoenix utility. Makes it very quick to tune

Just put some safety blocks in place

Currently Glass requires Enter to be hit to apply a value change. We did this so the values didn’t change “live” as you type each character.

The workaround currently is to use two computers (one running the DS, the other running Glass).

It does look like there may be a way we could change this in the future to also apply a value change when focus is lost (so clicking somewhere else after editing text would apply it as well). We’ll look at adding this feature for 2022.


We normally do it through Shuffleboard/SmartDashboard (though we took last year off so seems like Glass is the next thing we have to figure out).

Here’s our source code from Infinite Recharge that we’ve used to tune pids live.

1 Like

If you have the ability, +1 for many-laptop tuning sessions:


This is the kind of thing that’s really good to do from Test Mode:

(These were taken running with no robot, so all the values are uninteresting.)

So, one feature that people have mentioned but should be stressed: once you have tuned certain values, those values should be copied into the code, or in a file which is checked into your version control repo (eg Github).

Last year, we had code in our robot to build a calibration table for our shooter directly in the Rio; a command would cause the current value to put into a CSV file on the Rio. It did make the calibrating the shooter much faster. The trouble is, it never got cleanly copied off and put into the code repo. In addition, when we were locked out of our space and could not access the robot, we had no clue what values had been stored. We went about a year without those numbers.

So, again, whatever you do, make sure the “good” numbers are either set as the default in the code, or the official file is put into “deploy/”, or…

1 Like

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