Major refactoring of RFCP backend: - Modular propagation models (8 models) - SharedMemoryManager for terrain data - ProcessPoolExecutor parallel processing - WebSocket progress streaming - Building filtering pipeline (351k → 15k) - 82 unit tests Performance: Standard preset 38s → 5s (7.6x speedup) Known issue: Detailed preset timeout (fix in 3.1.0)
44 lines
1.1 KiB
Python
44 lines
1.1 KiB
Python
"""
|
|
Free Space Path Loss (FSPL) model.
|
|
|
|
Used as baseline and for LOS conditions.
|
|
FSPL = 20*log10(d) + 20*log10(f) + 32.45
|
|
where d in km, f in MHz
|
|
"""
|
|
|
|
import math
|
|
from app.propagation.base import PropagationModel, PropagationInput, PropagationOutput
|
|
|
|
|
|
class FreeSpaceModel(PropagationModel):
|
|
"""Free Space Path Loss — theoretical minimum propagation loss."""
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return "Free-Space"
|
|
|
|
@property
|
|
def frequency_range(self) -> tuple:
|
|
return (1, 100000)
|
|
|
|
@property
|
|
def distance_range(self) -> tuple:
|
|
return (1, 1000000) # 1m to 1000km
|
|
|
|
def calculate(self, input: PropagationInput) -> PropagationOutput:
|
|
d_km = max(input.distance_m / 1000, 0.001)
|
|
f = input.frequency_mhz
|
|
|
|
L = 20 * math.log10(d_km) + 20 * math.log10(f) + 32.45
|
|
|
|
return PropagationOutput(
|
|
path_loss_db=L,
|
|
model_name=self.name,
|
|
is_los=True,
|
|
breakdown={
|
|
"distance_loss": 20 * math.log10(d_km),
|
|
"frequency_loss": 20 * math.log10(f),
|
|
"constant": 32.45,
|
|
},
|
|
)
|