Skip to content

Pileup: work the strongest caller first (opt-in) + SNR on caller-queue chips#692

Merged
patrickrb merged 1 commit into
devfrom
optio/task-985af3f3-f098-457d-92ac-3c139a9bc191
Jul 24, 2026
Merged

Pileup: work the strongest caller first (opt-in) + SNR on caller-queue chips#692
patrickrb merged 1 commit into
devfrom
optio/task-985af3f3-f098-457d-92ac-3c139a9bc191

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

What & why

When you run a pileup — calling CQ and getting several answers in the same slot during a DXpedition, POTA activation, or contest — FT8AF queues the extra callers and works them one after another. Until now that queue was strict FIFO: the station that called earliest was always worked next, regardless of how well you were copying it. On a busy run that means strong, easy-to-complete stations sit waiting behind marginal ones, and you burn cycles on exchanges that may never finish.

This adds an opt-in operating option that lets the app work the strongest waiting caller next instead, so you complete the best-copy contacts first and keep the run moving.

What changed

  • New Auto-Sequence setting — "Work strongest caller first" (Settings → CAT & Transmission → Auto-Sequence). Off by default, preserving the historic first-heard/FIFO order for anyone who prefers it.
  • When on, the pileup auto-dequeue picks the highest-SNR waiting caller next. Ties break toward the earliest-queued caller, so equal signals still go in the order they called (fair, deterministic).
  • The caller-queue chips in the active-QSO panel now show each waiting caller's SNR and sort strongest-first to match, so you can see at a glance who the engine will work next — and still tap any chip to pick someone else.

Implementation

  • GeneralVariables.pileupStrongestFirst (persisted via DB key pileupStrongestFirst, default off; volatile — written on the UI thread, read on the transmit thread).
  • Selection policy extracted to a pure, side-effect-free CallerQueueOrdering.pickNextIndex(queue, strongestFirst); FT8TransmitSignal.dequeueNextCaller() now uses it instead of remove(0).
  • Display helpers orderCallerQueue / callerSnrLabel extracted from ActiveQsoPanel for testing.
  • No change to the FT8 protocol, decoder, or waveform — this only reorders which already-queued caller is answered next.

Tests

  • CallerQueueOrderingTest (Java, pure): FIFO vs. strongest-first selection, negative-SNR handling, tie-break to earliest, full-drain ordering, no-mutation, empty/null guards.
  • CallerQueueDisplayTest (Kotlin, pure): display ordering mirrors the engine policy, stable-for-ties, SNR label formatting.

Verification

  • ./gradlew :app:testDebugUnitTest — full suite green.
  • ./gradlew :app:assembleDebug — APK builds clean.

…ller chips)

When running a pileup (calling CQ and getting several answers at once during a
DXpedition, POTA activation, or contest), the caller queue always worked the
oldest waiting station first (FIFO). On a busy run the best-copy stations then
wait behind marginal ones, wasting cycles on exchanges that may not complete.

Add an opt-in Auto-Sequence setting, "Work strongest caller first", that makes
the auto-dequeue pick the highest-SNR waiting caller next instead (ties break
toward the earliest-queued, so equal signals keep first-heard order). The
selection policy is extracted to a pure, unit-tested
CallerQueueOrdering.pickNextIndex; default is off, preserving the historic FIFO
behavior for anyone who prefers it.

The on-screen caller-queue chips now also show each waiting caller's SNR and
sort strongest-first to match, so the operator can see at a glance who the
engine will work next (and tap to pick someone else).

- GeneralVariables.pileupStrongestFirst (DB key pileupStrongestFirst, default off)
- CallerQueueOrdering pure policy; FT8TransmitSignal.dequeueNextCaller uses it
- ActiveQsoPanel: orderCallerQueue + callerSnrLabel helpers, SNR chip label
- Tests: CallerQueueOrderingTest (Java), CallerQueueDisplayTest (Kotlin)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.33333% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 36.68%. Comparing base (f8fc1f6) to head (a788b05).

Files with missing lines Patch % Lines
...o/ks3ckc/ft8af/ui/settings/TransmissionSettings.kt 0.00% 12 Missing ⚠️
...radio/ks3ckc/ft8af/ui/components/ActiveQsoPanel.kt 16.66% 10 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                dev     #692      +/-   ##
============================================
- Coverage     36.70%   36.68%   -0.03%     
  Complexity      211      211              
============================================
  Files           222      222              
  Lines         27479    27500      +21     
  Branches       3395     3398       +3     
============================================
+ Hits          10087    10089       +2     
- Misses        17147    17166      +19     
  Partials        245      245              
Flag Coverage Δ
android 15.78% <8.33%> (-0.01%) ⬇️
native 9.93% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...radio/ks3ckc/ft8af/ui/components/ActiveQsoPanel.kt 9.69% <16.66%> (+0.29%) ⬆️
...o/ks3ckc/ft8af/ui/settings/TransmissionSettings.kt 0.86% <0.00%> (-0.03%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@patrickrb
patrickrb merged commit 5f036f3 into dev Jul 24, 2026
17 checks passed
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.

1 participant