Merge pull request #2 from nzkarit/refactor2

Refactor2
This commit is contained in:
nzkarit
2017-09-08 21:41:33 +12:00
committed by GitHub
6 changed files with 107 additions and 163 deletions

View File

@@ -1,4 +1,5 @@
from location import *
from ModeSLocation import ModeSLocation
import math
class ModeS:
"""This class handles the ModeS ADSB manipulation
@@ -11,12 +12,13 @@ class ModeS:
format = 17 #The format type of an ADSB message
enc_alt = encode_alt_modes(alt, surface)
location = ModeSLocation()
enc_alt = location.encode_alt_modes(alt, surface)
#print "Alt(%r): %X " % (surface, enc_alt)
#encode that position
(evenenclat, evenenclon) = cpr_encode(lat, lon, False, surface)
(oddenclat, oddenclon) = cpr_encode(lat, lon, True, surface)
(evenenclat, evenenclon) = location.cpr_encode(lat, lon, False, surface)
(oddenclat, oddenclon) = location.cpr_encode(lat, lon, True, surface)
#print "Even Lat/Lon: %X/%X " % (evenenclat, evenenclon)
#print "Odd Lat/Lon: %X/%X " % (oddenclat, oddenclon)

100
ModeSLocation.py Normal file
View File

@@ -0,0 +1,100 @@
import math
class ModeSLocation:
"""This class does ModeS/ADSB Location calulations"""
##########################################################################
# Copyright 2010, 2012 Nick Foster
#
# This file is part of gr-air-modes
#
# gr-air-modes is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# gr-air-modes is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-air-modes; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
def encode_alt_modes(self, alt, bit13):
mbit = False
qbit = True
encalt = (int(alt) + 1000) / 25
if bit13 is True:
tmp1 = (encalt & 0xfe0) << 2
tmp2 = (encalt & 0x010) << 1
else:
tmp1 = (encalt & 0xff8) << 1
tmp2 = 0
return (encalt & 0x0F) | tmp1 | tmp2 | (mbit << 6) | (qbit << 4)
latz = 15
def nz(self, ctype):
"""
Number of geographic latitude zones between equator and a pole. It is set to NZ = 15 for Mode-S CPR encoding
https://adsb-decode-guide.readthedocs.io/en/latest/content/cpr.html
"""
return 4 * self.latz - ctype
def dlat(self, ctype, surface):
if surface == 1:
tmp = 90.0
else:
tmp = 360.0
nzcalc = self.nz(ctype)
if nzcalc == 0:
return tmp
else:
return tmp / nzcalc
def nl(self, declat_in):
if abs(declat_in) >= 87.0:
return 1.0
return math.floor( (2.0*math.pi) * math.acos(1.0- (1.0-math.cos(math.pi/(2.0*self.latz))) / math.cos( (math.pi/180.0)*abs(declat_in) )**2 )**-1)
def dlon(self, declat_in, ctype, surface):
if surface:
tmp = 90.0
else:
tmp = 360.0
nlcalc = max(self.nl(declat_in)-ctype, 1)
return tmp / nlcalc
#encode CPR position
# https://adsb-decode-guide.readthedocs.io/en/latest/content/cpr.html
# compact position reporting
def cpr_encode(self, lat, lon, ctype, surface):
if surface is True:
scalar = 2.**19
else:
scalar = 2.**17
#encode using 360 constant for segment size.
dlati = self.dlat(ctype, False)
yz = math.floor(scalar * ((lat % dlati)/dlati) + 0.5)
rlat = dlati * ((yz / scalar) + math.floor(lat / dlati))
#encode using 360 constant for segment size.
dloni = self.dlon(lat, ctype, False)
xz = math.floor(scalar * ((lon % dloni)/dloni) + 0.5)
yz = int(yz) & (2**17-1)
xz = int(xz) & (2**17-1)
return (yz, xz) #lat, lon

View File

@@ -16,15 +16,7 @@ $ ls Samples.iq8s
Samples.iq8s
$
```
2. Make the raw signal file aligned to 256K buffer size:
```
$ dd if=Samples.iq8s of=Samples_256K.iq8s bs=4k seek=63
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.00110421 s, 3.7 MB/s
$
```
3. Transmit the signal into air:
2. Transmit the signal into air:
```
$ hackrf_transfer -t Samples_256K.iq8s -f 868000000 -s 2000000 -x 10
call hackrf_sample_rate_set(2000000 Hz/2.000 MHz)

View File

@@ -1,6 +0,0 @@
import math

View File

@@ -1,95 +0,0 @@
##########################################################################
# Copyright 2010, 2012 Nick Foster
#
# This file is part of gr-air-modes
#
# gr-air-modes is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# gr-air-modes is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-air-modes; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
import math
def encode_alt_modes(alt, bit13):
mbit = False
qbit = True
encalt = (int(alt) + 1000) / 25
if bit13 is True:
tmp1 = (encalt & 0xfe0) << 2
tmp2 = (encalt & 0x010) << 1
else:
tmp1 = (encalt & 0xff8) << 1
tmp2 = 0
return (encalt & 0x0F) | tmp1 | tmp2 | (mbit << 6) | (qbit << 4)
latz = 15
def nz(ctype):
"""
Number of geographic latitude zones between equator and a pole. It is set to NZ = 15 for Mode-S CPR encoding
https://adsb-decode-guide.readthedocs.io/en/latest/content/cpr.html
"""
return 4 * latz - ctype
def dlat(ctype, surface):
if surface == 1:
tmp = 90.0
else:
tmp = 360.0
nzcalc = nz(ctype)
if nzcalc == 0:
return tmp
else:
return tmp / nzcalc
def nl(declat_in):
if abs(declat_in) >= 87.0:
return 1.0
return math.floor( (2.0*math.pi) * math.acos(1.0- (1.0-math.cos(math.pi/(2.0*latz))) / math.cos( (math.pi/180.0)*abs(declat_in) )**2 )**-1)
def dlon(declat_in, ctype, surface):
if surface:
tmp = 90.0
else:
tmp = 360.0
nlcalc = max(nl(declat_in)-ctype, 1)
return tmp / nlcalc
#encode CPR position
# https://adsb-decode-guide.readthedocs.io/en/latest/content/cpr.html
# compact position reporting
def cpr_encode(lat, lon, ctype, surface):
if surface is True:
scalar = 2.**19
else:
scalar = 2.**17
#encode using 360 constant for segment size.
dlati = dlat(ctype, False)
yz = math.floor(scalar * ((lat % dlati)/dlati) + 0.5)
rlat = dlati * ((yz / scalar) + math.floor(lat / dlati))
#encode using 360 constant for segment size.
dloni = dlon(lat, ctype, False)
xz = math.floor(scalar * ((lon % dloni)/dloni) + 0.5)
yz = int(yz) & (2**17-1)
xz = int(xz) & (2**17-1)
return (yz, xz) #lat, lon

View File

@@ -1,49 +0,0 @@
'''
Copyright 2015 Wolfgang Nagele
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
def bin2dec(buf):
if 0 == len(buf): # Crap input
return -1
return int(buf, 2)
# Ported from: http://www.radarspotters.eu/forum/index.php?topic=5617.msg41293#msg41293
def get_parity(msg, extended):
msg_length = len(msg)
payload = msg[:msg_length - 24]
parity = msg[msg_length - 24:]
data = bin2dec(payload[0:32])
if extended:
data1 = bin2dec(payload[32:64])
data2 = bin2dec(payload[64:]) << 8
hex_id = bin2dec(parity) << 8
for i in range(0, len(payload)):
if ((data & 0x80000000) != 0):
data ^= 0xFFFA0480
data <<= 1
if extended:
if ((data1 & 0x80000000) != 0):
data |= 1
data1 <<= 1
if ((data2 & 0x80000000) != 0):
data1 = data1 | 1
data2 <<= 1
return data
#return (data ^ hex_id) >> 8