Распространение радиоволн в помещении
作者
贡献者
import numpy as np
import matplotlib.pyplot as plt
# ПАРАМЕТРЫ МОДЕЛИ
TX_POWER = 20.0 # Мощность роутера, dBm
D0 = 1.0 # Опорное расстояние, м
FREQ_24 = 2.4e9
FREQ_5 = 5.0e9
# Базовые потери на 1 м (FSPL)
PL0_24 = 20*np.log10(D0) + 20*np.log10(FREQ_24) - 147.55
PL0_5 = 20*np.log10(D0) + 20*np.log10(FREQ_5) - 147.55
# Коэффициенты затухания среды
N_24 = 2.2
N_5 = 2.8
# Препятствия: (расстояние_м, потери_2.4_dB, потери_5_dB, название)
walls = [
(2.5, 3.0, 5.0, "Дверь (МДФ)"),
(5.5, 4.5, 8.0, "Гипсокартон"),
(8.0, 9.0, 14.0,"Кирпич/бетон")
]
# РАСЧЁТ RSSI
distances = np.linspace(0.5, 16.0, 800)
wall_pos = np.array([w[0] for w in walls])
loss_24_ar = np.array([w[1] for w in walls])
loss_5_ar = np.array([w[2] for w in walls])
mask = distances[:, None] >= wall_pos[None, :]
cum_loss_24 = np.sum(mask * loss_24_ar, axis=1)
cum_loss_5 = np.sum(mask * loss_5_ar, axis=1)
rssi_24 = TX_POWER - (PL0_24 + 10 * N_24 * np.log10(distances / D0)) - cum_loss_24
rssi_5 = TX_POWER - (PL0_5 + 10 * N_5 * np.log10(distances / D0)) - cum_loss_5
# Реальная чувствительность Wi-Fi чипов
rssi_24 = np.clip(rssi_24, -95, TX_POWER)
rssi_5 = np.clip(rssi_5, -95, TX_POWER)
# ПОРОГИ И РАСЧЁТ ДАЛЬНОСТИ ОБРЫВА
THRESH_MIN = -85 # Минимум для базовой связи (мессенджеры, веб)
THRESH_GOOD = -70 # Стабильная связь (видео, игры)
def find_drop_distance(dist, rssi, threshold):
"""Возвращает расстояние, где сигнал впервые падает ниже порога"""
idx = np.where(rssi < threshold)[0]
return dist[idx[0]] if len(idx) > 0 else dist[-1]
drop_5 = find_drop_distance(distances, rssi_5, THRESH_MIN)
drop_24 = find_drop_distance(distances, rssi_24, THRESH_MIN)
# ВИЗУАЛИЗАЦИЯ
plt.figure(figsize=(11, 6.5))
plt.plot(distances, rssi_24, label='2.4 ГГц', linewidth=2.5, color='#1f77b4')
plt.plot(distances, rssi_5, label='5 ГГц', linewidth=2.5, color='#d62728')
# Пороговые линии
plt.axhline(THRESH_MIN, color='black', linestyle='--', linewidth=1.5,
label=f'Мин. порог связи ({THRESH_MIN} dBm)')
plt.axhline(THRESH_GOOD, color='gray', linestyle=':', linewidth=1.2,
label=f'Стабильная связь ({THRESH_GOOD} dBm)')
# Ключевая зона: 5 ГГц уже не работает, 2.4 ГГц ещё держит связь
if drop_5 < drop_24:
plt.axvspan(drop_5, drop_24, color='#1f77b4', alpha=0.18,
label=f'Зона: 5 ГГц / 2.4 ГГц ({drop_5:.1f}–{drop_24:.1f} м)')
# Стены
for pos, l24, l5, name in walls:
plt.axvline(pos, color='#888888', linestyle='-', alpha=0.5, linewidth=1)
plt.text(pos+0.15, -38, name, rotation=90, va='center', fontsize=9, color='#555555')
# Аннотации обрыва
plt.annotate(f'5 ГГц обрывается ≈ {drop_5:.1f} м',
xy=(drop_5, THRESH_MIN-6), fontsize=10, color='#d62728', ha='center',
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", edgecolor="#d62728", alpha=0.8))
plt.annotate(f'2.4 ГГц работает до ≈ {drop_24:.1f} м',
xy=(drop_24, THRESH_MIN-6), fontsize=10, color='#1f77b4', ha='center',
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", edgecolor="#1f77b4", alpha=0.8))
plt.title('Сравнение рабочей дальности Wi-Fi: 2.4 ГГц vs 5 ГГц', fontsize=14, pad=10)
plt.xlabel('Расстояние от роутера (м)', fontsize=12)
plt.ylabel('Мощность сигнала RSSI (dBm)', fontsize=12)
plt.grid(True, linestyle=':', alpha=0.5)
plt.legend(loc='lower left', fontsize=10)
plt.xlim(0.4, 16.5)
plt.ylim(-95, 22)
plt.tight_layout()
plt.savefig('wifi_range_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
print(f"5 ГГц теряет связь на ~{drop_5:.1f} м")
print(f"2.4 ГГц сохраняет связь более ~{drop_24:.1f} м")
print("График сохранён как wifi_range_comparison.png")