rip out the energy stuff, int-and-dump filter takes care of it

This commit is contained in:
Nick Foster
2011-05-30 20:45:59 -07:00
parent f86635430e
commit 52ebfcf4d4
7 changed files with 52 additions and 122 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
*/
}

View File

@@ -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);

View File

@@ -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)