From 9f522cf082303b7ba165f4ab6820b0ecc5eb11b0 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 18 Sep 2013 08:53:00 -0700 Subject: [PATCH 01/24] Add checking for ZMQ/PyZMQ to CMakeLists.txt --- CMakeLists.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1d26ed..7a9ca90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,20 @@ if(NOT GNURADIO_RUNTIME_FOUND) message(FATAL_ERROR "GnuRadio Runtime required to compile gr-air-modes") endif() +######################################################################## +# Find ZMQ and get version +######################################################################## +include(FindZeroMQ) + +######################################################################## +# Find PyZMQ bindings +######################################################################## +include(GrPython) +GR_PYTHON_CHECK_MODULE("PyZMQ" "zmq" "int(zmq.__version__.split('.')[0]) >= 13" ZMQ_FOUND) +if(NOT ZMQ_FOUND) + message(FATAL_ERROR "Python ZMQ bindings not found.") +endif() + ######################################################################## # Setup the include and linker paths ######################################################################## From e47992d800fc789fc9926ee72b9c024c0ec4c431 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 18 Sep 2013 08:57:44 -0700 Subject: [PATCH 02/24] Actually looking for both ZMQ and PyZMQ now. --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a9ca90..5384817 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,13 +79,16 @@ endif() # Find ZMQ and get version ######################################################################## include(FindZeroMQ) +if(NOT ZEROMQ_FOUND) + message(FATAL_ERROR "ZMQ not found.") +endif() ######################################################################## # Find PyZMQ bindings ######################################################################## include(GrPython) -GR_PYTHON_CHECK_MODULE("PyZMQ" "zmq" "int(zmq.__version__.split('.')[0]) >= 13" ZMQ_FOUND) -if(NOT ZMQ_FOUND) +GR_PYTHON_CHECK_MODULE("PyZMQ" "zmq" "int(zmq.__version__.split('.')[0]) >= 13" PYZMQ_FOUND) +if(NOT PYZMQ_FOUND) message(FATAL_ERROR "Python ZMQ bindings not found.") endif() From aa5fdd17ea8b8442f91be4d7fb132a739edbf062 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 2 Oct 2013 21:06:51 -0400 Subject: [PATCH 03/24] Add pkgconfig searching for libzmq --- cmake/Modules/FindZeroMQ.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/Modules/FindZeroMQ.cmake b/cmake/Modules/FindZeroMQ.cmake index d823c6e..c4b9351 100644 --- a/cmake/Modules/FindZeroMQ.cmake +++ b/cmake/Modules/FindZeroMQ.cmake @@ -12,6 +12,10 @@ # Search for the zeromq framework on Apple. #CMAKE_FIND_FRAMEWORKS(ZeroMQ) +find_package(PkgConfig) +pkg_check_modules(PC_LIBZMQ libzmq) + + IF(WIN32) FIND_LIBRARY(ZEROMQ_DEBUG_LIBRARY NAMES libzmq_d zmq_d @@ -22,6 +26,7 @@ ENDIF(WIN32) FIND_LIBRARY(ZEROMQ_LIBRARY NAMES libzmq zmq + HINTS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS} PATHS ${ZEROMQ_LIBRARIES} ${NSCP_LIBRARYDIR} @@ -41,6 +46,8 @@ FIND_PATH(ZEROMQ_INCLUDE_DIR ${ZEROMQ_INCLUDE_DIRS} ${NSCP_INCLUDEDIR} ${ZEROMQ_INCLUDE_DIR} + ${PC_LIBZMQ_INCLUDEDIR} + ${PC_LIBZMQ_INCLUDE_DIRS} ) MARK_AS_ADVANCED( From ca4edd88088b319a81ce65af2d3bf1807fc965cd Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 2 Oct 2013 22:14:44 -0400 Subject: [PATCH 04/24] look for zmq.h instead of zmq.hpp, which is apparently missing in some installs. --- cmake/Modules/FindZeroMQ.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/Modules/FindZeroMQ.cmake b/cmake/Modules/FindZeroMQ.cmake index c4b9351..a988eb1 100644 --- a/cmake/Modules/FindZeroMQ.cmake +++ b/cmake/Modules/FindZeroMQ.cmake @@ -25,7 +25,7 @@ IF(WIN32) ENDIF(WIN32) FIND_LIBRARY(ZEROMQ_LIBRARY - NAMES libzmq zmq + NAMES libzmq zmq HINTS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS} PATHS ${ZEROMQ_LIBRARIES} @@ -40,7 +40,7 @@ FIND_LIBRARY(ZEROMQ_LIBRARY # ENDIF(ZeroMQ_FRAMEWORKS AND NOT ZEROMQ_INCLUDE_DIR) FIND_PATH(ZEROMQ_INCLUDE_DIR - NAMES zmq.hpp + NAMES zmq.h PATHS # ${ZEROMQ_FRAMEWORK_INCLUDES} ${ZEROMQ_INCLUDE_DIRS} From 585ecf1ba661e7af7bcc901e9a0f64db5291b5b6 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sat, 26 Oct 2013 21:53:49 -0700 Subject: [PATCH 05/24] Remove FindZeroMQ as it's causing more trouble than it's worth. Zero_Chaos, this is my hat I'm eating. --- CMakeLists.txt | 8 ----- cmake/Modules/FindZeroMQ.cmake | 63 ---------------------------------- python/radio.py | 2 +- 3 files changed, 1 insertion(+), 72 deletions(-) delete mode 100644 cmake/Modules/FindZeroMQ.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5384817..0210f12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,14 +75,6 @@ if(NOT GNURADIO_RUNTIME_FOUND) message(FATAL_ERROR "GnuRadio Runtime required to compile gr-air-modes") endif() -######################################################################## -# Find ZMQ and get version -######################################################################## -include(FindZeroMQ) -if(NOT ZEROMQ_FOUND) - message(FATAL_ERROR "ZMQ not found.") -endif() - ######################################################################## # Find PyZMQ bindings ######################################################################## diff --git a/cmake/Modules/FindZeroMQ.cmake b/cmake/Modules/FindZeroMQ.cmake deleted file mode 100644 index a988eb1..0000000 --- a/cmake/Modules/FindZeroMQ.cmake +++ /dev/null @@ -1,63 +0,0 @@ -# - Find zeromq libraries -# This module finds zeromq if it is installed and determines where the -# include files and libraries are. It also determines what the name of -# the library is. This code sets the following variables: -# -# ZEROMQ_FOUND - have the zeromq libs been found -# ZEROMQ_LIBRARIES - path to the zeromq library -# ZEROMQ_INCLUDE_DIRS - path to where zmq.h is found -# ZEROMQ_DEBUG_LIBRARIES - path to the debug library - -#INCLUDE(CMakeFindFrameworks) -# Search for the zeromq framework on Apple. -#CMAKE_FIND_FRAMEWORKS(ZeroMQ) - -find_package(PkgConfig) -pkg_check_modules(PC_LIBZMQ libzmq) - - -IF(WIN32) - FIND_LIBRARY(ZEROMQ_DEBUG_LIBRARY - NAMES libzmq_d zmq_d - PATHS - ${ZEROMQ_LIBRARIES} - ) -ENDIF(WIN32) - -FIND_LIBRARY(ZEROMQ_LIBRARY - NAMES libzmq zmq - HINTS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS} - PATHS - ${ZEROMQ_LIBRARIES} - ${NSCP_LIBRARYDIR} -) - -# IF(ZeroMQ_FRAMEWORKS AND NOT ZEROMQ_INCLUDE_DIR) -# FOREACH(dir ${ZeroMQ_FRAMEWORKS}) -# SET(ZEROMQ_FRAMEWORK_INCLUDES ${ZEROMQ_FRAMEWORK_INCLUDES} -# ${dir}/Versions/${_CURRENT_VERSION}/include/zeromq${_CURRENT_VERSION}) -# ENDFOREACH(dir) -# ENDIF(ZeroMQ_FRAMEWORKS AND NOT ZEROMQ_INCLUDE_DIR) - -FIND_PATH(ZEROMQ_INCLUDE_DIR - NAMES zmq.h - PATHS -# ${ZEROMQ_FRAMEWORK_INCLUDES} - ${ZEROMQ_INCLUDE_DIRS} - ${NSCP_INCLUDEDIR} - ${ZEROMQ_INCLUDE_DIR} - ${PC_LIBZMQ_INCLUDEDIR} - ${PC_LIBZMQ_INCLUDE_DIRS} -) - -MARK_AS_ADVANCED( - ZEROMQ_DEBUG_LIBRARY - ZEROMQ_LIBRARY - ZEROMQ_INCLUDE_DIR -) -SET(ZEROMQ_INCLUDE_DIRS "${ZEROMQ_INCLUDE_DIR}") -SET(ZEROMQ_LIBRARIES "${ZEROMQ_LIBRARY}") -SET(ZEROMQ_DEBUG_LIBRARIES "${ZEROMQ_DEBUG_LIBRARY}") - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZeroMQ DEFAULT_MSG ZEROMQ_LIBRARIES ZEROMQ_INCLUDE_DIRS) diff --git a/python/radio.py b/python/radio.py index 9d28b9f..0842d10 100644 --- a/python/radio.py +++ b/python/radio.py @@ -81,7 +81,7 @@ class modes_radio (gr.top_block, pubsub): @staticmethod def add_radio_options(parser): group = OptionGroup(parser, "Receiver setup options") - + #Choose source group.add_option("-s","--source", type="string", default="uhd", help="Choose source: uhd, osmocom, , or [default=%default]") From 27e0f8736139518718f819c3fe85744ff27e77e7 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 24 Dec 2013 12:51:45 -0800 Subject: [PATCH 06/24] CMake fixes (force Python2, use GnuradioConfig.cmake). --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0210f12..36c2078 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ # Project setup ######################################################################## cmake_minimum_required(VERSION 2.6) -project(gr-gr-air-modes CXX) +project(gr-gr-air-modes CXX C) set(gr-gr-air-modes_VERSION_MAJOR 0) set(gr-gr-air-modes_VERSION_MINOR 0) enable_testing() @@ -49,6 +49,8 @@ endif() ######################################################################## include(GrBoost) +find_package(PythonLibs 2) + ######################################################################## # Install directories ######################################################################## @@ -69,7 +71,8 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) ######################################################################## # Find gnuradio build dependencies ######################################################################## -find_package(GnuradioRuntime) +set(GR_REQUIRED_COMPONENTS RUNTIME) +find_package(Gnuradio "3.7.2" REQUIRED) if(NOT GNURADIO_RUNTIME_FOUND) message(FATAL_ERROR "GnuRadio Runtime required to compile gr-air-modes") From 42bf16ffc4d5772acd03913f1a6a6ca28d6a2f3b Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 7 Feb 2014 16:59:34 -0800 Subject: [PATCH 07/24] Fix FlightGear and SBS1 outputs. --- python/flightgear.py | 20 +++++++++----------- python/sbs1.py | 10 +++++----- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/python/flightgear.py b/python/flightgear.py index ebfed94..69c5f1a 100755 --- a/python/flightgear.py +++ b/python/flightgear.py @@ -18,7 +18,6 @@ class output_flightgear: def __init__(self, cprdec, hostname, port, pub): self.hostname = hostname self.port = port - self.localpos = localpos self.positions = {} self.velocities = {} self.callsigns = {} @@ -26,42 +25,41 @@ class output_flightgear: self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.connect((self.hostname, self.port)) - pub.subscribe("type17_dl", output) + pub.subscribe("type17_dl", self.output) def output(self, msg): - try: msgtype = msg.data["df"] if msgtype == 17: #ADS-B report icao24 = msg.data["aa"] bdsreg = msg.data["me"].get_type() if bdsreg == 0x08: #ident packet - (ident, actype) = air_modes.parseBDS08(data) + (ident, actype) = air_modes.parseBDS08(msg.data) #select model based on actype self.callsigns[icao24] = [ident, actype] - + elif bdsreg == 0x06: #BDS0,6 pos - [ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(data, self._cpr) + [ground_track, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS06(msg.data, self._cpr) self.positions[icao24] = [decoded_lat, decoded_lon, 0] self.update(icao24) elif bdsreg == 0x05: #BDS0,5 pos - [altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(data, self._cpr) + [altitude, decoded_lat, decoded_lon, rnge, bearing] = air_modes.parseBDS05(msg.data, self._cpr) self.positions[icao24] = [decoded_lat, decoded_lon, altitude] self.update(icao24) elif bdsreg == 0x09: #velocity - subtype = data["bds09"].get_type() + subtype = msg.data["bds09"].get_type() if subtype == 0: - [velocity, heading, vert_spd, turnrate] = air_modes.parseBDS09_0(data) + [velocity, heading, vert_spd, turnrate] = air_modes.parseBDS09_0(msg.data) elif subtype == 1: - [velocity, heading, vert_spd] = air_modes.parseBDS09_1(data) + [velocity, heading, vert_spd] = air_modes.parseBDS09_1(msg.data) turnrate = 0 else: return self.velocities[icao24] = [velocity, heading, vert_spd, turnrate] - + except ADSBError: pass diff --git a/python/sbs1.py b/python/sbs1.py index b0507ce..763d174 100644 --- a/python/sbs1.py +++ b/python/sbs1.py @@ -23,7 +23,7 @@ import time, os, sys, socket from string import split, join import air_modes -from datetime import * +import datetime from air_modes.exceptions import * import threading @@ -63,7 +63,7 @@ class output_sbs1: #it could be cleaner if there were separate output_* fns #but this works for i in (0, 4, 5, 11, 17): - pub.subscribe("type%i_dl" % i, output) + pub.subscribe("type%i_dl" % i, self.output) #spawn thread to add new connections as they come in self._runner = dumb_task_runner(self.add_pending_conns, 0.1) @@ -111,7 +111,7 @@ class output_sbs1: pass def current_time(self): - timenow = datetime.now() + timenow = datetime.datetime.now() return [timenow.strftime("%Y/%m/%d"), timenow.strftime("%H:%M:%S.%f")[0:-3]] def decode_fs(self, fs): @@ -154,7 +154,7 @@ class output_sbs1: [datestr, timestr] = self.current_time() 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, air_modes.decode_alt(shortdata["ac"], True)) - if vs: + if shortdata["vs"]: retstr += "1\r\n" else: retstr += "0\r\n" @@ -174,7 +174,7 @@ class output_sbs1: def pp11(self, shortdata, ecc): [datestr, timestr] = self.current_time() - aircraft_id = self.get_aircraft_id(icao24) + aircraft_id = self.get_aircraft_id(shortdata["aa"]) return "MSG,8,0,%i,%06X,%i,%s,%s,%s,%s,,,,,,,,,,,,\r\n" % (aircraft_id, shortdata["aa"], aircraft_id+100, datestr, timestr, datestr, timestr) def pp17(self, data): From cc0fa1801b077c139939bc963cff17fd65ebfca1 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 12 Feb 2014 15:15:32 -0800 Subject: [PATCH 08/24] Fix enumeration in SBS1 list pruning. --- python/sbs1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/sbs1.py b/python/sbs1.py index 763d174..eb1941c 100644 --- a/python/sbs1.py +++ b/python/sbs1.py @@ -83,7 +83,7 @@ class output_sbs1: # dictionary is getting too large. if len(self._aircraft_id_map) > 1e4: minimum = min(self._aircraft_id_map.values()) + (len(self._aircraft_id_map) - 1e4) - for icao, _id in self._aircraft_id_map: + for icao, _id in self._aircraft_id_map.iteritems(): if _id < minimum: del self._aircraft_id_map[icao] From 6f1177772404a04d86dd7ffe5b713778978235c4 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 21 Sep 2014 19:03:16 -0700 Subject: [PATCH 09/24] Fix rate setting for devices with <4Msps rates (RTL). --- python/radio.py | 19 +++++++++++++++++-- python/rx_path.py | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/python/radio.py b/python/radio.py index 0842d10..0268b33 100644 --- a/python/radio.py +++ b/python/radio.py @@ -27,6 +27,7 @@ from gnuradio import gr, gru, eng_notation, filter, blocks from gnuradio.filter import optfir from gnuradio.eng_option import eng_option from gnuradio.gr.pubsub import pubsub +from gnuradio.filter import pfb from optparse import OptionParser, OptionGroup import air_modes import zmq @@ -45,9 +46,16 @@ class modes_radio (gr.top_block, pubsub): self._resample = None self._setup_source(options) - self._rx_path = air_modes.rx_path(self._rate, options.threshold, + if self._rate < 4e6: + self._resample = pfb.arb_resampler_ccf(4.e6/self._rate) + self._rx_rate = 4e6 + else: + self._rx_rate = self._rate + + self._rx_path = air_modes.rx_path(self._rx_rate, options.threshold, self._queue, options.pmf, options.dcblock) + #now subscribe to set various options via pubsub self.subscribe("freq", self.set_freq) self.subscribe("gain", self.set_gain) @@ -125,7 +133,14 @@ class modes_radio (gr.top_block, pubsub): return self.get_gain() def set_rate(self, rate): - self._rx_path.set_rate(rate) + if(rate < 4e6 and self._rate > 4e6): + raise NotImplementedError("Lowering rate <4e6Msps not currently supported.") + if(rate < 4e6): + self._resample.set_rate(4e6/rate) + self._rx_rate = 4e6 + else: + self._rx_rate = rate + self._rx_path.set_rate(self._rx_rate) return self._u.set_rate(rate) if self.live_source() else 0 def set_threshold(self, threshold): diff --git a/python/rx_path.py b/python/rx_path.py index 36350c2..f948b97 100644 --- a/python/rx_path.py +++ b/python/rx_path.py @@ -37,7 +37,7 @@ class rx_path(gr.hier_block2): # Convert incoming I/Q baseband to amplitude self._demod = blocks.complex_to_mag_squared() if use_dcblock: - self._dcblock = filter.dc_blocker_cc(100*self._spc,True) + self._dcblock = filter.dc_blocker_cc(100*self._spc,False) self.connect(self, self._dcblock, self._demod) else: self.connect(self, self._demod) From 78c5500c80ac6d4fd9137075fc082129f217a9dd Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 21 Sep 2014 19:18:21 -0700 Subject: [PATCH 10/24] Fix GUI rate picking logic for <4Msps devices (RTL) --- apps/modes_gui | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/modes_gui b/apps/modes_gui index 9c09d6d..f53d23d 100755 --- a/apps/modes_gui +++ b/apps/modes_gui @@ -233,7 +233,9 @@ class mainwindow(QtGui.QMainWindow): try: import osmosdr self.src = osmosdr.source("") - self.rates = [rate.start() for rate in self.src.get_sample_rates() if (rate.start() % 2.e6) == 0] + self.rates = [rate.start() for rate in self.src.get_sample_rates() + if ((rate.start() % 2.e6) == 0) + or (rate.start() < 4.e6 and ((rate.start()%0.2e6) == 0))] self.antennas = ["RX"] self.src = None self.ui.combo_ant.setEnabled(False) @@ -263,10 +265,15 @@ class mainwindow(QtGui.QMainWindow): #set up recommended sample rate if len(self.rates) > 1: - recommended_rate = min(x for x in self.rates if x >= 4e6 and - max(self.rates) % x == 0) + if max(self.rates) > 4.e6: + recommended_rate = min(x for x in self.rates if x >= 4e6 and + max(self.rates) % x == 0) + else: + recommended_rate = max(self.rates) if recommended_rate >= 8.e6: self.ui.check_pmf.setChecked(True) + else: + self.ui.check_pmf.setChecked(False) self.ui.combo_rate.setCurrentIndex(self.rates.index(recommended_rate)) ################ action handlers #################### From 48f9c2a29a00cf2387e50c60a34496dc0ea17c03 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 21 Sep 2014 19:28:44 -0700 Subject: [PATCH 11/24] Live sample rate changing for RTL devices in modes_gui --- python/radio.py | 7 ++++++- python/rx_path.py | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/python/radio.py b/python/radio.py index 0268b33..8f50533 100644 --- a/python/radio.py +++ b/python/radio.py @@ -141,7 +141,12 @@ class modes_radio (gr.top_block, pubsub): else: self._rx_rate = rate self._rx_path.set_rate(self._rx_rate) - return self._u.set_rate(rate) if self.live_source() else 0 + if self._options.source in ("osmocom"): + return self._u.set_sample_rate(rate) + if self._options.source in ("uhd"): + return self._u.set_rate(rate) + else: + return 0 def set_threshold(self, threshold): self._rx_path.set_threshold(threshold) diff --git a/python/rx_path.py b/python/rx_path.py index f948b97..b89ff2d 100644 --- a/python/rx_path.py +++ b/python/rx_path.py @@ -65,13 +65,13 @@ class rx_path(gr.hier_block2): self.connect(self._sync, self._slicer) def set_rate(self, rate): - self._sync.set_rate(rate) + self._sync.set_rate(int(rate)) self._spc = int(rate/2e6) self._avg.set_length_and_scale(48*self._spc, 1.0/(48*self._spc)) if self._bb != self._demod: self._pmf.set_length_and_scale(self._spc, 1.0/self._spc) - if self._dcblock is not None: - self._dcblock.set_length(100*self._spc) +# if self._dcblock is not None: +# self._dcblock.set_length(100*self._spc) def set_threshold(self, threshold): self._sync.set_threshold(threshold) From 1536dae56ec2059516d1faed640b101ae186e5d0 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 28 Sep 2014 10:43:54 -0700 Subject: [PATCH 12/24] Fix issue with stop/restart in modes_gui. --- apps/modes_gui | 4 ++-- python/radio.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/modes_gui b/apps/modes_gui index f53d23d..ca44ced 100755 --- a/apps/modes_gui +++ b/apps/modes_gui @@ -407,10 +407,10 @@ class mainwindow(QtGui.QMainWindow): def on_quit(self): if self.running is True: - self._relay.close() self._radio.close() - self._relay = None self._radio = None + self._relay.close() + self._relay = None self._rps_timer = None try: self.kmlgen.done = True diff --git a/python/radio.py b/python/radio.py index 8f50533..5f41c45 100644 --- a/python/radio.py +++ b/python/radio.py @@ -228,5 +228,7 @@ class modes_radio (gr.top_block, pubsub): print "Rate is %i" % (options.rate,) def close(self): + self.stop() + self.wait() self._sender.close() self._u = None From 9891907e97b6bb46447aeffd2e619df35074443e Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Sun, 28 Sep 2014 15:09:07 -0700 Subject: [PATCH 13/24] Spruce up the Javascript map handler so it doesn't just wipe the map and repopulate. No "flashing icons". --- python/html_template.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/python/html_template.py b/python/html_template.py index d129c1a..1e6e5b0 100644 --- a/python/html_template.py +++ b/python/html_template.py @@ -53,7 +53,6 @@ def html_template(my_position, json_file): }; function jsonp_callback(results) { // from JSONP - clearMarkers(); airplanes = {}; for (var i = 0; i < results.length; i++) { airplanes[results[i].icao] = { @@ -67,10 +66,20 @@ def html_template(my_position, json_file): highlight: results[i].highlight }; } +// clearMarkers(); refreshIcons(); } function refreshIcons() { + //prune the list + for(var i = 0; i < planes.length; i++) { + icao = planes[i].get("icao") + if(!(icao in airplanes)) { + planes[i].setMap(null) + planes.splice(i, 1); + }; + }; + for (var airplane in airplanes) { if (airplanes[airplane].highlight != 0) { icon_file = "http://www.nerdnetworks.org/~bistromath/airplane_sprite_highlight.png"; @@ -86,7 +95,7 @@ def html_template(my_position, json_file): }; if (airplanes[airplane].ident.length != 8) { - identstr = airplane; + identstr = airplane; } else { identstr = airplanes[airplane].ident; }; @@ -94,14 +103,31 @@ def html_template(my_position, json_file): var planeOptions = { map: map, position: airplanes[airplane].center, + icao: airplane, icon: plane_icon, labelContent: identstr, labelAnchor: new google.maps.Point(35, -32), labelClass: "labels", labelStyle: {opacity: 0.75} }; - planeMarker = new MarkerWithLabel(planeOptions); - planes.push(planeMarker); + + var i = 0; + for(i; i Date: Wed, 21 Jan 2015 12:32:39 -0800 Subject: [PATCH 14/24] Check for PyZMQ at runtime instead of compile time to support cross-compiling. --- CMakeLists.txt | 8 ++++---- python/__init__.py | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36c2078..5ede330 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,10 +82,10 @@ endif() # Find PyZMQ bindings ######################################################################## include(GrPython) -GR_PYTHON_CHECK_MODULE("PyZMQ" "zmq" "int(zmq.__version__.split('.')[0]) >= 13" PYZMQ_FOUND) -if(NOT PYZMQ_FOUND) - message(FATAL_ERROR "Python ZMQ bindings not found.") -endif() +#GR_PYTHON_CHECK_MODULE("PyZMQ" "zmq" "int(zmq.__version__.split('.')[0]) >= 13" PYZMQ_FOUND) +#if(NOT PYZMQ_FOUND) +# message(FATAL_ERROR "Python ZMQ bindings not found.") +#endif() ######################################################################## # Setup the include and linker paths diff --git a/python/__init__.py b/python/__init__.py index 29e0475..77441bf 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -51,6 +51,12 @@ from air_modes_swig import * # import any pure python here # + +try: + import zmq +except ImportError: + raise RuntimeError("PyZMQ not found! Please install libzmq and PyZMQ to run gr-air-modes") + from rx_path import rx_path from zmq_socket import zmq_pubsub_iface from parse import * From 9bdac2a49951ee53a0ef616c05bf7f2b0d79f9f5 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 17 Apr 2015 14:07:28 -0700 Subject: [PATCH 15/24] Use whole/fractional timestamps in the whole chain. This prevents loss of precision when setting time to UTC. --- include/gr_air_modes/preamble.h | 6 ++-- lib/preamble_impl.cc | 57 ++++++++++++++++++++------------- lib/preamble_impl.h | 14 ++++---- lib/slicer_impl.cc | 6 ++-- lib/slicer_impl.h | 1 + python/parse.py | 4 +-- 6 files changed, 51 insertions(+), 37 deletions(-) diff --git a/include/gr_air_modes/preamble.h b/include/gr_air_modes/preamble.h index a07022c..a86aba0 100644 --- a/include/gr_air_modes/preamble.h +++ b/include/gr_air_modes/preamble.h @@ -37,11 +37,11 @@ class AIR_MODES_API preamble : virtual public gr::block { public: typedef boost::shared_ptr sptr; - static sptr make(int channel_rate, float threshold_db); + static sptr make(float channel_rate, float threshold_db); - virtual void set_rate(int channel_rate) = 0; + virtual void set_rate(float channel_rate) = 0; virtual void set_threshold(float threshold_db) = 0; - virtual int get_rate(void) = 0; + virtual float get_rate(void) = 0; virtual float get_threshold(void) = 0; }; diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index d367c98..af8644d 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -34,11 +34,11 @@ namespace gr { -air_modes::preamble::sptr air_modes::preamble::make(int channel_rate, float threshold_db) { +air_modes::preamble::sptr air_modes::preamble::make(float channel_rate, float threshold_db) { return gnuradio::get_initial_sptr(new air_modes::preamble_impl(channel_rate, threshold_db)); } -air_modes::preamble_impl::preamble_impl(int channel_rate, float threshold_db) : +air_modes::preamble_impl::preamble_impl(float channel_rate, float threshold_db) : gr::block ("preamble", gr::io_signature::make2 (2, 2, sizeof(float), sizeof(float)), //stream 0 is received data, stream 1 is moving average for reference gr::io_signature::make (1, 1, sizeof(float))) //the output soft symbols @@ -53,11 +53,11 @@ air_modes::preamble_impl::preamble_impl(int channel_rate, float threshold_db) : d_key = pmt::string_to_symbol("preamble_found"); } -void air_modes::preamble_impl::set_rate(int channel_rate) { +void air_modes::preamble_impl::set_rate(float channel_rate) { d_samples_per_chip = channel_rate / d_chip_rate; d_samples_per_symbol = d_samples_per_chip * 2; d_check_width = 120 * d_samples_per_symbol; - d_secs_per_sample = 1.0/channel_rate; + d_sample_rate = channel_rate; set_output_multiple(1+d_check_width*2); set_history(d_samples_per_symbol); } @@ -71,8 +71,8 @@ float air_modes::preamble_impl::get_threshold(void) { return d_threshold_db; } -int air_modes::preamble_impl::get_rate(void) { - return d_samples_per_chip * d_chip_rate; +float air_modes::preamble_impl::get_rate(void) { + return d_sample_rate; } static void integrate_and_dump(float *out, const float *in, int chips, int samps_per_chip) { @@ -97,19 +97,34 @@ static double correlate_preamble(const float *in, int samples_per_chip) { return corr; } -//todo: make it return a pair of some kind, otherwise you can lose precision -static double tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, double secs_per_sample) { - uint64_t ts_sample, last_whole_stamp; - double last_frac_stamp; - +static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, int rate) { if(tstamp.key == NULL || pmt::symbol_to_string(tstamp.key) != "rx_time") return 0; - last_whole_stamp = pmt::to_uint64(pmt::tuple_ref(tstamp.value, 0)); - last_frac_stamp = pmt::to_double(pmt::tuple_ref(tstamp.value, 1)); - ts_sample = tstamp.offset; + //the timestamp tag has tstamp.offset, the sample index of the timestamp tag + //also tstamp.value, a pmt pair with (uint64, double) representing int and + //fractional timestamp, respectively. + //this function also gets an abs_sample_cnt which represents the sample count to + //find a timestamp for. sps is obviously samples per second. + // + //so (abs_sample_cnt - tstamp.offset) is the delay we apply to the tag + // int((abs_sample_cnt - tstamp.offset)/sps) is the integer offset + // (abs_sample_cnt - tstamp.offset)/sps is the fractional offset + + uint64_t last_whole_stamp = pmt::to_uint64(pmt::tuple_ref(tstamp.value, 0)); + double last_frac_stamp = pmt::to_double(pmt::tuple_ref(tstamp.value, 1)); + std::cout << "Rate: " << rate << std::endl; + uint64_t int_offset = int(abs_sample_cnt - tstamp.offset)/rate; + double frac_offset = ((abs_sample_cnt - tstamp.offset) % rate) / double(rate); + + uint64_t abs_whole = last_whole_stamp + int_offset; + double abs_frac = last_frac_stamp + frac_offset; + if(abs_frac > 1.0f) { + abs_frac -= 1.0f; + abs_whole += 1.0f; + } + + pmt::pmt_t tstime = pmt::make_tuple(pmt::from_uint64(abs_whole), pmt::from_double(abs_frac)); - double tstime = double(abs_sample_cnt * secs_per_sample) + last_whole_stamp + last_frac_stamp; - if(0) std::cout << "HEY WE GOT A STAMP AT " << tstime << " TICKS AT SAMPLE " << ts_sample << " ABS SAMPLE CNT IS " << abs_sample_cnt << std::endl; return tstime; } @@ -124,7 +139,7 @@ int air_modes::preamble_impl::general_work(int noutput_items, 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); + const int ninputs = std::max(mininputs - (mininputs % int(d_samples_per_chip)) - int(d_samples_per_chip), 0); if (ninputs <= 0) { consume_each(0); return 0; } float *out = (float *) output_items[0]; @@ -194,22 +209,20 @@ int air_modes::preamble_impl::general_work(int noutput_items, //all right i'm prepared to call this a preamble for(int j=0; j<240; j++) { - out[j] = in[i+j*d_samples_per_chip] - inavg[i]; + out[j] = in[i+int(j*d_samples_per_chip)] - inavg[i]; } //get the timestamp of the preamble - double tstamp = tag_to_timestamp(d_timestamp, abs_sample_cnt + i, d_secs_per_sample); + pmt::pmt_t tstamp = tag_to_timestamp(d_timestamp, abs_sample_cnt + i, d_sample_rate); //now tag the preamble add_item_tag(0, //stream ID nitems_written(0), //sample d_key, //frame_info - pmt::from_double(tstamp), + tstamp, d_me //block src id ); - //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 << "with i=" << i << ", returned 240" << std::endl; diff --git a/lib/preamble_impl.h b/lib/preamble_impl.h index 482b46a..6d6509f 100644 --- a/lib/preamble_impl.h +++ b/lib/preamble_impl.h @@ -15,26 +15,26 @@ private: int d_check_width; int d_chip_rate; float d_preamble_length_us; - int d_samples_per_chip; - int d_samples_per_symbol; + float d_samples_per_chip; + float d_samples_per_symbol; float d_threshold_db; float d_threshold; - pmt::pmt_t d_me, d_key; gr::tag_t d_timestamp; - double d_secs_per_sample; + pmt::pmt_t d_me, d_key; + int d_sample_rate; public: - preamble_impl(int channel_rate, float threshold_db); + preamble_impl(float channel_rate, float threshold_db); int general_work (int noutput_items, 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_rate(float channel_rate); void set_threshold(float threshold_db); float get_threshold(void); - int get_rate(void); + float get_rate(void); }; } //namespace air_modes diff --git a/lib/slicer_impl.cc b/lib/slicer_impl.cc index c34e9e4..565f691 100644 --- a/lib/slicer_impl.cc +++ b/lib/slicer_impl.cc @@ -158,8 +158,6 @@ int air_modes::slicer_impl::work(int noutput_items, } } - rx_packet.timestamp = pmt::to_double(tag_iter->value); - //here you might want to traverse the whole packet and if you find all 0's, just toss it. don't know why these packets turn up, but they pass ECC. bool zeroes = 1; for(int m = 0; m < 14; m++) { @@ -183,13 +181,15 @@ int air_modes::slicer_impl::work(int noutput_items, //crc for the other short packets is usually nonzero, so they can't really be trusted that far if(rx_packet.crc && (rx_packet.message_type == 11 || rx_packet.message_type == 17)) {continue;} + pmt::pmt_t tstamp = tag_iter->value; + d_payload.str(""); for(int m = 0; m < packet_length/8; m++) { d_payload << std::hex << std::setw(2) << std::setfill('0') << unsigned(rx_packet.data[m]); } d_payload << " " << std::setw(6) << rx_packet.crc << " " << std::dec << rx_packet.reference_level - << " " << std::setprecision(10) << std::setw(10) << rx_packet.timestamp; + << " " << pmt::to_uint64(pmt::tuple_ref(tstamp, 0)) << " " << std::setprecision(10) << pmt::to_double(pmt::tuple_ref(tstamp, 1)); gr::message::sptr msg = gr::message::make_from_string(std::string(d_payload.str())); d_queue->handle(msg); } diff --git a/lib/slicer_impl.h b/lib/slicer_impl.h index bfdf3de..f4914ea 100644 --- a/lib/slicer_impl.h +++ b/lib/slicer_impl.h @@ -38,6 +38,7 @@ private: int d_chip_rate; int d_samples_per_chip; int d_samples_per_symbol; + gr::tag_t d_timestamp; gr::msg_queue::sptr d_queue; std::ostringstream d_payload; diff --git a/python/parse.py b/python/parse.py index 7fe3297..2fb5398 100644 --- a/python/parse.py +++ b/python/parse.py @@ -423,12 +423,12 @@ def parse_TCAS_CRM(data): def make_parser(pub): publisher = pub def publish(message): - [data, ecc, reference, timestamp] = message.split() + [data, ecc, reference, int_timestamp, frac_timestamp] = message.split() try: ret = air_modes.modes_report(modes_reply(int(data, 16)), int(ecc, 16), 10.0*math.log10(max(1e-8,float(reference))), - air_modes.stamp(0, float(timestamp))) + air_modes.stamp(int(int_timestamp), float(frac_timestamp))) pub["modes_dl"] = ret pub["type%i_dl" % ret.data.get_type()] = ret except ADSBError: From 95ff2cade01a429874a1a73bf483a524013ceaae Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 17 Apr 2015 22:16:55 -0700 Subject: [PATCH 16/24] Remove spurious print. --- lib/preamble_impl.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index af8644d..026fe2d 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -112,7 +112,6 @@ static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, in uint64_t last_whole_stamp = pmt::to_uint64(pmt::tuple_ref(tstamp.value, 0)); double last_frac_stamp = pmt::to_double(pmt::tuple_ref(tstamp.value, 1)); - std::cout << "Rate: " << rate << std::endl; uint64_t int_offset = int(abs_sample_cnt - tstamp.offset)/rate; double frac_offset = ((abs_sample_cnt - tstamp.offset) % rate) / double(rate); From f0323160a0c3c97039afef6ec9ba435370b87bec Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 7 May 2015 20:44:28 -0700 Subject: [PATCH 17/24] Fix SBS-1 ID list prune issue. Lousy fix, but it'll do for now. The backend needs a rewrite. --- python/sbs1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/sbs1.py b/python/sbs1.py index eb1941c..5d4886f 100644 --- a/python/sbs1.py +++ b/python/sbs1.py @@ -83,7 +83,7 @@ class output_sbs1: # dictionary is getting too large. if len(self._aircraft_id_map) > 1e4: minimum = min(self._aircraft_id_map.values()) + (len(self._aircraft_id_map) - 1e4) - for icao, _id in self._aircraft_id_map.iteritems(): + for icao, _id in map(self._aircraft_id_map).iteritems(): if _id < minimum: del self._aircraft_id_map[icao] From d569e31a68faa2d2255dedcbc3d268c9f37af189 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 7 May 2015 20:47:09 -0700 Subject: [PATCH 18/24] Fix parse error (shift on float) reported by 'engink1981'. --- python/parse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/parse.py b/python/parse.py index 2fb5398..4fd5832 100644 --- a/python/parse.py +++ b/python/parse.py @@ -335,13 +335,13 @@ def parseBDS09_1(data): ew = bool(data["dew"]) subtype = data["sub"] if subtype == 0x02: - ns_vel <<= 2 - ew_vel <<= 2 + ns_vel *= 4 + ew_vel *= 4 velocity = math.hypot(ns_vel, ew_vel) if ew: ew_vel = 0 - ew_vel - + if ns_vel == 0: heading = 0 else: From 93078a8caeb9b617f85d207d8da012eb53a8ca3a Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 8 May 2015 09:08:38 -0700 Subject: [PATCH 19/24] I'm the worst --- python/sbs1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/sbs1.py b/python/sbs1.py index 5d4886f..e4eb76a 100644 --- a/python/sbs1.py +++ b/python/sbs1.py @@ -83,7 +83,7 @@ class output_sbs1: # dictionary is getting too large. if len(self._aircraft_id_map) > 1e4: minimum = min(self._aircraft_id_map.values()) + (len(self._aircraft_id_map) - 1e4) - for icao, _id in map(self._aircraft_id_map).iteritems(): + for icao, _id in dict(self._aircraft_id_map).iteritems(): if _id < minimum: del self._aircraft_id_map[icao] From 3d1b95832a522c589bfad7808bb3527d7f362d6e Mon Sep 17 00:00:00 2001 From: Ian Crawford Date: Tue, 26 May 2015 13:01:58 -0700 Subject: [PATCH 20/24] Fix crash with missing gr.udp_source() in gnuradio-companion 3.7.7.1. Changed to blocks.udp_source(). --- python/radio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/radio.py b/python/radio.py index 5f41c45..a466629 100644 --- a/python/radio.py +++ b/python/radio.py @@ -219,7 +219,7 @@ class modes_radio (gr.top_block, pubsub): ip, port = re.search("(.*)\:(\d{1,5})", options.source).groups() except: raise Exception("Please input UDP source e.g. 192.168.10.1:12345") - self._u = gr.udp_source(gr.sizeof_gr_complex, ip, int(port)) + self._u = blocks.udp_source(gr.sizeof_gr_complex, ip, int(port)) print "Using UDP source %s:%s" % (ip, port) else: self._u = blocks.file_source(gr.sizeof_gr_complex, options.source) From c96dea7fa0f70e29ea41215cec05131117ae3466 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 9 Jul 2015 12:23:52 -0700 Subject: [PATCH 21/24] preamble: Check to see if PMT key is actually a symbol before converting to string. --- lib/preamble_impl.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index 026fe2d..7fd8143 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -98,7 +98,9 @@ static double correlate_preamble(const float *in, int samples_per_chip) { } static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, int rate) { - if(tstamp.key == NULL || pmt::symbol_to_string(tstamp.key) != "rx_time") return 0; + if(tstamp.key == NULL) return 0; + if(!pmt::is_symbol(tstamp.key)) return 0; + if(pmt::symbol_to_string(tstamp.key) != "rx_time") return 0; //the timestamp tag has tstamp.offset, the sample index of the timestamp tag //also tstamp.value, a pmt pair with (uint64, double) representing int and From 953a7ddded1dd5cb82ad51370b3b5b29ac32c055 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 9 Jul 2015 13:03:10 -0700 Subject: [PATCH 22/24] Correctly return a zero timestamp tag instead of a null tag. --- lib/preamble_impl.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index 7fd8143..5e2ac86 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -98,9 +98,10 @@ static double correlate_preamble(const float *in, int samples_per_chip) { } static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, int rate) { - if(tstamp.key == NULL) return 0; - if(!pmt::is_symbol(tstamp.key)) return 0; - if(pmt::symbol_to_string(tstamp.key) != "rx_time") return 0; + pmt::pmt_t tstime = pmt::make_tuple(pmt::from_uint64(0), pmt::from_double(0)); + if(tstamp.key == NULL) return tstime; + if(!pmt::is_symbol(tstamp.key)) return tstime; + if(pmt::symbol_to_string(tstamp.key) != "rx_time") return tstime; //the timestamp tag has tstamp.offset, the sample index of the timestamp tag //also tstamp.value, a pmt pair with (uint64, double) representing int and @@ -124,7 +125,7 @@ static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, in abs_whole += 1.0f; } - pmt::pmt_t tstime = pmt::make_tuple(pmt::from_uint64(abs_whole), pmt::from_double(abs_frac)); + tstime = pmt::make_tuple(pmt::from_uint64(abs_whole), pmt::from_double(abs_frac)); return tstime; } From 2c9ef501b889ed630af482abf80576720ee2e25d Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 9 Jul 2015 13:08:00 -0700 Subject: [PATCH 23/24] Correctly use zero offset for devices that don't issue proper timestamp tags. --- lib/preamble_impl.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index 5e2ac86..da9143e 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -98,10 +98,18 @@ static double correlate_preamble(const float *in, int samples_per_chip) { } static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, int rate) { + uint64_t last_whole_stamp; + double last_frac_stamp; pmt::pmt_t tstime = pmt::make_tuple(pmt::from_uint64(0), pmt::from_double(0)); - if(tstamp.key == NULL) return tstime; - if(!pmt::is_symbol(tstamp.key)) return tstime; - if(pmt::symbol_to_string(tstamp.key) != "rx_time") return tstime; + if(tstamp.key == NULL + || !pmt::is_symbol(tstamp.key) + || pmt::symbol_to_string(tstamp.key) != "rx_time") { + last_whole_stamp = 0; + last_frac_stamp = 0; + } else { + last_whole_stamp = pmt::to_uint64(pmt::tuple_ref(tstamp.value, 0)); + last_frac_stamp = pmt::to_double(pmt::tuple_ref(tstamp.value, 1)); + } //the timestamp tag has tstamp.offset, the sample index of the timestamp tag //also tstamp.value, a pmt pair with (uint64, double) representing int and @@ -113,8 +121,6 @@ static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, in // int((abs_sample_cnt - tstamp.offset)/sps) is the integer offset // (abs_sample_cnt - tstamp.offset)/sps is the fractional offset - uint64_t last_whole_stamp = pmt::to_uint64(pmt::tuple_ref(tstamp.value, 0)); - double last_frac_stamp = pmt::to_double(pmt::tuple_ref(tstamp.value, 1)); uint64_t int_offset = int(abs_sample_cnt - tstamp.offset)/rate; double frac_offset = ((abs_sample_cnt - tstamp.offset) % rate) / double(rate); From 514414f6b3caed015176549a8ee75c456cd1567a Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Thu, 3 Sep 2015 17:39:33 -0700 Subject: [PATCH 24/24] Fix integer truncation issue in tag_to_timestamp(). Thanks to John Ilig for finding it. --- lib/preamble_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/preamble_impl.cc b/lib/preamble_impl.cc index da9143e..c52523d 100644 --- a/lib/preamble_impl.cc +++ b/lib/preamble_impl.cc @@ -128,7 +128,7 @@ static pmt::pmt_t tag_to_timestamp(gr::tag_t tstamp, uint64_t abs_sample_cnt, in double abs_frac = last_frac_stamp + frac_offset; if(abs_frac > 1.0f) { abs_frac -= 1.0f; - abs_whole += 1.0f; + abs_whole += 1; } tstime = pmt::make_tuple(pmt::from_uint64(abs_whole), pmt::from_double(abs_frac));