コード例 #1
0
def mach53(msg):
    """MACH number, DBS 5,3 message

    Args:
        msg (String): 28 bytes hexadecimal message

    Returns:
        float: MACH number
    """
    d = hex2bin(data(msg))

    if d[23] == "0":
        return None

    mach = bin2int(d[24:33]) * 0.008
    return round(mach, 3)
コード例 #2
0
def tas53(msg):
    """Aircraft true airspeed, BDS 5,3 message

    Args:
        msg (String): 28 bytes hexadecimal message

    Returns:
        float: true airspeed in knots
    """
    d = hex2bin(data(msg))

    if d[33] == "0":
        return None

    tas = bin2int(d[34:46]) * 0.5  # kts
    return round(tas, 1)
コード例 #3
0
def ias53(msg):
    """Indicated airspeed, DBS 5,3 message

    Args:
        msg (String): 28 bytes hexadecimal message

    Returns:
        int: indicated arispeed in knots
    """
    d = hex2bin(data(msg))

    if d[12] == "0":
        return None

    ias = bin2int(d[13:23])  # knots
    return ias
コード例 #4
0
ファイル: adsb.py プロジェクト: JoseAndresMR/pyModeS
def sil(msg, version):
    """Calculate SIL, Surveillance Integrity Level

    Args:
        msg (string): 28 bytes hexadecimal message string with TC = 29, 31

    Returns:
        int or string: Probability of exceeding Horizontal Radius of Containment RCu 
        int or string: Probability of exceeding Vertical Integrity Containment Region VPL 
        string: SIL supplement based on "per hour" or "per sample"
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status messag, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    sil_df = pd.read_csv(
        '/home/josmilrom/Libraries/pyModeS/pyModeS/decoder/adsb_ua_parameters/SIL.csv',
        sep=',')

    msgbin = common.hex2bin(msg)

    if tc == 29:
        sil = common.bin2int(msgbin[76:78])
    elif tc == 31:
        sil = common.bin2int(msg[82:84])

    sil_df_extract = sil_df[sil_df.NACv == sil]
    PR_RCu = sil_df_extract['PR_RCu'][0]
    PE_VPL = sil_df_extract['PE_VPL'][0]

    if version == 1:
        return PR_RCu, PE_VPL
    if version == 2:
        if tc == 29:
            sil_sup = common.bin2int(msgbin[39])
        elif tc == 31:
            sil_sup = common.bin2int(msgbin[86])

        if sil_sup == 0:
            base = "per hour"
        elif sil_sup == 1:
            base = "per sample"

        return PR_RCu, PE_VPL, base
コード例 #5
0
def hum44(msg):
    """humidity

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        float: percentage of humidity, [0 - 100] %
    """
    d = hex2bin(data(msg))

    if d[49] == "0":
        return None

    hm = bin2int(d[50:56]) * 100.0 / 64  # %

    return round(hm, 1)
コード例 #6
0
ファイル: bds17.py プロジェクト: zh199225/pyModeS
def cap17(msg):
    """Extract capacities from BDS 1,7 message

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        list: list of support BDS codes
    """
    allbds = [
        "05",
        "06",
        "07",
        "08",
        "09",
        "0A",
        "20",
        "21",
        "40",
        "41",
        "42",
        "43",
        "44",
        "45",
        "48",
        "50",
        "51",
        "52",
        "53",
        "54",
        "55",
        "56",
        "5F",
        "60",
        "NA",
        "NA",
        "E1",
        "E2",
    ]

    d = hex2bin(data(msg))
    idx = [i for i, v in enumerate(d[:28]) if v == "1"]
    capacity = ["BDS" + allbds[i] for i in idx if allbds[i] is not "NA"]

    return capacity
コード例 #7
0
def sil(msg, version):
    """Calculate SIL, Surveillance Integrity Level

    Args:
        msg (string): 28 bytes hexadecimal message string with TC = 29, 31

    Returns:
        int or string: Probability of exceeding Horizontal Radius of Containment RCu
        int or string: Probability of exceeding Vertical Integrity Containment Region VPL
        string: SIL supplement based on per "hour" or "sample", or 'unknown'
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status messag, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    msgbin = common.hex2bin(msg)

    if tc == 29:
        SIL = common.bin2int(msgbin[76:78])
    elif tc == 31:
        SIL = common.bin2int(msgbin[82:84])

    try:
        PE_RCu = uncertainty.SIL[SIL]["PE_RCu"]
        PE_VPL = uncertainty.SIL[SIL]["PE_VPL"]
    except KeyError:
        PE_RCu, PE_VPL = uncertainty.NA, uncertainty.NA

    base = "unknown"

    if version == 2:
        if tc == 29:
            SIL_SUP = common.bin2int(msgbin[39])
        elif tc == 31:
            SIL_SUP = common.bin2int(msgbin[86])

        if SIL_SUP == 0:
            base = "hour"
        elif SIL_SUP == 1:
            base = "sample"

    return PE_RCu, PE_VPL, base
