diff --git a/README b/README index fda0589..c3201e4 100644 --- a/README +++ b/README @@ -65,7 +65,7 @@ Implementation of ADS-B is mandatory in European airspace as well as in Australia. North American implementation is still voluntary, with a mandate arriving in 2020 via the FAA's "NextGen" program. -The receiver uhd_modes.py is written for use with Ettus Research USRP +The receiver modes_rx is written for use with Ettus Research USRP devices, although the "RTLSDR" receivers are also supported via the Osmocom driver. In theory, any receiver which outputs complex samples at at least 2Msps should work via the file input or UDP input options, or @@ -122,10 +122,10 @@ install it on your system, generally in /usr/local/bin. ======================================================================== USAGE -The main application is uhd_modes.py. For a complete list of options, +The main application is modes_rx. For a complete list of options, run: -$ uhd_modes.py --help +$ modes_rx --help For use with Ettus UHD-compatible devices, the defaults should suffice to receive reports and print to the screen. Use the -d option to look @@ -141,7 +141,7 @@ FILES Interesting files and libraries included with the package: -* apps/uhd_modes.py: The main application. +* apps/modes_rx: The main application. * apps/get_correlated_records.py: Demonstration program for computing multilaterated time error for two unsynchronized receiver stations. * lib/air_modes_int_and_dump.cc: Unused integrate-and-dump filter for diff --git a/lib/air_modes_preamble.cc b/lib/air_modes_preamble.cc index 8046d78..6bcf2e6 100644 --- a/lib/air_modes_preamble.cc +++ b/lib/air_modes_preamble.cc @@ -157,7 +157,7 @@ int air_modes_preamble::general_work(int noutput_items, //be sure we've got enough room in the input buffer to copy out a whole packet if(ninputs-i < 240*d_samples_per_chip) { - consume_each(i-1); + consume_each(std::max(i-1,0)); return 0; } diff --git a/python/kml.py b/python/kml.py index 0eca9e9..3182113 100644 --- a/python/kml.py +++ b/python/kml.py @@ -73,7 +73,7 @@ class output_kml(threading.Thread): bearing = i*(2*math.pi/steps) #in radians lat_out = math.degrees(math.asin(math.sin(lat_rad)*math.cos(tmp0) + math.cos(lat_rad)*math.sin(tmp0)*math.cos(bearing))) lon_out = center_lon + math.degrees(math.atan2(math.sin(bearing)*math.sin(tmp0)*math.cos(lat_rad), math.cos(tmp0)-math.sin(lat_rad)*math.sin(math.radians(lat_out)))) - retstr += " %.8f, %.8f, 0" % (lon_out, lat_out,) + retstr += " %.8f,%.8f, 0" % (lon_out, lat_out,) retstr = string.lstrip(retstr) return retstr @@ -150,7 +150,7 @@ class output_kml(threading.Thread): heading = 0 vertical = 0 #now generate some KML - retstr+= "\n\t\t\n\t\t\t%s\n\t\t\t#airplane\n\t\t\t\n\t\t\t\tHeading: %i
Speed: %i
Vertical speed: %i
ICAO: %x
Last seen: %s]]>\n\t\t\t
\n\t\t\t\n\t\t\t\tabsolute\n\t\t\t\t1\n\t\t\t\t%s,%s,%i\n\t\t\t\n\t\t
" % (ident, alt, heading, speed, vertical, icao[0], seen, lon, lat, metric_alt, ) + retstr+= "\n\t\t\n\t\t\t%s\n\t\t\t\n\t\t\t#airplane\n\t\t\t\n\t\t\t\tHeading: %i
Speed: %i
Vertical speed: %i
ICAO: %x
Last seen: %s]]>\n\t\t\t
\n\t\t\t\n\t\t\t\tabsolute\n\t\t\t\t1\n\t\t\t\t%s,%s,%i\n\t\t\t\n\t\t
" % (ident, heading, alt, heading, speed, vertical, icao[0], seen, lon, lat, metric_alt, ) retstr+= "\n\t\t\n\t\t\t#track\n\t\t\t\n\t\t\t\t0\n\t\t\t\tabsolute\n\t\t\t\t%s\n\t\t\t\n\t\t" % (trackstr,) diff --git a/python/msprint.py b/python/msprint.py index 6858e0c..169337f 100644 --- a/python/msprint.py +++ b/python/msprint.py @@ -36,11 +36,10 @@ class output_print(air_modes.parse): reference = float(reference) timestamp = float(timestamp) - #TODO this is suspect if reference == 0.0: refdb = -150.0 else: - refdb = 10.0*math.log10(reference) + refdb = 20.0*math.log10(reference) output = "(%.0f %.10f) " % (refdb, timestamp); try: @@ -161,10 +160,18 @@ class output_print(air_modes.parse): elif bdsreg == 0x09: subtype = data["bds09"].get_type() - if subtype == 0 or subtype == 1: - parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1 - [velocity, heading, vert_spd] = parser(data) + if subtype == 0: + [velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data) + retstr = "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f turn rate %.0f" \ + % (subtype, icao24, velocity, heading, vert_spd, turnrate) + elif subtype == 1: + [velocity, heading, vert_spd] = self.parseBDS09_1(data) retstr = "Type 17 BDS0,9-%i (track report) from %x with velocity %.0fkt heading %.0f VS %.0f" % (subtype, icao24, velocity, heading, vert_spd) + elif subtype == 3: + [mag_hdg, vel_src, vel, vert_spd, geo_diff] = self.parseBDS09_3(data) + retstr = "Type 17 BDS0,9-%i (air course report) from %x with %s %.0fkt magnetic heading %.0f VS %.0f geo. diff. from baro. alt. %.0fft" \ + % (subtype, icao24, vel_src, vel, mag_hdg, vert_spd, geo_diff) + else: retstr = "Type 17 BDS0,9-%i from %x not implemented" % (subtype, icao24) diff --git a/python/parse.py b/python/parse.py index f5b8502..506aec0 100644 --- a/python/parse.py +++ b/python/parse.py @@ -345,6 +345,21 @@ class parse: return [velocity, heading, vert_spd] + def parseBDS09_3(self, data): + #3: {"sub", "icf", "ifr", "nuc", "mhs", "hdg", "ast", "spd", "vrsrc", + # "dvr", "vr", "dhd", "hd"} + mag_hdg = data["mhs"] * 360. / 1024 + vel_src = "TAS" if data["ast"] == 1 else "IAS" + vel = data["spd"] + if data["sub"] == 4: + vel *= 4 + vert_spd = float(data["vr"] - 1) * 64 + if data["dvr"] == 1: + vert_spd = 0 - vert_spd + geo_diff = float(data["hd"] - 1) * 25 + return [mag_hdg, vel_src, vel, vert_spd, geo_diff] + + def parseBDS62(self, data): eps_strings = ["NO EMERGENCY", "GENERAL EMERGENCY", "LIFEGUARD/MEDICAL", "FUEL EMERGENCY", "NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"] diff --git a/python/sbs1.py b/python/sbs1.py index 3077de2..0f9638d 100644 --- a/python/sbs1.py +++ b/python/sbs1.py @@ -146,7 +146,7 @@ class output_sbs1(air_modes.parse): def pp5(self, shortdata, ecc): # I'm not sure what to do with the identiifcation shortdata & 0x1FFF [datestr, timestr] = self.current_time() - [fs, dr, um] = self.parse5(shortdata) + [fs, dr, um, ident] = self.parse5(shortdata) aircraft_id = self.get_aircraft_id(ecc) retstr = "MSG,6,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr) return retstr + self.decode_fs(fs) + "\n" diff --git a/python/sql.py b/python/sql.py index 765c626..589f30d 100644 --- a/python/sql.py +++ b/python/sql.py @@ -125,9 +125,13 @@ class output_sql(air_modes.parse): elif bdsreg == 0x09: subtype = data["bds09"].get_type() - if subtype == 0 or subtype == 1: - parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1 - [velocity, heading, vert_spd] = parser(data) + if subtype == 0: + [velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data) retstr = "INSERT INTO vectors (icao, seen, speed, heading, vertical) VALUES (" + "%i" % icao24 + ", datetime('now'), " + "%.0f" % velocity + ", " + "%.0f" % heading + ", " + "%.0f" % vert_spd + ")" - + elif subtype == 1: + [velocity, heading, vert_spd] = self.parseBDS09_1(data) + retstr = "INSERT INTO vectors (icao, seen, speed, heading, vertical) VALUES (" + "%i" % icao24 + ", datetime('now'), " + "%.0f" % velocity + ", " + "%.0f" % heading + ", " + "%.0f" % vert_spd + ")" + else: + retstr = None + return retstr