diff --git a/apps/modes_rx b/apps/modes_rx index 62c586b..8cc7a6a 100755 --- a/apps/modes_rx +++ b/apps/modes_rx @@ -24,7 +24,6 @@ from optparse import OptionParser import time, os, sys, threading from string import split, join import air_modes -import csv from air_modes.exceptions import * import zmq @@ -55,6 +54,7 @@ class screen_printer(threading.Thread): self._subscriber.close() self.finished.set() +#todo: maybe move plugins to separate programs (flightgear, SBS1, etc.) def main(): my_position = None usage = "%prog: [options]" @@ -64,8 +64,8 @@ def main(): help="filename for Google Earth KML output") parser.add_option("-P","--sbs1", action="store_true", default=False, help="open an SBS-1-compatible server on port 30003") - parser.add_option("-w","--raw", action="store_true", default=False, - help="open a server outputting raw timestamped data on port 9988") + parser.add_option("-s","--servers", type="string", default="", + help="specify additional servers from which to take data in format tcp://x.x.x.x:y,tcp://....") parser.add_option("-n","--no-print", action="store_true", default=False, help="disable printing decoded packets to stdout") parser.add_option("-l","--location", type="string", default=None, @@ -74,17 +74,19 @@ def main(): help="Use UDP source on specified port") parser.add_option("-m","--multiplayer", type="string", default=None, help="FlightGear server to send aircraft data, in format host:port") + parser.add_option("-t","--tcp", type="int", default=None, + help="Open a TCP server on this port to publish reports") (options, args) = parser.parse_args() #construct the radio context = zmq.Context(1) tb = air_modes.modes_radio(options, context) - relay = air_modes.zmq_pubsub_iface(context, subaddr="inproc://modes-radio-pub", pubaddr=None) + servers = options.servers.split(",") + ["inproc://modes-radio-pub"] + relay = air_modes.zmq_pubsub_iface(context, subaddr=servers[-1], pubaddr=None) if options.location is not None: - reader = csv.reader([options.location], quoting=csv.QUOTE_NONNUMERIC) - my_position = reader.next() + my_position = [float(n) for n in options.location.split(",")] if options.kml is not None: dbname = 'adsb.db' diff --git a/include/air_modes_preamble.h b/include/air_modes_preamble.h index 2b3aff3..f419343 100644 --- a/include/air_modes_preamble.h +++ b/include/air_modes_preamble.h @@ -57,6 +57,10 @@ public: gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void set_rate(int channel_rate); + void set_threshold(float threshold_db); + float get_threshold(void); }; #endif /* INCLUDED_AIR_MODES_PREAMBLE_H */ diff --git a/include/air_modes_slicer.h b/include/air_modes_slicer.h index eb9e6a6..1ddcf5f 100644 --- a/include/air_modes_slicer.h +++ b/include/air_modes_slicer.h @@ -53,6 +53,8 @@ public: int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void set_rate(int channel_rate); }; #endif /* INCLUDED_AIR_MODES_slicer_H */ diff --git a/lib/air_modes_preamble.cc b/lib/air_modes_preamble.cc index 4cc86cc..612d581 100644 --- a/lib/air_modes_preamble.cc +++ b/lib/air_modes_preamble.cc @@ -42,14 +42,8 @@ air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) : gr_make_io_signature2 (2, 2, sizeof(float), sizeof(float)), //stream 0 is received data, stream 1 is moving average for reference gr_make_io_signature (1, 1, sizeof(float))) //the output packets { - d_chip_rate = 2000000; //2Mchips per second - d_samples_per_chip = channel_rate / d_chip_rate; //must be integer number of samples per chip to work - d_samples_per_symbol = d_samples_per_chip * 2; - d_check_width = 120 * d_samples_per_symbol; //only search to this far from the end of the stream buffer - d_threshold_db = threshold_db; - d_threshold = powf(10., threshold_db/20.); //the level that the sample must be above the moving average in order to qualify as a pulse - d_secs_per_sample = 1.0 / channel_rate; - set_output_multiple(1+d_check_width*2); + set_rate(channel_rate); + set_threshold(threshold_db); std::stringstream str; str << name() << unique_id(); @@ -58,6 +52,27 @@ air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) : set_history(d_samples_per_symbol); } +void air_modes_preamble::set_rate(int channel_rate) +{ + d_chip_rate = 2000000; //2Mchips per second + d_samples_per_chip = channel_rate / d_chip_rate; //must be integer number of samples per chip to work + d_samples_per_symbol = d_samples_per_chip * 2; + d_secs_per_sample = 1.0 / channel_rate; + d_check_width = 240 * d_samples_per_symbol; //only search to this far from the end of the stream buffer + set_output_multiple(1+d_check_width); +} + +void air_modes_preamble::set_threshold(float threshold_db) +{ + d_threshold_db = threshold_db; + d_threshold = powf(10., threshold_db/20.); //the level that the sample must be above the moving average in order to qualify as a pulse +} + +float air_modes_preamble::get_threshold(void) +{ + return d_threshold_db; +} + static void integrate_and_dump(float *out, const float *in, int chips, int samps_per_chip) { for(int i=0; i