rip out the energy stuff, int-and-dump filter takes care of it
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <air_modes_framer.h>
|
||||
#include <gr_io_signature.h>
|
||||
#include <air_modes_types.h>
|
||||
#include <modes_energy.h>
|
||||
#include <gr_tag_info.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <air_modes_preamble.h>
|
||||
#include <gr_io_signature.h>
|
||||
#include <modes_energy.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <modes_parity.h>
|
||||
#include <modes_energy.h>
|
||||
#include <gr_tag_info.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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 <air_modes_types.h>
|
||||
#include <modes_energy.h>
|
||||
|
||||
//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;
|
||||
*/
|
||||
}
|
||||
@@ -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 <air_modes_types.h>
|
||||
|
||||
int early_late(const float *data, int samples_per_chip);
|
||||
float bit_energy(const float *data, int samples_per_chip);
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user