Merge branch 'master' into qtapp

Conflicts:
	CMakeLists.txt
	lib/air_modes_preamble.cc
	python/sql.py
This commit is contained in:
Johnathan Corgan 2012-10-07 17:54:03 -07:00
commit f18d111e1c
9 changed files with 56 additions and 32 deletions

View File

@ -22,7 +22,9 @@
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.6)
project(gr-air-modes CXX)
project(gr-gr-air-modes CXX)
set(gr-gr-air-modes_VERSION_MAJOR 0)
set(gr-gr-air-modes_VERSION_MINOR 0)
enable_testing()
#select the release build type by default to get optimization flags

View File

@ -1,11 +1,11 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_CORE gnuradio-core QUIET)
PKG_CHECK_MODULES(PC_GNURADIO_CORE gnuradio-core)
FIND_PATH(
GNURADIO_CORE_INCLUDE_DIRS
NAMES gr_random.h
HINTS $ENV{GNURADIO_CORE_DIR}/include/gnuradio
${PC_GNURADIO_CORE_INCLUDE_DIR}
${PC_GNURADIO_CORE_INCLUDEDIR}
PATHS /usr/local/include/gnuradio
/usr/include/gnuradio
)

View File

@ -1,11 +1,11 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GRUEL gnuradio-core QUIET)
PKG_CHECK_MODULES(PC_GRUEL gnuradio-core)
FIND_PATH(
GRUEL_INCLUDE_DIRS
NAMES gruel/attributes.h
HINTS $ENV{GRUEL_DIR}/include
${PC_GRUEL_INCLUDE_DIR}
${PC_GRUEL_INCLUDEDIR}
PATHS /usr/local/include
/usr/include
)

View File

@ -29,6 +29,8 @@ add_library(air_modes SHARED
)
target_link_libraries(air_modes ${Boost_LIBRARIES} ${GRUEL_LIBRARIES} ${GNURADIO_CORE_LIBRARIES})
set_target_properties(air_modes PROPERTIES DEFINE_SYMBOL "AIR_MODES_EXPORTS")
set_target_properties(air_modes PROPERTIES SOVERSION "${gr-gr-air-modes_VERSION_MAJOR}")
set_target_properties(air_modes PROPERTIES VERSION "${gr-gr-air-modes_VERSION_MAJOR}.${gr-gr-air-modes_VERSION_MINOR}")
########################################################################
# Install built library files

View File