コード例 #8
0
def p44(msg):
    """Static pressure.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: static pressure in hPa

    """
    d = hex2bin(data(msg))

    if d[34] == "0":
        return None

    p = bin2int(d[35:46])  # hPa

    return p
コード例 #9
0
def turb44(msg):
    """Turblence.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: turbulence level. 0=NIL, 1=Light, 2=Moderate, 3=Severe

    """
    d = hex2bin(data(msg))

    if d[46] == "0":
        return None

    turb = bin2int(d[47:49])

    return turb
コード例 #10
0
def cap17(msg):
    """Extract capacities from BDS 1,7 message

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        list: list of suport BDS codes
    """
    allbds = ['05', '06', '07', '08', '09', '0A', '20', '21', '40', '41',
              '42', '43', '44', '45', '48', '50', '51', '52', '53', '54',
              '55', '56', '5F', '60', 'NA', 'NA', 'E1', 'E2']

    d = hex2bin(data(msg))
    idx = [i for i, v in enumerate(d[:28]) if v=='1']
    capacity = ['BDS'+allbds[i] for i in idx if allbds[i] is not 'NA']

    return capacity
コード例 #11
0
def version(msg):
    """ADS-B Version

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 31

    Returns:
        int: version number
    """
    tc = typecode(msg)

    if tc != 31:
        raise RuntimeError(
            "%s: Not a status operation message, expecting TC = 31" % msg)

    msgbin = common.hex2bin(msg)
    version = common.bin2int(msgbin[72:75])

    return version
コード例 #12
0
def nic_s(msg):
    """Obtain NIC supplement bit, TC=31 message

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        int: NICs number (0 or 1)
    """
    tc = typecode(msg)

    if tc != 31:
        raise RuntimeError(
            "%s: Not a status operation message, expecting TC = 31" % msg)

    msgbin = common.hex2bin(msg)
    nic_s = int(msgbin[75])

    return nic_s
コード例 #13
0
def nic_b(msg):
    """Obtain NICb, navigation integrity category supplement-b

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        int: NICb number (0 or 1)
    """
    tc = typecode(msg)

    if tc < 9 or tc > 18:
        raise RuntimeError(
            "%s: Not a airborne position message, expecting 8<TC<19" % msg)

    msgbin = common.hex2bin(msg)
    nic_b = int(msgbin[39])

    return nic_b
コード例 #14
0
def is44(msg):
    """Check if a message is likely to be BDS code 4,4.

    Meteorological routine air report

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False

    """
    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    # status bit 5, 35, 47, 50
    if wrongstatus(d, 5, 6, 23):
        return False

    if wrongstatus(d, 35, 36, 46):
        return False

    if wrongstatus(d, 47, 48, 49):
        return False

    if wrongstatus(d, 50, 51, 56):
        return False

    # Bits 1-4 indicate source, values > 4 reserved and should not occur
    if bin2int(d[0:4]) > 4:
        return False

    vw, dw = wind44(msg)
    if vw is not None and vw > 250:
        return False

    temp, temp2 = temp44(msg)
    if min(temp, temp2) > 60 or max(temp, temp2) < -80:
        return False

    return True
