Как стать автором
Обновить

Хак радара

Время на прочтение2 мин
Количество просмотров62K


Некоторое время назад увидел на одном из форумов обсуждение возможности пеленговать самолёты, принимая отражённые сигналы радаров. Идея казалась интересной, а цель недостижимой для использования в быту, до появления 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М
Теги:
Хабы:
Всего голосов 74: ↑69 и ↓5+64
Комментарии51

Публикации

Истории

Работа

Python разработчик
135 вакансий
Data Scientist
60 вакансий

Ближайшие события