[antenna] Add SWR sweep power and PGXL amplifier safety hardening#2220
Conversation
There was a problem hiding this comment.
Nice work on decoupling sweep power from the TX applet Tune Power, @jensenpat. The PGXL safety gate is a good addition — preventing an SWR sweep from driving RF into an amplifier in operate mode is the right call. A few observations:
Looks good
- Sweep power save/restore lifecycle — saving sweep power to
AppSettings, applying it before RF, and restoringoriginalTunePowerafterfinishSwrSweepAfterTuneStoppedis clean and correct. The restore is positioned before the TGXL restore branch so it always runs. QSignalBlockerinsetSwrSweepPowerWatts— prevents feedback loops when syncing the slider across panadapters. Good.const auto& tunerinadvanceSwrSweep— correct, the sweep timer path is read-only there.- Suppressing the empty SWR plot (
SpectrumWidget.cpp) — removing the&& !m_swrSweepRunningcheck is the right fix; no reason to enter the draw path with zero points. - AppletPanel includes —
QContextMenuEvent/QMenuadditions look like they were already needed by existing code but missing; fine to include here.
Items worth a look
-
setTunePoweroptimistic update — The new code updatesm_tunePowerlocally and emitsstateChanged()before the command reaches the radio. This is fine for the sweep's immediate needs, but note thatsetRfPower()does not do this — the two setters now behave asymmetrically. If the radio responds with a status update carrying the same value, the status handler at line 46–48 will no-op (no double-emit), so there's no functional bug. But if the command fails silently (radio rejects the power level), the local model will be out of sync until the next status push. Worth a comment noting the intentional asymmetry, or consider reverting the model on command failure if that's feasible. Not blocking. -
Tune power restore on abort — If the sweep is aborted before
tx.setTunePower(sweepPowerWatts)is reached (e.g., TGXL bypass wait times out and the sweep never starts RF),finishSwrSweepAfterTuneStoppedwill still callsetTunePower(originalTunePower). SinceoriginalTunePower == tx.tunePower()at that point (the sweep power was never applied), theoriginalTunePower != sweepTunePowerguard correctly prevents a no-op restore — nice. Just wanted to confirm I traced that right. -
kSwrSweepPowerSettingKeyisconstexpr const char*— Minor: in C++20 you could useconstexpr auto kSwrSweepPowerSettingKey = "SwrSweepPowerWatts";orconstexpr std::string_view. The current form is fine and consistent with the existing constants above it, so no action needed unless you want to tighten it. -
Signal signature change —
swrSweepStartRequested(int, int)is a breaking signal change. Since this is internal (no QML/plugin consumers), it should be fine, but if any out-of-tree code connects to this signal by name they'll get a runtime connect failure. Just flagging.
Overall this is solid and well-scoped. Thanks for the contribution!
Summary
Follow-up polish for the SWR sweep feature after #2202.
Changes
SwrSweepPowerWattsand loads it into each panadapter overlay on startup.TransmitModel::setTunePower()update optimistically so moving Tune Power from 0 W back up no longer leaves the sweep blocked on a stale model value.Safety Notes
The sweep now avoids depending on the TX applet Tune Power state. The selected sweep power is applied immediately before the sweep and restored only after the tune carrier has stopped. PGXL operate mode is treated as a hard precondition failure so users must put the amplifier in standby before the sweep can drive RF.
Validation
git diff --checkcmake --build build -j10./build/transmit_model_test./build/transmit_model_apd_test👨🏼💻 Generated with OpenAI Codex (GPT-5.5 Pro 4/23) and tested by @jensenpat