Package com.crossbotics.ftchelper.tuning
Class Tunable
java.lang.Object
com.crossbotics.ftchelper.tuning.Tunable
A number you can change while the robot runs, from the gamepad (
TuningMenu),
without rebuilding. Saved values stay on the Control Hub until you reset them.
// Make it once (a static field is easiest):
static final Tunable LIFT_KP = Tunable.number("Lift/kP", 0.004, 0.0005);
// Read it every loop, so a change takes effect at once:
pid.setGains(LIFT_KP.get(), 0, 0, 0);
The part before "/" is the group shown in the menu ("Lift"). When you are happy with a value, copy it into the code as the new default, then reset the saved value: the code is the record, the saved file is only for tuning.
Saved values are kept in the robot's SettingsFile, under names that start with
"tunable.". Tutorial 15 (docs/tutorials/15-telemetry-profiles-tuning.md) walks through it.
Docs: docs/guides/tuning.md
-
Method Summary
Modifier and TypeMethodDescriptionall()Every tunable made so far, in the order they were made.The values that differ from the code, as lines to copy into it: "Lift: kP = 0.0050" meanskP = 0.0050inTunables.java, classLift.static intHow many tunables use a saved value that is different from the code.voiddecrease()One step down.doubleThe value written in the code.display()The value as short text, e.g.static voidFor JUnit tests only: forgets every tunable in memory (they are shared by the whole app, so one test's robot would otherwise see another's numbers).static TunableLikenumber(java.lang.String, double, double), for a number written in the team's code (the robot in five files uses it for everyTunables.javafield).doubleget()The current value.group()The group: the part of the name before the first "/" ("" if none).The groups hidden now (parts not on the robot), in order, e.g.static voidHides (or shows again) every tunable of one group, e.g.voidincrease()One step up.booleanTrue if the value is not the code value.booleanisHidden()True while it is hidden from the menu (its part is not on the robot).name()The full name, e.g.static TunableMakes a tunable number, or returns the existing one with this name.outsideRangeNotes(Collection<String> groups) INIT notes for code values outside their allowed range, e.g.range(double min, double max) Limits the value to a range (the menu will not go past it).voidreset()Back to the code value.static booleanresetAll()Puts every tunable back to its code value and deletes the saved values.static voidresetAllInBackground(Consumer<Boolean> whenDone) resetAll(), with the file written on a background thread.static booleansaveAll()Saves every tunable's value on the Control Hub.static voidsaveAllInBackground(Consumer<Boolean> whenDone) Saves every tunable's value on a background thread; returns at once.voidset(double newValue) Sets the value (inside the range).shown()The tunables the tuning menu shows: every one but those of parts that are not on the robot (seehideGroup(java.lang.String, boolean)).source()Where the code value came from (seesource(String)), "" when it was written as a number.Says where the code value came from, shown next to it in the tuning menu while it is not changed: Tunables.java wrote DEFAULT_FROM_CATALOG, so the library worked it out ("from the catalog (gobilda-5203-435)", "general starting value (no part in Robot.java)").doublestep()How much one D-pad press changes the value.
-
Method Details
-
fromCode
Likenumber(java.lang.String, double, double), for a number written in the team's code (the robot in five files uses it for everyTunables.javafield). If a tunable with this name already exists, was not changed (not tuned, nothing saved) and has another code value, it takes this code value: the code is the record. Example: two robots in one app withTunables.Auto.leaveInches24 and 12; each robot drives its own distance. The step of an existing one is kept.- Parameters:
name- "Group/Name", e.g. "Auto/leaveInches"defaultValue- the value in the codestep- how much one D-pad press changes it, used only when the tunable is new- Returns:
- the tunable
-
number
Makes a tunable number, or returns the existing one with this name. (If one with this name already exists, the default and step given here are not used.)- Parameters:
name- "Group/Name", e.g. "Lift/kP"defaultValue- the value in the codestep- how much one D-pad press changes it- Returns:
- the tunable
-
all
Every tunable made so far, in the order they were made. -
shown
The tunables the tuning menu shows: every one but those of parts that are not on the robot (seehideGroup(java.lang.String, boolean)). -
hideGroup
Hides (or shows again) every tunable of one group, e.g. "IntakeDeploy" for "IntakeDeploy/deployed". The robot in five files hides the numbers of a part that is not on the robot (markedoptional(), its device not in the configuration): changing them would do nothing. Their saved values are kept, for the day the part is there. Set again at every INIT.- Parameters:
group- the group (a part's Tunables section)hidden- true = left out of the menu
-
isHidden
public boolean isHidden()True while it is hidden from the menu (its part is not on the robot). -
countChanged
public static int countChanged()How many tunables use a saved value that is different from the code. Show it in INIT. -
changedAsCode
The values that differ from the code, as lines to copy into it: "Lift: kP = 0.0050" meanskP = 0.0050inTunables.java, classLift. Empty if none differ. The code is the record: a value saved only on the hub is lost with a new Control Hub. -
saveAll
public static boolean saveAll()Saves every tunable's value on the Control Hub. WAITS for the storage: in a running OpMode usesaveAllInBackground(java.util.function.Consumer<java.lang.Boolean>)(the tuning menu does).- Returns:
- true if it worked
-
saveAllInBackground
Saves every tunable's value on a background thread; returns at once.- Parameters:
whenDone- gets true if it worked (runs on the background thread); may be null
-
resetAll
public static boolean resetAll()Puts every tunable back to its code value and deletes the saved values. WAITS for the storage: in a running OpMode useresetAllInBackground(java.util.function.Consumer<java.lang.Boolean>).- Returns:
- true if the file was saved
-
resetAllInBackground
resetAll(), with the file written on a background thread. The values change at once. -
forgetAllForTests
public static void forgetAllForTests()For JUnit tests only: forgets every tunable in memory (they are shared by the whole app, so one test's robot would otherwise see another's numbers).new PretendDevices()calls it. Never in robot code: the tuning menu would lose its numbers. -
range
Limits the value to a range (the menu will not go past it). Use it so tuning can never reach a dangerous number, for example a negative gain.- Parameters:
min- the smallest allowed valuemax- the largest allowed value- Returns:
- this tunable, so you can write
Tunable.number(...).range(0, 1)
-
outsideRangeNotes
INIT notes for code values outside their allowed range, e.g. "Tunables.Claw.open = 1.2 is outside its allowed range 0 to 1: 1 is used. Fix it in Tunables.java". Only for these groups (a robot's Tunables sections); empty when all are fine.- Parameters:
groups- the sections to look at, e.g. ["Claw", "Lift"]
-
get
public double get()The current value. Read it every loop. -
set
public void set(double newValue) Sets the value (inside the range). Not saved untilsaveAll().- Parameters:
newValue- the new value; outside the range it is pulled back to the nearest end
-
increase
public void increase()One step up. -
decrease
public void decrease()One step down. -
reset
public void reset()Back to the code value. -
isChanged
public boolean isChanged()True if the value is not the code value. -
name
The full name, e.g. "Lift/kP". -
defaultValue
public double defaultValue()The value written in the code. -
step
public double step()How much one D-pad press changes the value. -
group
The group: the part of the name before the first "/" ("" if none). -
source
Says where the code value came from, shown next to it in the tuning menu while it is not changed: Tunables.java wrote DEFAULT_FROM_CATALOG, so the library worked it out ("from the catalog (gobilda-5203-435)", "general starting value (no part in Robot.java)"). The "copy into Tunables.java" lines stay real numbers.- Parameters:
words- the words, "" for none- Returns:
- this tunable
-
source
Where the code value came from (seesource(String)), "" when it was written as a number. -
display
The value as short text, e.g. "0.0040".
-