-
ADRC firmware adrc-pr15400-b10.1 — prebuilt hex Pre-release
released this
2026-08-28 18:01:27 +03:00 | -86 commits to master since this releaseADRC — experimental tester firmware based on betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
b10.1 — release-integrity maintenance rebuild
b10.1 keeps the b10 control law, defaults, PID-profile layout and Blackbox wire
schema unchanged. It does not choose LINEAR versus SQRT, add automatic
derating/protection, touch ELRS, or prescribe a new flight programme.This patch release closes the publication gaps found in the post-b10 review:
- the seven exact ADRC observability fields now have regression tests covering
their names/order, ADRC/debug/field-mask condition, and I/P-frame encoding; - board build failures now stop the release instead of producing a silently
partial matrix; explicit platform-SDK/output-format skips remain reported; - re-running a release updates its title and notes from the tagged source
instead of retaining stale metadata; - the public documentation distinguishes the 615 supported board configs, 14
explicit skips and 15 generic images, and states prominently that F446 images
are classic-PID-only because ADRC does not fit their flash budget.
The production writer now shares the same small I/P-field helpers exercised by
the tests; this is a testability refactor, not an intended flight-control or log
format change.make EXTRA_FLAGS=-Werror checks, the complete 74-suite
test-all, and cleanSTM32F411,STM32F446andMAMBAF722_I2Cbuilds pass.
The Blackbox unit suite is now 10/10. Test-only entry points are absent from the
firmware ELF files.Upgrading from b10 to b10.1 preserves PID profiles: both use PG version 13
and the same stored layout. The b10 first-boot reset and API-1.49 UART migration
warning below still apply when upgrading from b9 or another older base. F446
still does not contain ADRC.b10 — current Betaflight master, exact ADRC observability
b10 merges the b9 tester line plus ADRC-029 into Betaflight master
e8580ad977(2026-08-28), 118 upstream commits after the base used by the
ADRC line. This is a large platform integration, not a new flight-validated
ADRC tune. The automatic protection/derating idea remains deferred and is not
present in this build.The ADRC control-law policy stays on the b9/ADRC-029 line. New instrumentation
underset debug_mode = ADRCrecords, in the same PID iteration:- exact final controller sums
adrcPidSum[0..2](scale in
adrc_pid_sum_scale); - commanded and actually-applied collective (scale in
adrc_collective_scale); - gate-open state, the branch that opened it (commanded, gyro, or sustained
applied collective), and the axes whosez3growth was actually inhibited; adrcGateResetCount, so a reset epoch remains visible even if Blackbox
decimation skipped the exact loop;- the ADRC-029 profile-derived
adrc_z3_log_scale, replacing the old fixed
/16telemetry range. Old logs without this header still decode with 16.
Upgrade warning: restore selectively, then verify the ports
PID profiles intentionally reset on first boot. Current upstream uses PID
profile PG version 12 without ADRC fields, while b9 used wrapped version 0 with
a different layout. b10 uses version 13 so neither incompatible binary layout
is copied into the other. Back updiff all, then re-enter and verify every PID
profile and explicitly selectpid_type = ADRCwhere intended.Do not paste an old dump blindly. Upstream replaced the writable
serial ...
bitmask with per-feature UART settings; the oldserial ...command is now a
read-only synthesized view. Released Configurator 2026.6.1 predates firmware
API 1.49; use a current development Configurator containing
betaflight/betaflight-configurator#5420, betaflight/betaflight-configurator#5451
and betaflight/betaflight-configurator#5452, or use the CLI. On API
1.49 the Ports tab is deliberately
read-only and UART assignments live on each feature's own tab. Apply the board's
custom defaults, then verify the relevant*_uart/*_baudsettings (at least
receiver, MSP, Blackbox, VTX and GPS where used). Keep and verify the motor
protocol you chose; b10 does not require DShot.Other upstream-visible changes include removal of Integrated Yaw, the new
autopilot/Position Hold/GPS Rescue stack, and generic target renames
STM32F7X2→STM32F722andSTM32G47X→STM32G474. The release workflow
has been updated for both the renamed targets and the current nested config
repository layout.Verification and remaining risks
make EXTRA_FLAGS=-Werror checksand the completemake EXTRA_FLAGS=-Werror test-allsuite pass on the integrated tree.- Clean local builds pass for generic
STM32F411,MAMBAF722_I2C, and
BETAFPVG473_V2; the release CI builds the supported ARM target/config
matrix and reports configs requiring other platform SDKs separately. - Generic F411 is close to full:
FLASH1is 97.09% (about 14 KiB free).
Generic F446, which still excludes ADRC, is at 99.62% (about 1.8 KiB free).
Generic F722 is at 97.75% AXIM flash and 96.48% ITCM (576 bytes free in
ITCM);MAMBAF722_I2Chas 512 bytes of ITCM free. A later upstream addition
or a larger board config can overflow these regions and must be treated as a
build failure, not ignored. - ADRC-028's mechanism and a universal production b0 law/default remain open.
The F411 8 kHz real-hardware DWT timing measurement is also still pending. - This merged 2026.12-alpha base has not yet been validated by a new hardware
log. Testers decide what further hardware or flight checks are appropriate.
b9 — the z3 pre-takeoff blind spot, and yaw D is finally logged
Two changes over b8, both narrow. All behaviour and safety caveats under b8 and earlier
still apply.1. The z3 growth inhibit now keys on the gate alone. It used to key on
!liftoff && throttleAtIdle, andthrottleAtIdleclears at half the liftoff threshold —
so a craft still on the ground with the stick past that point charged its disturbance
estimate freely while the gate was still shut, and carried the result into the first
gate-open loop. It now keys on!liftoff.Hardware-checked before release rather than after, on six distinct arms on one 5" Mamba
F722: two props-on flights and four props-off bench arms.z3before the gate is exactly
zero in every one — that exactness is code-derived, from the arm reset and the inhibit,
and the logged field corroborates it at its own resolution. Roll/pitch tracking error is
unchanged from b8 at a median of 6 °/s, measured as the per-frame maximum of roll and
pitch|setpoint − gyroADC|over gate-open saved frames. Frames with a motor on a rail
after gate opening were 2.8 % in the preceding b8 payload flight and 0.2 % / 0.0 % in the
two fixed-code flights; that is descriptive, not a demonstrated causal reduction.A configuration workaround was tried first — raising
adrc_liftoff_throttleto shrink the
blind window — and measured not to work: on the loggedsetpoint[3]proxy the interval
shortened by roughly 6–7×, but peak logged roll/pitchz3went 1312 → 1491 and the
value carried into gate opening was higher, not lower (411 → 1054). The exact
runtime-domain ratio is not recoverable from that rounded, pre-thrust-linearisation field.This blind spot is live in b8 and executes on real takeoffs: all eight logs in @8ksal8's
two b0-law sweeps enter the interval, and five reach thez3telemetry rail before the
gate opens. The full commanded-floor-to-gate interval is 25.9–76.5 ms. Those logs do
not demonstrate a resulting flight-quality penalty, so this is a correctness fix, not
a rescue.2.
axisDis now logged on all three axes under ADRC. The field was gated on the
legacy profile D-gain being non-zero, which ADRC never reads — so on the shipped
defaults, wherepid[FD_YAW].Dis 0, the D-equivalent term was not recorded at all on
yaw. That is the axis that showed the fast-growing oscillation in ADRC-028. On the shipped
defaults this adds one signed-VB field per main frame, typically 1–5 bytes/frame; a custom
profile with more zero legacy D gains can add up to three fields under ADRC. The field was
verified in a hardware log, but this narrow schema branch does not yet have an automated
ADRC/classic-PID condition regression test.What b9 does not fix. Neither change fixes the ADRC-028 control-law path; b9 leaves
ADRC-028 open. In that event the gate never opened andz3was exactly zero, so the z3
change does not reach it, and the second change is instrumentation. Read the safety note
under "Enabling ADRC" before your first arm.b8 — b7 is withdrawn, use this instead
If you downloaded b7, replace it. b7 carried a defect in the very gate path it was
built to fix: the hold timer drained at the same rate it filled, which turned "250 ms
continuously above the threshold" into "above it more than half the time". Any duty cycle
over 50 % latched eventually — 1.8 s at 55 %, 0.9 s at 60 % — and ground oscillation is
exactly that kind of signal, so the ground false-open could come back. Raising
adrc_liftoff_hold_msdid not help either (22.5 s at 55 % duty for a 1000 ms setting).b8 resets the timer outright below the threshold, so the hold means what it says. Nothing
else changed; everything described under b7 below still applies. Three tests were added
that the b7 suite let through: ten seconds of bursts, twenty seconds at 60 % duty, and one
that checksadrc_liftoff_hold_msis honoured by this path.What's new in b7 (carried into b8)
This build exists because of one defect: the liftoff gate opened on the ground, by
itself, on every single arm. Across ten logs from @8ksal8 on 2026-08-06 the gate opened
with the throttle stick at exactly 0.0 %, between 25 and 710 ms after arming and 0.97-2.66 s
before the pilot first touched the throttle. The mechanism is the mixer, not the pilot:
when the controller asks for more authority than the mixer has, the mixer normalises the
axis mix and pins the collective at a value that crossesadrc_liftoff_throttleon its own.
Once open, the gate admitsb0*uand lifts the z3 inhibit, and the observer winds up
against a plant that cannot respond.The gate now reads two different things for two different questions:
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
airmode headroom (this landed in b6). Automatic modes are included: ALT_HOLD and
GPS_RESCUE override the throttle upstream of that sample. - "Is thrust actually being applied, and for long enough to mean flight?" - the applied
collective, held above the threshold continuously. Duration is what separates the two
cases: across those ten logs the longest unbroken run above the threshold before takeoff
was 43.5 ms (68.2 ms at a 25 % threshold), while a flying craft holds it for
0.37-16.3 s. The hold is 250 ms, oradrc_liftoff_hold_msif you set it higher.
The applied path also requires that something asked for thrust - the same idle interlock
the toss-launch path uses. Without it a held stick, a craft resting wedged or tilted, and
launch control (which forces the commanded collective to zero while forcing airmode on)
would each hold the applied collective up indefinitely on the ground and open the gate
anyway. With it, the timer stays at exactly zero through every pre-takeoff phase in all ten
logs.Your PID profiles survive the upgrade from b5 - the stored layout is byte-identical,
includingadrc_b0_law, so b5 tunes carry over unchanged. (From b1-b4 the b5 reset still
applies, see below.)Set
adrc_liftoff_throttlebelow your hover, not above itWorth checking before you fly this build. In those same logs the craft hovered at
26.8-37.0 % collective whileadrc_liftoff_throttlewas 40 - so in two of the flights
the threshold was never crossed at all, and only the ground defect above opened the gate.
A threshold above your real hover means the gate can stay shut for a whole flight, which is
the opposite failure: the observer then flies without its actuator feedback. Measure your
hover from a log and set the threshold under it.What is still open
Host-tested only - 63/63 unit suites including three ADRC suites, and the new behaviour is
pinned from both sides by tests that fail on b5 and on b6 respectively. Nothing here has
been flown. Bench first, props off, and if the motors run away as you arm, disarm
immediately. This build also does not touch loop timing: one tester measured the PID loop
running at half its configured rate with an external serial logger enabled, and since
dTis a compile-time constant the observer's effective bandwidth halves with it. That is
a separate open question.What's new in b6
Superseded by b7 and never released as a build. b6 made the gate read only the commanded
collective, which closed the ground false-open but created the opposite failure: thrust the
mixer applied without the pilot commanding it can still lift the craft, and then nothing
opened the gate at all. b7 keeps the commanded path and adds the applied one behind the
duration test.What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.Builds b1–b9 are ready-to-flash snapshots of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. b10 is different: it is a fork-only integration on newer Betaflight master
and cannot be reproduced by entering#15400in the official cloud builder. The exact
source is the release tag.Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.12.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F722for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveSafety, read before your first ADRC arm. ADRC-028 has been observed once: a
single props-on ground arm on a 5" craft using the shipped ADRC
defaults reached the yaw command limit 87 ms into the recording and an upper
motor rail 127 ms in, with the mean collective dragged from 7.7 % to 49.6 % at
zero throttle stick (both 30 ms window means). Measured against the log's earliest arming marker those
are 246 ms and 286 ms; the physical arm is earlier still. That is one craft and one arm — not a demonstration that it happens
everywhere — but 87 and 127 ms leave no credible margin for a manual cutoff.
Do not make your first ADRC arm with props on and the craft unrestrained.
Use props off, or a restraint/test stand with an automatic cutoff. Analysis:
pr15400-dedlike-mamba.Starting tunables (see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000. These are the
shipped defaults and a starting point only;
they are not validated as safe across airframes, and the arm-time behaviour
above was seen on exactly this tune, on a 5". Whoop pilots: ask in the thread
rather than take a number from here — the values that have flown well on small
frames differ a lot and none of them is validated as a safe default either. Set
debug_mode = ADRCand enable blackbox if you can — logs are the most valuable
thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- the seven exact ADRC observability fields now have regression tests covering
-
ADRC firmware adrc-pr15400-b10 — prebuilt hex Pre-release
released this
2026-08-28 14:23:13 +03:00 | -81 commits to master since this releaseADRC — experimental tester firmware based on betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
b10 — current Betaflight master, exact ADRC observability
b10 merges the b9 tester line plus ADRC-029 into Betaflight master
e8580ad977(2026-08-28), 118 upstream commits after the base used by the
ADRC line. This is a large platform integration, not a new flight-validated
ADRC tune. The automatic protection/derating idea remains deferred and is not
present in this build.The ADRC control-law policy stays on the b9/ADRC-029 line. New instrumentation
underset debug_mode = ADRCrecords, in the same PID iteration:- exact final controller sums
adrcPidSum[0..2](scale in
adrc_pid_sum_scale); - commanded and actually-applied collective (scale in
adrc_collective_scale); - gate-open state, the branch that opened it (commanded, gyro, or sustained
applied collective), and the axes whosez3growth was actually inhibited; adrcGateResetCount, so a reset epoch remains visible even if Blackbox
decimation skipped the exact loop;- the ADRC-029 profile-derived
adrc_z3_log_scale, replacing the old fixed
/16telemetry range. Old logs without this header still decode with 16.
Upgrade warning: restore selectively, then verify the ports
PID profiles intentionally reset on first boot. Current upstream uses PID
profile PG version 12 without ADRC fields, while b9 used wrapped version 0 with
a different layout. b10 uses version 13 so neither incompatible binary layout
is copied into the other. Back updiff all, then re-enter and verify every PID
profile and explicitly selectpid_type = ADRCwhere intended.Do not paste an old dump blindly. Upstream replaced the writable
serial ...
bitmask with per-feature UART settings; the oldserial ...command is now a
read-only synthesized view. Released Configurator 2026.6.1 predates firmware
API 1.49; use a current development Configurator containing
betaflight/betaflight-configurator#5420, betaflight/betaflight-configurator#5451
and betaflight/betaflight-configurator#5452, or use the CLI. On API
1.49 the Ports tab is deliberately
read-only and UART assignments live on each feature's own tab. Apply the board's
custom defaults, then verify the relevant*_uart/*_baudsettings (at least
receiver, MSP, Blackbox, VTX and GPS where used). Keep and verify the motor
protocol you chose; b10 does not require DShot.Other upstream-visible changes include removal of Integrated Yaw, the new
autopilot/Position Hold/GPS Rescue stack, and generic target renames
STM32F7X2→STM32F722andSTM32G47X→STM32G474. The release workflow
has been updated for both the renamed targets and the current nested config
repository layout.Verification and remaining risks
make EXTRA_FLAGS=-Werror checksand the completemake EXTRA_FLAGS=-Werror test-allsuite pass on the integrated tree.- Clean local builds pass for generic
STM32F411,MAMBAF722_I2C, and
BETAFPVG473_V2; the release CI builds the supported ARM target/config
matrix and reports configs requiring other platform SDKs separately. - Generic F411 is close to full:
FLASH1is 97.09% (about 14 KiB free).
Generic F446, which still excludes ADRC, is at 99.62% (about 1.8 KiB free).
Generic F722 is at 97.75% AXIM flash and 96.48% ITCM (576 bytes free in
ITCM);MAMBAF722_I2Chas 512 bytes of ITCM free. A later upstream addition
or a larger board config can overflow these regions and must be treated as a
build failure, not ignored. - ADRC-028's mechanism and a universal production b0 law/default remain open.
The F411 8 kHz real-hardware DWT timing measurement is also still pending. - This merged 2026.12-alpha base has not yet been validated by a new hardware
log. Testers decide what further hardware or flight checks are appropriate.
b9 — the z3 pre-takeoff blind spot, and yaw D is finally logged
Two changes over b8, both narrow. All behaviour and safety caveats under b8 and earlier
still apply.1. The z3 growth inhibit now keys on the gate alone. It used to key on
!liftoff && throttleAtIdle, andthrottleAtIdleclears at half the liftoff threshold —
so a craft still on the ground with the stick past that point charged its disturbance
estimate freely while the gate was still shut, and carried the result into the first
gate-open loop. It now keys on!liftoff.Hardware-checked before release rather than after, on six distinct arms on one 5" Mamba
F722: two props-on flights and four props-off bench arms.z3before the gate is exactly
zero in every one — that exactness is code-derived, from the arm reset and the inhibit,
and the logged field corroborates it at its own resolution. Roll/pitch tracking error is
unchanged from b8 at a median of 6 °/s, measured as the per-frame maximum of roll and
pitch|setpoint − gyroADC|over gate-open saved frames. Frames with a motor on a rail
after gate opening were 2.8 % in the preceding b8 payload flight and 0.2 % / 0.0 % in the
two fixed-code flights; that is descriptive, not a demonstrated causal reduction.A configuration workaround was tried first — raising
adrc_liftoff_throttleto shrink the
blind window — and measured not to work: on the loggedsetpoint[3]proxy the interval
shortened by roughly 6–7×, but peak logged roll/pitchz3went 1312 → 1491 and the
value carried into gate opening was higher, not lower (411 → 1054). The exact
runtime-domain ratio is not recoverable from that rounded, pre-thrust-linearisation field.This blind spot is live in b8 and executes on real takeoffs: all eight logs in @8ksal8's
two b0-law sweeps enter the interval, and five reach thez3telemetry rail before the
gate opens. The full commanded-floor-to-gate interval is 25.9–76.5 ms. Those logs do
not demonstrate a resulting flight-quality penalty, so this is a correctness fix, not
a rescue.2.
axisDis now logged on all three axes under ADRC. The field was gated on the
legacy profile D-gain being non-zero, which ADRC never reads — so on the shipped
defaults, wherepid[FD_YAW].Dis 0, the D-equivalent term was not recorded at all on
yaw. That is the axis that showed the fast-growing oscillation in ADRC-028. On the shipped
defaults this adds one signed-VB field per main frame, typically 1–5 bytes/frame; a custom
profile with more zero legacy D gains can add up to three fields under ADRC. The field was
verified in a hardware log, but this narrow schema branch does not yet have an automated
ADRC/classic-PID condition regression test.What b9 does not fix. Neither change fixes the ADRC-028 control-law path; b9 leaves
ADRC-028 open. In that event the gate never opened andz3was exactly zero, so the z3
change does not reach it, and the second change is instrumentation. Read the safety note
under "Enabling ADRC" before your first arm.b8 — b7 is withdrawn, use this instead
If you downloaded b7, replace it. b7 carried a defect in the very gate path it was
built to fix: the hold timer drained at the same rate it filled, which turned "250 ms
continuously above the threshold" into "above it more than half the time". Any duty cycle
over 50 % latched eventually — 1.8 s at 55 %, 0.9 s at 60 % — and ground oscillation is
exactly that kind of signal, so the ground false-open could come back. Raising
adrc_liftoff_hold_msdid not help either (22.5 s at 55 % duty for a 1000 ms setting).b8 resets the timer outright below the threshold, so the hold means what it says. Nothing
else changed; everything described under b7 below still applies. Three tests were added
that the b7 suite let through: ten seconds of bursts, twenty seconds at 60 % duty, and one
that checksadrc_liftoff_hold_msis honoured by this path.What's new in b7 (carried into b8)
This build exists because of one defect: the liftoff gate opened on the ground, by
itself, on every single arm. Across ten logs from @8ksal8 on 2026-08-06 the gate opened
with the throttle stick at exactly 0.0 %, between 25 and 710 ms after arming and 0.97-2.66 s
before the pilot first touched the throttle. The mechanism is the mixer, not the pilot:
when the controller asks for more authority than the mixer has, the mixer normalises the
axis mix and pins the collective at a value that crossesadrc_liftoff_throttleon its own.
Once open, the gate admitsb0*uand lifts the z3 inhibit, and the observer winds up
against a plant that cannot respond.The gate now reads two different things for two different questions:
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
airmode headroom (this landed in b6). Automatic modes are included: ALT_HOLD and
GPS_RESCUE override the throttle upstream of that sample. - "Is thrust actually being applied, and for long enough to mean flight?" - the applied
collective, held above the threshold continuously. Duration is what separates the two
cases: across those ten logs the longest unbroken run above the threshold before takeoff
was 43.5 ms (68.2 ms at a 25 % threshold), while a flying craft holds it for
0.37-16.3 s. The hold is 250 ms, oradrc_liftoff_hold_msif you set it higher.
The applied path also requires that something asked for thrust - the same idle interlock
the toss-launch path uses. Without it a held stick, a craft resting wedged or tilted, and
launch control (which forces the commanded collective to zero while forcing airmode on)
would each hold the applied collective up indefinitely on the ground and open the gate
anyway. With it, the timer stays at exactly zero through every pre-takeoff phase in all ten
logs.Your PID profiles survive the upgrade from b5 - the stored layout is byte-identical,
includingadrc_b0_law, so b5 tunes carry over unchanged. (From b1-b4 the b5 reset still
applies, see below.)Set
adrc_liftoff_throttlebelow your hover, not above itWorth checking before you fly this build. In those same logs the craft hovered at
26.8-37.0 % collective whileadrc_liftoff_throttlewas 40 - so in two of the flights
the threshold was never crossed at all, and only the ground defect above opened the gate.
A threshold above your real hover means the gate can stay shut for a whole flight, which is
the opposite failure: the observer then flies without its actuator feedback. Measure your
hover from a log and set the threshold under it.What is still open
Host-tested only - 63/63 unit suites including three ADRC suites, and the new behaviour is
pinned from both sides by tests that fail on b5 and on b6 respectively. Nothing here has
been flown. Bench first, props off, and if the motors run away as you arm, disarm
immediately. This build also does not touch loop timing: one tester measured the PID loop
running at half its configured rate with an external serial logger enabled, and since
dTis a compile-time constant the observer's effective bandwidth halves with it. That is
a separate open question.What's new in b6
Superseded by b7 and never released as a build. b6 made the gate read only the commanded
collective, which closed the ground false-open but created the opposite failure: thrust the
mixer applied without the pilot commanding it can still lift the craft, and then nothing
opened the gate at all. b7 keeps the commanded path and adds the applied one behind the
duration test.What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.Builds b1–b9 are ready-to-flash snapshots of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. b10 is different: it is a fork-only integration on newer Betaflight master
and cannot be reproduced by entering#15400in the official cloud builder. The exact
source is the release tag.Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.12.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F722for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveSafety, read before your first ADRC arm. ADRC-028 has been observed once: a
single props-on ground arm on a 5" craft using the shipped ADRC
defaults reached the yaw command limit 87 ms into the recording and an upper
motor rail 127 ms in, with the mean collective dragged from 7.7 % to 49.6 % at
zero throttle stick (both 30 ms window means). Measured against the log's earliest arming marker those
are 246 ms and 286 ms; the physical arm is earlier still. That is one craft and one arm — not a demonstration that it happens
everywhere — but 87 and 127 ms leave no credible margin for a manual cutoff.
Do not make your first ADRC arm with props on and the craft unrestrained.
Use props off, or a restraint/test stand with an automatic cutoff. Analysis:
pr15400-dedlike-mamba.Starting tunables (see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000. These are the
shipped defaults and a starting point only;
they are not validated as safe across airframes, and the arm-time behaviour
above was seen on exactly this tune, on a 5". Whoop pilots: ask in the thread
rather than take a number from here — the values that have flown well on small
frames differ a lot and none of them is validated as a safe default either. Set
debug_mode = ADRCand enable blackbox if you can — logs are the most valuable
thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- exact final controller sums
-
ADRC firmware adrc-pr15400-b9 — prebuilt hex Pre-release
released this
2026-08-09 19:33:22 +03:00 | 42 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
b9 — the z3 pre-takeoff blind spot, and yaw D is finally logged
Two changes over b8, both narrow. All behaviour and safety caveats under b8 and earlier
still apply.1. The z3 growth inhibit now keys on the gate alone. It used to key on
!liftoff && throttleAtIdle, andthrottleAtIdleclears at half the liftoff threshold —
so a craft still on the ground with the stick past that point charged its disturbance
estimate freely while the gate was still shut, and carried the result into the first
gate-open loop. It now keys on!liftoff.Hardware-checked before release rather than after, on six distinct arms on one 5" Mamba
F722: two props-on flights and four props-off bench arms.z3before the gate is exactly
zero in every one — that exactness is code-derived, from the arm reset and the inhibit,
and the logged field corroborates it at its own resolution. Roll/pitch tracking error is
unchanged from b8 at a median of 6 °/s, measured as the per-frame maximum of roll and
pitch|setpoint − gyroADC|over gate-open saved frames. Frames with a motor on a rail
after gate opening were 2.8 % in the preceding b8 payload flight and 0.2 % / 0.0 % in the
two fixed-code flights; that is descriptive, not a demonstrated causal reduction.A configuration workaround was tried first — raising
adrc_liftoff_throttleto shrink the
blind window — and measured not to work: on the loggedsetpoint[3]proxy the interval
shortened by roughly 6–7×, but peak logged roll/pitchz3went 1312 → 1491 and the
value carried into gate opening was higher, not lower (411 → 1054). The exact
runtime-domain ratio is not recoverable from that rounded, pre-thrust-linearisation field.This blind spot is live in b8 and executes on real takeoffs: all eight logs in @8ksal8's
two b0-law sweeps enter the interval, and five reach thez3telemetry rail before the
gate opens. The full commanded-floor-to-gate interval is 25.9–76.5 ms. Those logs do
not demonstrate a resulting flight-quality penalty, so this is a correctness fix, not
a rescue.2.
axisDis now logged on all three axes under ADRC. The field was gated on the
legacy profile D-gain being non-zero, which ADRC never reads — so on the shipped
defaults, wherepid[FD_YAW].Dis 0, the D-equivalent term was not recorded at all on
yaw. That is the axis that showed the fast-growing oscillation in ADRC-028. On the shipped
defaults this adds one signed-VB field per main frame, typically 1–5 bytes/frame; a custom
profile with more zero legacy D gains can add up to three fields under ADRC. The field was
verified in a hardware log, but this narrow schema branch does not yet have an automated
ADRC/classic-PID condition regression test.What b9 does not fix. Neither change fixes the ADRC-028 control-law path; b9 leaves
ADRC-028 open. In that event the gate never opened andz3was exactly zero, so the z3
change does not reach it, and the second change is instrumentation. Read the safety note
under "Enabling ADRC" before your first arm.b8 — b7 is withdrawn, use this instead
If you downloaded b7, replace it. b7 carried a defect in the very gate path it was
built to fix: the hold timer drained at the same rate it filled, which turned "250 ms
continuously above the threshold" into "above it more than half the time". Any duty cycle
over 50 % latched eventually — 1.8 s at 55 %, 0.9 s at 60 % — and ground oscillation is
exactly that kind of signal, so the ground false-open could come back. Raising
adrc_liftoff_hold_msdid not help either (22.5 s at 55 % duty for a 1000 ms setting).b8 resets the timer outright below the threshold, so the hold means what it says. Nothing
else changed; everything described under b7 below still applies. Three tests were added
that the b7 suite let through: ten seconds of bursts, twenty seconds at 60 % duty, and one
that checksadrc_liftoff_hold_msis honoured by this path.What's new in b7 (carried into b8)
This build exists because of one defect: the liftoff gate opened on the ground, by
itself, on every single arm. Across ten logs from @8ksal8 on 2026-08-06 the gate opened
with the throttle stick at exactly 0.0 %, between 25 and 710 ms after arming and 0.97-2.66 s
before the pilot first touched the throttle. The mechanism is the mixer, not the pilot:
when the controller asks for more authority than the mixer has, the mixer normalises the
axis mix and pins the collective at a value that crossesadrc_liftoff_throttleon its own.
Once open, the gate admitsb0*uand lifts the z3 inhibit, and the observer winds up
against a plant that cannot respond.The gate now reads two different things for two different questions:
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
airmode headroom (this landed in b6). Automatic modes are included: ALT_HOLD and
GPS_RESCUE override the throttle upstream of that sample. - "Is thrust actually being applied, and for long enough to mean flight?" - the applied
collective, held above the threshold continuously. Duration is what separates the two
cases: across those ten logs the longest unbroken run above the threshold before takeoff
was 43.5 ms (68.2 ms at a 25 % threshold), while a flying craft holds it for
0.37-16.3 s. The hold is 250 ms, oradrc_liftoff_hold_msif you set it higher.
The applied path also requires that something asked for thrust - the same idle interlock
the toss-launch path uses. Without it a held stick, a craft resting wedged or tilted, and
launch control (which forces the commanded collective to zero while forcing airmode on)
would each hold the applied collective up indefinitely on the ground and open the gate
anyway. With it, the timer stays at exactly zero through every pre-takeoff phase in all ten
logs.Your PID profiles survive the upgrade from b5 - the stored layout is byte-identical,
includingadrc_b0_law, so b5 tunes carry over unchanged. (From b1-b4 the b5 reset still
applies, see below.)Set
adrc_liftoff_throttlebelow your hover, not above itWorth checking before you fly this build. In those same logs the craft hovered at
26.8-37.0 % collective whileadrc_liftoff_throttlewas 40 - so in two of the flights
the threshold was never crossed at all, and only the ground defect above opened the gate.
A threshold above your real hover means the gate can stay shut for a whole flight, which is
the opposite failure: the observer then flies without its actuator feedback. Measure your
hover from a log and set the threshold under it.What is still open
Host-tested only - 63/63 unit suites including three ADRC suites, and the new behaviour is
pinned from both sides by tests that fail on b5 and on b6 respectively. Nothing here has
been flown. Bench first, props off, and if the motors run away as you arm, disarm
immediately. This build also does not touch loop timing: one tester measured the PID loop
running at half its configured rate with an external serial logger enabled, and since
dTis a compile-time constant the observer's effective bandwidth halves with it. That is
a separate open question.What's new in b6
Superseded by b7 and never released as a build. b6 made the gate read only the commanded
collective, which closed the ground false-open but created the opposite failure: thrust the
mixer applied without the pilot commanding it can still lift the craft, and then nothing
opened the gate at all. b7 keeps the commanded path and adds the applied one behind the
duration test.What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveSafety, read before your first ADRC arm. ADRC-028 has been observed once: a
single props-on ground arm on a 5" craft using the shipped ADRC
defaults reached the yaw command limit 87 ms into the recording and an upper
motor rail 127 ms in, with the mean collective dragged from 7.7 % to 49.6 % at
zero throttle stick (both 30 ms window means). Measured against the log's earliest arming marker those
are 246 ms and 286 ms; the physical arm is earlier still. That is one craft and one arm — not a demonstration that it happens
everywhere — but 87 and 127 ms leave no credible margin for a manual cutoff.
Do not make your first ADRC arm with props on and the craft unrestrained.
Use props off, or a restraint/test stand with an automatic cutoff. Analysis:
pr15400-dedlike-mamba.Starting tunables (see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000. These are the
shipped defaults and a starting point only;
they are not validated as safe across airframes, and the arm-time behaviour
above was seen on exactly this tune, on a 5". Whoop pilots: ask in the thread
rather than take a number from here — the values that have flown well on small
frames differ a lot and none of them is validated as a safe default either. Set
debug_mode = ADRCand enable blackbox if you can — logs are the most valuable
thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
-
ADRC firmware adrc-pr15400-b8 — prebuilt hex Pre-release
released this
2026-08-07 16:57:09 +03:00 | 54 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
b8 — b7 is withdrawn, use this instead
If you downloaded b7, replace it. b7 carried a defect in the very gate path it was
built to fix: the hold timer drained at the same rate it filled, which turned "250 ms
continuously above the threshold" into "above it more than half the time". Any duty cycle
over 50 % latched eventually — 1.8 s at 55 %, 0.9 s at 60 % — and ground oscillation is
exactly that kind of signal, so the ground false-open could come back. Raising
adrc_liftoff_hold_msdid not help either (22.5 s at 55 % duty for a 1000 ms setting).b8 resets the timer outright below the threshold, so the hold means what it says. Nothing
else changed; everything described under b7 below still applies. Three tests were added
that the b7 suite let through: ten seconds of bursts, twenty seconds at 60 % duty, and one
that checksadrc_liftoff_hold_msis honoured by this path.What's new in b7 (carried into b8)
This build exists because of one defect: the liftoff gate opened on the ground, by
itself, on every single arm. Across ten logs from @8ksal8 on 2026-08-06 the gate opened
with the throttle stick at exactly 0.0 %, between 25 and 710 ms after arming and 0.97-2.66 s
before the pilot first touched the throttle. The mechanism is the mixer, not the pilot:
when the controller asks for more authority than the mixer has, the mixer normalises the
axis mix and pins the collective at a value that crossesadrc_liftoff_throttleon its own.
Once open, the gate admitsb0*uand lifts the z3 inhibit, and the observer winds up
against a plant that cannot respond.The gate now reads two different things for two different questions:
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
airmode headroom (this landed in b6). Automatic modes are included: ALT_HOLD and
GPS_RESCUE override the throttle upstream of that sample. - "Is thrust actually being applied, and for long enough to mean flight?" - the applied
collective, held above the threshold continuously. Duration is what separates the two
cases: across those ten logs the longest unbroken run above the threshold before takeoff
was 43.5 ms (68.2 ms at a 25 % threshold), while a flying craft holds it for
0.37-16.3 s. The hold is 250 ms, oradrc_liftoff_hold_msif you set it higher.
The applied path also requires that something asked for thrust - the same idle interlock
the toss-launch path uses. Without it a held stick, a craft resting wedged or tilted, and
launch control (which forces the commanded collective to zero while forcing airmode on)
would each hold the applied collective up indefinitely on the ground and open the gate
anyway. With it, the timer stays at exactly zero through every pre-takeoff phase in all ten
logs.Your PID profiles survive the upgrade from b5 - the stored layout is byte-identical,
includingadrc_b0_law, so b5 tunes carry over unchanged. (From b1-b4 the b5 reset still
applies, see below.)Set
adrc_liftoff_throttlebelow your hover, not above itWorth checking before you fly this build. In those same logs the craft hovered at
26.8-37.0 % collective whileadrc_liftoff_throttlewas 40 - so in two of the flights
the threshold was never crossed at all, and only the ground defect above opened the gate.
A threshold above your real hover means the gate can stay shut for a whole flight, which is
the opposite failure: the observer then flies without its actuator feedback. Measure your
hover from a log and set the threshold under it.What is still open
Host-tested only - 63/63 unit suites including three ADRC suites, and the new behaviour is
pinned from both sides by tests that fail on b5 and on b6 respectively. Nothing here has
been flown. Bench first, props off, and if the motors run away as you arm, disarm
immediately. This build also does not touch loop timing: one tester measured the PID loop
running at half its configured rate with an external serial logger enabled, and since
dTis a compile-time constant the observer's effective bandwidth halves with it. That is
a separate open question.What's new in b6
Superseded by b7 and never released as a build. b6 made the gate read only the commanded
collective, which closed the ground false-open but created the opposite failure: thrust the
mixer applied without the pilot commanding it can still lift the craft, and then nothing
opened the gate at all. b7 keeps the commanded path and adds the applied one behind the
duration test.What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveSafety update, 2026-08-09 — read before your first ADRC arm. ADRC-028 has
been observed once: a single props-on ground arm on a 5" craft
using the shipped ADRC defaults reached the yaw command limit 87 ms into the
recording and an upper motor rail 127 ms in, with the mean collective dragged
from 7.7 % to 49.6 % at zero throttle stick (both 30 ms window means). Those times are from the first
saved log frame; against the log's earliest arming marker they are 246 ms and
286 ms, and the physical arm is earlier still. That is one craft and one arm —
not a demonstration that it happens everywhere — but neither figure leaves a
credible margin for a manual cutoff. Do not make your first ADRC arm with props on and
the craft unrestrained. Use props off, or a restraint/test stand with an
automatic cutoff. Analysis:
pr15400-dedlike-mamba.Starting tunables (see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000. These are the
shipped defaults and a starting point only;
they are not validated as safe across airframes, and the arm-time behaviour
above was seen on exactly this tune, on a 5". Whoop pilots: ask in the thread
rather than take a number from here — the values that have flown well on small
frames differ a lot and none of them is validated as a safe default either. Set
debug_mode = ADRCand enable blackbox
if you can — logs are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
-
ADRC firmware adrc-pr15400-b7 — prebuilt hex Pre-release
released this
2026-08-07 14:34:43 +03:00 | 56 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
What's new in b7
This build exists because of one defect: the liftoff gate opened on the ground, by
itself, on every single arm. Across ten logs from @8ksal8 on 2026-08-06 the gate opened
with the throttle stick at exactly 0.0 %, between 25 and 710 ms after arming and 0.97-2.66 s
before the pilot first touched the throttle. The mechanism is the mixer, not the pilot:
when the controller asks for more authority than the mixer has, the mixer normalises the
axis mix and pins the collective at a value that crossesadrc_liftoff_throttleon its own.
Once open, the gate admitsb0*uand lifts the z3 inhibit, and the observer winds up
against a plant that cannot respond.The gate now reads two different things for two different questions:
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
airmode headroom (this landed in b6). Automatic modes are included: ALT_HOLD and
GPS_RESCUE override the throttle upstream of that sample. - "Is thrust actually being applied, and for long enough to mean flight?" - the applied
collective, held above the threshold continuously. Duration is what separates the two
cases: across those ten logs the longest unbroken run above the threshold before takeoff
was 43.5 ms (68.2 ms at a 25 % threshold), while a flying craft holds it for
0.37-16.3 s. The hold is 250 ms, oradrc_liftoff_hold_msif you set it higher.
The applied path also requires that something asked for thrust - the same idle interlock
the toss-launch path uses. Without it a held stick, a craft resting wedged or tilted, and
launch control (which forces the commanded collective to zero while forcing airmode on)
would each hold the applied collective up indefinitely on the ground and open the gate
anyway. With it, the timer stays at exactly zero through every pre-takeoff phase in all ten
logs.Your PID profiles survive the upgrade from b5 - the stored layout is byte-identical,
includingadrc_b0_law, so b5 tunes carry over unchanged. (From b1-b4 the b5 reset still
applies, see below.)Set
adrc_liftoff_throttlebelow your hover, not above itWorth checking before you fly this build. In those same logs the craft hovered at
26.8-37.0 % collective whileadrc_liftoff_throttlewas 40 - so in two of the flights
the threshold was never crossed at all, and only the ground defect above opened the gate.
A threshold above your real hover means the gate can stay shut for a whole flight, which is
the opposite failure: the observer then flies without its actuator feedback. Measure your
hover from a log and set the threshold under it.What is still open
Host-tested only - 63/63 unit suites including three ADRC suites, and the new behaviour is
pinned from both sides by tests that fail on b5 and on b6 respectively. Nothing here has
been flown. Bench first, props off, and if the motors run away as you arm, disarm
immediately. This build also does not touch loop timing: one tester measured the PID loop
running at half its configured rate with an external serial logger enabled, and since
dTis a compile-time constant the observer's effective bandwidth halves with it. That is
a separate open question.What's new in b6
Superseded by b7 and never released as a build. b6 made the gate read only the commanded
collective, which closed the ground false-open but created the opposite failure: thrust the
mixer applied without the pilot commanding it can still lift the craft, and then nothing
opened the gate at all. b7 keeps the commanded path and adds the applied one behind the
duration test.What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- "Was thrust commanded?" - the collective as commanded, sampled before the mixer adds
-
ADRC firmware adrc-pr15400-b5 — prebuilt hex Pre-release
released this
2026-07-18 15:04:47 +03:00 | 58 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
What's new in b5
-
adrc_b0_law— A/B selector for the throttle→b0 schedule (ADRC-021,
fork-side only, will not go upstream): flight logs from two crafts measured
the shipped quadratic(throttle/hover)²law applying ×2.3–3 where the
plant gain only grows ×1.3–1.7; the data reject the quadratic but cannot
separate the sqrt vs linear candidates — that needs a controlled same-craft
A/B. New per-PID-profile CLI setting:set adrc_b0_law = QUADRATIC # (throttle/hover)^2 — b4 behavior, default set adrc_b0_law = SQRT # sqrt(throttle/hover) set adrc_b0_law = LINEAR # throttle/hover set adrc_b0_law = FIXED # no throttle schedulingSuggested protocol: profile 1 = QUADRATIC, profile 2 = SQRT, profile 3 =
LINEAR — same craft, same day, same pack rotation, same maneuver script
(doublets, hover ring check, punch→chop), law switched by PID profile
between flights, randomized order if you can. The active law is recorded in
the blackbox header (adrc_b0_law);set debug_mode = ADRCas always.
Default QUADRATIC flies exactly like b4. -
Mid-air liftoff-gate re-arm removed entirely (ADRC-020): b4 shipped it
off-by-default, b5 deletes it — throttle+gyro alone cannot distinguish a
landing from a calm mid-air float, and the fresh-epoch-on-arm behavior
already covers the ground-rep use case it existed for. -
PID profiles reset on first boot when upgrading from any earlier
build (b1–b4): the profile layout changed twice since b4 (ADRC-020 field
removal, the new selector).diff allbefore flashing, re-apply and verify
after. (Technical footnote: the config version field is 4 bits, so this
bump wraps 15 → 0 — the version check is an equality check and no build in
this lineage ever shipped 0, so the wrap still forces the reset everywhere.)
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- The "twitchy" feel is gone: b3's authority-scaled observer feedback
silently over-gained the loop by up to ~1.9× at 10–30% throttle without
airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The observer
feedback semantics are reverted to the frame every flight-validated b0 was
calibrated in. - Throttle-punch "nose dip rebound" reduced: the b0 throttle schedule now
reads an ~80 ms low-passed collective, so a throttle chop no longer yanks
the effective gain back up 3× faster than the disturbance estimate can
re-adapt (also removes a gain modulation at the loop resonance that the
post-mixer collective was feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
-
ADRC firmware adrc-pr15400-b4 — prebuilt hex Pre-release
released this
2026-07-12 19:45:03 +03:00 | 61 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
What's new in b4
The first flight logs on b3 (thanks @bvandevliet) caught a regression of the
b3 remediation round — both defects root-caused from the logs and fixed:- Observer feedback over-gain reverted: b3's authority-scaled observer
feedback silently over-gained the loop by up to ~1.9× at 10–30% throttle
without airmode, producing a sustained 24–26 Hz roll/pitch limit cycle. The
observer feedback semantics are reverted to the frame every flight-validated
b0 was calibrated in. - b0 throttle schedule low-passed: the schedule now reads an ~80 ms
low-passed collective, so a throttle chop no longer yanks the effective gain
back up 3× faster than the disturbance estimate can re-adapt (also removes a
gain modulation at the loop resonance that the post-mixer collective was
feeding in under airmode). - Settings survive from b2/b3 (same PG layout) —
diff allbackup first,
as always.
Flight-verified status of b4 (updated 2026-07-15)
Four b4 flight logs are analyzed — data, methods and scripts in
docs/flight-test-analysis/pr15400-b4/.
Measured verdicts, replacing the pre-flight wording of this section:- The gain-modulation fix is flight-confirmed (steady-stick
debug[7]
swing p90 = 0.27–0.29 vs the pre-fix 1.0↔2.8), and b3's always-on over-gain
did not reproduce. - An episodic 24–27 Hz ring remains: it ignites on events (gate open,
propwash re-entry after a punch→chop, landing approach), self-sustains for
seconds in the 10–30% throttle band, then decays. Open item ADRC-024,
root cause not yet established. - The throttle-punch "nose dip rebound" is not measurably improved by
the release LPF alone (calm-stick post-chop pitch peaks: pooled median
76 deg/s across 9 events vs b3's 80). Open item ADRC-025.
Heads-up for the next build: the PR head moved past b4 (
eda3bb16eb,
ADRC-020 re-arm removal) and bumps the profile version 14 → 15 — flashing the
current head or the future b5 over b4 resets your PID profiles.diff all
backup first.What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Observer feedback over-gain reverted: b3's authority-scaled observer
-
ADRC firmware adrc-pr15400-b3 — prebuilt hex Pre-release
released this
2026-07-11 19:50:45 +03:00 | 65 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
What's new in b3
- Rebased onto current Betaflight master (
6ecfb45f93). - Full remediation round (17 tracked findings, each with characterization
tests): bumpless liftoff-gate open (fixes the takeoff oscillation bout seen
in the first airmode log), crash recovery decoupled from classic D, stable
TD/ESO discretization at every supported loop rate, finite-value defenses
that survive-ffast-math, the observer now fed the actually-applied mixer
output (normalization, saturation, ALT_HOLD/GPS_RESCUE overrides,
thrust-linearization domain), clean yaw-spin/Crash Flip state handling. - Fresh ADRC epoch on every arm (ADRC-017): the liftoff gate and
disturbance estimate no longer survive disarm into the next arm cycle
(flight-reproduced on b2-era code: a post-landing z3 windup entered the
next arm with the gate already open). - Settings survive from b2: the profile layout and PG version are
unchanged, so upgrading b2 → b3 keeps your tune (still:diff allbackup
first). Upgrading from b1 resets profiles — see below. - STM32F446 builds don't include ADRC: that MCU's 512k flash is full with
the default feature set. F446-based boards get a working classic-PID build;
set pid_type = ADRCwon't exist there. All other targets are unaffected.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Rebased onto current Betaflight master (
-
ADRC firmware adrc-pr15400-b2 — prebuilt hex Pre-release
released this
2026-07-10 20:54:16 +03:00 | 97 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
Upgrading from b1
The first freestyle blackbox on this branch exposed two tuning-default problems, both
fixed here (see the PR discussion for the full log analysis):- Mid-air gate re-arm is now off by default (
adrc_liftoff_idle_hold_ms = 0): the
old landing heuristic false-triggered on smooth zero-throttle floats, dumping the
disturbance estimate mid-air — the reason airmode felt broken on b1. Airmode is fine
again on this build. adrc_b0_scale_maxdefault 9 → 3: the throttle-scaled b0 over-weakened the
controller on throttle punches (huge uncommanded pitch excursions with motors
nowhere near saturation).
Because keeping the old stored values would silently re-create both problems, the
profile version was bumped: your PID profiles reset to defaults on first boot of
this build —diff allbefore flashing and re-apply your tune after.These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Mid-air gate re-arm is now off by default (
-
ADRC firmware adrc-pr15400-b1 — prebuilt hex Pre-release
released this
2026-07-10 14:28:39 +03:00 | 103 commits to master since this releaseADRC — prebuilt hex of upstream PR betaflight/betaflight#15400
⚠️ Experimental. Bench-test before flying. Use at your own risk.
These are ready-to-flash builds of the upstream ADRC pull request
betaflight/betaflight#15400
(opt-inpid_type = ADRCper PID profile, classic PID untouched by default), so you
don't have to wait on the Configurator cloud build — or fight it when it queues or
errors out. The exact source commit is in the release tag description; the same code
can also be cloud-built by entering#15400in the Configurator's Select commit
field (visible only when the2026.6.0-alphaversion is selected in the dropdown).Which file do I flash?
Same convention as official Betaflight releases:
- Your board has its own hex (
betaflight_2026.6.0-alpha_<BOARDNAME>.hex) — use it. - Board not listed? Use the generic hex for your MCU (
STM32F7X2for any F722,
STM32F405,STM32H743,AT32F435M/G, …) and accept Apply custom defaults on
first connect.
Flash via Configurator → Firmware Flasher → Load Firmware [Local].
Enabling ADRC
ADRC is off by default — the firmware flies classic PID until you opt in:
set pid_type = ADRC saveStarting tunables (flight-validated on two 5" and a 65 mm whoop; see the
tuning guide):
adrc_wc_* = 60,adrc_wo_* = 100(yaw 80),adrc_b0_* = 2000(5") — whoops need
roughly33/65/3200. Setdebug_mode = ADRCand enable blackbox if you can — logs
are the most valuable thing you can send.Where to report
Flight reports, logs and issues: danusha2345/ADRC-betaflight#2
(or directly on the PR). Both good and bad results help.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Your board has its own hex (