Like most teams my team has a Constants.java file which we store a large variety of things, from Talon IDs to PID values.
We waste a lot of time changing values and redeploying code to the point where I’ve wondered if we should start putting some of these values in the network tables so we can modify those on the fly. Obviously its a case by case thing but there are certain scenarios where this would be great.
Has anyone ever implemented something like this? Can’t imagine we’d be the first.
Could setup some sort of periodic refresh thread that would read the smartdashboard and put any changes into code, with either some sort of data structure or reflection.
Could also force all subsystems to have a parameter update function but would then have to map every individual parameter.
I’ve always wanted an excuse to do some weird stuff with switches or potentiometers on the operator console, but never found a good one. Physical inputs are pretty cool!
When we want to do this we use a slightly modified version of 6328’s tunable number. I’m sure someone on their team could talk more about it but using just the hasChanged in the appropriate periodic method is simple enough and suffices its requirement.
Another option is to put these all in a json file and read them in (most likely, during robotInit). This means you still need to deploy to place this file and does not allow changes dynamically, but it does mean you don’t have to build.
The idea with TunableNumber is that the values are stored in the code (version controlled with no way to lose a config file), but we can tune them over NetworkTables when needed. We have a line in Constants to enable “tuning mode”. When not in tuning mode, the tunable numbers ignore NetworkTables and act like constants. This eliminates any risk of accidentally leaving the wrong number set on the dashboard during a match. It’s worked really well for us, and that class has been essentially unchanged for five years…
My team uses a custom encapsulation of Robot Preferences (SN_Preference, part of SuperCORE), which are used almost identically to 6328’s TunableNumber.
We make heavy use of SN_Preferences for many types of values, such as all closed loop values, preset positions, and the speed of a motor in subsystems like an intake. In my experience, preferences are most valuable when tuning a closed loop system, as the time it takes to redeploy code after every value change really adds up.
We do not use preferences for values that do not need to be tuned, or things that are only ever set once. This includes Talon IDs, gear ratios, whether a motor is inverted, diameter of a wheel, position of a field element, etc. There isn’t a strict reason why you can’t use preferences for these things, I just prefer preferences to only be values can and will change.
There are some things to be wary of when using preferences though. Making sure that the network table value is actually being used is important. To insure this, we often write methods that take an SN_DoublePreference as a parameter and only get the value in the method just to insure that the network tables value is being read at the last possible point. For closed loop values, we need to reconfigure all the motor controllers after changing a value.
It’s a bit more basic than what some other teams do, but basically we just use networktables and fetch the latest version of the number to use while testing.
We can change network tables values on our dashboard