Added channelizer for one channel

pull/61/head
Pieter Robyns 2017-07-28 10:24:22 +02:00
rodzic 1f77075ee1
commit 80902dacca
15 zmienionych plików z 441 dodań i 67 usunięć

Wyświetl plik

@ -111,7 +111,7 @@ find_package(Doxygen)
# components required to the list of GR_REQUIRED_COMPONENTS (in all
# caps such as FILTER or FFT) and change the version to the minimum
# API compatible version required.
set(GR_REQUIRED_COMPONENTS RUNTIME)
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER)
find_package(Gnuradio "3.7.2" REQUIRED)
if(NOT CPPUNIT_FOUND)

Wyświetl plik

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<block>
<name>channelizer</name>
<key>lora_channelizer</key>
<category></category>
<import>import lora</import>
<make>lora.channelizer($in_samp_rate, $out_samp_rate, $center_freq, $channel_list)</make>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>complex</type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>out</name>
<type>complex</type>
</source>
</block>

Wyświetl plik

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<block>
<name>controller</name>
<key>lora_controller</key>
<category></category>
<import>import lora</import>
<make>lora.controller($parent)</make>
</block>

Wyświetl plik

@ -4,19 +4,13 @@
<key>lora_lora_receiver</key>
<category>[LoRa]</category>
<import>import lora</import>
<make>lora.lora_receiver($in_samp_rate, $freq, $offset, $sf, $out_samp_rate, $threshold)</make>
<make>lora.lora_receiver($in_samp_rate, $center_freq, $channel_list, $sf, $out_samp_rate, $threshold)</make>
<callback>set_center_freq($freq)</callback>
<callback>set_sf($sf)</callback>
<callback>set_offset($offset)</callback>
<callback>set_out_samp_rate($out_samp_rate)</callback>
<callback>set_threshold($threshold)</callback>
<param>
<name>Spreading factor</name>
<key>sf</key>
<type>int</type>
</param>
<param>
<name>Sample rate</name>
<key>in_samp_rate</key>
@ -24,24 +18,30 @@
<type>float</type>
</param>
<param>
<name>Detection threshold</name>
<key>threshold</key>
<value>0.01</value>
<type>float</type>
</param>
<param>
<name>Frequency</name>
<key>freq</key>
<name>Center frequency</name>
<key>center_freq</key>
<value>868e6</value>
<type>float</type>
</param>
<param>
<name>Offset</name>
<key>offset</key>
<value>100e3</value>
<name>Channel list</name>
<key>channel_list</key>
<value>[868.1e6]</value>
<type>float_vector</type>
</param>
<param>
<name>Spreading factor</name>
<key>sf</key>
<type>int</type>
</param>
<param>
<name>Detection threshold</name>
<key>threshold</key>
<value>0.01</value>
<type>float</type>
</param>
@ -63,10 +63,4 @@
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>debug</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

Wyświetl plik

@ -24,5 +24,7 @@ install(FILES
api.h
decoder.h
message_file_sink.h
message_socket_sink.h DESTINATION include/lora
message_socket_sink.h
channelizer.h
controller.h DESTINATION include/lora
)

Wyświetl plik

@ -0,0 +1,55 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_LORA_CHANNELIZER_H
#define INCLUDED_LORA_CHANNELIZER_H
#include <lora/api.h>
#include <gnuradio/hier_block2.h>
namespace gr {
namespace lora {
/*!
* \brief <+description of block+>
* \ingroup lora
*
*/
class LORA_API channelizer : virtual public gr::hier_block2
{
public:
typedef boost::shared_ptr<channelizer> sptr;
/*!
* \brief Return a shared_ptr to a new instance of lora::channelizer.
*
* To avoid accidental use of raw pointers, lora::channelizer's
* constructor is in a private implementation
* class. lora::channelizer::make is the public interface for
* creating new instances.
*/
static sptr make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list);
};
} // namespace lora
} // namespace gr
#endif /* INCLUDED_LORA_CHANNELIZER_H */

Wyświetl plik

@ -0,0 +1,55 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_LORA_CONTROLLER_H
#define INCLUDED_LORA_CONTROLLER_H
#include <lora/api.h>
#include <gnuradio/block.h>
namespace gr {
namespace lora {
/*!
* \brief <+description of block+>
* \ingroup lora
*
*/
class channelizer_impl;
class LORA_API controller : virtual public gr::block
{
public:
typedef boost::shared_ptr<controller> sptr;
/*!
* \brief Return a shared_ptr to a new instance of lora::controller.
*
* To avoid accidental use of raw pointers, lora::controller's
* constructor is in a private implementation
* class. lora::controller::make is the public interface for
* creating new instances.
*/
static sptr make(void* parent);
};
} // namespace lora
} // namespace gr
#endif /* INCLUDED_LORA_CONTROLLER_H */

Wyświetl plik

@ -29,6 +29,8 @@ list(APPEND lora_sources
decoder_impl.cc
message_file_sink_impl.cc
message_socket_sink_impl.cc
channelizer_impl.cc
controller_impl.cc
)
set(lora_sources "${lora_sources}" PARENT_SCOPE)

