Add a generic clear text message sink.

For now the generic clear text message sink just prints the decoded
clear text messages in the stdout. In the future and depending the needs
of the project, the clear text messages can be forwarded at other
services on the same host or via the network.

Also the debug message source block now supports injection of artificial
errors, for more robust decoding of the Morse decoder block.
This commit is contained in:
Manolis Surligas 2016-01-24 21:43:17 +02:00
parent 52411357a7
commit 5d4884cf0d
18 changed files with 387 additions and 88 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ apps/*.py
.cproject
.pyproject
.pydevproject
nbproject/

View File

@ -5,9 +5,9 @@ for decoding signals from various scientific and academic sattelites.
## Install
### Requirements
1. GNU Radio
2. CMake
3. G++
1. GNU Radio ( > 3.7.2 )
2. CMake ( > 3.1)
3. G++ (with C++11 support)
4. VOLK
5. git

View File

@ -109,7 +109,7 @@
</param>
</block>
<block>
<key>satnogs_morse_debug_source</key>
<key>satnogs_clear_text_msg_sink</key>
<param>
<key>alias</key>
<value></value>
@ -126,6 +126,41 @@
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(944, 184)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>satnogs_clear_text_msg_sink_0</value>
</param>
</block>
<block>
<key>satnogs_morse_debug_source</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>p</key>
<value>0.1</value>
</param>
<param>
<key>_coordinate</key>
<value>(240, 196)</value>
@ -138,6 +173,10 @@
<key>id</key>
<value>satnogs_morse_debug_source_0</value>
</param>
<param>
<key>errors</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
@ -148,7 +187,7 @@
</param>
<param>
<key>debug_seq</key>
<value>"HELLO EARTH WORLD"</value>
<value>"HELLO EARTH WORLD 123456789"</value>
</param>
</block>
<block>
@ -171,7 +210,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(752, 276)</value>
<value>(672, 180)</value>
</param>
<param>
<key>_rotation</key>
@ -181,6 +220,14 @@
<key>id</key>
<value>satnogs_morse_decoder_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>unrecognized_char</key>
<value>ord('#')</value>
@ -192,4 +239,10 @@
<source_key>out</source_key>
<sink_key>in</sink_key>
</connection>
<connection>
<source_block_id>satnogs_morse_decoder_0</source_block_id>
<sink_block_id>satnogs_clear_text_msg_sink_0</sink_block_id>
<source_key>out</source_key>
<sink_key>in</sink_key>
</connection>
</flow_graph>

View File

@ -19,5 +19,6 @@
install(FILES
satnogs_cw_matched_filter_ff.xml
satnogs_morse_decoder.xml
satnogs_morse_debug_source.xml DESTINATION share/gnuradio/grc/blocks
satnogs_morse_debug_source.xml
satnogs_clear_text_msg_sink.xml DESTINATION share/gnuradio/grc/blocks
)

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<block>
<name>Clear Text Message Sink</name>
<key>satnogs_clear_text_msg_sink</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.clear_text_msg_sink()</make>
<sink>
<name>in</name>
<type>message</type>
</sink>
</block>

View File

@ -1,37 +1,38 @@
<?xml version="1.0"?>
<block>
<name>CW Matched Filter</name>
<key>satnogs_cw_matched_filter_ff</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm)</make>
<name>CW Matched Filter</name>
<key>satnogs_cw_matched_filter_ff</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm)
</make>
<param>
<name>Sampling Rate</name>
<key>sampling_rate</key>
<type>real</type>
</param>
<param>
<name>Audio Frequency (Hz)</name>
<key>carrier_freq</key>
<type>real</type>
</param>
<param>
<name>Words per Minute</name>
<key>wpm</key>
<value>20</value>
<type>int</type>
</param>
<param>
<name>Sampling Rate</name>
<key>sampling_rate</key>
<type>real</type>
</param>
<sink>
<name>in</name>
<type>float</type>
</sink>
<param>
<name>Audio Frequency (Hz)</name>
<key>carrier_freq</key>
<type>real</type>
</param>
<source>
<name>out</name>
<type>float</type>
</source>
<param>
<name>Words per Minute</name>
<key>wpm</key>
<value>20</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>float</type>
</sink>
<source>
<name>out</name>
<type>float</type>
</source>
</block>

View File

@ -1,24 +1,41 @@
<?xml version="1.0"?>
<block>
<name>Morse code Debug Source</name>
<key>satnogs_morse_debug_source</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.morse_debug_source($debug_seq)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Sentence</name>
<key>debug_seq</key>
<value>"HELLO WORLD"</value>
<type>string</type>
</param>
<name>Morse code Debug Source</name>
<key>satnogs_morse_debug_source</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.morse_debug_source($debug_seq, $errors, $p)</make>
<source>
<name>out</name>
<type>message</type>
</source>
<param>
<name>Sentence</name>
<key>debug_seq</key>
<value>"HELLO WORLD"</value>
<type>string</type>
</param>
<param>
<name>Inject Errors</name>
<key>errors</key>
<type>enum</type>
<option>
<name>Yes</name>
<key>True</key>
</option>
<option>
<name>No</name>
<key>False</key>
</option>
</param>
<param>
<name>Error probability</name>
<key>p</key>
<value>0.1</value>
<type>real</type>
</param>
<source>
<name>out</name>
<type>message</type>
</source>
</block>

View File

@ -1,21 +1,26 @@
<?xml version="1.0"?>
<block>
<name>Morse Decoder</name>
<key>satnogs_morse_decoder</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.morse_decoder($unrecognized_char)</make>
<name>Morse Decoder</name>
<key>satnogs_morse_decoder</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.morse_decoder($unrecognized_char)</make>
<param>
<name>Unrecognized character</name>
<key>unrecognized_char</key>
<value>ord('#')</value>
<type>int</type>
</param>
<param>
<name>Unrecognized character</name>
<key>unrecognized_char</key>
<value>ord('#')</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
</source>
</block>

View File

@ -28,5 +28,6 @@ install(FILES
morse_tree.h
morse.h
morse_decoder.h
morse_debug_source.h DESTINATION include/satnogs
morse_debug_source.h
clear_text_msg_sink.h DESTINATION include/satnogs
)

View File

@ -0,0 +1,59 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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_SATNOGS_CLEAR_TEXT_MSG_SINK_H
#define INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_H
#include <satnogs/api.h>
#include <gnuradio/block.h>
namespace gr
{
namespace satnogs
{
/*!
* \brief Block accepting clear text messages from various decoders.
* Its purpose is to forward these messages at other services, programs,
* stdout, etc,
*
* \ingroup satnogs
*
*/
class SATNOGS_API clear_text_msg_sink : virtual public gr::block
{
public:
typedef boost::shared_ptr<clear_text_msg_sink> sptr;
/*!
* \brief Block accepting clear text messages from various decoders.
* Its purpose is to forward these messages at other services, programs,
* stdout, etc,
*
*/
static sptr
make ();
};
} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_H */

