Type spec fixes: - duct_usable_* return boolean→float (delegate to duct_usable_for_band) - sanitize/1 spec includes :unicode error tuples - match_delete/1 broadened from :ets.match_spec() - telemetry_event local type replaces :telemetry.event/0 - wgrib2 parse_lon_val_segment corrected to tuple spec - preloaded Ecto assoc types in get_mission/get_contact! specs Unmatched returns: - _ = prefix on Task.start, Oban.insert, Repo.query!, PubSub.subscribe, :ets.new, and if-expression returns across 18 files Pattern match fixes: - markdown: restructure acc!=[] guard as direct pattern match - path_compute/pskr/skewt_location_resolver: remove dead clauses - calibrate.aprs_144: remove unreachable format_float catch-all - unused.ex: suppress MapSet.union no_opaque Also: remove unused unicode_util_compat from mix.lock
35 lines
934 B
Elixir
35 lines
934 B
Elixir
defmodule Microwaveprop.Propagation.ModeThresholds do
|
|
@moduledoc """
|
|
Required-SNR thresholds (dB) for the modes the rover planner supports.
|
|
|
|
The rover predicts a per-link SNR margin; subtracting the mode's required
|
|
SNR yields "dB above decode threshold". Numbers come from the rover spec —
|
|
SSB needs full quieting, CW pulls signals well below the noise floor, and
|
|
Q65 modes go deeper still.
|
|
"""
|
|
|
|
@thresholds %{
|
|
ssb: 0.0,
|
|
cw: -18.0,
|
|
q65_60a: -24.0,
|
|
q65_120b: -26.0
|
|
}
|
|
|
|
@modes [
|
|
{:ssb, "SSB"},
|
|
{:cw, "CW"},
|
|
{:q65_60a, "Q65-60A"},
|
|
{:q65_120b, "Q65-120B"}
|
|
]
|
|
|
|
@type mode :: :ssb | :cw | :q65_60a | :q65_120b
|
|
|
|
@spec required_snr_db(mode()) :: float()
|
|
def required_snr_db(mode) when is_map_key(@thresholds, mode), do: Map.fetch!(@thresholds, mode)
|
|
|
|
@spec modes() :: [{mode(), String.t()}]
|
|
def modes, do: @modes
|
|
|
|
@spec default_mode() :: :ssb
|
|
def default_mode, do: :ssb
|
|
end
|