1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-16 05:00:35 +00:00

Improve memory management in Viterbi decoder

This commit is contained in:
Carles Fernandez 2018-04-23 07:52:49 +02:00
parent 3e0587b28c
commit 1b852336c6
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
4 changed files with 68 additions and 79 deletions

View File

@ -37,6 +37,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <glog/logging.h> #include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <iostream> #include <iostream>
@ -54,38 +55,8 @@ galileo_e1b_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump
void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits) void galileo_e1b_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
{ {
int CodeLength = 240;
int DataLength;
int nn, KK, mm, max_states;
int g_encoder[2];
nn = 2; // Coding rate 1/n
KK = 7; // Constraint Length
g_encoder[0] = 121; // Polynomial G1
g_encoder[1] = 91; // Polynomial G2
mm = KK - 1;
max_states = 1 << mm; /* 2^mm */
DataLength = (CodeLength / nn) - mm;
/* create appropriate transition matrices */
int *out0, *out1, *state0, *state1;
out0 = static_cast<int *>(calloc(max_states, sizeof(int)));
out1 = static_cast<int *>(calloc(max_states, sizeof(int)));
state0 = static_cast<int *>(calloc(max_states, sizeof(int)));
state1 = static_cast<int *>(calloc(max_states, sizeof(int)));
nsc_transit(out0, state0, 0, g_encoder, KK, nn);
nsc_transit(out1, state1, 1, g_encoder, KK, nn);
Viterbi(page_part_bits, out0, state0, out1, state1, Viterbi(page_part_bits, out0, state0, out1, state1,
page_part_symbols, KK, nn, DataLength); page_part_symbols, KK, nn, DataLength);
/* Clean up memory */
free(out0);
free(out1);
free(state0);
free(state1);
} }
@ -122,7 +93,7 @@ galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
memcpy(static_cast<unsigned short int *>(this->d_preambles_bits), static_cast<unsigned short int *>(preambles_bits), GALILEO_INAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int)); memcpy(static_cast<unsigned short int *>(this->d_preambles_bits), static_cast<unsigned short int *>(preambles_bits), GALILEO_INAV_PREAMBLE_LENGTH_BITS * sizeof(unsigned short int));
// preamble bits to sampled symbols // preamble bits to sampled symbols
d_preambles_symbols = static_cast<signed int *>(malloc(sizeof(signed int) * d_symbols_per_preamble)); d_preambles_symbols = static_cast<int *>(volk_gnsssdr_malloc(d_symbols_per_preamble * sizeof(int), volk_gnsssdr_get_alignment()));
int n = 0; int n = 0;
for (int i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++) for (int i = 0; i < GALILEO_INAV_PREAMBLE_LENGTH_BITS; i++)
{ {
@ -153,12 +124,28 @@ galileo_e1b_telemetry_decoder_cc::galileo_e1b_telemetry_decoder_cc(
d_flag_preamble = false; d_flag_preamble = false;
d_channel = 0; d_channel = 0;
flag_TOW_set = false; flag_TOW_set = false;
// vars for Viterbi decoder
int max_states = 1 << mm; /* 2^mm */
g_encoder[0] = 121; // Polynomial G1
g_encoder[1] = 91; // Polynomial G2
out0 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
out1 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
state0 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
state1 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
/* create appropriate transition matrices */
nsc_transit(out0, state0, 0, g_encoder, KK, nn);
nsc_transit(out1, state1, 1, g_encoder, KK, nn);
} }
galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc() galileo_e1b_telemetry_decoder_cc::~galileo_e1b_telemetry_decoder_cc()
{ {
delete d_preambles_symbols; volk_gnsssdr_free(d_preambles_symbols);
volk_gnsssdr_free(out0);
volk_gnsssdr_free(out1);
volk_gnsssdr_free(state0);
volk_gnsssdr_free(state1);
if (d_dump_file.is_open() == true) if (d_dump_file.is_open() == true)
{ {
try try
@ -213,13 +200,13 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols, in
d_nav.split_page(page_String, flag_even_word_arrived); d_nav.split_page(page_String, flag_even_word_arrived);
if (d_nav.flag_CRC_test == true) if (d_nav.flag_CRC_test == true)
{ {
LOG(INFO) << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite; LOG(INFO) << "Galileo E1 CRC correct in channel " << d_channel << " from satellite " << d_satellite;
//std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; //std::cout << "Galileo E1 CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl;
} }
else else
{ {
std::cout << "Galileo E1 CRC error on channel " << d_channel << " from satellite " << d_satellite << std::endl; std::cout << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl;
LOG(INFO) << "Galileo E1 CRC error on channel " << d_channel << " from satellite " << d_satellite; LOG(INFO) << "Galileo E1 CRC error in channel " << d_channel << " from satellite " << d_satellite;
} }
flag_even_word_arrived = 0; flag_even_word_arrived = 0;
} }
@ -235,21 +222,21 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols, in
{ {
// get object for this SV (mandatory) // get object for this SV (mandatory)
std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_nav.get_ephemeris()); std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_nav.get_ephemeris());
std::cout << "New Galileo E1 I/NAV message received: ephemeris from satellite " << d_satellite << std::endl; std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_nav.have_new_iono_and_GST() == true) if (d_nav.have_new_iono_and_GST() == true)
{ {
// get object for this SV (mandatory) // get object for this SV (mandatory)
std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_nav.get_iono()); std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_nav.get_iono());
std::cout << "New Galileo E1 I/NAV message received: iono/GST model parameters from satellite " << d_satellite << std::endl; std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_nav.have_new_utc_model() == true) if (d_nav.have_new_utc_model() == true)
{ {
// get object for this SV (mandatory) // get object for this SV (mandatory)
std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_nav.get_utc_model()); std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_nav.get_utc_model());
std::cout << "New Galileo E1 I/NAV message received: UTC model parameters from satellite " << d_satellite << std::endl; std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_nav.have_new_almanac() == true) if (d_nav.have_new_almanac() == true)
@ -257,7 +244,7 @@ void galileo_e1b_telemetry_decoder_cc::decode_word(double *page_part_symbols, in
std::shared_ptr<Galileo_Almanac> tmp_obj = std::make_shared<Galileo_Almanac>(d_nav.get_almanac()); std::shared_ptr<Galileo_Almanac> tmp_obj = std::make_shared<Galileo_Almanac>(d_nav.get_almanac());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
//debug //debug
std::cout << "Galileo E1 I/NAV almanac received!" << std::endl; std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel << " from satellite " << d_satellite << std::endl;
DLOG(INFO) << "GPS_to_Galileo time conversion:"; DLOG(INFO) << "GPS_to_Galileo time conversion:";
DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10; DLOG(INFO) << "A0G=" << tmp_obj->A_0G_10;
DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10; DLOG(INFO) << "A1G=" << tmp_obj->A_1G_10;

View File

@ -112,6 +112,15 @@ private:
std::string d_dump_filename; std::string d_dump_filename;
std::ofstream d_dump_file; std::ofstream d_dump_file;
// vars for Viterbi decoder
int *out0, *out1, *state0, *state1;
int g_encoder[2];
const int nn = 2; // Coding rate 1/n
const int KK = 7; // Constraint Length
int mm = KK - 1;
const int CodeLength = 240;
int DataLength = (CodeLength / nn) - mm;
}; };
#endif #endif