View File

@ -28,7 +28,9 @@ namespace gr {
namespace satnogs {
/*!
* \brief A Morse debug source block
* \brief A Morse debug source block that supports injection of random
* errors based on a Bernulli distribution with probability p.
*
* \ingroup satnogs
*
*/
@ -40,10 +42,16 @@ namespace gr {
/*!
* \brief A Morse debug source block that produces messages corresponding
* to Morse symbols, based on the given debug_seq string.
* This block can also inject random errors, based on a Bernoulli
* distribution.
*
* @param debug_seq A string containing the debug sentence
* @param inject_errors if set the debug source block will produce
* errors that follow a Bernoulli distribution
* @param error_prob the probability p of error for the Bernulli distribution
*/
static sptr make(const std::string& debug_seq);
static sptr make(const std::string& debug_seq, bool inject_errors = false,
float error_prob = 0.1);
};
} // namespace satnogs

View File

@ -28,7 +28,8 @@ list(APPEND satnogs_sources
cw_matched_filter_ff_impl.cc
morse_tree.cc
morse_decoder_impl.cc
morse_debug_source_impl.cc )
morse_debug_source_impl.cc
clear_text_msg_sink_impl.cc )
set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE)
if(NOT satnogs_sources)

View File

@ -0,0 +1,61 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "clear_text_msg_sink_impl.h"
namespace gr {
namespace satnogs {
clear_text_msg_sink::sptr
clear_text_msg_sink::make()
{
return gnuradio::get_initial_sptr
(new clear_text_msg_sink_impl());
}
void
clear_text_msg_sink_impl::msg_handler (pmt::pmt_t msg)
{
std::string s((const char *)pmt::blob_data(msg), pmt::blob_length(msg));
std::cout << s << " " << std::endl;
}
/*
* The private constructor
*/
clear_text_msg_sink_impl::clear_text_msg_sink_impl()
: gr::block("clear_text_msg_sink",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0))
{
message_port_register_in(pmt::mp("in"));
set_msg_handler (
pmt::mp ("in"),
boost::bind (&clear_text_msg_sink_impl::msg_handler, this, _1));
}
} /* namespace satnogs */
} /* namespace gr */

View File

@ -0,0 +1,46 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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_SATNOGS_CLEAR_TEXT_MSG_SINK_IMPL_H
#define INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_IMPL_H
#include <satnogs/clear_text_msg_sink.h>
namespace gr
{
namespace satnogs
{
class clear_text_msg_sink_impl : public clear_text_msg_sink
{
private:
void
msg_handler(pmt::pmt_t msg);
public:
clear_text_msg_sink_impl ();
};
} // namespace satnogs
} // namespace gr
#endif /* INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_IMPL_H */

