示例#1
0
def test_adsb_velocity():
    vgs = adsb.velocity("8D485020994409940838175B284F")
    vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
    vgs_surface = adsb.velocity("8FC8200A3AB8F5F893096B000000")
    assert vgs == (159, 182.9, -832, 'GS')
    assert vas == (376, 244.0, -2304, 'AS')
    assert vgs_surface == (19.0, 42.2, 0, 'GS')
示例#2
0
def test_adsb_velocity():
    vgs = adsb.velocity("8D485020994409940838175B284F")
    vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
    vgs_surface = adsb.velocity("8FC8200A3AB8F5F893096B000000")
    assert vgs == (159, 182.88, -832, "GS")
    assert vas == (375, 243.98, -2304, "TAS")
    assert vgs_surface == (19, 42.2, 0, "GS")
    assert adsb.altitude_diff("8D485020994409940838175B284F") == 550
示例#3
0
def adsb_decode_all(n=None):
    print("===== Decode ADS-B sample data=====")
    import csv
    f = open('tests/data/sample_data_adsb.csv', 'rt')

    msg0 = None
    msg1 = None

    for i, r in enumerate(csv.reader(f)):
        if n and i > n:
            break

        ts = r[0]
        m = r[1]
        icao = adsb.icao(m)
        tc = adsb.typecode(m)
        if 1 <= tc <= 4:
            print(ts, m, icao, tc, adsb.category(m), adsb.callsign(m))
        if tc == 19:
            print(ts, m, icao, tc, adsb.velocity(m))
        if 5 <= tc <= 18:
            if adsb.oe_flag(m):
                msg1 = m
                t1 = ts
            else:
                msg0 = m
                t0 = ts

            if msg0 and msg1:
                pos = adsb.position(msg0, msg1, t0, t1)
                alt = adsb.altitude(m)
                print(ts, m, icao, tc, pos, alt)
示例#4
0
文件: run.py 项目: aeroevan/pyModeS
def adsb_decode_all(n=None):
    print "===== Decode all ADS-B sample data====="
    import csv
    f = open('adsb.csv', 'rt')

    msg0 = None
    msg1 = None

    for i, r in enumerate(csv.reader(f)):
        if n and i > n:
            break

        ts = r[0]
        m = r[1]
        icao = adsb.icao(m)
        tc = adsb.typecode(m)
        if 1 <= tc <= 4:
            print ts, m, icao, tc, adsb.category(m), adsb.callsign(m)
        if tc == 19:
            print ts, m, icao, tc, adsb.velocity(m)
        if 5 <= tc <= 18:
            if adsb.oe_flag(m):
                msg1 = m
                t1 = ts
            else:
                msg0 = m
                t0 = ts

            if msg0 and msg1:
                pos = adsb.position(msg0, msg1, t0, t1)
                alt = adsb.altitude(m)
                print ts, m, icao, tc, pos, alt
    def createFromMessageBuffer(messageBuffer):
        info = None
        if messageBuffer.isComplete():
            latLng = adsb.position(messageBuffer.dataPositionEven[0].frame[1:29],
                                   messageBuffer.dataPositionOdd[0].frame[1:29],
                                   messageBuffer.dataPositionEven[0].timestamp,
                                   messageBuffer.dataPositionOdd[0].timestamp)
            velocity = adsb.velocity(messageBuffer.dataVelocity[0].frame[1:29])
            if latLng:
                info = ADSBInfo(
                    collector=COLLECTOR_ID,
                    modeSCode=adsb.icao(messageBuffer.dataId[0].frame[1:29]),
                    callsign=adsb.callsign(messageBuffer.dataId[0].frame[1:29]).replace("_", ""),
                    latitude=latLng[0],
                    longitude=latLng[1],
                    altitude=adsb.altitude(messageBuffer.dataPositionEven[0].frame[1:29]),
                    horizontalVelocity=velocity[0],
                    groundTrackHeading=velocity[1],
                    verticalVelocity=velocity[2],
                    messagDataId=messageBuffer.dataId[0].frame[1:29],
                    messagDataPositionEven=messageBuffer.dataId[0].frame[1:29],
                    messagDataPositionOdd=messageBuffer.dataId[0].frame[1:29],
                    messagDataVelocity=messageBuffer.dataId[0].frame[1:29],
                    timestamp=int(systemTimestamp() * 1000),
                    timestampSent=int(systemTimestamp() * 1000)
                )

        messageBuffer.clearPositionMessages()
        return info
