mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat: QO-100 beacon lock — stabilise LNB drift to NB transponder beacon
Click the beacon on the spectrum; the controller tracks it and continuously trims the transverter LO so the whole downlink stays put as the LNB drifts. - BeaconLock.pas: TBeaconTracker scaffold (narrowband NCO/FLL) — kept but no longer in the control path (FLL diverged on the suppressed-carrier BPSK beacon + Pluto DC offset). Measurement now uses the proven display-FFT path. - RadioController: FBeaconLockHz folded into XvtrTranslate (on top of LOError). MeasureBeaconFFT finds the beacon by POWER-WEIGHTED CENTROID of the lobe (BPSK has a suppressed carrier → broad symmetric ~2.4 kHz lobe, not a line; a peak-finder jitters, the centroid sits on the carrier). Track position in ABSOLUTE display Hz (FBeaconTrackHz) so scrolling the waterfall/centre never moves the search window off the beacon. Closed loop: e = tracked - ref, d(e)/d(LockHz) = -1 -> LockHz += gain*e; settle cooldown after each correction (display-FFT lags the LO retune -> avoids overshoot); deadband 75 Hz + centroid/prominence smoothing + lock hysteresis for a steady lock. Correction applied only after the user clicks (manual seed), so a crowded band can't pull a neighbour to the reference. - WDSPEngine: SetBeaconTracker + RX-IQ tap (tracker idle now, ~1 check/sample). - SpectrumView + GL: beacon markers — green = reference (10489.750), orange = tracked centroid. - MainForm: BEACON button (RX block, XVTR-only). Flow: BEACON -> "CLICK BCN" -> click beacon -> "L<corr> /<prom>". ServiceBeaconLock driven by MeterTimer. Reference defaults to the middle BPSK beacon 10489.750. Tested on-air against Es'hail-2: locks and holds, survives waterfall drag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+17
-1
@@ -25,7 +25,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Math, SyncObjs,
|
||||
WDSP;
|
||||
WDSP, BeaconLock;
|
||||
|
||||
const
|
||||
// WDSP mode integers (нет именованных констант в WDSP.pas)
|
||||
@@ -292,6 +292,7 @@ type
|
||||
FMuted: Boolean;
|
||||
FVolume: Double;
|
||||
FLastError: string;
|
||||
FBeaconTracker: TBeaconTracker; // QO-100 beacon lock (НЕ владеем; см. контроллер)
|
||||
|
||||
function ModeToWDSP(Mode: Integer): Integer;
|
||||
procedure ApplyDefaultFilter;
|
||||
@@ -354,6 +355,9 @@ type
|
||||
procedure UpdateAGCLines(SpectrumW: Integer); // читает hang/thresh из WDSP для линии на спектре
|
||||
procedure SetSpectrumWidth(W: Integer); // обновляет FLastSpectrumW для корректных AGC линий
|
||||
procedure SetShift(ShiftHz: Double); // CTUN NCO сдвиг
|
||||
// QO-100 beacon lock: трекер кормится RX-IQ из DSP-потока. Владелец —
|
||||
// контроллер; движок лишь подаёт сэмплы и сообщает sample rate.
|
||||
procedure SetBeaconTracker(T: TBeaconTracker);
|
||||
procedure SetNRMode(Mode: Integer);
|
||||
procedure SetNR(Enable: Boolean);
|
||||
procedure SetNBMode(Mode: Integer);
|
||||
@@ -1119,6 +1123,7 @@ begin
|
||||
// Обновляем параметры
|
||||
FSampleRate := NewRate;
|
||||
FBufSize := FAudioBufSize * NewRate div FAudioRate;
|
||||
if FBeaconTracker <> nil then FBeaconTracker.Configure(FSampleRate);
|
||||
|
||||
// Перераспределяем буферы под новый размер
|
||||
SetLength(FRXIn, FBufSize * 2);
|
||||
@@ -1213,6 +1218,11 @@ begin
|
||||
|
||||
FeedDisplaySample(IR * SCALE, QR * SCALE);
|
||||
|
||||
// QO-100 beacon lock: тот же baseband-IQ @ FSampleRate (трекер сам
|
||||
// мгновенно выходит, если лок не активен — стоимость ~1 проверка/сэмпл).
|
||||
if FBeaconTracker <> nil then
|
||||
FBeaconTracker.Feed(IR * SCALE, QR * SCALE);
|
||||
|
||||
FRXAccI[FRXAccPos] := IR * SCALE;
|
||||
FRXAccQ[FRXAccPos] := QR * SCALE;
|
||||
Inc(FRXAccPos);
|
||||
@@ -1371,6 +1381,12 @@ begin
|
||||
UpdateAGCLines(FLastSpectrumW);
|
||||
end;
|
||||
|
||||
procedure TWDSPEngine.SetBeaconTracker(T: TBeaconTracker);
|
||||
begin
|
||||
FBeaconTracker := T;
|
||||
if (T <> nil) and (FSampleRate > 0) then T.Configure(FSampleRate);
|
||||
end;
|
||||
|
||||
procedure TWDSPEngine.SetShift(ShiftHz: Double);
|
||||
begin
|
||||
FShiftHz := ShiftHz;
|
||||
|
||||
Reference in New Issue
Block a user