@ -53,7 +53,7 @@ air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) :
str << name() << unique_id();
d_me = pmt::pmt_string_to_symbol(str.str());
d_key = pmt::pmt_string_to_symbol("preamble_found");
set_history(d_check_width);
set_history(d_samples_per_symbol);
}
static void integrate_and_dump(float *out, const float *in, int chips, int samps_per_chip) {
@ -101,7 +101,13 @@ int air_modes_preamble::general_work(int noutput_items,
{
const float *in = (const float *) input_items[0];
const float *inavg = (const float *) input_items[1];
const int ninputs = std::min(ninput_items[0], ninput_items[1]); //just in case
int mininputs = std::min(ninput_items[0], ninput_items[1]); //they should be matched but let's be safe
//round number of input samples down to nearest d_samples_per_chip
//we also subtract off d_samples_per_chip to allow the bit center finder some leeway
const int ninputs = std::max(mininputs - (mininputs % d_samples_per_chip) - d_samples_per_chip, 0);
if (ninputs <= 0) { consume_each(0); return 0; }
float *out = (float *) output_items[0];
if(0) std::cout << "Preamble called with " << ninputs << " samples" << std::endl;
@ -132,15 +138,18 @@ int air_modes_preamble::general_work(int noutput_items,
//get a more accurate bit center by finding the correlation peak across all four preamble bits
bool late, early;
int how_late = 0;
do {
double now_corr = correlate_preamble(in+i, d_samples_per_chip);
double late_corr = correlate_preamble(in+i+1, d_samples_per_chip);
double early_corr = correlate_preamble(in+i-1, d_samples_per_chip);
late = (late_corr > now_corr);
//early = (early_corr > now_corr);
if(late) i++;
if(late) { i++; how_late++; }
//if(early && i>0) { std::cout << "EARLY " << i << std::endl; i--; }
} while(late);// xor early);
} while(late and how_late < d_samples_per_chip);// xor early);
if(0) std::cout << "We were " << how_late << " samples late" << std::endl;
//now check to see that the non-peak symbols in the preamble
//are below the peaks by threshold dB
@ -160,6 +169,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(std::max(i-1,0));
if(0) std::cout << "Preamble consumed " << std::max(i-1,0) << ", returned 0 (no room)" << std::endl;
return 0;
}
@ -190,7 +200,8 @@ int air_modes_preamble::general_work(int noutput_items,
//std::cout << "PREAMBLE" << std::endl;
//produce only one output per work call -- TODO this should probably change
if(0) std::cout << "Preamble consumed " << i+240*d_samples_per_chip << ", returned 240" << std::endl;
if(0) std::cout << "Preamble consumed " << i+240*d_samples_per_chip << "with i=" << i << ", returned 240" << std::endl;
consume_each(i+240*d_samples_per_chip);
return 240;
}

View File

@ -93,14 +93,14 @@ class output_kml(threading.Thread):
#read the database and add KML
q = "select distinct icao from positions where seen > datetime('now', '-5 minute')"
c = self._db.cursor()
c.execute(q)
self.locked_execute(c, q)
icaolist = c.fetchall()
#now we have a list icaolist of all ICAOs seen in the last 5 minutes
for icao in icaolist:
#print "ICAO: %x" % icao
q = "select * from positions where icao=%i and seen > datetime('now', '-2 hour') ORDER BY seen DESC" % icao
c.execute(q)
self.locked_execute(c, q)
track = c.fetchall()
#print "Track length: %i" % len(track)
if len(track) != 0:
@ -128,7 +128,7 @@ class output_kml(threading.Thread):
#now get metadata
q = "select ident from ident where icao=%i" % icao
c.execute(q)
self.locked_execute(c, q)
r = c.fetchall()
if len(r) != 0:
ident = r[0][0]
@ -136,7 +136,7 @@ class output_kml(threading.Thread):
#if ident is None: ident = ""
#get most recent speed/heading/vertical
q = "select seen, speed, heading, vertical from vectors where icao=%i order by seen desc limit 1" % icao
c.execute(q)
self.locked_execute(c, q)
r = c.fetchall()
if len(r) != 0:
seen = r[0][0]

View File

@ -180,7 +180,7 @@ class output_print(air_modes.parse):
retstr = "Type 17 BDS6,2 (emergency) from %x type %s" % (icao24, emerg_str)
else:
retstr = "Type 17 subtype %i from %x not implemented" % (subtype, icao24)
retstr = "Type 17 with FTC=%i from %x not implemented" % (data["ftc"], icao24)
return retstr

View File

@ -131,9 +131,9 @@ class output_sbs1(air_modes.parse):
aircraft_id = self.get_aircraft_id(ecc)
retstr = "MSG,7,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, altitude)
if vs:
retstr += "1\n"
retstr += "1\r\n"
else:
retstr += "0\n"
retstr += "0\r\n"
return retstr
def pp4(self, shortdata, ecc):
@ -141,7 +141,7 @@ class output_sbs1(air_modes.parse):
[fs, dr, um, altitude] = self.parse4(shortdata)
aircraft_id = self.get_aircraft_id(ecc)
retstr = "MSG,5,0,%i,%06X,%i,%s,%s,%s,%s,,%s,,,,,,," % (aircraft_id, ecc, aircraft_id+100, datestr, timestr, datestr, timestr, altitude)
return retstr + self.decode_fs(fs) + "\n"
return retstr + self.decode_fs(fs) + "\r\n"
def pp5(self, shortdata, ecc):
# I'm not sure what to do with the identiifcation shortdata & 0x1FFF
@ -149,13 +149,13 @@ class output_sbs1(air_modes.parse):
[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"
return retstr + self.decode_fs(fs) + "\r\n"
def pp11(self, shortdata, ecc):
[datestr, timestr] = self.current_time()
[icao24, interrogator, ca] = self.parse11(shortdata, ecc)
aircraft_id = self.get_aircraft_id(icao24)
return "MSG,8,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,,,,,\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr)
return "MSG,8,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr)
def pp17(self, data):
icao24 = data["aa"]
@ -170,7 +170,7 @@ class output_sbs1(air_modes.parse):
if bdsreg == 0x08:
# Aircraft Identification
(msg, typestring) = self.parseBDS08(data)
retstr = "MSG,1,0,%i,%06X,%i,%s,%s,%s,%s,%s,,,,,,,,,,,\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, msg)
retstr = "MSG,1,0,%i,%06X,%i,%s,%s,%s,%s,%s,,,,,,,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, msg)
elif bdsreg == 0x06:
# Surface position measurement
@ -179,7 +179,7 @@ class output_sbs1(air_modes.parse):
if decoded_lat is None: #no unambiguously valid position available
retstr = None
else:
retstr = "MSG,2,0,%i,%06X,%i,%s,%s,%s,%s,,%i,,,%.5f,%.5f,,,,0,0,0\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, altitude, decoded_lat, decoded_lon)
retstr = "MSG,2,0,%i,%06X,%i,%s,%s,%s,%s,,%i,,,%.5f,%.5f,,,,0,0,0\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, altitude, decoded_lat, decoded_lon)
elif bdsreg == 0x05:
# Airborne position measurements
@ -188,7 +188,7 @@ class output_sbs1(air_modes.parse):
if decoded_lat is None: #no unambiguously valid position available
retstr = None
else:
retstr = "MSG,3,0,%i,%06X,%i,%s,%s,%s,%s,,%i,,,%.5f,%.5f,,,,0,0,0\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, altitude, decoded_lat, decoded_lon)
retstr = "MSG,3,0,%i,%06X,%i,%s,%s,%s,%s,,%i,,,%.5f,%.5f,,,,0,0,0\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, altitude, decoded_lat, decoded_lon)
elif bdsreg == 0x09:
# Airborne velocity measurements
@ -197,6 +197,6 @@ class output_sbs1(air_modes.parse):
if subtype == 0 or subtype == 1:
parser = self.parseBDS09_0 if subtype == 0 else self.parseBDS09_1
[velocity, heading, vert_spd] = parser(data)
retstr = "MSG,4,0,%i,%06X,%i,%s,%s,%s,%s,,,%.1f,%.1f,,,%i,,,,,\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, velocity, heading, vert_spd)
retstr = "MSG,4,0,%i,%06X,%i,%s,%s,%s,%s,,,%.1f,%.1f,,,%i,,,,,\r\n" % (aircraft_id, icao24, aircraft_id+100, datestr, timestr, datestr, timestr, velocity, heading, vert_spd)
return retstr

View File

@ -19,7 +19,7 @@
# Boston, MA 02110-1301, USA.
#
import time, os, sys
import time, os, sys, threading
from string import split, join
import air_modes
import sqlite3
@ -28,6 +28,9 @@ from air_modes.exceptions import *
class output_sql(air_modes.parse):
def __init__(self, mypos, filename):
air_modes.parse.__init__(self, mypos)
self._lock = threading.Lock()
#create the database
self.filename = filename
self.db = sqlite3.connect(filename)
@ -40,7 +43,7 @@ class output_sql(air_modes.parse):
"lat" REAL,
"lon" REAL
);"""
c.execute(query)
self.locked_execute(c, query)
query = """CREATE TABLE IF NOT EXISTS "vectors" (
"icao" INTEGER KEY NOT NULL,
"seen" TEXT NOT NULL,
@ -48,12 +51,12 @@ class output_sql(air_modes.parse):
"heading" REAL,
"vertical" REAL
);"""
c.execute(query)
self.locked_execute(c, query)
query = """CREATE TABLE IF NOT EXISTS "ident" (
"icao" INTEGER PRIMARY KEY NOT NULL,
"ident" TEXT NOT NULL
);"""
c.execute(query)
self.locked_execute(c, query)
c.close()
self.db.commit()
#we close the db conn now to reopen it in the output() thread context.
@ -63,6 +66,10 @@ class output_sql(air_modes.parse):
def __del__(self):
self.db = None
def locked_execute(self, c, query):
with self._lock:
c.execute(query)
def output(self, message):
try:
#we're checking to see if the db is empty, and creating the db object
@ -74,10 +81,12 @@ class output_sql(air_modes.parse):
query = self.make_insert_query(message)
if query is not None:
c = self.db.cursor()
c.execute(query)
c.close()
self.db.commit() #don't know if this is necessary
with self._lock:
c = self.db.cursor()
c.execute(query)
c.close()
self.db.commit()
except ADSBError:
pass