View File

@ -37,9 +37,11 @@
#include "galileo_e5a_telemetry_decoder_cc.h" #include "galileo_e5a_telemetry_decoder_cc.h"
#include "control_message_factory.h" #include "control_message_factory.h"
#include "convolutional.h" #include "convolutional.h"
#include "display.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <gnuradio/io_signature.h> #include <gnuradio/io_signature.h>
#include <glog/logging.h> #include <glog/logging.h>
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
@ -58,42 +60,8 @@ galileo_e5a_make_telemetry_decoder_cc(const Gnss_Satellite &satellite, bool dump
void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits) void galileo_e5a_telemetry_decoder_cc::viterbi_decoder(double *page_part_symbols, int *page_part_bits)
{ {
// int CodeLength = 240;
int CodeLength = 488;
int DataLength;
int nn, KK, mm, max_states;
int g_encoder[2];
nn = 2; // Coding rate 1/n
KK = 7; // Constraint Length
g_encoder[0] = 121; // Polynomial G1
g_encoder[1] = 91; // Polynomial G2
// g_encoder[0] = 171; // Polynomial G1
// g_encoder[1] = 133; // Polynomial G2
mm = KK - 1;
max_states = 1 << mm; // 2^mm
DataLength = (CodeLength / nn) - mm;
//create appropriate transition matrices
int *out0, *out1, *state0, *state1;
out0 = static_cast<int *>(calloc(max_states, sizeof(int)));
out1 = static_cast<int *>(calloc(max_states, sizeof(int)));
state0 = static_cast<int *>(calloc(max_states, sizeof(int)));
state1 = static_cast<int *>(calloc(max_states, sizeof(int)));
nsc_transit(out0, state0, 0, g_encoder, KK, nn);
nsc_transit(out1, state1, 1, g_encoder, KK, nn);
Viterbi(page_part_bits, out0, state0, out1, state1, Viterbi(page_part_bits, out0, state0, out1, state1,
page_part_symbols, KK, nn, DataLength); page_part_symbols, KK, nn, DataLength);
//Clean up memory
free(out0);
free(out1);
free(state0);
free(state1);
} }
@ -147,32 +115,32 @@ void galileo_e5a_telemetry_decoder_cc::decode_word(double *page_symbols, int fra
d_nav.split_page(page_String); d_nav.split_page(page_String);
if (d_nav.flag_CRC_test == true) if (d_nav.flag_CRC_test == true)
{ {
LOG(INFO) << "Galileo E5a CRC correct on channel " << d_channel << " from satellite " << d_satellite; LOG(INFO) << "Galileo E5a CRC correct in channel " << d_channel << " from satellite " << d_satellite;
//std::cout << "Galileo E5a CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl; //std::cout << "Galileo E5a CRC correct on channel " << d_channel << " from satellite " << d_satellite << std::endl;
} }
else else
{ {
std::cout << "Galileo E5a CRC error on channel " << d_channel << " from satellite " << d_satellite << std::endl; std::cout << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite << std::endl;
LOG(INFO) << "Galileo E5a CRC error on channel " << d_channel << " from satellite " << d_satellite; LOG(INFO) << "Galileo E5a CRC error in channel " << d_channel << " from satellite " << d_satellite;
} }
// 4. Push the new navigation data to the queues // 4. Push the new navigation data to the queues
if (d_nav.have_new_ephemeris() == true) if (d_nav.have_new_ephemeris() == true)
{ {
std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_nav.get_ephemeris()); std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_nav.get_ephemeris());
std::cout << "New Galileo E5a F/NAV message received: ephemeris from satellite " << d_satellite << std::endl; std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_nav.have_new_iono_and_GST() == true) if (d_nav.have_new_iono_and_GST() == true)
{ {
std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_nav.get_iono()); std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_nav.get_iono());
std::cout << "New Galileo E5a F/NAV message received: iono/GST model parameters from satellite " << d_satellite << std::endl; std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": iono/GST model parameters from satellite " << d_satellite << TEXT_RESET << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
if (d_nav.have_new_utc_model() == true) if (d_nav.have_new_utc_model() == true)
{ {
std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_nav.get_utc_model()); std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_nav.get_utc_model());
std::cout << "New Galileo E5a F/NAV message received: UTC model parameters from satellite " << d_satellite << std::endl; std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " << d_channel << ": UTC model parameters from satellite " << d_satellite << TEXT_RESET << std::endl;
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
} }
} }
@ -226,11 +194,27 @@ galileo_e5a_telemetry_decoder_cc::galileo_e5a_telemetry_decoder_cc(
flag_bit_start = false; flag_bit_start = false;
new_symbol = false; new_symbol = false;
required_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS; required_symbols = GALILEO_FNAV_SYMBOLS_PER_PAGE + GALILEO_FNAV_PREAMBLE_LENGTH_BITS;
// vars for Viterbi decoder
int max_states = 1 << mm; /* 2^mm */
g_encoder[0] = 121; // Polynomial G1
g_encoder[1] = 91; // Polynomial G2
out0 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
out1 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
state0 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
state1 = static_cast<int *>(volk_gnsssdr_malloc(max_states * sizeof(int), volk_gnsssdr_get_alignment()));
/* create appropriate transition matrices */
nsc_transit(out0, state0, 0, g_encoder, KK, nn);
nsc_transit(out1, state1, 1, g_encoder, KK, nn);
} }
galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc() galileo_e5a_telemetry_decoder_cc::~galileo_e5a_telemetry_decoder_cc()
{ {
volk_gnsssdr_free(out0);
volk_gnsssdr_free(out1);
volk_gnsssdr_free(state0);
volk_gnsssdr_free(state1);
if (d_dump_file.is_open() == true) if (d_dump_file.is_open() == true)
{ {
try try

View File

@ -112,6 +112,15 @@ private:
Gnss_Satellite d_satellite; Gnss_Satellite d_satellite;
// navigation message vars // navigation message vars
Galileo_Fnav_Message d_nav; Galileo_Fnav_Message d_nav;
// vars for Viterbi decoder
int *out0, *out1, *state0, *state1;
int g_encoder[2];
const int nn = 2; // Coding rate 1/n
const int KK = 7; // Constraint Length
int mm = KK - 1;
const int CodeLength = 488;
int DataLength = (CodeLength / nn) - mm;
}; };
#endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ */ #endif /* GNSS_SDR_GALILEO_E5A_TELEMETRY_DECODER_CC_H_ */