Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

233 linhas
9.5KB

  1. package pipeline
  2. import "sdr-wideband-suite/internal/config"
  3. type Policy struct {
  4. Mode string `json:"mode"`
  5. Profile string `json:"profile,omitempty"`
  6. Intent string `json:"intent"`
  7. MonitorCenterHz float64 `json:"monitor_center_hz,omitempty"`
  8. MonitorStartHz float64 `json:"monitor_start_hz,omitempty"`
  9. MonitorEndHz float64 `json:"monitor_end_hz,omitempty"`
  10. MonitorSpanHz float64 `json:"monitor_span_hz,omitempty"`
  11. MonitorWindows []MonitorWindow `json:"monitor_windows,omitempty"`
  12. SignalPriorities []string `json:"signal_priorities,omitempty"`
  13. AutoRecordClasses []string `json:"auto_record_classes,omitempty"`
  14. AutoDecodeClasses []string `json:"auto_decode_classes,omitempty"`
  15. SurveillanceFFTSize int `json:"surveillance_fft_size"`
  16. SurveillanceFPS int `json:"surveillance_fps"`
  17. DisplayBins int `json:"display_bins"`
  18. DisplayFPS int `json:"display_fps"`
  19. SurveillanceStrategy string `json:"surveillance_strategy"`
  20. SurveillanceDerivedDetection string `json:"surveillance_derived_detection"`
  21. RefinementStrategy string `json:"refinement_strategy,omitempty"`
  22. RefinementEnabled bool `json:"refinement_enabled"`
  23. MaxRefinementJobs int `json:"max_refinement_jobs"`
  24. RefinementMaxConcurrent int `json:"refinement_max_concurrent"`
  25. RefinementDetailFFTSize int `json:"refinement_detail_fft_size"`
  26. MinCandidateSNRDb float64 `json:"min_candidate_snr_db"`
  27. RefinementMinSpanHz float64 `json:"refinement_min_span_hz"`
  28. RefinementMaxSpanHz float64 `json:"refinement_max_span_hz"`
  29. RefinementAutoSpan bool `json:"refinement_auto_span"`
  30. PreferGPU bool `json:"prefer_gpu"`
  31. MaxRecordingStreams int `json:"max_recording_streams"`
  32. MaxDecodeJobs int `json:"max_decode_jobs"`
  33. DecisionHoldMs int `json:"decision_hold_ms"`
  34. SurveillanceDetection SurveillanceDetectionPolicy `json:"surveillance_detection,omitempty"`
  35. }
  36. func PolicyFromConfig(cfg config.Config) Policy {
  37. detailFFT := cfg.Refinement.DetailFFTSize
  38. if detailFFT <= 0 {
  39. detailFFT = cfg.Surveillance.AnalysisFFTSize
  40. }
  41. p := Policy{
  42. Mode: cfg.Pipeline.Mode,
  43. Profile: cfg.Pipeline.Profile,
  44. Intent: cfg.Pipeline.Goals.Intent,
  45. MonitorCenterHz: cfg.CenterHz,
  46. MonitorStartHz: cfg.Pipeline.Goals.MonitorStartHz,
  47. MonitorEndHz: cfg.Pipeline.Goals.MonitorEndHz,
  48. MonitorSpanHz: cfg.Pipeline.Goals.MonitorSpanHz,
  49. SignalPriorities: append([]string(nil), cfg.Pipeline.Goals.SignalPriorities...),
  50. AutoRecordClasses: append([]string(nil), cfg.Pipeline.Goals.AutoRecordClasses...),
  51. AutoDecodeClasses: append([]string(nil), cfg.Pipeline.Goals.AutoDecodeClasses...),
  52. SurveillanceFFTSize: cfg.Surveillance.AnalysisFFTSize,
  53. SurveillanceFPS: cfg.Surveillance.FrameRate,
  54. DisplayBins: cfg.Surveillance.DisplayBins,
  55. DisplayFPS: cfg.Surveillance.DisplayFPS,
  56. SurveillanceStrategy: cfg.Surveillance.Strategy,
  57. SurveillanceDerivedDetection: cfg.Surveillance.DerivedDetection,
  58. RefinementEnabled: cfg.Refinement.Enabled,
  59. MaxRefinementJobs: cfg.Resources.MaxRefinementJobs,
  60. RefinementMaxConcurrent: cfg.Refinement.MaxConcurrent,
  61. RefinementDetailFFTSize: detailFFT,
  62. MinCandidateSNRDb: cfg.Refinement.MinCandidateSNRDb,
  63. RefinementMinSpanHz: cfg.Refinement.MinSpanHz,
  64. RefinementMaxSpanHz: cfg.Refinement.MaxSpanHz,
  65. RefinementAutoSpan: config.BoolValue(cfg.Refinement.AutoSpan, true),
  66. PreferGPU: cfg.Resources.PreferGPU,
  67. MaxRecordingStreams: cfg.Resources.MaxRecordingStreams,
  68. MaxDecodeJobs: cfg.Resources.MaxDecodeJobs,
  69. DecisionHoldMs: cfg.Resources.DecisionHoldMs,
  70. }
  71. p.RefinementStrategy, _ = refinementStrategy(p)
  72. p.SurveillanceDetection = SurveillanceDetectionPolicyFromPolicy(p)
  73. p.MonitorWindows = NormalizeMonitorWindows(cfg.Pipeline.Goals, cfg.CenterHz)
  74. if len(p.MonitorWindows) > 0 {
  75. if start, end, ok := MonitorWindowBounds(p.MonitorWindows); ok {
  76. p.MonitorStartHz = start
  77. p.MonitorEndHz = end
  78. if end > start {
  79. p.MonitorSpanHz = end - start
  80. }
  81. }
  82. }
  83. if p.MonitorSpanHz <= 0 && p.MonitorStartHz != 0 && p.MonitorEndHz != 0 && p.MonitorEndHz > p.MonitorStartHz {
  84. p.MonitorSpanHz = p.MonitorEndHz - p.MonitorStartHz
  85. }
  86. return p
  87. }
  88. func ApplyNamedProfile(cfg *config.Config, name string) {
  89. if cfg == nil || name == "" {
  90. return
  91. }
  92. cfg.Pipeline.Profile = name
  93. if prof, ok := ResolveProfile(*cfg, name); ok {
  94. MergeProfile(cfg, prof)
  95. }
  96. switch name {
  97. case "legacy":
  98. cfg.Pipeline.Mode = "legacy"
  99. cfg.Pipeline.Goals.Intent = "general-monitoring"
  100. cfg.Surveillance.Strategy = "single-resolution"
  101. cfg.Refinement.Enabled = true
  102. if cfg.Resources.MaxRefinementJobs <= 0 {
  103. cfg.Resources.MaxRefinementJobs = 8
  104. }
  105. case "wideband-balanced":
  106. cfg.Pipeline.Mode = "wideband-balanced"
  107. cfg.Pipeline.Goals.Intent = "wideband-surveillance"
  108. cfg.Surveillance.Strategy = "multi-resolution"
  109. if cfg.Surveillance.AnalysisFFTSize < 4096 {
  110. cfg.Surveillance.AnalysisFFTSize = 4096
  111. }
  112. if cfg.FrameRate < 12 {
  113. cfg.FrameRate = 12
  114. }
  115. if cfg.Surveillance.FrameRate < 12 {
  116. cfg.Surveillance.FrameRate = 12
  117. }
  118. cfg.Refinement.Enabled = true
  119. if cfg.Refinement.MaxConcurrent < 16 {
  120. cfg.Refinement.MaxConcurrent = 16
  121. }
  122. if cfg.Resources.MaxRefinementJobs < 16 {
  123. cfg.Resources.MaxRefinementJobs = 16
  124. }
  125. if cfg.Refinement.MinSpanHz <= 0 {
  126. cfg.Refinement.MinSpanHz = 4000
  127. }
  128. if cfg.Refinement.MaxSpanHz <= 0 {
  129. cfg.Refinement.MaxSpanHz = 200000
  130. }
  131. if len(cfg.Pipeline.Goals.SignalPriorities) == 0 {
  132. cfg.Pipeline.Goals.SignalPriorities = []string{"digital", "wfm"}
  133. }
  134. cfg.Resources.PreferGPU = true
  135. case "wideband-aggressive":
  136. cfg.Pipeline.Mode = "wideband-aggressive"
  137. cfg.Pipeline.Goals.Intent = "high-density-wideband-surveillance"
  138. cfg.Surveillance.Strategy = "multi-resolution"
  139. if cfg.Surveillance.AnalysisFFTSize < 8192 {
  140. cfg.Surveillance.AnalysisFFTSize = 8192
  141. }
  142. if cfg.FrameRate < 10 {
  143. cfg.FrameRate = 10
  144. }
  145. if cfg.Surveillance.FrameRate < 10 {
  146. cfg.Surveillance.FrameRate = 10
  147. }
  148. cfg.Refinement.Enabled = true
  149. if cfg.Refinement.MaxConcurrent < 32 {
  150. cfg.Refinement.MaxConcurrent = 32
  151. }
  152. if cfg.Resources.MaxRefinementJobs < 32 {
  153. cfg.Resources.MaxRefinementJobs = 32
  154. }
  155. if cfg.Refinement.MinSpanHz <= 0 {
  156. cfg.Refinement.MinSpanHz = 6000
  157. }
  158. if cfg.Refinement.MaxSpanHz <= 0 {
  159. cfg.Refinement.MaxSpanHz = 250000
  160. }
  161. if len(cfg.Pipeline.Goals.SignalPriorities) == 0 {
  162. cfg.Pipeline.Goals.SignalPriorities = []string{"digital", "wfm", "trunk"}
  163. }
  164. cfg.Resources.PreferGPU = true
  165. case "archive":
  166. cfg.Pipeline.Mode = "archive"
  167. cfg.Pipeline.Goals.Intent = "archive-and-triage"
  168. cfg.Refinement.Enabled = true
  169. if cfg.Refinement.MaxConcurrent < 12 {
  170. cfg.Refinement.MaxConcurrent = 12
  171. }
  172. if cfg.Resources.MaxRefinementJobs < 12 {
  173. cfg.Resources.MaxRefinementJobs = 12
  174. }
  175. if cfg.Resources.MaxRecordingStreams < 24 {
  176. cfg.Resources.MaxRecordingStreams = 24
  177. }
  178. if cfg.Resources.MaxDecodeJobs < 12 {
  179. cfg.Resources.MaxDecodeJobs = 12
  180. }
  181. if len(cfg.Pipeline.Goals.SignalPriorities) == 0 {
  182. cfg.Pipeline.Goals.SignalPriorities = []string{"wfm", "nfm", "digital"}
  183. }
  184. if !cfg.Recorder.Enabled {
  185. cfg.Recorder.Enabled = true
  186. }
  187. case "digital-hunting":
  188. cfg.Pipeline.Mode = "digital-hunting"
  189. cfg.Pipeline.Goals.Intent = "digital-surveillance"
  190. cfg.Surveillance.Strategy = "multi-resolution"
  191. if cfg.Surveillance.AnalysisFFTSize < 4096 {
  192. cfg.Surveillance.AnalysisFFTSize = 4096
  193. }
  194. if cfg.FrameRate < 12 {
  195. cfg.FrameRate = 12
  196. }
  197. if cfg.Surveillance.FrameRate < 12 {
  198. cfg.Surveillance.FrameRate = 12
  199. }
  200. cfg.Refinement.Enabled = true
  201. if cfg.Refinement.MaxConcurrent < 16 {
  202. cfg.Refinement.MaxConcurrent = 16
  203. }
  204. if cfg.Resources.MaxRefinementJobs < 16 {
  205. cfg.Resources.MaxRefinementJobs = 16
  206. }
  207. if cfg.Refinement.MinSpanHz <= 0 {
  208. cfg.Refinement.MinSpanHz = 3000
  209. }
  210. if cfg.Refinement.MaxSpanHz <= 0 {
  211. cfg.Refinement.MaxSpanHz = 120000
  212. }
  213. if len(cfg.Pipeline.Goals.SignalPriorities) == 0 {
  214. cfg.Pipeline.Goals.SignalPriorities = []string{"ft8", "wspr", "fsk", "psk", "dmr"}
  215. }
  216. cfg.Resources.PreferGPU = true
  217. }
  218. if cfg.Pipeline.Goals.MonitorSpanHz <= 0 && cfg.SampleRate > 0 {
  219. cfg.Pipeline.Goals.MonitorSpanHz = float64(cfg.SampleRate)
  220. }
  221. if cfg.Resources.MaxDecodeJobs <= 0 {
  222. cfg.Resources.MaxDecodeJobs = cfg.Resources.MaxRecordingStreams
  223. }
  224. if cfg.Refinement.DetailFFTSize <= 0 {
  225. cfg.Refinement.DetailFFTSize = cfg.Surveillance.AnalysisFFTSize
  226. }
  227. cfg.FFTSize = cfg.Surveillance.AnalysisFFTSize
  228. }