diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 94354fb..c1b40b9 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -27,7 +27,6 @@ grinclude_HEADERS = \ air_modes_framer.h \ air_modes_slicer.h \ air_modes_types.h \ - modes_energy.h \ modes_parity.h ################################### @@ -52,7 +51,6 @@ air_la_swig_sources = \ air_modes_preamble.cc \ air_modes_framer.cc \ air_modes_slicer.cc \ - modes_energy.cc \ modes_parity.cc # additional arguments to the SWIG command diff --git a/src/lib/air_modes_framer.cc b/src/lib/air_modes_framer.cc index a167a31..56095a1 100644 --- a/src/lib/air_modes_framer.cc +++ b/src/lib/air_modes_framer.cc @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -81,18 +80,18 @@ int air_modes_framer::work(int noutput_items, packet_attrib = Long_Packet; //let's use the preamble marker to get a reference level for the packet - reference_level = (bit_energy(&inraw[i], d_samples_per_chip) - + bit_energy(&inraw[i+int(1.0*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(3.5*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(4.5*d_samples_per_symbol)], d_samples_per_chip)) / 4; + reference_level = (inraw[i] + + inraw[i+int(1.0*d_samples_per_symbol)] + + inraw[i+int(3.5*d_samples_per_symbol)] + + inraw[i+int(4.5*d_samples_per_symbol)]) / 4; //armed with our reference level, let's look for marks within 3dB of the reference level in bits 57-62 (65-70, see above) //if bits 57-62 have marks in either chip, we've got a long packet //otherwise we have a short packet //NOTE: you can change the default here to be short packet, and then check for a long packet. don't know which way is better. for(int j = (65 * d_samples_per_symbol); j < (70 * d_samples_per_symbol); j += d_samples_per_symbol) { - float t_max = std::max(bit_energy(&inraw[i+j], d_samples_per_chip), - bit_energy(&inraw[i+j+d_samples_per_chip], d_samples_per_chip) + float t_max = std::max(inraw[i+j], + inraw[i+j+d_samples_per_chip] ); if(t_max < (reference_level / 2.0)) packet_attrib = Short_Packet; } diff --git a/src/lib/air_modes_preamble.cc b/src/lib/air_modes_preamble.cc index 05a969e..17efbe6 100644 --- a/src/lib/air_modes_preamble.cc +++ b/src/lib/air_modes_preamble.cc @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -54,6 +53,18 @@ air_modes_preamble::air_modes_preamble(int channel_rate, float threshold_db) : set_history(d_check_width); } +static int early_late(const float *data) { + float gate_sum_early, gate_sum_now, gate_sum_late; + + gate_sum_early = data[-1]; + gate_sum_now = data[0]; + gate_sum_late = data[1]; + + if(gate_sum_early > gate_sum_now) return -1; + else if(gate_sum_late > gate_sum_now) return 1; + else return 0; +} + int air_modes_preamble::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) @@ -73,12 +84,12 @@ int air_modes_preamble::work(int noutput_items, uint64_t abs_out_sample_cnt = nitems_written(0); for(int i = d_samples_per_chip; i < size; i++) { - float pulse_threshold = bit_energy(&inavg[i], d_samples_per_chip) * d_threshold; + float pulse_threshold = inavg[i] * d_threshold; bool valid_preamble = false; float gate_sum_now = 0, gate_sum_early = 0, gate_sum_late = 0; - if(bit_energy(&inraw[i], d_samples_per_chip) > pulse_threshold) { //if the sample is greater than the reference level by the specified amount - int gate_sum = early_late(&inraw[i], d_samples_per_chip); //see modes_energy.cc + if(inraw[i] > pulse_threshold) { //if the sample is greater than the reference level by the specified amount + int gate_sum = early_late(&inraw[i]); if(gate_sum != 0) continue; //if either the early gate or the late gate had greater energy, keep moving. //the packets are so short we choose not to do any sort of closed-loop synchronization after this simple gating. //if we get a good center sample, the drift should be negligible. @@ -87,10 +98,10 @@ int air_modes_preamble::work(int noutput_items, pulse_offsets[2] = int(3.5 * d_samples_per_symbol); pulse_offsets[3] = int(4.5 * d_samples_per_symbol); - bit_energies[0] = bit_energy(&inraw[i+pulse_offsets[0]], d_samples_per_chip); - bit_energies[1] = bit_energy(&inraw[i+pulse_offsets[1]], d_samples_per_chip); - bit_energies[2] = bit_energy(&inraw[i+pulse_offsets[2]], d_samples_per_chip); - bit_energies[3] = bit_energy(&inraw[i+pulse_offsets[3]], d_samples_per_chip); + bit_energies[0] = inraw[i+pulse_offsets[0]]; + bit_energies[1] = inraw[i+pulse_offsets[1]]; + bit_energies[2] = inraw[i+pulse_offsets[2]]; + bit_energies[3] = inraw[i+pulse_offsets[3]]; //search for the rest of the pulses at their expected positions if( bit_energies[1] < pulse_threshold) continue; @@ -105,9 +116,9 @@ int air_modes_preamble::work(int noutput_items, //search between pulses and all the way out to 8.0us to make sure there are no pulses inside the "0" chips. make sure all the samples are <= (inraw[peak] * d_threshold). //so 0.5us has to be < space_threshold, as does (1.5-3), 4, (5-7.5) in order to qualify. for(int j = 1.5 * d_samples_per_symbol; j <= 3 * d_samples_per_symbol; j+=d_samples_per_chip) - if(bit_energy(&inraw[i+j], d_samples_per_chip) > space_threshold) valid_preamble = false; + if(inraw[i+j] > space_threshold) valid_preamble = false; for(int j = 5 * d_samples_per_symbol; j <= 7.5 * d_samples_per_symbol; j+=d_samples_per_chip) - if(bit_energy(&inraw[i+j], d_samples_per_chip) > space_threshold) valid_preamble = false; + if(inraw[i+j] > space_threshold) valid_preamble = false; //make sure all four peaks are within 3dB of each other float minpeak = avgpeak * 0.5;//-3db, was 0.631; //-2db @@ -125,20 +136,20 @@ int air_modes_preamble::work(int noutput_items, bool early, late; do { early = late = false; - //gate_sum_early= bit_energy(&inraw[i+pulse_offsets[0]-1], d_samples_per_chip) - // + bit_energy(&inraw[i+pulse_offsets[1]-1], d_samples_per_chip) - // + bit_energy(&inraw[i+pulse_offsets[2]-1], d_samples_per_chip) - // + bit_energy(&inraw[i+pulse_offsets[3]-1], d_samples_per_chip); + //gate_sum_early= inraw[i+pulse_offsets[0]-1] + // + inraw[i+pulse_offsets[1]-1] + // + inraw[i+pulse_offsets[2]-1] + // + inraw[i+pulse_offsets[3]-1]; - gate_sum_now = bit_energy(&inraw[i+pulse_offsets[0]], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[1]], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[2]], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[3]], d_samples_per_chip); + gate_sum_now = inraw[i+pulse_offsets[0]] + + inraw[i+pulse_offsets[1]] + + inraw[i+pulse_offsets[2]] + + inraw[i+pulse_offsets[3]]; - gate_sum_late = bit_energy(&inraw[i+pulse_offsets[0]+1], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[1]+1], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[2]+1], d_samples_per_chip) - + bit_energy(&inraw[i+pulse_offsets[3]+1], d_samples_per_chip); + gate_sum_late = inraw[i+pulse_offsets[0]+1] + + inraw[i+pulse_offsets[1]+1] + + inraw[i+pulse_offsets[2]+1] + + inraw[i+pulse_offsets[3]+1]; early = (gate_sum_early > gate_sum_now); late = (gate_sum_late > gate_sum_now); diff --git a/src/lib/air_modes_slicer.cc b/src/lib/air_modes_slicer.cc index 241c209..acdee8f 100644 --- a/src/lib/air_modes_slicer.cc +++ b/src/lib/air_modes_slicer.cc @@ -30,7 +30,6 @@ #include #include #include -#include #include extern "C" @@ -111,10 +110,10 @@ int air_modes_slicer::work(int noutput_items, rx_packet.numlowconf = 0; //let's use the preamble marker to get a reference level for the packet - rx_packet.reference_level = (bit_energy(&inraw[i], d_samples_per_chip) - + bit_energy(&inraw[i+int(1.0*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(3.5*d_samples_per_symbol)], d_samples_per_chip) - + bit_energy(&inraw[i+int(4.5*d_samples_per_symbol)], d_samples_per_chip)) / 4; + rx_packet.reference_level = (inraw[i] + + inraw[i+int(1.0*d_samples_per_symbol)] + + inraw[i+int(3.5*d_samples_per_symbol)] + + inraw[i+int(4.5*d_samples_per_symbol)]) / 4; i += 8 * d_samples_per_symbol; //move to the center of the first bit of the data @@ -125,8 +124,8 @@ int air_modes_slicer::work(int noutput_items, bool slice, confidence; float firstchip_energy=0, secondchip_energy=0; - firstchip_energy = bit_energy(&inraw[firstchip], d_samples_per_chip); - secondchip_energy = bit_energy(&inraw[secondchip], d_samples_per_chip); + firstchip_energy = inraw[firstchip]; + secondchip_energy = inraw[secondchip]; //3dB limits for bit slicing and confidence measurement float highlimit=rx_packet.reference_level*2; diff --git a/src/lib/modes_energy.cc b/src/lib/modes_energy.cc deleted file mode 100644 index ecb3687..0000000 --- a/src/lib/modes_energy.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* -# Copyright 2010 Nick Foster -# -# This file is part of gr-air-modes -# -# gr-air-modes is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# gr-air-modes is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with gr-air-modes; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# -*/ - -#include -#include - -//helper functions to calculate bit energy and Eb/No - -//this is a really cheesy early/late gate synchronizer. compares bit energy -int early_late(const float *data, int samples_per_chip) { - float gate_sum_early=0, gate_sum_now=0, gate_sum_late=0; - - gate_sum_early = bit_energy(&data[-1], samples_per_chip); - gate_sum_now = bit_energy(&data[0], samples_per_chip); - gate_sum_late = bit_energy(&data[1], samples_per_chip); - - if(gate_sum_early > gate_sum_now) return -1; - else if(gate_sum_late > gate_sum_now) return 1; - else return 0; -} - -//return total bit energy of a chip centered at the current point (we bias right for even samples per chip) -float bit_energy(const float *data, int samples_per_chip) { - return *data; -/* float energy = 0; - if(samples_per_chip <= 2) { - energy = data[0]; - } else { - for(int j = 1-samples_per_chip/2; j < samples_per_chip/2; j++) { - energy += data[j]; - } - } - return energy; -*/ -} diff --git a/src/lib/modes_energy.h b/src/lib/modes_energy.h deleted file mode 100644 index 7cf9c9c..0000000 --- a/src/lib/modes_energy.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -# Copyright 2010 Nick Foster -# -# This file is part of gr-air-modes -# -# gr-air-modes is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# gr-air-modes is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with gr-air-modes; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# -*/ - -#include - -int early_late(const float *data, int samples_per_chip); -float bit_energy(const float *data, int samples_per_chip); diff --git a/src/python/uhd_modes.py b/src/python/uhd_modes.py index b280b26..b2d7a3e 100755 --- a/src/python/uhd_modes.py +++ b/src/python/uhd_modes.py @@ -96,19 +96,22 @@ class adsb_rx_block (gr.top_block): # self.filter = gr.fir_filter_fff(1, self.filtcoeffs) #this is an integrate-and-dump filter to act as a matched filter + #for the essentially rectangular Mode S pulses. + #you could get fancy here and shape it accordingly but i'm pretty + #sure you wouldn't get anything out of it self.filtcoeffs = list(numpy.ones(int(rate/2e6))) #i think downstream blocks can therefore process at 2Msps -- try this #self.filter = gr.fir_filter_fff(int(rate/2e6), self.filtcoeffs) self.filter = gr.fir_filter_fff(1, self.filtcoeffs) + #rate = int(2e6) - #rate = 2e6 self.preamble = air.modes_preamble(rate, options.threshold) self.framer = air.modes_framer(rate) self.slicer = air.modes_slicer(rate, queue) - self.connect(self.u, self.demod) - self.connect(self.demod, self.avg) - self.connect(self.demod, (self.preamble, 0)) + self.connect(self.u, self.demod, self.filter) + self.connect(self.filter, self.avg) + self.connect(self.filter, (self.preamble, 0)) self.connect(self.avg, (self.preamble, 1)) self.connect((self.preamble, 0), (self.framer, 0)) self.connect(self.framer, self.slicer)