示例#6
0
文件: run.py 项目: aeroevan/pyModeS
def test_adsb_velocity():
    vgs = adsb.velocity("8D485020994409940838175B284F")
    vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
    assert vgs == (159, 182.9, -263, 'GS')
    assert vas == (376, 244.0, -274, 'AS')
示例#7
0
def tell(msg: str) -> None:
    from pyModeS import common, adsb, commb, bds

    def _print(label, value, unit=None):
        print("%20s: " % label, end="")
        print("%s " % value, end="")
        if unit:
            print(unit)
        else:
            print()

    df = common.df(msg)
    icao = common.icao(msg)

    _print("Message", msg)
    _print("ICAO address", icao)
    _print("Downlink Format", df)

    if df == 17:
        _print("Protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            _print("Type", "Identitification and category")
            _print("Callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            _print("Type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Speed", v[0], "knots")
            _print("Track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            _print("Type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 19:
            _print("Type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            _print("Speed", spd, "knots")
            _print("Track", trk, "degrees")
            _print("Vertical rate", vr, "feet/minute")
            _print("Type", types[t])

        if 20 <= tc <= 22:  # airborne position
            _print("Type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

    if df == 20:
        _print("Protocol", "Mode-S Comm-B altitude reply")
        _print("Altitude", common.altcode(msg), "feet")

    if df == 21:
        _print("Protocol", "Mode-S Comm-B identity reply")
        _print("Squawk code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            _print("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            _print("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            _print("Callsign", callsign)

        if BDS == "BDS40":
            _print("MCP target alt", commb.selalt40mcp(msg), "feet")
            _print("FMS Target alt", commb.selalt40fms(msg), "feet")
            _print("Pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            _print("Roll angle", commb.roll50(msg), "degrees")
            _print("Track angle", commb.trk50(msg), "degrees")
            _print("Track rate", commb.rtrk50(msg), "degree/second")
            _print("Ground speed", commb.gs50(msg), "knots")
            _print("True airspeed", commb.tas50(msg), "knots")

        if BDS == "BDS60":
            _print("Megnatic Heading", commb.hdg60(msg), "degrees")
            _print("Indicated airspeed", commb.ias60(msg), "knots")
            _print("Mach number", commb.mach60(msg))
            _print("Vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            _print("Vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            _print("Wind speed", commb.wind44(msg)[0], "knots")
            _print("Wind direction", commb.wind44(msg)[1], "degrees")
            _print("Temperature 1", commb.temp44(msg)[0], "Celsius")
            _print("Temperature 2", commb.temp44(msg)[1], "Celsius")
            _print("Pressure", commb.p44(msg), "hPa")
            _print("Humidity", commb.hum44(msg), "%")
            _print("Turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            _print("Turbulence", commb.turb45(msg))
            _print("Wind shear", commb.ws45(msg))
            _print("Microbust", commb.mb45(msg))
            _print("Icing", commb.ic45(msg))
            _print("Wake vortex", commb.wv45(msg))
            _print("Temperature", commb.temp45(msg), "Celsius")
            _print("Pressure", commb.p45(msg), "hPa")
            _print("Radio height", commb.rh45(msg), "feet")
示例#8
0
    def message(self, msg):
        # Printout of statistics
        if self.signal_hup == 1:
            self.logstats()
            self.signal_hup = 0

        ret_dict = {}
        ret_dict['ret'] = 0
        ret_dict['type'] = ""

        self.msgs_curr_total = self.msgs_curr_total + 1

        if len(msg) == 26 or len(msg) == 40:
            # Some version of dump1090 have the 12 first characters used w/
            # some date (timestamp ?). E.g. sdbr245 feeding flightradar24.
            # Strip 12 first characters.
            msg = msg[12:]

        if len(msg) < 28:  # Message length 112 bits
            self.msgs_curr_short = self.msgs_curr_short + 1
        else:
            self.msgs_curr_len28 = self.msgs_curr_len28 + 1

        ret_dict['crc'] = self.check_msg(msg)
        if ret_dict['crc']:
            self.parity_check_ok = self.parity_check_ok + 1
        else:
            self.parity_check_ko = self.parity_check_ko + 1

        # Do not manage messages with bad CRC
        if ret_dict['crc'] is not True:
            raise ValueError("CrcKO")

        dfmt = common.df(msg)
        ret_dict['dfmt'] = dfmt
        self.df[dfmt] = self.df[dfmt] + 1

        ret_dict['ic'] = common.icao(msg)

        if dfmt in [17, 18]:  # Downlink format 17 or 18
            tc = common.typecode(msg)
            ret_dict['tc'] = tc
            self.tc[tc] = self.tc[tc] + 1

            lat_ref = float(self.params["lat"])
            long_ref = float(self.params["long"])

            if tc == 4:  # Aircraft identification
                self.msgs_discovered = self.msgs_discovered + 1
                ret_dict['type'] = "CS"
                ret_dict['cs'] = adsb.callsign(msg)
                ca = adsb_ca(msg)
                ret_dict['ca'] = ca_msg[ca]
                self.ca[ca] = self.ca[ca] + 1
            elif 9 <= tc <= 18:
                self.msgs_discovered = self.msgs_discovered + 1
                ret_dict['type'] = "LB"
                ret_dict['altb'] = adsb.altitude(msg)
                (lat, long) = adsb.position_with_ref(msg, lat_ref, long_ref)
                ret_dict['lat'] = lat
                ret_dict['long'] = long
            elif tc == 19:
                self.msgs_discovered = self.msgs_discovered + 1
                ret_dict['type'] = "VH"
                _dict = adsb.velocity(msg)
                if _dict is None:
                    raise ValueError("AdsbVelocity")
                (ret_dict['speed'], ret_dict['head'], ret_dict['rocd'],
                 var) = _dict
                if ret_dict['head'] is None:
                    raise ValueError("AdsbHeading")
                if ret_dict['rocd'] is None:
                    raise ValueError("AdsbRocd")
            elif 20 <= tc <= 22:
                self.msgs_discovered = self.msgs_discovered + 1
                ret_dict['type'] = "LG"
                ret_dict['altg'] = adsb.altitude(msg)
                (lat, long) = adsb.position_with_ref(msg, lat_ref, long_ref)
                ret_dict['lat'] = lat
                ret_dict['long'] = long
        elif dfmt in [5, 21]:
            self.msgs_discovered = self.msgs_discovered + 1
            ret_dict['type'] = "SQ"
            ret_dict['sq'] = common.idcode(msg)

        if dfmt in [0, 4, 16, 20]:
            self.msgs_discovered = self.msgs_discovered + 1
            ret_dict['type'] = "AL"
            _alt = common.altcode(msg)
            alt = _alt if _alt is not None else 0
            ret_dict['alt'] = alt

        return ret_dict
示例#9
0
  def _parse(self, msg_ascii):
    if not msg_ascii or msg_ascii[0] != '*':
      raise ValueError

    msg_hex = msg_ascii[1:].split(';', 1)[0]

    try:
      icao = adsb.icao(msg_hex).lower()
      downlink_format = df(msg_hex)
      type_code = adsb.typecode(msg_hex)
    except:
      raise ValueError

    # version 0 is assumed, so populate it on initialisation
    ac_data = self.positions.get(icao, {"version": 0})

    if downlink_format == 17 or downlink_format == 18:
      # An aircraft airborne position message has downlink format 17 (or 18) with
      # type code from 9 to 18 (baro altitude) or 20 to 22 (GNSS altitude)
      # ref https://mode-s.org/decode/adsb/airborne-position.html
      if ac_data.get("version", None) == 1 and ac_data.get("nic_s", None):
        ac_data["nic"] = adsb.nic_v1(msg_hex, ac_data["nic_s"])

      if (type_code >= 1 and type_code <= 4):
        # Slightly normalise the callsign - it's supposed to only be [0-9A-Z]
        # with space padding. PyModeS uses _ padding, which I think is an older
        # version of the spec.
        ac_data["callsign"] = adsb.callsign(msg_hex).upper().replace("_", " ")[:8]
        ac_data["emitter_category"] = adsb.category(msg_hex)
      elif (type_code >= 9 and type_code <= 18) or (type_code >= 20 and type_code <= 22):
        nuc_p = None
        if ac_data.get("version", None) == 0:
          # In ADSB version 0, the type code encodes the nuc_p (navigational
          # uncertianty category - position) value via this magic lookup table
          nuc_p_lookup = {
            9: 9,
            10: 8,
            11: 7,
            12: 6,
            13: 5,
            14: 4,
            15: 3,
            16: 2,
            17: 1,
            18: 0,
            20: 9,
            21: 8,
            22: 0,
          }
          ac_data["nuc_p"] = nuc_p_lookup.get(type_code, None)

        elif ac_data.get("version", None) == 2:
          ac_data["nic_b"] = adsb.nic_b(msg_hex)

        if ac_data.get("version", None) == 2 and "nic_a" in ac_data.keys() and "nic_c" in ac_data.keys():
          nic_a = ac_data["nic_a"]
          nic_c = ac_data["nic_c"]
          ac_data["nic"] = adsb.nic_v2(msg_hex, nic_a, nic_c)

        # Aircraft position
        if not self.gps.is_fresh():
          #print("aircraft: not updating {0} df={1} tc={2} as my GPS position is unknown ({3})".format(icao, downlink_format, type_code, msg_hex))
          raise ValueError

        # Use the known location of the receiver to calculate the aircraft position
        # from one messsage
        try:
          my_latitude, my_longitude = self.gps.position()
        except NoFixError:
          # For testing
          my_latitude, my_longitude = (51.519559, -0.114227)
          # a rare race condition
          #raise ValueError

        ac_lat, ac_lon = adsb.position_with_ref(msg_hex, my_latitude, my_longitude)
        #print("aircraft: update {0} df={1} tc={2} {3}, {4} ({5})".format(icao, downlink_format, type_code, ac_lat, ac_lon, msg_hex))

        ac_data["lat"] = ac_lat
        ac_data["lon"] = ac_lon

      elif type_code == 19:
        # From the docs: returns speed (kt) ground track or heading (degree),
        # rate of climb/descent (ft/min), speed type (‘GS’ for ground speed,
        # ‘AS’ for airspeed), direction source (‘true_north’ for ground track /
        # true north as refrence, ‘mag_north’ for magnetic north as reference),
        # rate of climb/descent source (‘Baro’ for barometer, ‘GNSS’ for GNSS
        # constellation).
        if ac_data.get("version", None) == 1 or ac_data.get("version", None) == 2:
          ac_data["nac_v"] = adsb.nac_v(msg_hex)

        try:
          (speed, track, climb, speed_source, track_source, climb_source) = adsb.velocity(msg_hex, rtn_sources=True)
          ac_data["speed_h"] = speed
          ac_data["track"] = track
          ac_data["speed_v"] = climb
          ac_data["speed_h_source"] = speed_source
          ac_data["track_source"] = track_source
          ac_data["speed_v_source"] = climb_source
        except TypeError:
          # adsb.velocity can return None
          raise ValueError

      elif type_code == 31:
        # Operational status
        version = adsb.version(msg_hex)
        nic_s = adsb.nic_s(msg_hex)

        # v0 nuc_p is determined by type_code above
        if version == 1:
          try:
            # Is this the right place for nucp? The docs say yes, but one error
            # I've received says 8d3c5ee6f81300000039283c21cf: Not a surface
            # position message (5<TC<8), airborne position message (8<TC<19),
            # or airborne position with GNSS height (20<TC<22)
            nuc_p = adsb.nuc_p(msg_hex)
            nuc_v = adsb.nuc_v(msg_hex)
          except RuntimeError as e:
            print("aircraft: error parsing v1 NUC: {}".format(e))
            raise ValueError

          ac_data["nic_s"] = nic_s
          ac_data["nuc_p"] = nuc_p
          ac_data["nuc_v"] = nuc_v
          ac_data["nac_p"] = adsb.nac_p(msg_hex)
          ac_data["sil"] = adsb.sil(msg_hex, version)
        elif version == 2:
          ac_data["nac_p"] = adsb.nac_p(msg_hex)
          (nic_a, nic_c) = adsb.nic_a_c(msg_hex)
          ac_data["nic_a"] = nic_a
          ac_data["nic_c"] = nic_c
          ac_data["sil"] = adsb.sil(msg_hex, version)

        ac_data["version"] = version
        ac_data["nic_s"] = nic_s
      else:
        raise ValueError

    elif downlink_format == 4 or downlink_format == 20:
      altitude = adsb_common.altcode(msg_hex)
      ac_data["altitude"] = altitude
    else:
      # unsupported message
      raise ValueError

    ac_data["updated"] = datetime.now()
    self.positions[icao] = ac_data
示例#10
0
def tell(msg: str) -> None:
    from pyModeS import common, adsb, commb, bds

    def _print(label, value, unit=None):
        print("%20s: " % label, end="")
        print("%s " % value, end="")
        if unit:
            print(unit)
        else:
            print()

    df = common.df(msg)
    icao = common.icao(msg)

    _print("Message", msg)
    _print("ICAO address", icao)
    _print("Downlink Format", df)

    if df == 17:
        _print("Protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            _print("Type", "Identification and category")
            _print("Callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            _print("Type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Speed", v[0], "knots")
            _print("Track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            _print("Type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 19:
            _print("Type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            _print("Speed", spd, "knots")
            _print("Track", trk, "degrees")
            _print("Vertical rate", vr, "feet/minute")
            _print("Type", types[t])

        if 20 <= tc <= 22:  # airborne position
            _print("Type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            _print("CPR format", "Odd" if oe else "Even")
            _print("CPR Latitude", cprlat)
            _print("CPR Longitude", cprlon)
            _print("Altitude", alt, "feet")

        if tc == 29:  # target state and status
            _print("Type", "Target State and Status")
            subtype = common.bin2int((common.hex2bin(msg)[32:])[5:7])
            _print("Subtype", subtype)
            tcas_operational = adsb.tcas_operational(msg)
            types = {0: "Not Engaged", 1: "Engaged"}
            tcas_operational_types = {0: "Not Operational", 1: "Operational"}
            if subtype == 0:
                emergency_types = {
                    0: "No emergency",
                    1: "General emergency",
                    2: "Lifeguard/medical emergency",
                    3: "Minimum fuel",
                    4: "No communications",
                    5: "Unlawful interference",
                    6: "Downed aircraft",
                    7: "Reserved"
                }
                vertical_horizontal_types = {
                    1: "Acquiring mode",
                    2: "Capturing/Maintaining mode"
                }
                tcas_ra_types = {0: "Not active", 1: "Active"}
                alt, alt_source, alt_ref = adsb.target_altitude(msg)
                angle, angle_type, angle_source = adsb.target_angle(msg)
                vertical_mode = adsb.vertical_mode(msg)
                horizontal_mode = adsb.horizontal_mode(msg)
                tcas_ra = adsb.tcas_ra(msg)
                emergency_status = adsb.emergency_status(msg)
                _print("Target altitude", alt, "feet")
                _print("Altitude source", alt_source)
                _print("Altitude reference", alt_ref)
                _print("Angle", angle, "°")
                _print("Angle Type", angle_type)
                _print("Angle Source", angle_source)
                _print("Vertical mode",
                       vertical_horizontal_types[vertical_mode])
                _print("Horizontal mode",
                       vertical_horizontal_types[horizontal_mode])
                _print("TCAS/ACAS", tcas_operational_types[tcas_operational])
                _print("TCAS/ACAS RA", tcas_ra_types[tcas_ra])
                _print("Emergency status", emergency_types[emergency_status])
            else:
                alt, alt_source = adsb.selected_altitude(msg)
                baro = adsb.baro_pressure_setting(msg)
                hdg = adsb.selected_heading(msg)
                autopilot = adsb.autopilot(msg)
                vnav = adsb.vnav_mode(msg)
                alt_hold = adsb.altitude_hold_mode(msg)
                app = adsb.approach_mode(msg)
                lnav = adsb.lnav_mode(msg)
                _print("Selected altitude", alt, "feet")
                _print("Altitude source", alt_source)
                _print("Barometric pressure setting", baro, "millibars")
                _print("Selected Heading", hdg, "°")
                if not (common.bin2int((common.hex2bin(msg)[32:])[46]) == 0):
                    _print("Autopilot", types[autopilot])
                    _print("VNAV mode", types[vnav])
                    _print("Altitude hold mode", types[alt_hold])
                    _print("Approach mode", types[app])
                    _print("TCAS/ACAS",
                           tcas_operational_types[tcas_operational])
                    _print("LNAV mode", types[lnav])

    if df == 20:
        _print("Protocol", "Mode-S Comm-B altitude reply")
        _print("Altitude", common.altcode(msg), "feet")

    if df == 21:
        _print("Protocol", "Mode-S Comm-B identity reply")
        _print("Squawk code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            _print("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            _print("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            _print("Callsign", callsign)

        if BDS == "BDS40":
            _print("MCP target alt", commb.selalt40mcp(msg), "feet")
            _print("FMS Target alt", commb.selalt40fms(msg), "feet")
            _print("Pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            _print("Roll angle", commb.roll50(msg), "degrees")
            _print("Track angle", commb.trk50(msg), "degrees")
            _print("Track rate", commb.rtrk50(msg), "degree/second")
            _print("Ground speed", commb.gs50(msg), "knots")
            _print("True airspeed", commb.tas50(msg), "knots")

        if BDS == "BDS60":
            _print("Megnatic Heading", commb.hdg60(msg), "degrees")
            _print("Indicated airspeed", commb.ias60(msg), "knots")
            _print("Mach number", commb.mach60(msg))
            _print("Vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            _print("Vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            _print("Wind speed", commb.wind44(msg)[0], "knots")
            _print("Wind direction", commb.wind44(msg)[1], "degrees")
            _print("Temperature 1", commb.temp44(msg)[0], "Celsius")
            _print("Temperature 2", commb.temp44(msg)[1], "Celsius")
            _print("Pressure", commb.p44(msg), "hPa")
            _print("Humidity", commb.hum44(msg), "%")
            _print("Turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            _print("Turbulence", commb.turb45(msg))
            _print("Wind shear", commb.ws45(msg))
            _print("Microbust", commb.mb45(msg))
            _print("Icing", commb.ic45(msg))
            _print("Wake vortex", commb.wv45(msg))
            _print("Temperature", commb.temp45(msg), "Celsius")
            _print("Pressure", commb.p45(msg), "hPa")
            _print("Radio height", commb.rh45(msg), "feet")
示例#11
0
文件: run.py 项目: astrofrog/pyModeS
def test_adsb_velocity():
    vgs = adsb.velocity("8D485020994409940838175B284F")
    vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
    assert vgs == (159, 182.9, -263, 'GS')
    assert vas == (376, 244.0, -274, 'AS')
示例#12
0
def get_all(msg: str) -> dict:
    from pyModeS import common, adsb, commb, bds
    _dict = {}

    def push(key, data, unit=None):
        _dict[key] = data

    df = common.df(msg)
    icao = common.icao(msg)

    push("message", msg)
    push("icao", icao)
    push("downlink_format", df)

    if df == 17:
        push("protocol", "Mode-S Extended Squitter (ADS-B)")

        tc = common.typecode(msg)
        if 1 <= tc <= 4:  # callsign
            callsign = adsb.callsign(msg)
            push("type", "Identitification and category")
            push("callsign:", callsign)

        if 5 <= tc <= 8:  # surface position
            push("type", "Surface position")
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            v = adsb.surface_velocity(msg)
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("speed", v[0] * 1.85200, "km")
            push("track", v[1], "degrees")

        if 9 <= tc <= 18:  # airborne position
            push("type", "Airborne position (with barometric altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("altitude", alt, "feet")

        if tc == 19:
            push("type", "Airborne velocity")
            spd, trk, vr, t = adsb.velocity(msg)
            types = {"GS": "Ground speed", "TAS": "True airspeed"}
            push("speed", spd * 1.85200, "km")
            push("track", trk, "degrees")
            push("vertical rate", vr, "feet/minute")
            push("type", types[t])

        if 20 <= tc <= 22:  # airborne position
            push("type", "Airborne position (with GNSS altitude)")
            alt = adsb.altitude(msg)
            oe = adsb.oe_flag(msg)
            msgbin = common.hex2bin(msg)
            cprlat = common.bin2int(msgbin[54:71]) / 131072.0
            cprlon = common.bin2int(msgbin[71:88]) / 131072.0
            push("cpr_format", "Odd" if oe else "Even")
            push("cpr_latitude", cprlat)
            push("cpr_longitude", cprlon)
            push("altitude", alt, "feet")

        if tc == 29:  # target state and status
            push("type", "Target State and Status")
            subtype = common.bin2int((common.hex2bin(msg)[32:])[5:7])
            push("subtype", subtype)
            tcas_operational = adsb.tcas_operational(msg)
            types = {0: "Not Engaged", 1: "Engaged"}
            tcas_operational_types = {0: "Not Operational", 1: "Operational"}
            if subtype == 0:
                emergency_types = {
                    0: "No emergency",
                    1: "General emergency",
                    2: "Lifeguard/medical emergency",
                    3: "Minimum fuel",
                    4: "No communications",
                    5: "Unlawful interference",
                    6: "Downed aircraft",
                    7: "Reserved"
                }
                vertical_horizontal_types = {
                    1: "Acquiring mode",
                    2: "Capturing/Maintaining mode"
                }
                tcas_ra_types = {0: "Not active", 1: "Active"}
                altitude = adsb.target_altitude(msg)
                if altitude is not None:
                    alt, alt_source, alt_ref = altitude
                angle, angle_type, angle_source = adsb.target_angle(msg)
                vertical_mode = adsb.vertical_mode(msg)
                horizontal_mode = adsb.horizontal_mode(msg)
                tcas_ra = adsb.tcas_ra(msg)
                emergency_status = adsb.emergency_status(msg)
                push("target_altitude", alt, "feet")
                push("altitude_source", alt_source)
                push("altitude_reference", alt_ref)
                push("angle", angle, "°")
                push("angle Type", angle_type)
                push("angle Source", angle_source)
                push("vertical mode", vertical_horizontal_types[vertical_mode])
                push("horizontal mode", vertical_horizontal_types[horizontal_mode])
                push("TCAS/ACAS", tcas_operational_types[tcas_operational])
                push("TCAS/ACAS_RA", tcas_ra_types[tcas_ra])
                push("emergency_status", emergency_types[emergency_status])
            else:
                alt, alt_source = adsb.selected_altitude(msg)
                baro = adsb.baro_pressure_setting(msg)
                hdg = adsb.selected_heading(msg)
                autopilot = adsb.autopilot(msg)
                vnav = adsb.vnav_mode(msg)
                alt_hold = adsb.altitude_hold_mode(msg)
                app = adsb.approach_mode(msg)
                lnav = adsb.lnav_mode(msg)
                push("selected_altitude", alt, "feet")
                push("altitude_source", alt_source)
                push("barometric_pressure_setting", baro, "millibars")
                push("selected_Heading", hdg, "°")
                if not (common.bin2int((common.hex2bin(msg)[32:])[46]) == 0):
                    push("autopilot", types[autopilot])
                    push("VNAV_mode", types[vnav])
                    push("altitude_hold_mode", types[alt_hold])
                    push("approach_mode", types[app])
                    push("TCAS/ACAS", tcas_operational_types[tcas_operational])
                    push("LNAV_mode", types[lnav])

    if df == 20:
        push("protocol", "Mode-S Comm-B altitude reply")
        push("altitude", common.altcode(msg), "feet")

    if df == 21:
        push("protocol", "Mode-S Comm-B identity reply")
        push("squawk_code", common.idcode(msg))

    if df == 20 or df == 21:
        labels = {
            "BDS10": "Data link capability",
            "BDS17": "GICB capability",
            "BDS20": "Aircraft identification",
            "BDS30": "ACAS resolution",
            "BDS40": "Vertical intention report",
            "BDS50": "Track and turn report",
            "BDS60": "Heading and speed report",
            "BDS44": "Meteorological routine air report",
            "BDS45": "Meteorological hazard report",
            "EMPTY": "[No information available]",
        }

        BDS = bds.infer(msg, mrar=True)
        if BDS in labels.keys():
            push("BDS", "%s (%s)" % (BDS, labels[BDS]))
        else:
            push("BDS", BDS)

        if BDS == "BDS20":
            callsign = commb.cs20(msg)
            push("callsign", callsign)

        if BDS == "BDS40":
            push("MCP_target_alt", commb.selalt40mcp(msg), "feet")
            push("FMS_Target_alt", commb.selalt40fms(msg), "feet")
            push("pressure", commb.p40baro(msg), "millibar")

        if BDS == "BDS50":
            push("roll_angle", commb.roll50(msg), "degrees")
            push("track_angle", commb.trk50(msg), "degrees")
            push("track_rate", commb.rtrk50(msg), "degree/second")
            push("ground_speed", commb.gs50(msg)  * 1.85200, "km")
            push("true_airspeed", commb.tas50(msg)  * 1.85200, "km")

        if BDS == "BDS60":
            push("megnatic Heading", commb.hdg60(msg), "degrees")
            push("indicated airspeed", commb.ias60(msg)  * 1.85200, "km")
            push("mach number", commb.mach60(msg))
            push("vertical rate (Baro)", commb.vr60baro(msg), "feet/minute")
            push("vertical rate (INS)", commb.vr60ins(msg), "feet/minute")

        if BDS == "BDS44":
            push("wind_speed", commb.wind44(msg)[0]  * 1.85200, "km")
            push("wind_direction", commb.wind44(msg)[1], "degrees")
            push("temperature_1", commb.temp44(msg)[0], "Celsius")
            push("temperature_2", commb.temp44(msg)[1], "Celsius")
            push("pressure", commb.p44(msg), "hPa")
            push("humidity", commb.hum44(msg), "%")
            push("turbulence", commb.turb44(msg))

        if BDS == "BDS45":
            push("turbulence", commb.turb45(msg))
            push("wind_shear", commb.ws45(msg))
            push("microbust", commb.mb45(msg))
            push("icing", commb.ic45(msg))
            push("wake_vortex", commb.wv45(msg))
            push("temperature", commb.temp45(msg), "Celsius")
            push("pressure", commb.p45(msg), "hPa")
            push("radio_height", commb.rh45(msg), "feet")

    return _dict