Skip to content

Add loop antenna controls#2863

Merged
ten9876 merged 2 commits into
aethersdr:mainfrom
rfoust:codex/loop-ant-buttons
May 23, 2026
Merged

Add loop antenna controls#2863
ten9876 merged 2 commits into
aethersdr:mainfrom
rfoust:codex/loop-ant-buttons

Conversation

@rfoust

@rfoust rfoust commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add LoopA/LoopB support to panadapter status and ANT overlay controls
  • show loop controls only for radios with FlexLib loop capabilities
  • keep loop selections mutually exclusive and disable selection unless RX ANT is ANT1 or ANT2

Verification

  • cmake --build build --parallel 8
  • ctest --test-dir build -R model_capabilities_test --output-on-failure
  • git diff --check
  • merge-tree checks against PR 2860, PR 2862, and both combined

Copilot AI review requested due to automatic review settings May 18, 2026 21:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds LoopA/LoopB awareness to panadapter state and the spectrum ANT overlay, using model capabilities to expose loop controls only on supported radios.

Changes:

  • Extends ModelCapabilities and tests with LoopA/LoopB flags.
  • Tracks panadapter RX antenna and loop state from status updates.
  • Adds loop controls to the spectrum overlay and wires commands through MainWindow.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/model_capabilities_test.cpp Adds LoopA/LoopB expectations to capability tests.
src/models/PanadapterModel.h Adds RX antenna and loop state accessors/signals/storage.
src/models/PanadapterModel.cpp Parses rxant, loopa, and loopb from panadapter status.
src/models/ModelCapabilities.h Adds loop capability fields.
src/models/ModelCapabilities.cpp Populates loop capability table per model.
src/gui/SpectrumOverlayMenu.h Adds loop UI API, signals, and panadapter wiring state.
src/gui/SpectrumOverlayMenu.cpp Adds loop buttons, visibility gating, and panadapter RX antenna synchronization.
src/gui/MainWindow.cpp Wires overlay pan/model/capabilities and sends loop commands.
Comments suppressed due to low confidence (1)

src/gui/SpectrumOverlayMenu.cpp:384

  • This mirrors the LoopA switching path: unchecking LoopA under QSignalBlocker suppresses loopAToggled(false), so switching from LoopA to LoopB only sends loopb=1 and does not explicitly clear LoopA on the radio. Emit/send the complete state transition so the radio and UI stay mutually exclusive.
        if (on && m_loopABtn && m_loopABtn->isChecked()) {
            QSignalBlocker blocker(m_loopABtn);
            m_loopABtn->setChecked(false);
        }
        emit loopBToggled(on);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/gui/MainWindow.cpp Outdated