コード例 #15
0
def surface_position_with_ref(msg, lat_ref, lon_ref):
    """Decode surface position with only one message,
    knowing reference nearby location, such as previously calculated location,
    ground station, or airport location, etc. The reference position shall
    be with in 45NM of the true position.

    Args:
        msg (string): even message (28 bytes hexadecimal string)
        lat_ref: previous known latitude
        lon_ref: previous known longitude

    Returns:
        (float, float): (latitude, longitude) of the aircraft
    """

    mb = common.hex2bin(msg)[32:]

    cprlat = common.bin2int(mb[22:39]) / 131072.0
    cprlon = common.bin2int(mb[39:56]) / 131072.0

    i = int(mb[21])
    d_lat = 90.0 / 59 if i else 90.0 / 60

    j = common.floor(lat_ref / d_lat) + common.floor(
        0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
    )

    lat = d_lat * (j + cprlat)

    ni = common.cprNL(lat) - i

    if ni > 0:
        d_lon = 90.0 / ni
    else:
        d_lon = 90.0

    m = common.floor(lon_ref / d_lon) + common.floor(
        0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
    )

    lon = d_lon * (m + cprlon)

    return round(lat, 5), round(lon, 5)
コード例 #16
0
def surface_velocity(msg):
    """Decode surface velocity from from a surface position message
    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        (int, float, int, string): speed (kt), ground track (degree),
            rate of climb/descend (ft/min), and speed type
            ('GS' for ground speed, 'AS' for airspeed)
    """

    if common.typecode(msg) < 5 or common.typecode(msg) > 8:
        raise RuntimeError("%s: Not a surface message, expecting 5<TC<8" % msg)

    mb = common.hex2bin(msg)[32:]

    # ground track
    trk_status = int(mb[12])
    if trk_status == 1:
        trk = common.bin2int(mb[13:20]) * 360.0 / 128.0
        trk = round(trk, 1)
    else:
        trk = None

    # ground movment / speed
    mov = common.bin2int(mb[5:12])

    if mov == 0 or mov > 124:
        spd = None
    elif mov == 1:
        spd = 0
    elif mov == 124:
        spd = 175
    else:
        movs = [2, 9, 13, 39, 94, 109, 124]
        kts = [0.125, 1, 2, 15, 70, 100, 175]
        i = next(m[0] for m in enumerate(movs) if m[1] > mov)
        step = (kts[i] - kts[i - 1]) * 1.0 / (movs[i] - movs[i - 1])
        spd = kts[i - 1] + (mov - movs[i - 1]) * step
        spd = round(spd, 2)

    return spd, trk, 0, 'GS'
コード例 #17
0
def nic_a_c(msg):
    """Obtain NICa/c, navigation integrity category supplements a and c

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        (int, int): NICa and NICc number (0 or 1)
    """
    tc = typecode(msg)

    if tc != 31:
        raise RuntimeError(
            "%s: Not a status operation message, expecting TC = 31" % msg)

    msgbin = common.hex2bin(msg)
    nic_a = int(msgbin[75])
    nic_c = int(msgbin[51])

    return nic_a, nic_c
コード例 #18
0
def wind44(msg):
    """Wind speed and direction.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        (int, float): speed (kt), direction (degree)

    """
    d = hex2bin(data(msg))

    status = int(d[4])
    if not status:
        return None, None

    speed = bin2int(d[5:14])  # knots
    direction = bin2int(d[14:23]) * 180.0 / 256.0  # degree

    return round(speed, 0), round(direction, 1)
