62 lines
1.4 KiB
Python
62 lines
1.4 KiB
Python
"""Radio propagation model."""
|
|
|
|
import math
|
|
import random
|
|
from sim import config
|
|
|
|
|
|
def calculate_distance(x1: float, y1: float, x2: float, y2: float) -> float:
|
|
"""Calculate Euclidean distance between two points."""
|
|
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
|
|
|
|
|
|
def calculate_rssi(tx_power: float, distance: float) -> float:
|
|
"""
|
|
Calculate RSSI using free-space path loss model.
|
|
|
|
RSSI = TX_POWER - 10*n*log10(d) + Gaussian_noise
|
|
|
|
Args:
|
|
tx_power: Transmit power in dBm
|
|
distance: Distance in meters
|
|
|
|
Returns:
|
|
RSSI in dBm
|
|
"""
|
|
if distance < 1.0:
|
|
distance = 1.0 # Avoid log(0)
|
|
|
|
# Path loss
|
|
path_loss = 10 * config.PATH_LOSS_EXPONENT * math.log10(distance)
|
|
|
|
# Gaussian noise
|
|
noise = random.gauss(0, config.NOISE_SIGMA)
|
|
|
|
rssi = tx_power - path_loss + noise
|
|
return rssi
|
|
|
|
|
|
def can_receive(rssi: float) -> bool:
|
|
"""Check if packet can be received based on RSSI threshold."""
|
|
return rssi >= config.RSSI_THRESHOLD
|
|
|
|
|
|
def calculate_link_penalty(rssi: float) -> float:
|
|
"""
|
|
Calculate link penalty for routing.
|
|
|
|
penalty = max(0, (RSSI_THRESHOLD - RSSI) / SCALE)
|
|
|
|
Args:
|
|
rssi: Received signal strength
|
|
|
|
Returns:
|
|
Link penalty (higher = worse link)
|
|
"""
|
|
return max(0.0, (config.RSSI_THRESHOLD - rssi) / config.LINK_PENALTY_SCALE)
|
|
|
|
|
|
def is_link_viable(rssi: float) -> bool:
|
|
"""Check if link is viable for communication."""
|
|
return can_receive(rssi)
|