Merge branch 'convolutional' into next

This commit is contained in:
Carles Fernandez 2019-09-07 11:16:51 +02:00
commit 35063985cd
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
5 changed files with 46 additions and 70 deletions

View File

@ -207,14 +207,14 @@ galileo_telemetry_decoder_gs::~galileo_telemetry_decoder_gs()
}
void galileo_telemetry_decoder_gs::viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits)
void galileo_telemetry_decoder_gs::viterbi_decoder(float *page_part_symbols, int32_t *page_part_bits)
{
Viterbi(page_part_bits, out0.data(), state0.data(), out1.data(), state1.data(),
page_part_symbols, KK, nn, DataLength);
}
void galileo_telemetry_decoder_gs::deinterleaver(int32_t rows, int32_t cols, const double *in, double *out)
void galileo_telemetry_decoder_gs::deinterleaver(int32_t rows, int32_t cols, const float *in, float *out)
{
for (int32_t r = 0; r < rows; r++)
{
@ -226,10 +226,10 @@ void galileo_telemetry_decoder_gs::deinterleaver(int32_t rows, int32_t cols, con
}
void galileo_telemetry_decoder_gs::decode_INAV_word(double *page_part_symbols, int32_t frame_length)
void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, int32_t frame_length)
{
// 1. De-interleave
std::vector<double> page_part_symbols_deint(frame_length);
std::vector<float> page_part_symbols_deint(frame_length);
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint.data());
// 2. Viterbi decoder
@ -318,10 +318,10 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(double *page_part_symbols, i
}
void galileo_telemetry_decoder_gs::decode_FNAV_word(double *page_symbols, int32_t frame_length)
void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t frame_length)
{
// 1. De-interleave
std::vector<double> page_symbols_deint(frame_length);
std::vector<float> page_symbols_deint(frame_length);
deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint.data());
// 2. Viterbi decoder

View File

@ -81,12 +81,12 @@ private:
galileo_telemetry_decoder_gs(const Gnss_Satellite &satellite, int frame_type, bool dump);
void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits);
void viterbi_decoder(float *page_part_symbols, int32_t *page_part_bits);
void deinterleaver(int32_t rows, int32_t cols, const double *in, double *out);
void deinterleaver(int32_t rows, int32_t cols, const float *in, float *out);
void decode_INAV_word(double *page_part_symbols, int32_t frame_length);
void decode_FNAV_word(double *page_symbols, int32_t frame_length);
void decode_INAV_word(float *page_part_symbols, int32_t frame_length);
void decode_FNAV_word(float *page_symbols, int32_t frame_length);
int d_frame_type;
int32_t d_bits_per_preamble;
@ -96,7 +96,7 @@ private:
uint32_t d_PRN_code_period_ms;
uint32_t d_required_symbols;
uint32_t d_frame_length_symbols;
std::vector<double> d_page_part_symbols;
std::vector<float> d_page_part_symbols;
boost::circular_buffer<float> d_symbol_history;

View File

