Calculate the speed, track (or heading), and vertical rate

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

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

def airborne_velocity(msg):
    """Calculate the speed, track (or heading), and vertical rate

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

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

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

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

    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):
        v_ew_sign = -1 if mb[13]=='1' else 1
        v_ew = common.bin2int(mb[14:24]) - 1       # east-west velocity

        v_ns_sign = -1 if mb[24]=='1' else 1
        v_ns = common.bin2int(mb[25:35]) - 1       # north-south velocity

        v_we = v_ew_sign * v_ew
        v_sn = v_ns_sign * v_ns

        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

        tag = 'GS'
        trk_or_hdg = round(trk, 2)

    else:
        if mb[13] == '0':
            hdg = None
        else:
            hdg = common.bin2int(mb[14:24]) / 1024.0 * 360.0
            hdg = round(hdg, 2)

        trk_or_hdg = hdg

        spd = common.bin2int(mb[25:35])
        spd = None if spd==0 else spd-1

        if mb[24]=='0':
            tag = 'IAS'
        else:
            tag = 'TAS'

    vr_sign = -1 if mb[36]=='1' else 1
    vr = common.bin2int(mb[37:46])
    rocd = None if vr==0 else int(vr_sign*(vr-1)*64)

    return spd, trk_or_hdg, rocd, tag