View File

@ -25,24 +25,31 @@
#include <gnuradio/io_signature.h>
#include "morse_debug_source_impl.h"
#include <satnogs/morse.h>
#include <random>
namespace gr {
namespace satnogs {
morse_debug_source::sptr
morse_debug_source::make(const std::string& debug_seq)
morse_debug_source::make(const std::string& debug_seq,
bool inject_errors,
float error_prob)
{
return gnuradio::get_initial_sptr
(new morse_debug_source_impl(debug_seq));
(new morse_debug_source_impl(debug_seq, inject_errors, error_prob));
}
/*
* The private constructor
*/
morse_debug_source_impl::morse_debug_source_impl(std::string debug_seq)
morse_debug_source_impl::morse_debug_source_impl(std::string debug_seq,
bool inject_errors,
float error_prob)
: gr::block("morse_debug_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_inject_errors(inject_errors),
d_p(error_prob),
d_run(true),
d_chars { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
@ -81,12 +88,17 @@ namespace gr {
size_t idx;
std::string s;
char c;
std::random_device rd;
std::mt19937 gen(rd());
std::bernoulli_distribution error_distr(d_p);
bool inject_error;
size_t len = sentence.length();
pmt::pmt_t port = pmt::mp("out");
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
while(d_run) {
/* Not the best approach, but hey, this is only for debug */
/* Not the best approach, but hey, this is only for debug */
for(i = 0; i < len; i++){
c = std::toupper(sentence[i]);
if(c == ' '){
@ -95,13 +107,26 @@ namespace gr {
idx = find_char_idx(d_chars, sizeof(d_chars), c);
if(idx != sizeof(d_chars)){
s = d_symbols[idx];
/* Get from the random distribution if an error should be injected */
inject_error = d_inject_errors && error_distr(gen);
for(j = 0; j < s.length(); j++) {
if(s[j] == '.'){
message_port_pub(port, pmt::from_long(MORSE_DOT));
if(inject_error){
message_port_pub(port, pmt::from_long(MORSE_DASH));
}
else{
message_port_pub(port, pmt::from_long(MORSE_DOT));
}
}
else{
message_port_pub(port, pmt::from_long(MORSE_DASH));
if(inject_error){
message_port_pub(port, pmt::from_long(MORSE_DOT));
}
else{
message_port_pub(port, pmt::from_long(MORSE_DASH));
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

View File

@ -32,6 +32,8 @@ namespace gr {
class morse_debug_source_impl : public morse_debug_source
{
private:
const bool d_inject_errors;
const float d_p;
bool d_run;
const char d_chars[36];
const std::vector<std::string> d_symbols;
@ -41,7 +43,8 @@ namespace gr {
send_debug_msg(std::string sentence);
public:
morse_debug_source_impl(std::string debug_seq);
morse_debug_source_impl(std::string debug_seq, bool inject_errors,
float error_prob);
~morse_debug_source_impl();
};

View File

@ -49,7 +49,6 @@ namespace gr
case MORSE_DOT:
case MORSE_DASH:
case MORSE_S_SPACE:
LOG_DEBUG("Received %d", s);
res = d_morse_tree.received_symbol(s);
break;
/*
@ -59,7 +58,8 @@ namespace gr
case MORSE_L_SPACE:
str = d_morse_tree.get_word();
d_morse_tree.reset();
std::cout << "Received word: " << str << std::endl;
message_port_pub(pmt::mp("out"), pmt::make_blob(str.c_str(),
str.length()));
break;
default:
LOG_ERROR("Unknown Morse symbol");
@ -91,8 +91,9 @@ namespace gr
gr::io_signature::make (0, 0, 0)),
d_morse_tree (unrecognized_char)
{
/* Register the input msg handler */
/* Register the input and output msg handler */
message_port_register_in (pmt::mp ("in"));
message_port_register_out(pmt::mp("out"));
set_msg_handler (
pmt::mp ("in"),
boost::bind (&morse_decoder_impl::symbol_msg_handler, this, _1));

View File

@ -12,6 +12,7 @@
#include "satnogs/morse_tree.h"
#include "satnogs/morse_decoder.h"
#include "satnogs/morse_debug_source.h"
#include "satnogs/clear_text_msg_sink.h"
%}
%include "satnogs/cw_matched_filter_ff.h"
@ -21,3 +22,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, cw_matched_filter_ff);
GR_SWIG_BLOCK_MAGIC2(satnogs, morse_decoder);
%include "satnogs/morse_debug_source.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, morse_debug_source);
%include "satnogs/clear_text_msg_sink.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, clear_text_msg_sink);