@@ -0,0 +1,29 @@
|
|||||||
|
# This workflows will upload a Python Package using Twine when a release is created
|
||||||
|
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||||
|
|
||||||
|
name: PyPI Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: "3.x"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install setuptools wheel twine
|
||||||
|
- name: Build and publish
|
||||||
|
env:
|
||||||
|
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||||
|
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
python setup.py sdist bdist_wheel
|
||||||
|
twine upload dist/*
|
||||||
@@ -228,7 +228,7 @@ cpdef int cprNL(double lat):
|
|||||||
|
|
||||||
cdef int nz = 15
|
cdef int nz = 15
|
||||||
cdef double a = 1 - cos(pi / (2 * nz))
|
cdef double a = 1 - cos(pi / (2 * nz))
|
||||||
cdef double b = cos(pi / 180.0 * fabs(lat)) ** 2
|
cdef double b = cos(pi / 180 * fabs(lat)) ** 2
|
||||||
cdef double nl = 2 * pi / (acos(1 - a / b))
|
cdef double nl = 2 * pi / (acos(1 - a / b))
|
||||||
NL = floor(nl)
|
NL = floor(nl)
|
||||||
return NL
|
return NL
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ def airborne_position(msg0, msg1, t0, t1):
|
|||||||
raise RuntimeError("Both even and odd CPR frames are required.")
|
raise RuntimeError("Both even and odd CPR frames are required.")
|
||||||
|
|
||||||
# 131072 is 2^17, since CPR lat and lon are 17 bits each.
|
# 131072 is 2^17, since CPR lat and lon are 17 bits each.
|
||||||
cprlat_even = common.bin2int(mb0[22:39]) / 131072.0
|
cprlat_even = common.bin2int(mb0[22:39]) / 131072
|
||||||
cprlon_even = common.bin2int(mb0[39:56]) / 131072.0
|
cprlon_even = common.bin2int(mb0[39:56]) / 131072
|
||||||
cprlat_odd = common.bin2int(mb1[22:39]) / 131072.0
|
cprlat_odd = common.bin2int(mb1[22:39]) / 131072
|
||||||
cprlon_odd = common.bin2int(mb1[39:56]) / 131072.0
|
cprlon_odd = common.bin2int(mb1[39:56]) / 131072
|
||||||
|
|
||||||
air_d_lat_even = 360.0 / 60
|
air_d_lat_even = 360 / 60
|
||||||
air_d_lat_odd = 360.0 / 59
|
air_d_lat_odd = 360 / 59
|
||||||
|
|
||||||
# compute latitude index 'j'
|
# compute latitude index 'j'
|
||||||
j = common.floor(59 * cprlat_even - 60 * cprlat_odd + 0.5)
|
j = common.floor(59 * cprlat_even - 60 * cprlat_odd + 0.5)
|
||||||
@@ -64,13 +64,13 @@ def airborne_position(msg0, msg1, t0, t1):
|
|||||||
nl = common.cprNL(lat)
|
nl = common.cprNL(lat)
|
||||||
ni = max(common.cprNL(lat) - 0, 1)
|
ni = max(common.cprNL(lat) - 0, 1)
|
||||||
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
||||||
lon = (360.0 / ni) * (m % ni + cprlon_even)
|
lon = (360 / ni) * (m % ni + cprlon_even)
|
||||||
else:
|
else:
|
||||||
lat = lat_odd
|
lat = lat_odd
|
||||||
nl = common.cprNL(lat)
|
nl = common.cprNL(lat)
|
||||||
ni = max(common.cprNL(lat) - 1, 1)
|
ni = max(common.cprNL(lat) - 1, 1)
|
||||||
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
||||||
lon = (360.0 / ni) * (m % ni + cprlon_odd)
|
lon = (360 / ni) * (m % ni + cprlon_odd)
|
||||||
|
|
||||||
if lon > 180:
|
if lon > 180:
|
||||||
lon = lon - 360
|
lon = lon - 360
|
||||||
@@ -95,11 +95,11 @@ def airborne_position_with_ref(msg, lat_ref, lon_ref):
|
|||||||
|
|
||||||
mb = common.hex2bin(msg)[32:]
|
mb = common.hex2bin(msg)[32:]
|
||||||
|
|
||||||
cprlat = common.bin2int(mb[22:39]) / 131072.0
|
cprlat = common.bin2int(mb[22:39]) / 131072
|
||||||
cprlon = common.bin2int(mb[39:56]) / 131072.0
|
cprlon = common.bin2int(mb[39:56]) / 131072
|
||||||
|
|
||||||
i = int(mb[21])
|
i = int(mb[21])
|
||||||
d_lat = 360.0 / 59 if i else 360.0 / 60
|
d_lat = 360 / 59 if i else 360 / 60
|
||||||
|
|
||||||
j = common.floor(lat_ref / d_lat) + common.floor(
|
j = common.floor(lat_ref / d_lat) + common.floor(
|
||||||
0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
|
0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
|
||||||
@@ -110,9 +110,9 @@ def airborne_position_with_ref(msg, lat_ref, lon_ref):
|
|||||||
ni = common.cprNL(lat) - i
|
ni = common.cprNL(lat) - i
|
||||||
|
|
||||||
if ni > 0:
|
if ni > 0:
|
||||||
d_lon = 360.0 / ni
|
d_lon = 360 / ni
|
||||||
else:
|
else:
|
||||||
d_lon = 360.0
|
d_lon = 360
|
||||||
|
|
||||||
m = common.floor(lon_ref / d_lon) + common.floor(
|
m = common.floor(lon_ref / d_lon) + common.floor(
|
||||||
0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
|
0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
|
||||||
@@ -143,9 +143,8 @@ def altitude(msg):
|
|||||||
|
|
||||||
if tc < 19:
|
if tc < 19:
|
||||||
altcode = altbin[0:6] + "0" + altbin[6:]
|
altcode = altbin[0:6] + "0" + altbin[6:]
|
||||||
|
alt = common.altitude(altcode)
|
||||||
else:
|
else:
|
||||||
altcode = altbin[0:6] + "0" + altbin[6:]
|
alt = common.bin2int(altbin) * 3.28084
|
||||||
|
|
||||||
alt = common.altitude(altcode)
|
|
||||||
|
|
||||||
return alt
|
return alt
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ def surface_position(msg0, msg1, t0, t1, lat_ref, lon_ref):
|
|||||||
msgbin1 = common.hex2bin(msg1)
|
msgbin1 = common.hex2bin(msg1)
|
||||||
|
|
||||||
# 131072 is 2^17, since CPR lat and lon are 17 bits each.
|
# 131072 is 2^17, since CPR lat and lon are 17 bits each.
|
||||||
cprlat_even = common.bin2int(msgbin0[54:71]) / 131072.0
|
cprlat_even = common.bin2int(msgbin0[54:71]) / 131072
|
||||||
cprlon_even = common.bin2int(msgbin0[71:88]) / 131072.0
|
cprlon_even = common.bin2int(msgbin0[71:88]) / 131072
|
||||||
cprlat_odd = common.bin2int(msgbin1[54:71]) / 131072.0
|
cprlat_odd = common.bin2int(msgbin1[54:71]) / 131072
|
||||||
cprlon_odd = common.bin2int(msgbin1[71:88]) / 131072.0
|
cprlon_odd = common.bin2int(msgbin1[71:88]) / 131072
|
||||||
|
|
||||||
air_d_lat_even = 90.0 / 60
|
air_d_lat_even = 90 / 60
|
||||||
air_d_lat_odd = 90.0 / 59
|
air_d_lat_odd = 90 / 59
|
||||||
|
|
||||||
# compute latitude index 'j'
|
# compute latitude index 'j'
|
||||||
j = common.floor(59 * cprlat_even - 60 * cprlat_odd + 0.5)
|
j = common.floor(59 * cprlat_even - 60 * cprlat_odd + 0.5)
|
||||||
@@ -43,8 +43,8 @@ def surface_position(msg0, msg1, t0, t1, lat_ref, lon_ref):
|
|||||||
lat_odd_n = float(air_d_lat_odd * (j % 59 + cprlat_odd))
|
lat_odd_n = float(air_d_lat_odd * (j % 59 + cprlat_odd))
|
||||||
|
|
||||||
# solution for north hemisphere
|
# solution for north hemisphere
|
||||||
lat_even_s = lat_even_n - 90.0
|
lat_even_s = lat_even_n - 90
|
||||||
lat_odd_s = lat_odd_n - 90.0
|
lat_odd_s = lat_odd_n - 90
|
||||||
|
|
||||||
# chose which solution corrispondes to receiver location
|
# chose which solution corrispondes to receiver location
|
||||||
lat_even = lat_even_n if lat_ref > 0 else lat_even_s
|
lat_even = lat_even_n if lat_ref > 0 else lat_even_s
|
||||||
@@ -60,16 +60,16 @@ def surface_position(msg0, msg1, t0, t1, lat_ref, lon_ref):
|
|||||||
nl = common.cprNL(lat_even)
|
nl = common.cprNL(lat_even)
|
||||||
ni = max(common.cprNL(lat_even) - 0, 1)
|
ni = max(common.cprNL(lat_even) - 0, 1)
|
||||||
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
||||||
lon = (90.0 / ni) * (m % ni + cprlon_even)
|
lon = (90 / ni) * (m % ni + cprlon_even)
|
||||||
else:
|
else:
|
||||||
lat = lat_odd
|
lat = lat_odd
|
||||||
nl = common.cprNL(lat_odd)
|
nl = common.cprNL(lat_odd)
|
||||||
ni = max(common.cprNL(lat_odd) - 1, 1)
|
ni = max(common.cprNL(lat_odd) - 1, 1)
|
||||||
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
|
||||||
lon = (90.0 / ni) * (m % ni + cprlon_odd)
|
lon = (90 / ni) * (m % ni + cprlon_odd)
|
||||||
|
|
||||||
# four possible longitude solutions
|
# four possible longitude solutions
|
||||||
lons = [lon, lon + 90.0, lon + 180.0, lon + 270.0]
|
lons = [lon, lon + 90, lon + 180, lon + 270]
|
||||||
|
|
||||||
# make sure lons are between -180 and 180
|
# make sure lons are between -180 and 180
|
||||||
lons = [(l + 180) % 360 - 180 for l in lons]
|
lons = [(l + 180) % 360 - 180 for l in lons]
|
||||||
@@ -99,11 +99,11 @@ def surface_position_with_ref(msg, lat_ref, lon_ref):
|
|||||||
|
|
||||||
mb = common.hex2bin(msg)[32:]
|
mb = common.hex2bin(msg)[32:]
|
||||||
|
|
||||||
cprlat = common.bin2int(mb[22:39]) / 131072.0
|
cprlat = common.bin2int(mb[22:39]) / 131072
|
||||||
cprlon = common.bin2int(mb[39:56]) / 131072.0
|
cprlon = common.bin2int(mb[39:56]) / 131072
|
||||||
|
|
||||||
i = int(mb[21])
|
i = int(mb[21])
|
||||||
d_lat = 90.0 / 59 if i else 90.0 / 60
|
d_lat = 90 / 59 if i else 90 / 60
|
||||||
|
|
||||||
j = common.floor(lat_ref / d_lat) + common.floor(
|
j = common.floor(lat_ref / d_lat) + common.floor(
|
||||||
0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
|
0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
|
||||||
@@ -114,9 +114,9 @@ def surface_position_with_ref(msg, lat_ref, lon_ref):
|
|||||||
ni = common.cprNL(lat) - i
|
ni = common.cprNL(lat) - i
|
||||||
|
|
||||||
if ni > 0:
|
if ni > 0:
|
||||||
d_lon = 90.0 / ni
|
d_lon = 90 / ni
|
||||||
else:
|
else:
|
||||||
d_lon = 90.0
|
d_lon = 90
|
||||||
|
|
||||||
m = common.floor(lon_ref / d_lon) + common.floor(
|
m = common.floor(lon_ref / d_lon) + common.floor(
|
||||||
0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
|
0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
|
||||||
@@ -153,7 +153,7 @@ def surface_velocity(msg, source=False):
|
|||||||
# ground track
|
# ground track
|
||||||
trk_status = int(mb[12])
|
trk_status = int(mb[12])
|
||||||
if trk_status == 1:
|
if trk_status == 1:
|
||||||
trk = common.bin2int(mb[13:20]) * 360.0 / 128.0
|
trk = common.bin2int(mb[13:20]) * 360 / 128
|
||||||
trk = round(trk, 1)
|
trk = round(trk, 1)
|
||||||
else:
|
else:
|
||||||
trk = None
|
trk = None
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ def airborne_velocity(msg, source=False):
|
|||||||
- Angle (degree), either ground track or heading
|
- Angle (degree), either ground track or heading
|
||||||
- Vertical rate (ft/min)
|
- Vertical rate (ft/min)
|
||||||
- Speed type ('GS' for ground speed, 'AS' for airspeed)
|
- Speed type ('GS' for ground speed, 'AS' for airspeed)
|
||||||
- [Optional] Direction source ('TRUE_NORTH' or 'MAGENTIC_NORTH')
|
- [Optional] Direction source ('TRUE_NORTH' or 'MAGNETIC_NORTH')
|
||||||
- [Optional] Vertical rate source ('BARO' or 'GNSS')
|
- [Optional] Vertical rate source ('BARO' or 'GNSS')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -35,29 +35,35 @@ def airborne_velocity(msg, source=False):
|
|||||||
|
|
||||||
subtype = common.bin2int(mb[5:8])
|
subtype = common.bin2int(mb[5:8])
|
||||||
|
|
||||||
if common.bin2int(mb[14:24]) == 0 or common.bin2int(mb[25:35]) == 0:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if subtype in (1, 2):
|
if subtype in (1, 2):
|
||||||
v_ew_sign = -1 if mb[13] == "1" else 1
|
|
||||||
v_ew = common.bin2int(mb[14:24]) - 1 # east-west velocity
|
|
||||||
if subtype == 2: # Supersonic
|
|
||||||
v_ew *= 4
|
|
||||||
|
|
||||||
v_ns_sign = -1 if mb[24] == "1" else 1
|
v_ew = common.bin2int(mb[14:24])
|
||||||
v_ns = common.bin2int(mb[25:35]) - 1 # north-south velocity
|
v_ns = common.bin2int(mb[25:35])
|
||||||
if subtype == 2: # Supersonic
|
|
||||||
v_ns *= 4
|
|
||||||
|
|
||||||
v_we = v_ew_sign * v_ew
|
if v_ew == 0 or v_ns == 0:
|
||||||
v_sn = v_ns_sign * v_ns
|
spd = None
|
||||||
|
trk_or_hdg = None
|
||||||
|
vs = None
|
||||||
|
else:
|
||||||
|
v_ew_sign = -1 if mb[13] == "1" else 1
|
||||||
|
v_ew = v_ew - 1 # east-west velocity
|
||||||
|
if subtype == 2: # Supersonic
|
||||||
|
v_ew *= 4
|
||||||
|
|
||||||
spd = math.sqrt(v_sn * v_sn + v_we * v_we) # unit in kts
|
v_ns_sign = -1 if mb[24] == "1" else 1
|
||||||
spd = int(spd)
|
v_ns = v_ns - 1 # north-south velocity
|
||||||
|
if subtype == 2: # Supersonic
|
||||||
|
v_ns *= 4
|
||||||
|
|
||||||
trk = math.atan2(v_we, v_sn)
|
v_we = v_ew_sign * v_ew
|
||||||
trk = math.degrees(trk) # convert to degrees
|
v_sn = v_ns_sign * v_ns
|
||||||
trk = trk if trk >= 0 else trk + 360 # no negative val
|
|
||||||
|
spd = math.sqrt(v_sn * v_sn + v_we * v_we) # unit in kts
|
||||||
|
spd = int(spd)
|
||||||
|
|
||||||
|
trk = math.atan2(v_we, v_sn)
|
||||||
|
trk = math.degrees(trk) # convert to degrees
|
||||||
|
trk = trk if trk >= 0 else trk + 360 # no negative val
|
||||||
|
|
||||||
spd_type = "GS"
|
spd_type = "GS"
|
||||||
trk_or_hdg = round(trk, 2)
|
trk_or_hdg = round(trk, 2)
|
||||||
@@ -67,13 +73,15 @@ def airborne_velocity(msg, source=False):
|
|||||||
if mb[13] == "0":
|
if mb[13] == "0":
|
||||||
hdg = None
|
hdg = None
|
||||||
else:
|
else:
|
||||||
hdg = common.bin2int(mb[14:24]) / 1024.0 * 360.0
|
hdg = common.bin2int(mb[14:24]) / 1024 * 360.0
|
||||||
hdg = round(hdg, 2)
|
hdg = round(hdg, 2)
|
||||||
|
|
||||||
trk_or_hdg = hdg
|
trk_or_hdg = hdg
|
||||||
|
|
||||||
spd = common.bin2int(mb[25:35])
|
spd = common.bin2int(mb[25:35])
|
||||||
|
|
||||||
spd = None if spd == 0 else spd - 1
|
spd = None if spd == 0 else spd - 1
|
||||||
|
|
||||||
if subtype == 4: # Supersonic
|
if subtype == 4: # Supersonic
|
||||||
spd *= 4
|
spd *= 4
|
||||||
|
|
||||||
@@ -82,7 +90,7 @@ def airborne_velocity(msg, source=False):
|
|||||||
else:
|
else:
|
||||||
spd_type = "TAS"
|
spd_type = "TAS"
|
||||||
|
|
||||||
dir_type = "MAGENTIC_NORTH"
|
dir_type = "MAGNETIC_NORTH"
|
||||||
|
|
||||||
vr_source = "GNSS" if mb[35] == "0" else "BARO"
|
vr_source = "GNSS" if mb[35] == "0" else "BARO"
|
||||||
vr_sign = -1 if mb[36] == "1" else 1
|
vr_sign = -1 if mb[36] == "1" else 1
|
||||||
@@ -96,7 +104,7 @@ def airborne_velocity(msg, source=False):
|
|||||||
|
|
||||||
|
|
||||||
def altitude_diff(msg):
|
def altitude_diff(msg):
|
||||||
"""Decode the differece between GNSS and barometric altitude.
|
"""Decode the difference between GNSS and barometric altitude.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg (str): 28 hexdigits string, TC=19
|
msg (str): 28 hexdigits string, TC=19
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def wind44(msg):
|
|||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
speed = common.bin2int(d[5:14]) # knots
|
speed = common.bin2int(d[5:14]) # knots
|
||||||
direction = common.bin2int(d[14:23]) * 180.0 / 256.0 # degree
|
direction = common.bin2int(d[14:23]) * 180 / 256 # degree
|
||||||
|
|
||||||
return round(speed, 0), round(direction, 1)
|
return round(speed, 0), round(direction, 1)
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ def hum44(msg):
|
|||||||
if d[49] == "0":
|
if d[49] == "0":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
hm = common.bin2int(d[50:56]) * 100.0 / 64 # %
|
hm = common.bin2int(d[50:56]) * 100 / 64 # %
|
||||||
|
|
||||||
return round(hm, 1)
|
return round(hm, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def roll50(msg):
|
|||||||
if sign:
|
if sign:
|
||||||
value = value - 512
|
value = value - 512
|
||||||
|
|
||||||
angle = value * 45.0 / 256.0 # degree
|
angle = value * 45 / 256 # degree
|
||||||
return round(angle, 1)
|
return round(angle, 1)
|
||||||
|
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ def trk50(msg):
|
|||||||
if sign:
|
if sign:
|
||||||
value = value - 1024
|
value = value - 1024
|
||||||
|
|
||||||
trk = value * 90.0 / 512.0
|
trk = value * 90 / 512.0
|
||||||
|
|
||||||
# convert from [-180, 180] to [0, 360]
|
# convert from [-180, 180] to [0, 360]
|
||||||
if trk < 0:
|
if trk < 0:
|
||||||
@@ -151,7 +151,7 @@ def rtrk50(msg):
|
|||||||
if sign:
|
if sign:
|
||||||
value = value - 512
|
value = value - 512
|
||||||
|
|
||||||
angle = value * 8.0 / 256.0 # degree / sec
|
angle = value * 8 / 256 # degree / sec
|
||||||
return round(angle, 3)
|
return round(angle, 3)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def hdg53(msg):
|
|||||||
if sign:
|
if sign:
|
||||||
value = value - 1024
|
value = value - 1024
|
||||||
|
|
||||||
hdg = value * 90.0 / 512.0 # degree
|
hdg = value * 90 / 512 # degree
|
||||||
|
|
||||||
# convert from [-180, 180] to [0, 360]
|
# convert from [-180, 180] to [0, 360]
|
||||||
if hdg < 0:
|
if hdg < 0:
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def hdg60(msg):
|
|||||||
if sign:
|
if sign:
|
||||||
value = value - 1024
|
value = value - 1024
|
||||||
|
|
||||||
hdg = value * 90 / 512.0 # degree
|
hdg = value * 90 / 512 # degree
|
||||||
|
|
||||||
# convert from [-180, 180] to [0, 360]
|
# convert from [-180, 180] to [0, 360]
|
||||||
if hdg < 0:
|
if hdg < 0:
|
||||||
|
|||||||
@@ -35,18 +35,18 @@ ft = 0.3048 # ft -> m
|
|||||||
fpm = 0.00508 # ft/min -> m/s
|
fpm = 0.00508 # ft/min -> m/s
|
||||||
inch = 0.0254 # inch -> m
|
inch = 0.0254 # inch -> m
|
||||||
sqft = 0.09290304 # 1 square foot
|
sqft = 0.09290304 # 1 square foot
|
||||||
nm = 1852.0 # nautical mile -> m
|
nm = 1852 # nautical mile -> m
|
||||||
lbs = 0.453592 # pound -> kg
|
lbs = 0.453592 # pound -> kg
|
||||||
g0 = 9.80665 # m/s2, Sea level gravity constant
|
g0 = 9.80665 # m/s2, Sea level gravity constant
|
||||||
R = 287.05287 # m2/(s2 x K), gas constant, sea level ISA
|
R = 287.05287 # m2/(s2 x K), gas constant, sea level ISA
|
||||||
p0 = 101325.0 # Pa, air pressure, sea level ISA
|
p0 = 101325 # Pa, air pressure, sea level ISA
|
||||||
rho0 = 1.225 # kg/m3, air density, sea level ISA
|
rho0 = 1.225 # kg/m3, air density, sea level ISA
|
||||||
T0 = 288.15 # K, temperature, sea level ISA
|
T0 = 288.15 # K, temperature, sea level ISA
|
||||||
gamma = 1.40 # cp/cv for air
|
gamma = 1.40 # cp/cv for air
|
||||||
gamma1 = 0.2 # (gamma-1)/2 for air
|
gamma1 = 0.2 # (gamma-1)/2 for air
|
||||||
gamma2 = 3.5 # gamma/(gamma-1) for air
|
gamma2 = 3.5 # gamma/(gamma-1) for air
|
||||||
beta = -0.0065 # [K/m] ISA temp gradient below tropopause
|
beta = -0.0065 # [K/m] ISA temp gradient below tropopause
|
||||||
r_earth = 6371000.0 # m, average earth radius
|
r_earth = 6371000 # m, average earth radius
|
||||||
a0 = 340.293988 # m/s, sea level speed of sound ISA, sqrt(gamma*R*T0)
|
a0 = 340.293988 # m/s, sea level speed of sound ISA, sqrt(gamma*R*T0)
|
||||||
|
|
||||||
|
|
||||||
@@ -94,8 +94,8 @@ def distance(lat1, lon1, lat2, lon2, H=0):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# phi = 90 - latitude
|
# phi = 90 - latitude
|
||||||
phi1 = np.radians(90.0 - lat1)
|
phi1 = np.radians(90 - lat1)
|
||||||
phi2 = np.radians(90.0 - lat2)
|
phi2 = np.radians(90 - lat2)
|
||||||
|
|
||||||
# theta = longitude
|
# theta = longitude
|
||||||
theta1 = np.radians(lon1)
|
theta1 = np.radians(lon1)
|
||||||
@@ -158,16 +158,16 @@ def tas2eas(Vtas, H):
|
|||||||
def cas2tas(Vcas, H):
|
def cas2tas(Vcas, H):
|
||||||
"""Calibrated Airspeed to True Airspeed"""
|
"""Calibrated Airspeed to True Airspeed"""
|
||||||
p, rho, T = atmos(H)
|
p, rho, T = atmos(H)
|
||||||
qdyn = p0 * ((1.0 + rho0 * Vcas * Vcas / (7.0 * p0)) ** 3.5 - 1.0)
|
qdyn = p0 * ((1 + rho0 * Vcas * Vcas / (7 * p0)) ** 3.5 - 1.0)
|
||||||
Vtas = np.sqrt(7.0 * p / rho * ((1.0 + qdyn / p) ** (2.0 / 7.0) - 1.0))
|
Vtas = np.sqrt(7 * p / rho * ((1 + qdyn / p) ** (2 / 7.0) - 1.0))
|
||||||
return Vtas
|
return Vtas
|
||||||
|
|
||||||
|
|
||||||
def tas2cas(Vtas, H):
|
def tas2cas(Vtas, H):
|
||||||
"""True Airspeed to Calibrated Airspeed"""
|
"""True Airspeed to Calibrated Airspeed"""
|
||||||
p, rho, T = atmos(H)
|
p, rho, T = atmos(H)
|
||||||
qdyn = p * ((1.0 + rho * Vtas * Vtas / (7.0 * p)) ** 3.5 - 1.0)
|
qdyn = p * ((1 + rho * Vtas * Vtas / (7 * p)) ** 3.5 - 1.0)
|
||||||
Vcas = np.sqrt(7.0 * p0 / rho0 * ((qdyn / p0 + 1.0) ** (2.0 / 7.0) - 1.0))
|
Vcas = np.sqrt(7 * p0 / rho0 * ((qdyn / p0 + 1.0) ** (2 / 7.0) - 1.0))
|
||||||
return Vcas
|
return Vcas
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ def cprNL(lat: float) -> int:
|
|||||||
|
|
||||||
nz = 15
|
nz = 15
|
||||||
a = 1 - np.cos(np.pi / (2 * nz))
|
a = 1 - np.cos(np.pi / (2 * nz))
|
||||||
b = np.cos(np.pi / 180.0 * abs(lat)) ** 2
|
b = np.cos(np.pi / 180 * abs(lat)) ** 2
|
||||||
nl = 2 * np.pi / (np.arccos(1 - a / b))
|
nl = 2 * np.pi / (np.arccos(1 - a / b))
|
||||||
NL = floor(nl)
|
NL = floor(nl)
|
||||||
return NL
|
return NL
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ with open(path.join(here, "README.rst"), encoding="utf-8") as f:
|
|||||||
|
|
||||||
details = dict(
|
details = dict(
|
||||||
name="pyModeS",
|
name="pyModeS",
|
||||||
version="2.8",
|
version="2.9",
|
||||||
description="Python Mode-S and ADS-B Decoder",
|
description="Python Mode-S and ADS-B Decoder",
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
url="https://github.com/junzis/pyModeS",
|
url="https://github.com/junzis/pyModeS",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ def test_icao():
|
|||||||
|
|
||||||
|
|
||||||
def test_interrogator():
|
def test_interrogator():
|
||||||
assert allcall.interrogator("5D484FDEA248F5") == 22
|
assert allcall.interrogator("5D484FDEA248F5") == "SI6"
|
||||||
|
|
||||||
|
|
||||||
def test_capability():
|
def test_capability():
|
||||||
|
|||||||
Reference in New Issue
Block a user