diff --git a/.gitignore b/.gitignore index f2f50e3..4e2c807 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ apps/*.py .cproject .pyproject .pydevproject +nbproject/ \ No newline at end of file diff --git a/README.md b/README.md index ec25485..cab3341 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/examples/test_morse_decoder.grc b/examples/test_morse_decoder.grc index 23d9000..2338e06 100644 --- a/examples/test_morse_decoder.grc +++ b/examples/test_morse_decoder.grc @@ -109,7 +109,7 @@ - satnogs_morse_debug_source + satnogs_clear_text_msg_sink alias @@ -126,6 +126,41 @@ _enabled True + + _coordinate + (944, 184) + + + _rotation + 0 + + + id + satnogs_clear_text_msg_sink_0 + + + + satnogs_morse_debug_source + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + p + 0.1 + _coordinate (240, 196) @@ -138,6 +173,10 @@ id satnogs_morse_debug_source_0 + + errors + True + maxoutbuf 0 @@ -148,7 +187,7 @@ debug_seq - "HELLO EARTH WORLD" + "HELLO EARTH WORLD 123456789" @@ -171,7 +210,7 @@ _coordinate - (752, 276) + (672, 180) _rotation @@ -181,6 +220,14 @@ id satnogs_morse_decoder_0 + + maxoutbuf + 0 + + + minoutbuf + 0 + unrecognized_char ord('#') @@ -192,4 +239,10 @@ out in + + satnogs_morse_decoder_0 + satnogs_clear_text_msg_sink_0 + out + in + diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index e7f9f22..5564406 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -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 ) diff --git a/grc/satnogs_clear_text_msg_sink.xml b/grc/satnogs_clear_text_msg_sink.xml new file mode 100644 index 0000000..497c8f5 --- /dev/null +++ b/grc/satnogs_clear_text_msg_sink.xml @@ -0,0 +1,13 @@ + + + Clear Text Message Sink + satnogs_clear_text_msg_sink + satnogs + import satnogs + satnogs.clear_text_msg_sink() + + + in + message + + diff --git a/grc/satnogs_cw_matched_filter_ff.xml b/grc/satnogs_cw_matched_filter_ff.xml index 6143b75..7888e22 100644 --- a/grc/satnogs_cw_matched_filter_ff.xml +++ b/grc/satnogs_cw_matched_filter_ff.xml @@ -1,37 +1,38 @@ - CW Matched Filter - satnogs_cw_matched_filter_ff - satnogs - import satnogs - satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm) + CW Matched Filter + satnogs_cw_matched_filter_ff + satnogs + import satnogs + satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm) + - - Sampling Rate - sampling_rate - real - - - - Audio Frequency (Hz) - carrier_freq - real - - - - Words per Minute - wpm - 20 - int - + + Sampling Rate + sampling_rate + real + - - in - float - + + Audio Frequency (Hz) + carrier_freq + real + - - out - float - + + Words per Minute + wpm + 20 + int + + + + in + float + + + + out + float + diff --git a/grc/satnogs_morse_debug_source.xml b/grc/satnogs_morse_debug_source.xml index 1993acd..cdc01c9 100644 --- a/grc/satnogs_morse_debug_source.xml +++ b/grc/satnogs_morse_debug_source.xml @@ -1,24 +1,41 @@ - Morse code Debug Source - satnogs_morse_debug_source - satnogs - import satnogs - satnogs.morse_debug_source($debug_seq) - - - Sentence - debug_seq - "HELLO WORLD" - string - + Morse code Debug Source + satnogs_morse_debug_source + satnogs + import satnogs + satnogs.morse_debug_source($debug_seq, $errors, $p) - - out - message - + + Sentence + debug_seq + "HELLO WORLD" + string + + + + Inject Errors + errors + enum + + + + + + Error probability + p + 0.1 + real + + + + out + message + diff --git a/grc/satnogs_morse_decoder.xml b/grc/satnogs_morse_decoder.xml index 9eb7a32..52b41e6 100644 --- a/grc/satnogs_morse_decoder.xml +++ b/grc/satnogs_morse_decoder.xml @@ -1,21 +1,26 @@ - Morse Decoder - satnogs_morse_decoder - satnogs - import satnogs - satnogs.morse_decoder($unrecognized_char) + Morse Decoder + satnogs_morse_decoder + satnogs + import satnogs + satnogs.morse_decoder($unrecognized_char) - - Unrecognized character - unrecognized_char - ord('#') - int - + + Unrecognized character + unrecognized_char + ord('#') + int + - - in - message - + + in + message + + + + out + message + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index ee0b40b..c512fa6 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -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 ) diff --git a/include/satnogs/clear_text_msg_sink.h b/include/satnogs/clear_text_msg_sink.h new file mode 100644 index 0000000..4164581 --- /dev/null +++ b/include/satnogs/clear_text_msg_sink.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifndef INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_H +#define INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_H + +#include +#include + +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 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 */ + diff --git a/include/satnogs/morse_debug_source.h b/include/satnogs/morse_debug_source.h index c2939c1..a972d6b 100644 --- a/include/satnogs/morse_debug_source.h +++ b/include/satnogs/morse_debug_source.h @@ -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 diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 61851b1..d7c46cb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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) diff --git a/lib/clear_text_msg_sink_impl.cc b/lib/clear_text_msg_sink_impl.cc new file mode 100644 index 0000000..cc633a6 --- /dev/null +++ b/lib/clear_text_msg_sink_impl.cc @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#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 */ + diff --git a/lib/clear_text_msg_sink_impl.h b/lib/clear_text_msg_sink_impl.h new file mode 100644 index 0000000..51c6364 --- /dev/null +++ b/lib/clear_text_msg_sink_impl.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifndef INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_IMPL_H +#define INCLUDED_SATNOGS_CLEAR_TEXT_MSG_SINK_IMPL_H + +#include + +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 */ + diff --git a/lib/morse_debug_source_impl.cc b/lib/morse_debug_source_impl.cc index 1808b48..7fd4425 100644 --- a/lib/morse_debug_source_impl.cc +++ b/lib/morse_debug_source_impl.cc @@ -25,24 +25,31 @@ #include #include "morse_debug_source_impl.h" #include +#include 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)); } diff --git a/lib/morse_debug_source_impl.h b/lib/morse_debug_source_impl.h index 5c1f7e2..c88d70a 100644 --- a/lib/morse_debug_source_impl.h +++ b/lib/morse_debug_source_impl.h @@ -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 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(); }; diff --git a/lib/morse_decoder_impl.cc b/lib/morse_decoder_impl.cc index fc014b5..f1a90b6 100644 --- a/lib/morse_decoder_impl.cc +++ b/lib/morse_decoder_impl.cc @@ -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)); diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index ad58389..240d84f 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -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);