The Adaptive Tuner¶
The adaptive tuner is the older, experimental optimizer. For deciding single settings use setting trials.
Using it¶
$ beebo settings repeater.routing.tuning.adaptive.enabled on # start observe-only logging
$ beebo monitor capture tuning on # make sure tuning records are captured
$ beebo monitor decode -k adaptive --limit 20 # see recent proposals
$ beebo monitor pull # pull a full capture for offline analysis
$ beebo monitor decode --save # convert the pulled capture for `analyze`
$ beebo analyze tuning indicators --window 5 # per-window diagnostics (delivery proxy, TX success, ...)
$ beebo settings repeater.routing.tuning.adaptive.applied 1 # promote rx_delay_base (bit 0) to live actuation
How it works¶
AdaptiveController (src/helpers/AdaptiveController.h) runs one small
multi-choice bandit
(UCB1) per parameter, round-robin — every measurement window it advances exactly one
parameter's bandit by one tick, trying a neighboring value
(-step/stay/+step) and recording the objective score observed
just before the change. A full cycle through all 6 parameters (rx_delay_base, tx_delay_factor,
direct_tx_delay_factor, agc_reset_interval, interference_threshold,
airtime_factor) takes six windows.
Decision windows¶
The optimizer judges each change by the measurement
window that follows it. A window closes once the node has heard at least one
packet and has run at least tuning.adaptive.window.min_s seconds (default 300); if it
heard nothing at all by tuning.adaptive.window.max_s (default 3600) it counts as
insufficient data and nothing is changed. A window with real reception but
few or no actual forwards still closes and counts — for a repeater, failing
to convert reception into forwards is itself the service quality being
measured, not noise to discard. Busy nodes therefore close windows in minutes
and quiet ones take longer. A change is rolled back if the next window's
confirm ratio falls well below the one before it or the packet pool ran close
to full; each window is logged as a MON_EVAL record (beebo monitor decode
-k eval). These settings are RAM-only and reset on reboot.
Observe-only by default¶
Every decision is logged as a MON_ADAPTIVE MonRing
record (beebo monitor decode -k adaptive) regardless of whether
anything was actually changed — old_value, proposed_value, the reward
that preceded the decision, and whether it was applied. This is deliberate:
the reward signal and bandit behavior can (and should) be validated against
real traffic before trusting the optimizer to change anything live. Turn it
on with beebo settings repeater.routing.tuning.adaptive.enabled on.
Live actuation, per parameter¶
A separate bitmask
(repeater.routing.tuning.adaptive.applied) promotes individual parameters from observe-only
to actually writing the value — through the exact same setter path a human
changing that setting by hand would use, so a live-applied change can't
drift from manual behavior. Every other parameter stays observe-only
regardless. Every current parameter, including interference_threshold, can
be live-actuated this way — interference_threshold's getter is not hardcoded
to 0 as it is upstream (a stale leftover from before hardware CAD superseded
it, which silently discards any value written to it): beebo reads the stored
value.
Automatic rollback¶
After a live change, the parameter's next visit compares the freshly-observed confirm ratio against the one recorded just before that change. A drop of more than 15 percentage points reverts to the most recently confirmed-good value (not the very first value the parameter ever had) instead of trying a new step — a live-tuned parameter can regress, but it won't be left in a state that measurably hurt delivery.