Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0236c7d70c | |||
| dd69381a13 | |||
| 092e16f9de | |||
| 35f41a33b6 | |||
| 5bbe1f87ae | |||
| 2ba97c8d6d | |||
| 5ff9e43532 | |||
| 555a0895a5 | |||
| fb3ea60bc4 | |||
| 119d00d17c | |||
| eb6c6509ee | |||
| b5f59f0a2a | |||
| 49fa80691f | |||
| a3c4a21ac1 | |||
| 02ee21184a | |||
| 6f86f92ff4 | |||
| c171d3501a | |||
| 7bf5d07e94 | |||
| d32db7df76 |
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Channel Model</name>
|
||||||
|
<key>foo_channel_model</key>
|
||||||
|
<category>[Foo]</category>
|
||||||
|
<import>import foo</import>
|
||||||
|
<make>foo.channel_model(
|
||||||
|
noise_voltage=$noise_voltage,
|
||||||
|
frequency_offset=$freq_offset,
|
||||||
|
epsilon=$epsilon,
|
||||||
|
taps=$taps,
|
||||||
|
noise_seed=$seed,
|
||||||
|
block_tags=$block_tags
|
||||||
|
)</make>
|
||||||
|
<callback>set_noise_voltage($noise_voltage)</callback>
|
||||||
|
<callback>set_frequency_offset($freq_offset)</callback>
|
||||||
|
<callback>set_taps($taps)</callback>
|
||||||
|
<callback>set_timing_offset($epsilon)</callback>
|
||||||
|
<param>
|
||||||
|
<name>Noise Voltage</name>
|
||||||
|
<key>noise_voltage</key>
|
||||||
|
<value>0.0</value>
|
||||||
|
<type>real</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Frequency Offset</name>
|
||||||
|
<key>freq_offset</key>
|
||||||
|
<value>0.0</value>
|
||||||
|
<type>real</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Epsilon</name>
|
||||||
|
<key>epsilon</key>
|
||||||
|
<value>1.0</value>
|
||||||
|
<type>real</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Taps</name>
|
||||||
|
<key>taps</key>
|
||||||
|
<value>1.0 + 1.0j</value>
|
||||||
|
<type>complex_vector</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Seed</name>
|
||||||
|
<key>seed</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Block Tag Propagation</name>
|
||||||
|
<key>block_tags</key>
|
||||||
|
<value>False</value>
|
||||||
|
<type>enum</type>
|
||||||
|
<hide>$block_tags.hide_block</hide>
|
||||||
|
<option>
|
||||||
|
<name>Yes</name>
|
||||||
|
<key>True</key>
|
||||||
|
<opt>hide_block:</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>No</name>
|
||||||
|
<key>False</key>
|
||||||
|
<opt>hide_block:part</opt>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
<sink>
|
||||||
|
<name>in</name>
|
||||||
|
<type>complex</type>
|
||||||
|
</sink>
|
||||||
|
<source>
|
||||||
|
<name>out</name>
|
||||||
|
<type>complex</type>
|
||||||
|
</source>
|
||||||
|
</block>
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Selector</name>
|
||||||
|
<key>foo_selector</key>
|
||||||
|
<category>[Foo]</category>
|
||||||
|
<import>import foo</import>
|
||||||
|
<make>foo.selector(
|
||||||
|
item_size=$type.size*$vlen,
|
||||||
|
num_inputs=$num_inputs,
|
||||||
|
num_outputs=$num_outputs,
|
||||||
|
input_index=$input_index,
|
||||||
|
output_index=$output_index,
|
||||||
|
)</make>
|
||||||
|
<callback>set_input_index(int($input_index))</callback>
|
||||||
|
<callback>set_output_index(int($output_index))</callback>
|
||||||
|
<param>
|
||||||
|
<name>Type</name>
|
||||||
|
<key>type</key>
|
||||||
|
<type>enum</type>
|
||||||
|
<option>
|
||||||
|
<name>Complex</name>
|
||||||
|
<key>complex</key>
|
||||||
|
<opt>size:gr.sizeof_gr_complex</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Float</name>
|
||||||
|
<key>float</key>
|
||||||
|
<opt>size:gr.sizeof_float</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Int</name>
|
||||||
|
<key>int</key>
|
||||||
|
<opt>size:gr.sizeof_int</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Short</name>
|
||||||
|
<key>short</key>
|
||||||
|
<opt>size:gr.sizeof_short</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Byte</name>
|
||||||
|
<key>byte</key>
|
||||||
|
<opt>size:gr.sizeof_char</opt>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Num Inputs</name>
|
||||||
|
<key>num_inputs</key>
|
||||||
|
<value>2</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Num Outputs</name>
|
||||||
|
<key>num_outputs</key>
|
||||||
|
<value>2</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Input Index</name>
|
||||||
|
<key>input_index</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Output Index</name>
|
||||||
|
<key>output_index</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Vec Length</name>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<check>$vlen > 0</check>
|
||||||
|
<sink>
|
||||||
|
<name>in</name>
|
||||||
|
<type>$type</type>
|
||||||
|
<vlen>$vlen</vlen>
|
||||||
|
<nports>$num_inputs</nports>
|
||||||
|
</sink>
|
||||||
|
<source>
|
||||||
|
<name>out</name>
|
||||||
|
<type>$type</type>
|
||||||
|
<vlen>$vlen</vlen>
|
||||||
|
<nports>$num_outputs</nports>
|
||||||
|
</source>
|
||||||
|
<doc>
|
||||||
|
Connect the sink at input index to the source at output index. Leave all other ports disconnected.
|
||||||
|
</doc>
|
||||||
|
</block>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Valve</name>
|
||||||
|
<key>foo_valve</key>
|
||||||
|
<category>[Foo]</category>
|
||||||
|
<import>import foo</import>
|
||||||
|
<make>foo.valve(item_size=$type.size*$vlen, open=bool($open))</make>
|
||||||
|
<callback>set_open(bool($open))</callback>
|
||||||
|
<param>
|
||||||
|
<name>Type</name>
|
||||||
|
<key>type</key>
|
||||||
|
<type>enum</type>
|
||||||
|
<option>
|
||||||
|
<name>Complex</name>
|
||||||
|
<key>complex</key>
|
||||||
|
<opt>size:gr.sizeof_gr_complex</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Float</name>
|
||||||
|
<key>float</key>
|
||||||
|
<opt>size:gr.sizeof_float</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Int</name>
|
||||||
|
<key>int</key>
|
||||||
|
<opt>size:gr.sizeof_int</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Short</name>
|
||||||
|
<key>short</key>
|
||||||
|
<opt>size:gr.sizeof_short</opt>
|
||||||
|
</option>
|
||||||
|
<option>
|
||||||
|
<name>Byte</name>
|
||||||
|
<key>byte</key>
|
||||||
|
<opt>size:gr.sizeof_char</opt>
|
||||||
|
</option>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Open</name>
|
||||||
|
<key>open</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>raw</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Vec Length</name>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
<type>int</type>
|
||||||
|
</param>
|
||||||
|
<check>$vlen > 0</check>
|
||||||
|
<sink>
|
||||||
|
<name>in</name>
|
||||||
|
<type>$type</type>
|
||||||
|
<vlen>$vlen</vlen>
|
||||||
|
<nports>$num_inputs</nports>
|
||||||
|
</sink>
|
||||||
|
<source>
|
||||||
|
<name>out</name>
|
||||||
|
<type>$type</type>
|
||||||
|
<vlen>$vlen</vlen>
|
||||||
|
<nports>$num_outputs</nports>
|
||||||
|
</source>
|
||||||
|
<doc>
|
||||||
|
Connect output to input when valve is closed (not open).
|
||||||
|
</doc>
|
||||||
|
</block>
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
install(FILES
|
install(FILES
|
||||||
api.h
|
api.h
|
||||||
burst_tagger.h
|
burst_tagger.h
|
||||||
|
channel_model.h
|
||||||
packet_dropper.h
|
packet_dropper.h
|
||||||
packet_pad.h
|
packet_pad.h
|
||||||
packet_pad2.h
|
packet_pad2.h
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Bastian Bloessl <mail@bastibl.net>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_FOO_CHANNEL_MODEL_H
|
||||||
|
#define INCLUDED_FOO_CHANNEL_MODEL_H
|
||||||
|
|
||||||
|
#include <foo/api.h>
|
||||||
|
#include <gnuradio/hier_block2.h>
|
||||||
|
#include <gnuradio/types.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace foo {
|
||||||
|
|
||||||
|
class FOO_API channel_model : virtual public hier_block2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<channel_model> sptr;
|
||||||
|
|
||||||
|
static sptr make(double noise_voltage = 0.0, double frequency_offset = 0.0,
|
||||||
|
double epsilon = 1.0,
|
||||||
|
const std::vector<gr_complex> &taps = std::vector<gr_complex>(1, 1),
|
||||||
|
double noise_seed = 0, bool block_tags = false);
|
||||||
|
|
||||||
|
virtual void set_noise_voltage(double noise_voltage) = 0;
|
||||||
|
virtual void set_frequency_offset(double frequency_offset) = 0;
|
||||||
|
virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
|
||||||
|
virtual void set_timing_offset(double epsilon) = 0;
|
||||||
|
|
||||||
|
virtual double noise_voltage() const = 0;
|
||||||
|
virtual double frequency_offset() const = 0;
|
||||||
|
virtual std::vector<gr_complex> taps() const = 0;
|
||||||
|
virtual double timing_offset() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foo
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_FOO_CHANNEL_MODEL_H */
|
||||||
+1
-18
@@ -33,6 +33,7 @@ link_directories(
|
|||||||
|
|
||||||
list(APPEND foo_sources
|
list(APPEND foo_sources
|
||||||
burst_tagger_impl.cc
|
burst_tagger_impl.cc
|
||||||
|
channel_model_impl.cc
|
||||||
packet_dropper_impl.cc
|
packet_dropper_impl.cc
|
||||||
packet_pad2.cc
|
packet_pad2.cc
|
||||||
packet_pad_impl.cc
|
packet_pad_impl.cc
|
||||||
@@ -42,24 +43,6 @@ list(APPEND foo_sources
|
|||||||
wireshark_connector_impl.cc
|
wireshark_connector_impl.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PACKAGE_FIND_VERSION_MAJOR 0)
|
|
||||||
include(GnuradioConfigVersion)
|
|
||||||
|
|
||||||
if(${API_COMPAT} EQUAL 8)
|
|
||||||
message(STATUS "next branch (3.8 install), using new API")
|
|
||||||
add_definitions("-DGR_FOO_NEW_API")
|
|
||||||
elseif(${MINOR_VERSION} GREATER 7)
|
|
||||||
message(STATUS "recent 3.7.8 install, using new API")
|
|
||||||
add_definitions("-DGR_FOO_NEW_API")
|
|
||||||
elseif(${MINOR_VERSION} EQUAL 7 AND NOT ${MAINT_VERSION} STREQUAL "git")
|
|
||||||
message(STATUS "recent real 3.7.7 install, using new API")
|
|
||||||
add_definitions("-DGR_FOO_NEW_API")
|
|
||||||
elseif(${MINOR_VERSION} EQUAL 6 AND NOT ${MAINT_VERSION} STREQUAL "git" AND ${MAINT_VERSION} GREATER 0)
|
|
||||||
message(STATUS "3.7.6 with maint version >= 1 install, using new API")
|
|
||||||
add_definitions("-DGR_FOO_NEW_API")
|
|
||||||
else()
|
|
||||||
message(STATUS "using old API")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(gnuradio-foo SHARED ${foo_sources})
|
add_library(gnuradio-foo SHARED ${foo_sources})
|
||||||
target_link_libraries(gnuradio-foo ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES} ${UHD_LIBRARIES})
|
target_link_libraries(gnuradio-foo ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES} ${UHD_LIBRARIES})
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Bastian Bloessl <mail@bastibl.net>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "channel_model_impl.h"
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace foo {
|
||||||
|
|
||||||
|
channel_model::sptr
|
||||||
|
channel_model::make(double noise_voltage,
|
||||||
|
double frequency_offset,
|
||||||
|
double epsilon,
|
||||||
|
const std::vector<gr_complex> &taps,
|
||||||
|
double noise_seed,
|
||||||
|
bool block_tags)
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new channel_model_impl(noise_voltage,
|
||||||
|
frequency_offset,
|
||||||
|
epsilon,
|
||||||
|
taps,
|
||||||
|
noise_seed,
|
||||||
|
block_tags));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hierarchical block constructor
|
||||||
|
channel_model_impl::channel_model_impl(double noise_voltage,
|
||||||
|
double frequency_offset,
|
||||||
|
double epsilon,
|
||||||
|
const std::vector<gr_complex> &taps,
|
||||||
|
double noise_seed,
|
||||||
|
bool block_tags
|
||||||
|
)
|
||||||
|
: hier_block2("channel_model",
|
||||||
|
io_signature::make(1, 1, sizeof(gr_complex)),
|
||||||
|
io_signature::make(1, 1, sizeof(gr_complex)))
|
||||||
|
{
|
||||||
|
d_taps = taps;
|
||||||
|
while(d_taps.size() < 2) {
|
||||||
|
d_taps.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
d_timing_offset = filter::mmse_resampler_cc::make(0, epsilon);
|
||||||
|
|
||||||
|
d_multipath = filter::fir_filter_ccc::make(1, d_taps);
|
||||||
|
|
||||||
|
d_noise_adder = blocks::add_cc::make();
|
||||||
|
d_noise = analog::noise_source_c::make(analog::GR_GAUSSIAN,
|
||||||
|
noise_voltage, noise_seed);
|
||||||
|
d_freq_offset = analog::sig_source_c::make(1, analog::GR_SIN_WAVE,
|
||||||
|
frequency_offset, 1.0, 0.0);
|
||||||
|
d_mixer_offset = blocks::multiply_cc::make();
|
||||||
|
|
||||||
|
connect(self(), 0, d_timing_offset, 0);
|
||||||
|
connect(d_timing_offset, 0, d_multipath, 0);
|
||||||
|
connect(d_multipath, 0, d_mixer_offset, 0);
|
||||||
|
connect(d_freq_offset, 0, d_mixer_offset, 1);
|
||||||
|
connect(d_mixer_offset, 0, d_noise_adder, 1);
|
||||||
|
connect(d_noise, 0, d_noise_adder, 0);
|
||||||
|
connect(d_noise_adder, 0, self(), 0);
|
||||||
|
|
||||||
|
if (block_tags) {
|
||||||
|
d_timing_offset->set_tag_propagation_policy(gr::block::TPP_DONT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_model_impl::~channel_model_impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
channel_model_impl::set_noise_voltage(double noise_voltage)
|
||||||
|
{
|
||||||
|
d_noise->set_amplitude(noise_voltage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
channel_model_impl::set_frequency_offset(double frequency_offset)
|
||||||
|
{
|
||||||
|
d_freq_offset->set_frequency(frequency_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
channel_model_impl::set_taps(const std::vector<gr_complex> &taps)
|
||||||
|
{
|
||||||
|
d_taps = taps;
|
||||||
|
while(d_taps.size() < 2) {
|
||||||
|
d_taps.push_back(0);
|
||||||
|
}
|
||||||
|
d_multipath->set_taps(d_taps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
channel_model_impl::set_timing_offset(double epsilon)
|
||||||
|
{
|
||||||
|
d_timing_offset->set_resamp_ratio(epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
channel_model_impl::noise_voltage() const
|
||||||
|
{
|
||||||
|
return d_noise->amplitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
channel_model_impl::frequency_offset() const
|
||||||
|
{
|
||||||
|
return d_freq_offset->frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<gr_complex>
|
||||||
|
channel_model_impl::taps() const
|
||||||
|
{
|
||||||
|
return d_multipath->taps();
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
channel_model_impl::timing_offset() const
|
||||||
|
{
|
||||||
|
return d_timing_offset->resamp_ratio();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace channels */
|
||||||
|
} /* namespace gr */
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Bastian Bloessl <mail@bastibl.net>
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_FOO_CHANNEL_MODEL_IMPL_H
|
||||||
|
#define INCLUDED_FOO_CHANNEL_MODEL_IMPL_H
|
||||||
|
|
||||||
|
#include <foo/channel_model.h>
|
||||||
|
|
||||||
|
#include <gnuradio/top_block.h>
|
||||||
|
#include <gnuradio/blocks/add_cc.h>
|
||||||
|
#include <gnuradio/blocks/multiply_cc.h>
|
||||||
|
#include <gnuradio/analog/sig_source_c.h>
|
||||||
|
#include <gnuradio/analog/noise_source_c.h>
|
||||||
|
#include <gnuradio/filter/mmse_resampler_cc.h>
|
||||||
|
#include <gnuradio/filter/fir_filter_ccc.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace foo {
|
||||||
|
|
||||||
|
class FOO_API channel_model_impl : public foo::channel_model
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
blocks::add_cc::sptr d_noise_adder;
|
||||||
|
blocks::multiply_cc::sptr d_mixer_offset;
|
||||||
|
|
||||||
|
analog::sig_source_c::sptr d_freq_offset;
|
||||||
|
analog::noise_source_c::sptr d_noise;
|
||||||
|
|
||||||
|
filter::mmse_resampler_cc::sptr d_timing_offset;
|
||||||
|
filter::fir_filter_ccc::sptr d_multipath;
|
||||||
|
|
||||||
|
std::vector<gr_complex> d_taps;
|
||||||
|
|
||||||
|
public:
|
||||||
|
channel_model_impl(double noise_voltage,
|
||||||
|
double frequency_offset,
|
||||||
|
double epsilon,
|
||||||
|
const std::vector<gr_complex> &taps,
|
||||||
|
double noise_seed,
|
||||||
|
bool block_tags);
|
||||||
|
|
||||||
|
~channel_model_impl();
|
||||||
|
|
||||||
|
void set_noise_voltage(double noise_voltage);
|
||||||
|
void set_frequency_offset(double frequency_offset);
|
||||||
|
void set_taps(const std::vector<gr_complex> &taps);
|
||||||
|
void set_timing_offset(double epsilon);
|
||||||
|
|
||||||
|
double noise_voltage() const;
|
||||||
|
double frequency_offset() const;
|
||||||
|
std::vector<gr_complex> taps() const;
|
||||||
|
double timing_offset() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foo
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_FOO_CHANNEL_MODEL_IMPL_H */
|
||||||
@@ -54,8 +54,6 @@ periodic_msg_source_impl::~periodic_msg_source_impl() {
|
|||||||
void
|
void
|
||||||
periodic_msg_source_impl::run(periodic_msg_source_impl *instance) {
|
periodic_msg_source_impl::run(periodic_msg_source_impl *instance) {
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// flow graph startup delay
|
// flow graph startup delay
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
||||||
|
|
||||||
@@ -67,8 +65,7 @@ periodic_msg_source_impl::run(periodic_msg_source_impl *instance) {
|
|||||||
d_finished = true;
|
d_finished = true;
|
||||||
if(d_quit) {
|
if(d_quit) {
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
||||||
message_port_pub( pmt::mp("out"), pmt::PMT_EOF);
|
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::PMT_T));
|
||||||
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -85,17 +82,6 @@ periodic_msg_source_impl::run(periodic_msg_source_impl *instance) {
|
|||||||
}
|
}
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(boost::thread_interrupted) {
|
|
||||||
gr::thread::scoped_lock(d_mutex);
|
|
||||||
dout << "PMS: thread interrupted" << std::endl;
|
|
||||||
d_finished = true;
|
|
||||||
if(d_quit) {
|
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
|
||||||
message_port_pub( pmt::mp("out"), pmt::PMT_EOF);
|
|
||||||
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ random_periodic_msg_source_impl::~random_periodic_msg_source_impl() {
|
|||||||
void
|
void
|
||||||
random_periodic_msg_source_impl::run(random_periodic_msg_source_impl *instance) {
|
random_periodic_msg_source_impl::run(random_periodic_msg_source_impl *instance) {
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// flow graph startup delay
|
// flow graph startup delay
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
||||||
|
|
||||||
@@ -72,8 +70,7 @@ random_periodic_msg_source_impl::run(random_periodic_msg_source_impl *instance)
|
|||||||
d_finished = true;
|
d_finished = true;
|
||||||
if(d_quit) {
|
if(d_quit) {
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
||||||
message_port_pub( pmt::mp("out"), pmt::PMT_EOF);
|
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::PMT_T));
|
||||||
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -91,17 +88,6 @@ random_periodic_msg_source_impl::run(random_periodic_msg_source_impl *instance)
|
|||||||
}
|
}
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(boost::thread_interrupted) {
|
|
||||||
gr::thread::scoped_lock(d_mutex);
|
|
||||||
dout << "PMS: thread interrupted" << std::endl;
|
|
||||||
d_finished = true;
|
|
||||||
if(d_quit) {
|
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
|
|
||||||
message_port_pub( pmt::mp("out"), pmt::PMT_EOF);
|
|
||||||
post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a random message
|
// Generate a random message
|
||||||
|
|||||||
@@ -181,11 +181,7 @@ wireshark_connector_impl::general_work(int noutput, gr_vector_int& ninput_items,
|
|||||||
gr_complex *out = (gr_complex*)output_items[0];
|
gr_complex *out = (gr_complex*)output_items[0];
|
||||||
|
|
||||||
if(!d_msg_len) {
|
if(!d_msg_len) {
|
||||||
#ifdef GR_FOO_NEW_API
|
pmt::pmt_t msg(delete_head_nowait(pmt::mp("in")));
|
||||||
pmt::pmt_t msg(delete_head_blocking(pmt::mp("in"), 100));
|
|
||||||
#else
|
|
||||||
pmt::pmt_t msg(delete_head_blocking(pmt::mp("in")));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!msg) {
|
if(!msg) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ endif()
|
|||||||
GR_PYTHON_INSTALL(
|
GR_PYTHON_INSTALL(
|
||||||
FILES
|
FILES
|
||||||
__init__.py
|
__init__.py
|
||||||
|
selector.py
|
||||||
DESTINATION ${GR_PYTHON_DIR}/foo
|
DESTINATION ${GR_PYTHON_DIR}/foo
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ if _RTLD_GLOBAL != 0:
|
|||||||
|
|
||||||
# import swig generated symbols into the foo namespace
|
# import swig generated symbols into the foo namespace
|
||||||
from foo_swig import *
|
from foo_swig import *
|
||||||
|
from selector import *
|
||||||
|
|
||||||
# import any pure python here
|
# import any pure python here
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2017 Bastian Bloessl <mail@bastibl.net>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from gnuradio import gr
|
||||||
|
from gnuradio import blocks
|
||||||
|
|
||||||
|
class selector(gr.hier_block2):
|
||||||
|
"""A hier2 block with N inputs and M outputs, where data is only forwarded through input n to output m."""
|
||||||
|
def __init__(self, item_size, num_inputs, num_outputs, input_index, output_index):
|
||||||
|
"""
|
||||||
|
Selector constructor.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item_size: the size of the gr data stream in bytes
|
||||||
|
num_inputs: the number of inputs (integer)
|
||||||
|
num_outputs: the number of outputs (integer)
|
||||||
|
input_index: the index for the source data
|
||||||
|
output_index: the index for the destination data
|
||||||
|
"""
|
||||||
|
gr.hier_block2.__init__(
|
||||||
|
self, 'selector',
|
||||||
|
gr.io_signature(num_inputs, num_inputs, item_size),
|
||||||
|
gr.io_signature(num_outputs, num_outputs, item_size),
|
||||||
|
)
|
||||||
|
|
||||||
|
#terminator blocks for unused inputs and outputs
|
||||||
|
self.input_terminators = [blocks.null_sink(item_size) for i in range(num_inputs)]
|
||||||
|
self.output_terminators = [blocks.head(item_size, 0) for i in range(num_outputs)]
|
||||||
|
self.copy = blocks.copy(item_size)
|
||||||
|
#connections
|
||||||
|
for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
|
||||||
|
for i in range(num_outputs): self.connect(blocks.null_source(item_size),
|
||||||
|
self.output_terminators[i], (self, i))
|
||||||
|
self.item_size = item_size
|
||||||
|
self.input_index = input_index
|
||||||
|
self.output_index = output_index
|
||||||
|
self.num_inputs = num_inputs
|
||||||
|
self.num_outputs = num_outputs
|
||||||
|
self._connect_current()
|
||||||
|
|
||||||
|
def _indexes_valid(self):
|
||||||
|
"""
|
||||||
|
Are the input and output indexes within range of the number of inputs and outputs?
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
true if input index and output index are in range
|
||||||
|
"""
|
||||||
|
return self.input_index in range(self.num_inputs) and self.output_index in range(self.num_outputs)
|
||||||
|
|
||||||
|
def _connect_current(self):
|
||||||
|
"""If the input and output indexes are valid:
|
||||||
|
disconnect the blocks at the input and output index from their terminators,
|
||||||
|
and connect them to one another. Then connect the terminators to one another."""
|
||||||
|
if self._indexes_valid():
|
||||||
|
self.disconnect((self, self.input_index), self.input_terminators[self.input_index])
|
||||||
|
self.disconnect(self.output_terminators[self.output_index], (self, self.output_index))
|
||||||
|
self.connect((self, self.input_index), self.copy)
|
||||||
|
self.connect(self.copy, (self, self.output_index))
|
||||||
|
self.connect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
|
||||||
|
|
||||||
|
def _disconnect_current(self):
|
||||||
|
"""If the input and output indexes are valid:
|
||||||
|
disconnect the blocks at the input and output index from one another,
|
||||||
|
and the terminators at the input and output index from one another.
|
||||||
|
Reconnect the blocks to the terminators."""
|
||||||
|
if self._indexes_valid():
|
||||||
|
self.disconnect((self, self.input_index), self.copy)
|
||||||
|
self.disconnect(self.copy, (self, self.output_index))
|
||||||
|
self.disconnect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
|
||||||
|
self.connect((self, self.input_index), self.input_terminators[self.input_index])
|
||||||
|
self.connect(self.output_terminators[self.output_index], (self, self.output_index))
|
||||||
|
|
||||||
|
def set_input_index(self, input_index):
|
||||||
|
"""
|
||||||
|
Change the block to the new input index if the index changed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_index: the new input index
|
||||||
|
"""
|
||||||
|
if self.input_index != input_index:
|
||||||
|
self.lock()
|
||||||
|
self._disconnect_current()
|
||||||
|
self.input_index = input_index
|
||||||
|
self._connect_current()
|
||||||
|
self.unlock()
|
||||||
|
|
||||||
|
def set_output_index(self, output_index):
|
||||||
|
"""
|
||||||
|
Change the block to the new output index if the index changed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
output_index: the new output index
|
||||||
|
"""
|
||||||
|
if self.output_index != output_index:
|
||||||
|
self.lock()
|
||||||
|
self._disconnect_current()
|
||||||
|
self.output_index = output_index
|
||||||
|
self._connect_current()
|
||||||
|
self.unlock()
|
||||||
|
|
||||||
|
class valve(selector):
|
||||||
|
"""Wrapper for selector with 1 input and 1 output."""
|
||||||
|
|
||||||
|
def __init__(self, item_size, open):
|
||||||
|
"""
|
||||||
|
Constructor for valve.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item_size: the size of the gr data stream in bytes
|
||||||
|
open: true if initial valve state is open
|
||||||
|
"""
|
||||||
|
if open: output_index = -1
|
||||||
|
else: output_index = 0
|
||||||
|
selector.__init__(self, item_size, 1, 1, 0, output_index)
|
||||||
|
|
||||||
|
def set_open(self, open):
|
||||||
|
"""
|
||||||
|
Callback to set open state.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
open: true to set valve state to open
|
||||||
|
"""
|
||||||
|
if open: output_index = -1
|
||||||
|
else: output_index = 0
|
||||||
|
self.set_output_index(output_index)
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
%{
|
%{
|
||||||
#include "foo/burst_tagger.h"
|
#include "foo/burst_tagger.h"
|
||||||
|
#include "foo/channel_model.h"
|
||||||
#include "foo/packet_dropper.h"
|
#include "foo/packet_dropper.h"
|
||||||
#include "foo/packet_pad.h"
|
#include "foo/packet_pad.h"
|
||||||
#include "foo/packet_pad2.h"
|
#include "foo/packet_pad2.h"
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
|
|
||||||
|
|
||||||
%include "foo/burst_tagger.h"
|
%include "foo/burst_tagger.h"
|
||||||
|
%include "foo/channel_model.h"
|
||||||
%include "foo/packet_dropper.h"
|
%include "foo/packet_dropper.h"
|
||||||
%include "foo/packet_pad.h"
|
%include "foo/packet_pad.h"
|
||||||
%include "foo/packet_pad2.h"
|
%include "foo/packet_pad2.h"
|
||||||
@@ -27,6 +29,7 @@
|
|||||||
%include "foo/wireshark_connector.h"
|
%include "foo/wireshark_connector.h"
|
||||||
|
|
||||||
GR_SWIG_BLOCK_MAGIC2(foo, burst_tagger);
|
GR_SWIG_BLOCK_MAGIC2(foo, burst_tagger);
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(foo, channel_model);
|
||||||
GR_SWIG_BLOCK_MAGIC2(foo, packet_dropper);
|
GR_SWIG_BLOCK_MAGIC2(foo, packet_dropper);
|
||||||
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad);
|
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad);
|
||||||
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad2);
|
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad2);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
import sys, time
|
import sys, time
|
||||||
|
|
||||||
from gnuradio import gr, ctrlport
|
from gnuradio import gr, ctrlport
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
class MyApp(object):
|
class MyApp(object):
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
@@ -63,7 +64,7 @@ class MyApp(object):
|
|||||||
client.setKnobs(knobs)
|
client.setKnobs(knobs)
|
||||||
|
|
||||||
# let the flow graph run for some time
|
# let the flow graph run for some time
|
||||||
time.sleep(30)
|
time.sleep(60)
|
||||||
|
|
||||||
## get work time for all blocks
|
## get work time for all blocks
|
||||||
kl = map(lambda x: "%s::total work time" % x, blocks)
|
kl = map(lambda x: "%s::total work time" % x, blocks)
|
||||||
@@ -75,4 +76,7 @@ class MyApp(object):
|
|||||||
|
|
||||||
print(",".join(map(lambda x: str(x[1]), sorted(work_times.items()))))
|
print(",".join(map(lambda x: str(x[1]), sorted(work_times.items()))))
|
||||||
|
|
||||||
|
p = Popen("uptime", stdout=PIPE, close_fds=True, shell=True)
|
||||||
|
print(p.stdout.read())
|
||||||
|
|
||||||
MyApp(sys.argv)
|
MyApp(sys.argv)
|
||||||
|
|||||||
Reference in New Issue
Block a user