ADSBの電波を受信し、航空機の画像を撮影

利用ソフトdump1090-fapysynscan + 自作のpythonスクリプト

ADSB受信用SDR:RTL-SDR RTL2832U

カメラ制御用経緯台 SkyWatcherのAz-GTi

カメラ:ASI1600MC-COOL + カメラ用レンズ

撮影画像例:距離 10000m程度

おまけ

スマホで航空機を撮影:距離500m程度??

撮影場所、時刻、方向:スマホのGPS情報、加速度センサー等から取得

アメダスは:降水量を観測する観測所は全国に約1,300か所

問題点:

(1)経緯台の回転速度が比較的遅いので、カメラの指向が間に合わないことがある。

(2)航空機までの距離が遠いことが多く、200mm程度の望遠レンズでは、画像から機種の判別は困難

STEP1:ADSBの電波を受信し、航空機のICAOコードと位置(緯度、経度、高度)を取得。

STEP2:航空機の位置(緯度、経度、高度)と、観測場所の緯度、経度から航空機が見える方位と見上げ角度を計算。

STEP3:経緯台のモータを、航空機の方向に向ける。

STEP4:画像を撮影

# -*- coding: utf-8 -*-
from  math import *
import time,datetime
import os
import socket
import logging
import synscan
from optparse import OptionParser

PORT = 30003           # Running dump1090-fa
host = '192.168.68.61' #
BUFFER_SIZE = 1024

R_EARTH = 6378137
RAD = 3.14159265 / 180
LAT0,LON0=35.7973, 139.4462

parser = OptionParser()
parser.add_option("-r","--range",action="store",dest="MAX", default=0,type="int",help="Max range")
parser.add_option("-t","--tilt",action="store",dest="TILT_MIN", default=1,type="float",help="Min tilt")
(opts, args) = parser.parse_args()
MAX=opts.MAX
TILT_MIN=opts.TILT_MIN
#MAX = 20000
if MAX == 0:
    TEST = True
    pH,pT = 0,0
    MAX = 50000
    print("Test mode")
else:
    TEST = False
    smc=synscan.motors(udp_ip='192.168.68.200', udp_port=11880)
    pH,pT = smc.axis_get_pos(1),smc.axis_get_pos(2)
    print('Last PAN,TILT:',pH,pT)

H_MIN ,T_MIN = 0.1, 0.1

def distance(lat1,lon1,lat2,lon2):
    lat1,lat2 = lat1*RAD, lat2*RAD
    lon1,lon2 = lon1*RAD, lon2*RAD
    lat_c = (lat1 + lat2) / 2
    try:
       dx = R_EARTH*(lon2-lon1)*cos(lat_c)
       dy = R_EARTH*(lat2-lat1)
    except:
        dx,dy = 100000, 100000
        pass

    return sqrt(dx*dx + dy*dy)

def azimuth(y1,x1,y2,x2):
        x1=radians(x1)
        y1=radians(y1)
        x2=radians(x2)
        y2=radians(y2)

        deltax = x2 - x1
        ans = degrees(atan2(sin(deltax),(cos(y1)*tan(y2)-sin(y1)*cos(deltax))))%360
        return ans

Buf = {}
dBuf= {}
T_MAX, L_MAX = 0.5,10
dH, dT = 0, 0
start=time.time()
TGT=None
seq = 0
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((host, PORT))
    while True:
        str = s.recv(BUFFER_SIZE).decode()
        if 'MSG,3' in str:
            t = str.split(',')
            try:
                ID, Lat, Lon, Alt = t[4],t[14],t[15],t[11]
                LAT=float(Lat)
                LON=float(Lon)
                ALT=float(Alt)
            except:
                LAT, ALT = 0, 0
                pass
            if LAT>0 and ALT>0:
                dist = round(distance(LAT0, LON0, LAT, LON),1)
                if dist<MAX:
                    houi = round(azimuth(LAT0, LON0, LAT, LON),1) + 5 + dH
                    tilt = round(degrees(atan(ALT*0.3048/dist)),1) + 3 + dT
                    Buf[ID] ={'TIME':round(time.time(),0),'DIST':dist,'PAN':houi,'TILT':tilt}
                    dBuf[ID]=dist
                else:
                    pass
            if time.time()-start > T_MAX:
                now = time.time()
                start = time.time()
                os.system('clear')

                print('---',datetime.datetime.now(),'---','ICAO:',TGT,' PAN:',pH,' TILT:',pT)
                for k,v in list(Buf.items()):
                    last = Buf[k]['TIME']
                    if now - last > L_MAX:
                        print('deleted..',k)
                        del Buf[k]
                        if k == TGT:
                            TGT = None
                print('TGT:',TGT)
                for k,v in Buf.items():
                    if (TGT is None) or (TGT not in Buf):
                        TGT = k
                        print('New target:',TGT)
                        seq = 1
                        dH, dT = 0,0
                    print(k,v)
        if TGT is not None and TGT in Buf:
            houi, tilt = Buf[TGT]['PAN'], Buf[TGT]['TILT']
            #pH,pT = smc.axis_get_pos(1),smc.axis_get_pos(2)
            dH, dT = round(pH - houi,1), round(pT - tilt,1)
            if (abs(dH)>H_MIN or abs(dT)>T_MIN) and tilt>TILT_MIN and (houi<200 and tilt<80):
                pH, pT = houi, tilt
                print('*',TGT, houi,'(',dH,')', tilt,'(',dT,')','SEQ:',seq)
                seq = seq + 1
                if not TEST :
                    smc.goto(houi,tilt,syncronous=False)
            else:
                pass

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です