mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-28 09:54:51 +00:00
Merge branch 'convolutional' into next
This commit is contained in:
commit
35063985cd
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -39,6 +39,8 @@ add_library(telemetry_decoder_libs
|
||||
)
|
||||
|
||||
target_link_libraries(telemetry_decoder_libs
|
||||
PUBLIC
|
||||
Volkgnsssdr::volkgnsssdr
|
||||
PRIVATE
|
||||
Gflags::gflags
|
||||
Glog::glog
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user