Wyświetl plik

@ -0,0 +1,77 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "channelizer_impl.h"
namespace gr {
namespace lora {
channelizer::sptr
channelizer::make(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list) {
return gnuradio::get_initial_sptr
(new channelizer_impl(in_samp_rate, out_samp_rate, center_freq, channel_list));
}
/*
* The private constructor
*/
channelizer_impl::channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list)
: gr::hier_block2("channelizer",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(channel_list.size(), channel_list.size(), sizeof(gr_complex))),
d_cfo(0.0)
{
d_lpf = gr::filter::firdes::low_pass(1.0, out_samp_rate, 86000, 20000, gr::filter::firdes::WIN_HAMMING, 6.67);
d_freq_offset = channel_list[0] - center_freq;
d_xlating_fir_filter = gr::filter::freq_xlating_fir_filter_ccf::make(1, d_lpf, d_freq_offset, out_samp_rate);
d_controller = gr::lora::controller::make((void*)this);
d_resampler = gr::filter::fractional_resampler_cc::make(0, (float)in_samp_rate / (float)out_samp_rate);
//self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
//Create message ports
message_port_register_hier_in(pmt::intern("control"));
connect(self(), 0, d_resampler, 0);
connect(d_resampler, 0, d_xlating_fir_filter, 0);
connect(d_xlating_fir_filter, 0, self(), 0);
msg_connect(self(), pmt::intern("control"), d_controller, pmt::intern("control"));
}
/*
* Our virtual destructor.
*/
channelizer_impl::~channelizer_impl() {
}
void channelizer_impl::apply_cfo(float cfo) {
d_cfo += cfo;
//std::cout << d_freq_offset + d_cfo << std::endl;
d_xlating_fir_filter->set_center_freq(d_freq_offset + d_cfo);
}
} /* namespace lora */
} /* namespace gr */

Wyświetl plik

@ -0,0 +1,52 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_LORA_CHANNELIZER_IMPL_H
#define INCLUDED_LORA_CHANNELIZER_IMPL_H
#include <lora/channelizer.h>
#include <lora/controller.h>
#include <gnuradio/filter/freq_xlating_fir_filter_ccf.h>
#include <gnuradio/filter/fractional_resampler_cc.h>
#include <gnuradio/filter/firdes.h>
namespace gr {
namespace lora {
class channelizer_impl : public channelizer {
private:
gr::filter::freq_xlating_fir_filter_ccf::sptr d_xlating_fir_filter;
gr::filter::fractional_resampler_cc::sptr d_resampler;
std::vector<float> d_lpf;
float d_cfo;
uint32_t d_freq_offset;
gr::lora::controller::sptr d_controller;
public:
channelizer_impl(float in_samp_rate, float out_samp_rate, float center_freq, std::vector<float> channel_list);
~channelizer_impl();
void apply_cfo(float cfo);
// Where all the action really happens
};
} // namespace lora
} // namespace gr
#endif /* INCLUDED_LORA_CHANNELIZER_IMPL_H */

Wyświetl plik

@ -0,0 +1,68 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "controller_impl.h"
#include "channelizer_impl.h"
namespace gr {
namespace lora {
controller::sptr
controller::make(void* parent) {
return gnuradio::get_initial_sptr
(new controller_impl(parent));
}
/*
* The private constructor
*/
controller_impl::controller_impl(void* parent)
: gr::block("controller",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)) {
d_parent = parent;
d_port = pmt::intern("control");
message_port_register_in(d_port);
set_msg_handler(d_port, boost::bind(&controller_impl::handle_control, this, _1));
}
void controller_impl::handle_control(pmt::pmt_t msg){
if(pmt::symbol_to_string(pmt::car(msg)).compare("cfo") == 0) {
//std::cout << "Setting CFO " << pmt::to_float(pmt::cdr(msg)) << std::endl;
((channelizer_impl*)d_parent)->apply_cfo(pmt::to_float(pmt::cdr(msg))); // TODO: Pretty hacky cast, can we do this in a cleaner way?
}
}
/*
* Our virtual destructor.
*/
controller_impl::~controller_impl()
{
}
} /* namespace lora */
} /* namespace gr */

Wyświetl plik

@ -0,0 +1,46 @@
/* -*- c++ -*- */
/*
* Copyright 2017 Pieter Robyns.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_LORA_CONTROLLER_IMPL_H
#define INCLUDED_LORA_CONTROLLER_IMPL_H
#include <lora/controller.h>
namespace gr {
namespace lora {
class controller_impl : public controller {
private:
void* d_parent;
pmt::pmt_t d_port;
void handle_control(pmt::pmt_t msg);
public:
controller_impl(void* parent);
~controller_impl();
// Where all the action really happens
};
} // namespace lora
} // namespace gr
#endif /* INCLUDED_LORA_CONTROLLER_IMPL_H */

Wyświetl plik

