"""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)