Bläddra i källkod

feat: make refinement input an explicit phase handoff

master
Jan Svabenik 11 timmar sedan
förälder
incheckning
83c59adaa2
6 ändrade filer med 63 tillägg och 20 borttagningar
  1. +2
    -1
      cmd/sdrd/dsp_loop.go
  2. +3
    -2
      cmd/sdrd/phase_state.go
  3. +6
    -2
      cmd/sdrd/phase_state_test.go
  4. +23
    -12
      cmd/sdrd/pipeline_runtime.go
  5. +12
    -3
      internal/pipeline/phases.go
  6. +17
    -0
      internal/pipeline/phases_test.go

+ 2
- 1
cmd/sdrd/dsp_loop.go Visa fil

@@ -57,12 +57,13 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
rt.gotSamples = true
}
state.surveillance = rt.buildSurveillanceResult(art)
state.refinementInput = rt.buildRefinementInput(state.surveillance)
finished := state.surveillance.Finished
thresholds := state.surveillance.Thresholds
noiseFloor := state.surveillance.NoiseFloor
var displaySignals []detector.Signal
if len(art.iq) > 0 {
state.refinement = rt.refineSignals(art, state.surveillance.Scheduled, extractMgr, rec)
state.refinement = rt.refineSignals(art, state.refinementInput, extractMgr, rec)
displaySignals = state.refinement.Signals
if rec != nil && len(displaySignals) > 0 && len(art.allIQ) > 0 {
aqCfg := extractionConfig{firTaps: rt.cfg.Recorder.ExtractionTaps, bwMult: rt.cfg.Recorder.ExtractionBwMult}


+ 3
- 2
cmd/sdrd/phase_state.go Visa fil

@@ -3,6 +3,7 @@ package main
import "sdr-wideband-suite/internal/pipeline"

type phaseState struct {
surveillance pipeline.SurveillanceResult
refinement pipeline.RefinementResult
surveillance pipeline.SurveillanceResult
refinementInput pipeline.RefinementInput
refinement pipeline.RefinementResult
}

+ 6
- 2
cmd/sdrd/phase_state_test.go Visa fil

@@ -8,12 +8,16 @@ import (

func TestPhaseStateCarriesPhaseResults(t *testing.T) {
ps := &phaseState{
surveillance: pipeline.SurveillanceResult{NoiseFloor: -90, Scheduled: []pipeline.ScheduledCandidate{{Candidate: pipeline.Candidate{ID: 1}, Priority: 5}}},
refinement: pipeline.RefinementResult{Decisions: []pipeline.SignalDecision{{ShouldRecord: true}}, Candidates: []pipeline.Candidate{{ID: 1}}},
surveillance: pipeline.SurveillanceResult{NoiseFloor: -90, Scheduled: []pipeline.ScheduledCandidate{{Candidate: pipeline.Candidate{ID: 1}, Priority: 5}}},
refinementInput: pipeline.RefinementInput{Scheduled: []pipeline.ScheduledCandidate{{Candidate: pipeline.Candidate{ID: 1}, Priority: 5}}, SampleRate: 2048000, FFTSize: 2048, CenterHz: 7.1e6},
refinement: pipeline.RefinementResult{Decisions: []pipeline.SignalDecision{{ShouldRecord: true}}, Candidates: []pipeline.Candidate{{ID: 1}}},
}
if ps.surveillance.NoiseFloor != -90 || len(ps.surveillance.Scheduled) != 1 {
t.Fatalf("unexpected surveillance state: %+v", ps.surveillance)
}
if len(ps.refinementInput.Scheduled) != 1 || ps.refinementInput.SampleRate != 2048000 {
t.Fatalf("unexpected refinement input: %+v", ps.refinementInput)
}
if len(ps.refinement.Decisions) != 1 || !ps.refinement.Decisions[0].ShouldRecord || len(ps.refinement.Candidates) != 1 {
t.Fatalf("unexpected refinement state: %+v", ps.refinement)
}


+ 23
- 12
cmd/sdrd/pipeline_runtime.go Visa fil

@@ -43,14 +43,14 @@ type dspRuntime struct {
}

type spectrumArtifacts struct {
allIQ []complex64
iq []complex64
spectrum []float64
finished []detector.Event
detected []detector.Signal
thresholds []float64
noiseFloor float64
now time.Time
allIQ []complex64
iq []complex64
spectrum []float64
finished []detector.Event
detected []detector.Signal
thresholds []float64
noiseFloor float64
now time.Time
}

func newDSPRuntime(cfg config.Config, det *detector.Detector, window []float64, gpuState *gpuStatus) *dspRuntime {
@@ -229,14 +229,25 @@ func (rt *dspRuntime) buildSurveillanceResult(art *spectrumArtifacts) pipeline.S
}
}

func (rt *dspRuntime) refineSignals(art *spectrumArtifacts, scheduled []pipeline.ScheduledCandidate, extractMgr *extractionManager, rec *recorder.Manager) pipeline.RefinementResult {
func (rt *dspRuntime) buildRefinementInput(surv pipeline.SurveillanceResult) pipeline.RefinementInput {
return pipeline.RefinementInput{
Candidates: append([]pipeline.Candidate(nil), surv.Candidates...),
Scheduled: append([]pipeline.ScheduledCandidate(nil), surv.Scheduled...),
SampleRate: rt.cfg.SampleRate,
FFTSize: rt.cfg.FFTSize,
CenterHz: rt.cfg.CenterHz,
Source: "surveillance-detector",
}
}

func (rt *dspRuntime) refineSignals(art *spectrumArtifacts, input pipeline.RefinementInput, extractMgr *extractionManager, rec *recorder.Manager) pipeline.RefinementResult {
if art == nil || len(art.iq) == 0 {
return pipeline.RefinementResult{}
}
policy := pipeline.PolicyFromConfig(rt.cfg)
selectedCandidates := make([]pipeline.Candidate, 0, len(scheduled))
selectedSignals := make([]detector.Signal, 0, len(scheduled))
for _, sc := range scheduled {
selectedCandidates := make([]pipeline.Candidate, 0, len(input.Scheduled))
selectedSignals := make([]detector.Signal, 0, len(input.Scheduled))
for _, sc := range input.Scheduled {
selectedCandidates = append(selectedCandidates, sc.Candidate)
selectedSignals = append(selectedSignals, detector.Signal{
ID: sc.Candidate.ID,


+ 12
- 3
internal/pipeline/phases.go Visa fil

@@ -11,8 +11,17 @@ type SurveillanceResult struct {
Thresholds []float64 `json:"thresholds,omitempty"`
}

type RefinementInput struct {
Candidates []Candidate `json:"candidates,omitempty"`
Scheduled []ScheduledCandidate `json:"scheduled,omitempty"`
SampleRate int `json:"sample_rate"`
FFTSize int `json:"fft_size"`
CenterHz float64 `json:"center_hz"`
Source string `json:"source,omitempty"`
}

type RefinementResult struct {
Signals []detector.Signal `json:"signals"`
Decisions []SignalDecision `json:"decisions,omitempty"`
Candidates []Candidate `json:"candidates,omitempty"`
Signals []detector.Signal `json:"signals"`
Decisions []SignalDecision `json:"decisions,omitempty"`
Candidates []Candidate `json:"candidates,omitempty"`
}

+ 17
- 0
internal/pipeline/phases_test.go Visa fil

@@ -26,3 +26,20 @@ func TestSurveillanceResultCarriesScheduledCandidates(t *testing.T) {
t.Fatalf("unexpected surveillance result: %+v", res)
}
}

func TestRefinementInputCarriesScheduledCandidates(t *testing.T) {
res := RefinementInput{
Candidates: []Candidate{{ID: 2}},
Scheduled: []ScheduledCandidate{{Candidate: Candidate{ID: 2}, Priority: 4}},
SampleRate: 2048000,
FFTSize: 2048,
CenterHz: 7.1e6,
Source: "surveillance-detector",
}
if len(res.Candidates) != 1 || len(res.Scheduled) != 1 {
t.Fatalf("unexpected refinement input: %+v", res)
}
if res.SampleRate != 2048000 || res.FFTSize != 2048 || res.CenterHz != 7.1e6 {
t.Fatalf("unexpected refinement input fields: %+v", res)
}
}

Laddar…
Avbryt
Spara