@ -137,7 +137,7 @@ namespace gr {
// Register gnuradio ports
this->message_port_register_out(pmt::mp("frames"));
this->message_port_register_out(pmt::mp("debug"));
this->message_port_register_out(pmt::mp("control"));
// Whitening empty file
@ -775,7 +775,7 @@ namespace gr {
void decoder_impl::msg_raw_chirp_debug(const gr_complex *raw_samples, const uint32_t num_samples) {
pmt::pmt_t chirp_blob = pmt::make_blob(raw_samples, sizeof(gr_complex) * num_samples);
message_port_pub(pmt::mp("debug"), chirp_blob);
//message_port_pub(pmt::mp("debug"), chirp_blob);
}
void decoder_impl::msg_lora_frame(const uint8_t *frame_bytes, const uint32_t frame_len) {

Wyświetl plik

@ -20,76 +20,56 @@
#
from gnuradio import gr
from gnuradio.filter import freq_xlating_fir_filter_ccf, firdes, fractional_resampler_cc
from gnuradio.analog import quadrature_demod_cf
from gnuradio.blocks import null_sink, delay
import lora
import pmt
class lora_receiver(gr.hier_block2):
"""
docstring for block lora_receiver
"""
def __init__(self, in_samp_rate, freq, offset, sf, out_samp_rate, threshold = 0.01):
def __init__(self, in_samp_rate, center_freq, channel_list, sf, out_samp_rate, threshold = 0.01):
gr.hier_block2.__init__(self,
"lora_receiver", # Min, Max, gr.sizeof_<type>
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
gr.io_signature(0, 0, 0)) # Output signature
# Parameters
self.offset = offset
self.sf = sf
self.in_samp_rate = in_samp_rate
self.center_freq = center_freq
self.sf = sf
self.out_samp_rate = out_samp_rate
bw = 125000
self.channel_list = channel_list
# Define blocks
null1 = null_sink(gr.sizeof_float)
null2 = null_sink(gr.sizeof_float)
self.c_decoder = lora.decoder(out_samp_rate, sf)
self.channelizer = lora.channelizer(in_samp_rate, out_samp_rate, center_freq, channel_list)
self.decoder = lora.decoder(out_samp_rate, sf)
self.set_threshold(threshold)
decimation = 1
lpf = firdes.low_pass(1, out_samp_rate, 86000, 20000, firdes.WIN_HAMMING, 6.67)
channelizer = freq_xlating_fir_filter_ccf(decimation, lpf, offset, out_samp_rate)
self.channelizer = channelizer
resampler = fractional_resampler_cc(0, float(in_samp_rate) / float(out_samp_rate))
self.delay = delay(gr.sizeof_gr_complex, int((len(lpf)-1) / 2.0))
# Messages
self.message_port_register_hier_out('debug')
self.message_port_register_hier_out('frames')
# Connect blocks
self.connect( (self, 0), (resampler, 0) )
self.connect( (resampler, 0), (channelizer, 0) )
self.connect( (channelizer, 0), (self.c_decoder, 0) )
self.connect( (resampler, 0), (self.delay, 0) )
self.connect( (self.delay, 0), (self.c_decoder, 1) )
self.msg_connect( (self.c_decoder, 'debug' ), (self, 'debug' ) )
self.msg_connect( (self.c_decoder, 'frames'), (self, 'frames') )
self.connect((self, 0), (self.channelizer, 0))
self.connect((self.channelizer, 0), (self.decoder, 0))
self.msg_connect((self.decoder, 'frames'), (self, 'frames'))
self.msg_connect((self.decoder, 'control'), (self.channelizer, 'control'))
def get_sf(self):
return self.sf
def set_sf(self, sf):
self.sf = sf
## hier_block2 does not have a realtime attribute:
## http://gnuradio.org/doc/sphinx/runtime.html?highlight=hier_block2#gnuradio.gr.hier_block2
# if self.realtime:
self.c_decoder.set_sf(self.sf)
self.decoder.set_sf(self.sf)
def get_offset(self):
return self.offset
def get_center_freq(self):
return self.center_freq
def set_offset(self, offset):
self.offset = offset
self.channelizer.set_center_freq(self.offset)
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.channelizer.set_center_freq(self.center_freq)
def get_threshold(self):
return self.threshold
def set_threshold(self, threshold):
self.threshold = threshold
self.c_decoder.set_abs_threshold(self.threshold)
self.decoder.set_abs_threshold(self.threshold)

Wyświetl plik

@ -11,6 +11,8 @@
#include "lora/decoder.h"
#include "lora/message_file_sink.h"
#include "lora/message_socket_sink.h"
#include "lora/channelizer.h"
#include "lora/controller.h"
%}
@ -20,3 +22,7 @@ GR_SWIG_BLOCK_MAGIC2(lora, decoder);
GR_SWIG_BLOCK_MAGIC2(lora, message_file_sink);
%include "lora/message_socket_sink.h"
GR_SWIG_BLOCK_MAGIC2(lora, message_socket_sink);
%include "lora/channelizer.h"
GR_SWIG_BLOCK_MAGIC2(lora, channelizer);
%include "lora/controller.h"
GR_SWIG_BLOCK_MAGIC2(lora, controller);