[Из песочницы] Хак радара
Некоторое время назад увидел на одном из форумов обсуждение возможности пеленговать самолёты, принимая отражённые сигналы радаров. Идея казалась интересной, а цель недостижимой для использования в быту, до появления SDR приёмника на основе дешёвого DVB-T донгла на чипсете RTL2832U. С помощью донгла можно оцифровать принимаемый сигнал со скоростью, достаточной для получения разрешающей способности на местности порядка сотни метров, что вполне подходит для эксперимента.Справедливости ради, в возможность пеленговать самолёты таким способом не очень верю, но сигнал, отражённый крупными наземными объектами должен быть хорошо виден. Второе ограничение — радар использует остронаправленную антенну для излучения и её же для приёма, со слабонаправленной телевизионной антенной, которая использовалась в ходе эксперимента, ожидать высокого разрешения не приходится.
Эксперимент: SDR донгл подключаем к телевизионной антенне, достаём из кустов радар, благо, он находится в аэропорту всего в нескольких километрах и работает в метровом телевизионном диапазоне. Сигнал записываем при помощи SDR# в wav-файл со скоростью 2М измерений в секунду, что даст теоретическое разрешение на местности около 75 метров. Фактом, что излучатель и приёмник разнесены в пространстве пренебрегаем.
После того, как сигналы записаны и выбран лучший образец, пишем скрипт, имитирующий развёртку радара и синхронизацию по первому мощному импульсу.
import os from PIL import Image, ImageDraw import wave import math
dir = os.path.dirname (os.path.abspath (__file__))
image = Image.new («RGB», (1000, 1000), (0, 0, 0)) (w, h) = image.size
sync_level = 45 seconds_max = 40 px_from_center = 30 seconds_per_spin = 20
wav = wave.open (dir + »/samples/134201.wav», mode=«r») (nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams () data = wav.readframes (nframes) bytes = nframes * nchannels * sampwidth seconds = float (nframes) / framerate px_per_km = int (framerate / 300000.0×2)
print (str (bytes) + » bytes,» + str (seconds) + » seconds»)
t = 0 avg = 0 synchronized = 0 i = 0
while i < bytes - 4: l = abs(128 - ord(data[i])) r = abs(128 - ord(data[i + 2])) avg = avg * .9 + l * .1 level = l + r if not synchronized and avg > sync_level: synchronized = 1 if synchronized: s = float (i) / bytes * seconds if s >= seconds_max: break if t % (10 * px_per_km) == 0: level += 20 if t < 400: x = int(w/2 - (t + px_from_center) * math.cos(s / seconds_per_spin * 2 * math.pi)) y = int(h/2 - (t + px_from_center) * math.sin(s / seconds_per_spin * 2 * math.pi)) image.putpixel((x, y), (level, level, level)) t += 1 if t >= 400: t = 0 synchronized = 0 avg = 0 i += 4
image.save (dir + »/radar.png», «PNG») Один оборот радар делает за 20 секунд. Подбираем уровень синхронизации и получаем картинку, устойчиво повторяющуюся с каждым оборотом.
Что нам и требовалось. Картинка достаточно размытая, но ничего не мешает её улучшить, экспериментируя с параметрами и применяя лучшее оборудование.
Исходники вместе с оцифрованным сигналом — 73М