feat(gui): ATU band pre-tune sweep and clear memories (#2624)#2630
Conversation
Adds two entries to a new right-click menu on the ATU button in TxApplet: Pre-tune bands... opens AtuPreTuneDialog, which steps the active TX slice through calculated center frequencies across the selected HF/6m bands and issues "atu start" at each point. Band edges are derived from the active BandPlanManager so the sweep follows the region-correct plan from AppSettings. Step mode confirms each point; Auto mode runs unattended with an always-visible Abort, a 30 s per-point timeout, and a hard stop after three consecutive TUNE_FAIL_BYPASS results. The slice is restored to its pre-sweep frequency on exit. Clear ATU memories... wraps the new TransmitModel::atuClearMemories(), which emits "atu clear" — confirmed via FlexLib Radio.cs:11055-11060. There is no per-band variant in the protocol, so the dialog offers only the all-bands wipe with an explicit confirmation click. The Pre-tune entry is grayed out with a tooltip when MEM is not enabled, matching the safety gating required for the sweep results to be stored.
There was a problem hiding this comment.
Thanks for the thoughtful work here — this is a well-structured dialog. Conventions look right (AppSettings + FramelessWindow gate matches the established pattern, RAII via Qt parent ownership, WA_DeleteOnClose + destroyed lambda to null the cached pointer, slice restoration on every exit path including closeEvent). The safety story is good: visible Abort, 300 ms settle, 30 s per-point timeout, and the 3-consecutive-FailBypass abort. The disclaimer text is appropriate for an unattended-transmission feature.
A couple of edge cases worth handling before merge:
1. Locked TX slice silently breaks the sweep (AtuPreTuneDialog.cpp beginNextPoint)
SliceModel::setFrequency() is a no-op when m_locked is true (see src/models/SliceModel.cpp:36). If the active TX slice is locked (common during contesting / SO2R), the sweep will fire atu start repeatedly at whatever frequency the slice is currently sitting on — every point will appear to "succeed" but only one band actually gets a memory entry, and the user has no indication anything is wrong.
Suggest one of:
- Reject in
onStartClicked()with a clear message iftxSlice->isLocked(). - Or temporarily unlock for the duration of the sweep and restore in
finishSweep()/closeEvent()/onAbortClicked()alongside the existing frequency restore.
The same path is also vulnerable if m_radio->slice(m_txSliceId) returns null at any later point — currently beginNextPoint just silently skips the setFrequency call and proceeds to tune. A null check that aborts the sweep would be safer than continuing.
2. MEM gating is enforced at menu open only
showAtuContextMenu greys out "Pre-tune bands…" when MEM is off, and openPreTuneDialog re-checks. But once the dialog is up, nothing re-checks memoriesEnabled() at Start or per-point. If the user toggles MEM off after the dialog opens (the MEM button is still right next to the ATU button), the sweep proceeds and the radio won't store any of the tunes — defeating the entire purpose. A re-check in onStartClicked() (and ideally one in beginNextPoint with a visible warning, since the sweep can run for many minutes) would close that hole.
3. Minor: restoreOriginalFrequency early-returns on m_originalSliceFreqMhz <= 0.0
This is captured in onStartClicked as txSlice ? txSlice->frequency() : 0.0, so a null slice silently disables restore. Probably fine in practice, but the guard hides the failure rather than reporting it.
Scope-wise everything looks on-issue for #2624 — no stray files. atuClearMemories() in TransmitModel is appropriately small and the FlexLib reference in the comment is helpful.
Follow-up fixes surfaced during live testing of the ATU pre-tune sweep: - **Close button color**: after sweep completion the abort-red stylesheet stayed on the button even after its label changed to "Close". Split into setAbortButtonAbortMode() / setAbortButtonCloseMode() helpers so text + stylesheet stay in sync at every transition. - **Band zoom-out at transitions**: on the first point of each swept band the panadapter now zooms to the full-band view (center = band midpoint, bandwidth = band width × 1.10) so the operator sees the whole band being swept. Original pan center + bandwidth captured at sweep start and restored on completion/abort/WM-close. - **Waterfall follows the pan**: mirrors MainWindow::applyPanRangeRequest's optimistic-update pattern — push center+bandwidth together onto the PanadapterModel before sending the radio command so SpectrumWidget reprojects both FFT and waterfall in one shot. Without this only the FFT was tracking the new range. - **BYPASS as terminal-success**: when the ATU reports IN_PROGRESS → BYPASS it means the tune cycle completed and the ATU decided no inductors were needed. With MEM on the radio still writes a memory entry, so it counts as a successful pre-tune. Previously this caused the sweep to hang until the 30 s per-point timeout fired. - **Post-tune SWR readout**: sample MeterModel::txMetersChanged while waiting for the ATU terminal state and append the settled post-tune SWR to the result line (e.g. "Tune OK. SWR 1.41:1"). Filters out the radio's exact-1.0 SWR reset that appears in the final meter packet of each tune cycle even at full forward power. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ten9876
left a comment
There was a problem hiding this comment.
Approved after live-test on FLEX-8600. AetherClaude's feature + our hardware-tested follow-up commit (close button color, band-zoom + waterfall sync, BYPASS handling, SWR readout) all work as intended. Constitution compliant (Principles I + IV). Three considerations filed as separate follow-ups.
Summary
Fixes #2624
What was changed
feat(gui): ATU band pre-tune sweep and clear memories (#2624)
Files modified
CMakeLists.txtsrc/gui/AtuPreTuneDialog.cppsrc/gui/AtuPreTuneDialog.hsrc/gui/MainWindow.cppsrc/gui/TxApplet.cppsrc/gui/TxApplet.hsrc/models/TransmitModel.cppsrc/models/TransmitModel.hGenerated by AetherClaude (automated agent for AetherSDR)