コード例 #19
0
ファイル: bds40.py プロジェクト: swiich/pyModeS
def is40(msg):
    """Check if a message is likely to be BDS code 4,0

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    # status bit 1, 14, and 27

    if wrongstatus(d, 1, 2, 13):
        return False

    if wrongstatus(d, 14, 15, 26):
        return False

    if wrongstatus(d, 27, 28, 39):
        return False

    if wrongstatus(d, 48, 49, 51):
        return False

    if wrongstatus(d, 54, 55, 56):
        return False

    # bits 40-47 and 52-53 shall all be zero

    if bin2int(d[39:47]) != 0:
        return False

    if bin2int(d[51:53]) != 0:
        return False

    return True
コード例 #20
0
ファイル: bds45.py プロジェクト: zh199225/pyModeS
def temp45(msg):
    """Static air temperature.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        float: tmeperature in Celsius degree

    """
    d = hex2bin(data(msg))

    sign = int(d[16])
    value = bin2int(d[17:26])

    if sign:
        value = value - 512

    temp = value * 0.25  # celsius
    temp = round(temp, 1)

    return temp
コード例 #21
0
def temp44(msg, rev=False):
    """reported air temperature

    Args:
        msg (String): 28 bytes hexadecimal message (BDS44) string
        rev (bool): using revised version

    Returns:
        float: tmeperature in Celsius degree
    """
    d = hex2bin(data(msg))

    if not rev:
        # if d[22] == '0':
        #     return None

        sign = int(d[23])
        value = bin2int(d[24:34])

        if sign:
            value = value - 1024

        temp = value * 0.125   # celsius
        temp = round(temp, 1)
    else:
        # if d[23] == '0':
        #     return None

        sign = int(d[24])
        value = bin2int(d[25:35])

        if sign:
            value = value - 1024

        temp = value * 0.125   # celsius
        temp = round(temp, 1)

    return temp
コード例 #22
0
ファイル: bds09.py プロジェクト: Seanhsp/pyModeS
def altitude_diff(msg):
    """Decode the differece between GNSS and barometric altitude

    Args:
        msg (string): 28 bytes hexadecimal message string, TC=19

    Returns:
        int: Altitude difference in ft. Negative value indicates GNSS altitude
            below barometric altitude.
    """
    tc = common.typecode(msg)

    if tc != 19:
        raise RuntimeError("%s: Not a airborne velocity message, expecting TC=19" % msg)

    msgbin = common.hex2bin(msg)
    sign = -1 if int(msgbin[80]) else 1
    value = common.bin2int(msgbin[81:88])

    if value == 0 or value == 127:
        return None
    else:
        return sign * (value - 1) * 25  # in ft.
コード例 #23
0
ファイル: adsb.py プロジェクト: yzyGavin/pyModeS
def nuc_v(msg):
    """Calculate NUCv, Navigation Uncertainty Category - Velocity (ADS-B version 1)

    Args:
        msg (string): 28 bytes hexadecimal message string,

    Returns:
        int or string: 95% Horizontal Velocity Error
        int or string: 95% Vertical Velocity Error
    """
    tc = typecode(msg)

    if tc != 19:
        raise RuntimeError(
            "%s: Not an airborne velocity message, expecting TC = 19" % msg)

    msgbin = common.hex2bin(msg)
    NUCv = common.bin2int(msgbin[42:45])

    HVE = uncertainty.NUCv[NUCv]['HVE']
    VVE = uncertainty.NUCv[NUCv]['VVE']

    return HVE, VVE
コード例 #24
0
ファイル: adsb.py プロジェクト: yzyGavin/pyModeS
def nac_v(msg):
    """Calculate NACv, Navigation Accuracy Category - Velocity

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 19

    Returns:
        int or string: 95% horizontal accuracy bounds for velocity, Horizontal Figure of Merit
        int or string: 95% vertical accuracy bounds for velocity, Vertical Figure of Merit
    """
    tc = typecode(msg)

    if tc != 19:
        raise RuntimeError(
            "%s: Not an airborne velocity message, expecting TC = 19" % msg)

    msgbin = common.hex2bin(msg)
    NACv = common.bin2int(msgbin[42:45])

    HFOMr = uncertainty.NACv[NACv]['HFOMr']
    VFOMr = uncertainty.NACv[NACv]['VFOMr']

    return HFOMr, VFOMr
コード例 #25
0
ファイル: bds50.py プロジェクト: yzyGavin/pyModeS
def roll50(msg):
    """Roll angle, BDS 5,0 message

    Args:
        msg (String): 28 bytes hexadecimal message (BDS50) string

    Returns:
        float: angle in degrees,
               negative->left wing down, positive->right wing down
    """
    d = hex2bin(data(msg))

    if d[0] == '0':
        return None

    sign = int(d[1])  # 1 -> left wing down
    value = bin2int(d[2:11])

    if sign:
        value = value - 512

    angle = value * 45.0 / 256.0  # degree
    return round(angle, 1)
コード例 #26
0
ファイル: bds60.py プロジェクト: swiich/pyModeS
def vr60ins(msg):
    """Vertical rate messured by onbard equiments (IRS, AHRS)

    Args:
        msg (String): 28 bytes hexadecimal message (BDS60) string

    Returns:
        int: vertical rate in feet/minutes
    """
    d = hex2bin(data(msg))

    if d[45] == '0':
        return None

    sign = int(d[46])    # 1 -> negative value, two's complement
    value = bin2int(d[47:56])

    if value == 0 or value == 511:  # all zeros or all ones
        return 0

    value = value - 512 if sign else value

    roc = value * 32   # feet/min
    return roc
コード例 #27
0
ファイル: bds53.py プロジェクト: swiich/pyModeS
def vr53(msg):
    """Vertical rate

    Args:
        msg (String): 28 bytes hexadecimal message (BDS60) string

    Returns:
        int: vertical rate in feet/minutes
    """
    d = hex2bin(data(msg))

    if d[46] == '0':
        return None

    sign = int(d[47])  # 1 -> negative value, two's complement
    value = bin2int(d[48:56])

    if value == 0 or value == 255:  # all zeros or all ones
        return 0

    value = value - 256 if sign else value
    roc = value * 64  # feet/min

    return roc
コード例 #28
0
ファイル: bds50.py プロジェクト: yzyGavin/pyModeS
def rtrk50(msg):
    """Track angle rate, BDS 5,0 message

    Args:
        msg (String): 28 bytes hexadecimal message (BDS50) string

    Returns:
        float: angle rate in degrees/second
    """
    d = hex2bin(data(msg))

    if d[34] == '0':
        return None

    if d[36:45] == "111111111":
        return None

    sign = int(d[35])  # 1 -> negative value, two's complement
    value = bin2int(d[36:45])
    if sign:
        value = value - 512

    angle = value * 8.0 / 256.0  # degree / sec
    return round(angle, 3)
コード例 #29
0
ファイル: bds20.py プロジェクト: swiich/pyModeS
def is20(msg):
    """Check if a message is likely to be BDS code 2,0

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    if d[0:8] != '00100000':
        return False

    cs = cs20(msg)

    if '#' in cs:
        return False

    return True
コード例 #30
0
ファイル: bds20.py プロジェクト: swiich/pyModeS
def cs20(msg):
    """Aircraft callsign

    Args:
        msg (String): 28 bytes hexadecimal message (BDS40) string

    Returns:
        string: callsign, max. 8 chars
    """
    chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######'

    d = hex2bin(data(msg))

    cs = ''
    cs += chars[bin2int(d[8:14])]
    cs += chars[bin2int(d[14:20])]
    cs += chars[bin2int(d[20:26])]
    cs += chars[bin2int(d[26:32])]
    cs += chars[bin2int(d[32:38])]
    cs += chars[bin2int(d[38:44])]
    cs += chars[bin2int(d[44:50])]
    cs += chars[bin2int(d[50:56])]

    return cs