
Некоторое время назад увидел на одном из форумов обсуждение возможности пеленговать самолёты, принимая отражённые сигналы радаров. Идея казалась интересной, а цель недостижимой для использования в быту, до появления 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М