@ -39,6 +39,8 @@ add_library(telemetry_decoder_libs
)
target_link_libraries(telemetry_decoder_libs
PUBLIC
Volkgnsssdr::volkgnsssdr
PRIVATE
Gflags::gflags
Glog::glog

View File

@ -1,11 +1,13 @@
/*!
* \file convolutional.h
* \brief General functions used to implement convolutional encoding.
* \author Matthew C. Valenti
* \author Matthew C. Valenti, 2006-2008.
* \author C. Fernandez-Prades, 2019.
*
* -------------------------------------------------------------------------
*
* Copyright (C) 2006-2008 Matthew C. Valenti
* Copyright (C) 2019 C. Fernandez-Prades
*
* GNSS-SDR is a software defined Global Navigation
* Satellite Systems receiver
@ -19,8 +21,6 @@
*
* This file is a derived work of the original file, which had this note:
*
* Last updated on May 22, 2008
*
* The functions in this file are part of the Iterative Solutions
* Coded Modulation Library. The Iterative Solutions Coded Modulation
* Library is free software; you can redistribute it and/or modify it
@ -41,7 +41,8 @@
#ifndef GNSS_SDR_CONVOLUTIONAL_H_
#define GNSS_SDR_CONVOLUTIONAL_H_
#include <cstdlib> // for calloc
#include <volk_gnsssdr/volk_gnsssdr.h>
#include <vector>
/* define constants used throughout the library */
const float MAXLOG = 1e7; /* Define infinity */
@ -57,7 +58,7 @@ const float MAXLOG = 1e7; /* Define infinity */
*
* This function is used by nsc_enc_bit(), rsc_enc_bit(), and rsc_tail()
*/
inline static int parity_counter(int symbol, int length)
inline int parity_counter(int symbol, int length)
{
int counter;
int temp_parity = 0;
@ -85,7 +86,7 @@ inline static int parity_counter(int symbol, int length)
*
* This function is used by nsc_transit()
*/
inline static int nsc_enc_bit(int state_out_p[],
inline int nsc_enc_bit(int state_out_p[],
int input,
int state_in,
const int g[],
@ -115,7 +116,7 @@ inline static int nsc_enc_bit(int state_out_p[],
/*!
* \brief Function that creates the transit and output vectors
*/
inline static void nsc_transit(int output_p[],
inline void nsc_transit(int output_p[],
int trans_p[],
int input,
int g[],
@ -144,7 +145,7 @@ inline static void nsc_transit(int output_p[],
* \param[in] nn The length of the received vector
*
*/
inline static float Gamma(const float rec_array[],
inline float Gamma(const float rec_array[],
int symbol,
int nn)
{
@ -176,24 +177,20 @@ inline static float Gamma(const float rec_array[],
* \param[out] output_u_int[] Hard decisions on the data bits
*
*/
inline static void Viterbi(int output_u_int[],
inline void Viterbi(int output_u_int[],
const int out0[],
const int state0[],
const int out1[],
const int state1[],
const double input_c[],
const float input_c[],
int KK,
int nn,
int LL)
{
int i, t, state, mm, states;
int number_symbols;
uint32_t max_index;
float metric;
float *prev_section, *next_section;
int *prev_bit;
int *prev_state;
float *metric_c; /* Set of all possible branch metrics */
float *rec_array; /* Received values for one trellis section */
float max_val;
/* some derived constants */
@ -201,34 +198,24 @@ inline static void Viterbi(int output_u_int[],
states = 1 << mm; /* 2^mm */
number_symbols = 1 << nn; /* 2^nn */
/* dynamically allocate memory */
prev_section = static_cast<float *>(calloc(states, sizeof(float)));
next_section = static_cast<float *>(calloc(states, sizeof(float)));
prev_bit = static_cast<int *>(calloc(states * (LL + mm), sizeof(int)));
prev_state = static_cast<int *>(calloc(states * (LL + mm), sizeof(int)));
rec_array = static_cast<float *>(calloc(nn, sizeof(float)));
metric_c = static_cast<float *>(calloc(number_symbols, sizeof(float)));
std::vector<float> prev_section(states, -MAXLOG);
std::vector<float> next_section(states, -MAXLOG);
std::vector<int> prev_bit(states * (LL + mm), 0);
std::vector<int> prev_state(states * (LL + mm), 0);
std::vector<float> rec_array(nn);
std::vector<float> metric_c(number_symbols);
/* initialize trellis */
for (state = 0; state < states; state++)
{
prev_section[state] = -MAXLOG;
next_section[state] = -MAXLOG;
}
prev_section[0] = 0; /* start in all-zeros state */
prev_section[0] = 0.0; /* start in all-zeros state */
/* go through trellis */
for (t = 0; t < LL + mm; t++)
{
for (i = 0; i < nn; i++)
{
rec_array[i] = static_cast<float>(input_c[nn * t + i]);
}
rec_array.assign(input_c + nn * t, input_c + nn * t + (nn - 1));
/* precompute all possible branch metrics */
for (i = 0; i < number_symbols; i++)
{
metric_c[i] = Gamma(rec_array, i, nn);
metric_c[i] = Gamma(rec_array.data(), i, nn);
}
/* step through all states */
@ -258,14 +245,9 @@ inline static void Viterbi(int output_u_int[],
}
/* normalize */
max_val = 0;
for (state = 0; state < states; state++)
{
if (next_section[state] > max_val)
{
max_val = next_section[state];
}
}
volk_gnsssdr_32f_index_max_32u(&max_index, next_section.data(), states);
max_val = next_section[max_index];
for (state = 0; state < states; state++)
{
prev_section[state] = next_section[state] - max_val;
@ -287,14 +269,6 @@ inline static void Viterbi(int output_u_int[],
output_u_int[t] = prev_bit[t * states + state];
state = prev_state[t * states + state];
}
/* free the dynamically allocated memory */
free(prev_section);
free(next_section);
free(prev_bit);
free(prev_state);
free(rec_array);
free(metric_c);
}

View File

@ -54,14 +54,14 @@ public:
const int32_t KK = 7; // Constraint Length
int32_t mm = KK - 1;
int32_t flag_even_word_arrived;
void viterbi_decoder(double *page_part_symbols, int32_t *page_part_bits, int32_t _datalength)
void viterbi_decoder(float *page_part_symbols, int32_t *page_part_bits, int32_t _datalength)
{
Viterbi(page_part_bits, out0, state0, out1, state1,
page_part_symbols, KK, nn, _datalength);
}
void deinterleaver(int32_t rows, int32_t cols, const double *in, double *out)
void deinterleaver(int32_t rows, int32_t cols, const float *in, float *out)
{
for (int32_t r = 0; r < rows; r++)
{
@ -73,10 +73,10 @@ public:
}
bool decode_INAV_word(double *page_part_symbols, int32_t frame_length)
bool decode_INAV_word(float *page_part_symbols, int32_t frame_length)
{
// 1. De-interleave
auto *page_part_symbols_deint = static_cast<double *>(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment()));
auto *page_part_symbols_deint = static_cast<float *>(volk_gnsssdr_malloc(frame_length * sizeof(float), volk_gnsssdr_get_alignment()));
deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_deint);
// 2. Viterbi decoder
@ -134,10 +134,10 @@ public:
return crc_ok;
}
bool decode_FNAV_word(double *page_symbols, int32_t frame_length)
bool decode_FNAV_word(float *page_symbols, int32_t frame_length)
{
// 1. De-interleave
auto *page_symbols_deint = static_cast<double *>(volk_gnsssdr_malloc(frame_length * sizeof(double), volk_gnsssdr_get_alignment()));
auto *page_symbols_deint = static_cast<float *>(volk_gnsssdr_malloc(frame_length * sizeof(float), volk_gnsssdr_get_alignment()));
deinterleaver(GALILEO_FNAV_INTERLEAVER_ROWS, GALILEO_FNAV_INTERLEAVER_COLS, page_symbols, page_symbols_deint);
// 2. Viterbi decoder
@ -215,7 +215,7 @@ TEST_F(Galileo_FNAV_INAV_test, ValidationOfResults)
start = std::chrono::system_clock::now();
int repetitions = 10;
// FNAV FULLY ENCODED FRAME
double FNAV_frame[488] = {-1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
float FNAV_frame[488] = {-1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
-1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1,
-1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1,
@ -240,7 +240,7 @@ TEST_F(Galileo_FNAV_INAV_test, ValidationOfResults)
// INAV FULLY ENCODED FRAME
double INAV_frame_even[240] = {-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
float INAV_frame_even[240] = {-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1,
-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1,
@ -256,7 +256,7 @@ TEST_F(Galileo_FNAV_INAV_test, ValidationOfResults)
-1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1};
double INAV_frame_odd[240] = {1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
float INAV_frame_odd[240] = {1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1,
1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,
-1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1,