Merge branch 'master' into qtapp
This commit is contained in:
commit
73ca9e373e
8
README
8
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
|
in Australia. North American implementation is still voluntary, with
|
||||||
a mandate arriving in 2020 via the FAA's "NextGen" program.
|
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
|
devices, although the "RTLSDR" receivers are also supported via the
|
||||||
Osmocom driver. In theory, any receiver which outputs complex samples at
|
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
|
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
|
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:
|
run:
|
||||||
|
|
||||||
$ uhd_modes.py --help
|
$ modes_rx --help
|
||||||
|
|
||||||
For use with Ettus UHD-compatible devices, the defaults should suffice
|
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
|
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:
|
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
|
* apps/get_correlated_records.py: Demonstration program for computing
|
||||||
multilaterated time error for two unsynchronized receiver stations.
|
multilaterated time error for two unsynchronized receiver stations.
|
||||||
* lib/air_modes_int_and_dump.cc: Unused integrate-and-dump filter for
|
* lib/air_modes_int_and_dump.cc: Unused integrate-and-dump filter for
|
||||||
|
@ -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
|
//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) {
|
if(ninputs-i < 240*d_samples_per_chip) {
|
||||||
consume_each(i-1);
|
consume_each(std::max(i-1,0));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class output_kml(threading.Thread):
|
|||||||
bearing = i*(2*math.pi/steps) #in radians
|
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)))
|
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))))
|
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)
|
retstr = string.lstrip(retstr)
|
||||||
return retstr
|
return retstr
|
||||||
@ -150,7 +150,7 @@ class output_kml(threading.Thread):
|
|||||||
heading = 0
|
heading = 0
|
||||||
vertical = 0
|
vertical = 0
|
||||||
#now generate some KML
|
#now generate some KML
|
||||||
retstr+= "\n\t\t<Placemark>\n\t\t\t<name>%s</name>\n\t\t\t<styleUrl>#airplane</styleUrl>\n\t\t\t<description>\n\t\t\t\t<![CDATA[Altitude: %s<br/>Heading: %i<br/>Speed: %i<br/>Vertical speed: %i<br/>ICAO: %x<br/>Last seen: %s]]>\n\t\t\t</description>\n\t\t\t<Point>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<extrude>1</extrude>\n\t\t\t\t<coordinates>%s,%s,%i</coordinates>\n\t\t\t</Point>\n\t\t</Placemark>" % (ident, alt, heading, speed, vertical, icao[0], seen, lon, lat, metric_alt, )
|
retstr+= "\n\t\t<Placemark>\n\t\t\t<name>%s</name>\n\t\t\t<Style><IconStyle><heading>%i</heading></IconStyle></Style>\n\t\t\t<styleUrl>#airplane</styleUrl>\n\t\t\t<description>\n\t\t\t\t<![CDATA[Altitude: %s<br/>Heading: %i<br/>Speed: %i<br/>Vertical speed: %i<br/>ICAO: %x<br/>Last seen: %s]]>\n\t\t\t</description>\n\t\t\t<Point>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<extrude>1</extrude>\n\t\t\t\t<coordinates>%s,%s,%i</coordinates>\n\t\t\t</Point>\n\t\t</Placemark>" % (ident, heading, alt, heading, speed, vertical, icao[0], seen, lon, lat, metric_alt, )
|
||||||
|
|
||||||
retstr+= "\n\t\t<Placemark>\n\t\t\t<styleUrl>#track</styleUrl>\n\t\t\t<LineString>\n\t\t\t\t<extrude>0</extrude>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<coordinates>%s</coordinates>\n\t\t\t</LineString>\n\t\t</Placemark>" % (trackstr,)
|
retstr+= "\n\t\t<Placemark>\n\t\t\t<styleUrl>#track</styleUrl>\n\t\t\t<LineString>\n\t\t\t\t<extrude>0</extrude>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<coordinates>%s</coordinates>\n\t\t\t</LineString>\n\t\t</Placemark>" % (trackstr,)
|
||||||
|
|
||||||
|
@ -36,11 +36,10 @@ class output_print(air_modes.parse):
|
|||||||
reference = float(reference)
|
reference = float(reference)
|
||||||
timestamp = float(timestamp)
|
timestamp = float(timestamp)
|
||||||
|
|
||||||
#TODO this is suspect
|
|
||||||
if reference == 0.0:
|
if reference == 0.0:
|
||||||
refdb = -150.0
|
refdb = -150.0
|
||||||
else:
|
else:
|
||||||
refdb = 10.0*math.log10(reference)
|
refdb = 20.0*math.log10(reference)
|
||||||
output = "(%.0f %.10f) " % (refdb, timestamp);
|
output = "(%.0f %.10f) " % (refdb, timestamp);
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -161,10 +160,18 @@ class output_print(air_modes.parse):
|
|||||||
|
|
||||||
elif bdsreg == 0x09:
|
elif bdsreg == 0x09:
|
||||||
subtype = data["bds09"].get_type()
|
subtype = data["bds09"].get_type()
|
||||||
if subtype == 0 or subtype == 1:
|
if subtype == 0:
|
||||||
parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1
|
[velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data)
|
||||||
[velocity, heading, vert_spd] = parser(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)
|
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:
|
else:
|
||||||
retstr = "Type 17 BDS0,9-%i from %x not implemented" % (subtype, icao24)
|
retstr = "Type 17 BDS0,9-%i from %x not implemented" % (subtype, icao24)
|
||||||
|
|
||||||
|
@ -345,6 +345,21 @@ class parse:
|
|||||||
|
|
||||||
return [velocity, heading, vert_spd]
|
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):
|
def parseBDS62(self, data):
|
||||||
eps_strings = ["NO EMERGENCY", "GENERAL EMERGENCY", "LIFEGUARD/MEDICAL", "FUEL EMERGENCY",
|
eps_strings = ["NO EMERGENCY", "GENERAL EMERGENCY", "LIFEGUARD/MEDICAL", "FUEL EMERGENCY",
|
||||||
"NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"]
|
"NO COMMUNICATIONS", "UNLAWFUL INTERFERENCE", "RESERVED", "RESERVED"]
|
||||||
|
@ -146,7 +146,7 @@ class output_sbs1(air_modes.parse):
|
|||||||
def pp5(self, shortdata, ecc):
|
def pp5(self, shortdata, ecc):
|
||||||
# I'm not sure what to do with the identiifcation shortdata & 0x1FFF
|
# I'm not sure what to do with the identiifcation shortdata & 0x1FFF
|
||||||
[datestr, timestr] = self.current_time()
|
[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)
|
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)
|
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"
|
return retstr + self.decode_fs(fs) + "\n"
|
||||||
|
@ -125,9 +125,13 @@ class output_sql(air_modes.parse):
|
|||||||
|
|
||||||
elif bdsreg == 0x09:
|
elif bdsreg == 0x09:
|
||||||
subtype = data["bds09"].get_type()
|
subtype = data["bds09"].get_type()
|
||||||
if subtype == 0 or subtype == 1:
|
if subtype == 0:
|
||||||
parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1
|
[velocity, heading, vert_spd, turnrate] = self.parseBDS09_0(data)
|
||||||
[velocity, heading, vert_spd] = parser(data)
|
|
||||||
retstr = "INSERT INTO vectors (icao, seen, speed, heading, vertical) VALUES (" + "%i" % icao24 + ", datetime('now'), " + "%.0f" % velocity + ", " + "%.0f" % heading + ", " + "%.0f" % vert_spd + ")"
|
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
|
return retstr
|
||||||
|
Loading…
Reference in New Issue
Block a user