if (m_panStack->panadapter(pan->panId())) {
if (auto* sw = m_panStack->spectrum(pan->panId())) {
sw->overlayMenu()->setPanId(pan->panId());
sw->overlayMenu()->setRadioModel(&m_radioModel);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f281fc7 by mirroring the normal wirePanadapter initialization in the duplicate-pan path: the overlay now gets setPanId, setRadioModel, and setRadioCapabilities before that path returns. Verified with cmake --build build --parallel 8 and ctest --test-dir build -R model_capabilities_test --output-on-failure.

Comment on lines +366 to +370
if (on && m_loopBBtn && m_loopBBtn->isChecked()) {
QSignalBlocker blocker(m_loopBBtn);
m_loopBBtn->setChecked(false);
}
emit loopAToggled(on);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f281fc7. When switching LoopA/LoopB, the UI still blocks the opposite button signal while updating the check state, but now manually emits the opposite loop false signal so MainWindow sends loopb=0 or loopa=0 before the selected loop command. Verified with cmake --build build --parallel 8 and ctest --test-dir build -R model_capabilities_test --output-on-failure.

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good — nicely scoped feature with capability gating, RAII connection management via QPointer<PanadapterModel>, and the test table extended to cover the two new flags. Both Copilot findings are addressed in f281fc7:

  • The duplicate-panadapter path in MainWindow.cpp now mirrors wirePanadapter() by calling setPanId/setRadioModel/setRadioCapabilities before the early return, so loop button visibility is seeded correctly.
  • The loop-toggle mutex in SpectrumOverlayMenu.cpp now manually emits loopBToggled(false) / loopAToggled(false) when unchecking the opposite button under QSignalBlocker, so the radio receives the complete desired state.

A couple of minor notes (non-blocking):

  1. Implicit mutex in PanadapterModel::applyPanStatus (PanadapterModel.cpp +97): when the radio reports loopa=1, the parser proactively clears m_loopB (and vice versa) even if the status frame doesn't contain loopb. In practice FlexLib emits both keys, so this is defensive and harmless — but if a future firmware ever reported loopa=1 standalone with loopb unchanged-but-true, the client would silently drop the LoopB state without a radio echo. Worth a brief comment noting this is a UI-mirror assumption, not a protocol guarantee.

  2. Scope overlap with #2862: this PR's rxant parsing in PanadapterModel and the "send via pan set when panadapter-authoritative" change in the RX ANT combo overlap with PR #2862's stated changes. You called out the merge-tree check in the description, so this is just a flag for the maintainer's attention on landing order.

Thanks for the FlexLib-mirroring discipline (capability table + matching test row) and for citing the FLEX-6500 LoopA / FLEX-6700 LoopA+LoopB hardware specifics in the model table comments. Appreciate the contribution! 🎯

@rfoust rfoust force-pushed the codex/loop-ant-buttons branch from f281fc7 to a4e343a Compare May 21, 2026 03:37
# Conflicts:
#	src/gui/SpectrumOverlayMenu.cpp
#	src/gui/SpectrumOverlayMenu.h
@ten9876

ten9876 commented May 23, 2026

Copy link
Copy Markdown
Collaborator

Claude here — pushed merge commit `035a0a01` resolving the
`SpectrumOverlayMenu.{cpp,h}` conflicts against current main.

All four conflict regions were "PR adds loop-related logic, main has
nothing in that spot" — straight additive resolution. Plus PR #2862
landed independently with the same rxAntenna plumbing in
`PanadapterModel.{h}` (the auto-merge happily accepted both copies);
deduped the three redeclarations (`rxAntenna()` accessor,
`rxAntennaChanged` signal, `m_rxAntenna` field).

Local Release build green. CI re-running.

@rfoust — nice work on this. Verified the LoopA/LoopB capability
table row-for-row against `~/build/FlexLib/FlexLib/ModelInfo.cs` —
FLEX-6500 `(true, false)` and FLEX-6700 `(true, true)` both match.
The mutual-exclusion logic with explicit signal emission (toggle
loopA-on while loopB checked → uncheck B AND emit `loopBToggled(false)`)
is exactly right — without that explicit emit, the radio would still
hold loopB engaged after the visual flip.

Will admin-merge once CI lands.

73,
Jeremy KK7GWY & Claude (AI dev partner)

@ten9876 ten9876 merged commit c757974 into aethersdr:main May 23, 2026
5 checks passed
@ten9876

ten9876 commented May 23, 2026

Copy link
Copy Markdown
Collaborator

Claude here — merged. Thanks @rfoust, third PR in the panadapter-
scoped-routing series and the most user-visible.

Verified the LoopA/LoopB capability table row-for-row against
`~/build/FlexLib/FlexLib/ModelInfo.cs` before merge — FLEX-6500
`(true, false)` and FLEX-6700 `(true, true)` both match upstream.
The `tests/model_capabilities_test` extension covering all 16 model
rows × 4 capability flags will catch any future FlexLib drift, which
is exactly the safety net we want.

The mutual-exclusion logic with the explicit `loopBToggled(false)`
emit when toggling loopA on (rather than just unchecking the button
visually) is the load-bearing detail. Without that explicit signal,
the radio would still hold loopB engaged while the UI showed it off
— silent state drift between client and radio.

Ships in v26.5.3.

73,
Jeremy KK7GWY & Claude (AI dev partner)

G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
Summary
- add LoopA/LoopB support to panadapter status and ANT overlay controls
- show loop controls only for radios with FlexLib loop capabilities
- keep loop selections mutually exclusive and disable selection unless
RX ANT is ANT1 or ANT2

Verification
- cmake --build build --parallel 8
- ctest --test-dir build -R model_capabilities_test --output-on-failure
- git diff --check
- merge-tree checks against PR 2860, PR 2862, and both combined

Co-authored-by: Jeremy Fielder <kk7gwy@aethersdr.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants