1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-05-16 22:34:09 +00:00

Avoid using reserved identifiers

This commit is contained in:
Carles Fernandez 2020-12-29 14:47:28 +01:00
parent 36e98856d5
commit abd1032ca2
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
26 changed files with 864 additions and 875 deletions

View File

@ -190,10 +190,10 @@ void GalileoE1PcpsAmbiguousAcquisition::set_local_code()
} }
} }
own::span<gr_complex> code__span(code_.data(), vector_length_); own::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_ / 4; i++) for (unsigned int i = 0; i < sampled_ms_ / 4; i++)
{ {
std::copy_n(code.data(), code_length_, code__span.subspan(i * code_length_, code_length_).data()); std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
} }
acquisition_->set_local_code(code_.data()); acquisition_->set_local_code(code_.data());

View File

@ -163,10 +163,10 @@ void GalileoE6PcpsAcquisition::set_local_code()
gnss_synchro_->PRN, fs_in_, 0); gnss_synchro_->PRN, fs_in_, 0);
} }
own::span<gr_complex> code__span(code_.data(), vector_length_); own::span<gr_complex> code_span(code_.data(), vector_length_);
for (unsigned int i = 0; i < sampled_ms_; i++) for (unsigned int i = 0; i < sampled_ms_; i++)
{ {
std::copy_n(code.data(), code_length_, code__span.subspan(i * code_length_, code_length_).data()); std::copy_n(code.data(), code_length_, code_span.subspan(i * code_length_, code_length_).data());
} }
acquisition_->set_local_code(code_.data()); acquisition_->set_local_code(code_.data());

View File

@ -26,17 +26,17 @@
const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void beidou_b1i_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b1i_code_gen_int(own::span<int32_t> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 2046; constexpr uint32_t code_length = 2046;
const std::array<int32_t, 33> delays = {712 /*PRN1*/, 1581, 1414, 1550, 581, 771, 1311, 1043, 1549, 359, 710, 1579, 1548, 1103, 579, 769, 358, 709, 1411, 1547, const std::array<int32_t, 33> delays = {712 /*PRN1*/, 1581, 1414, 1550, 581, 771, 1311, 1043, 1549, 359, 710, 1579, 1548, 1103, 579, 769, 358, 709, 1411, 1547,
1102, 578, 357, 1577, 1410, 1546, 1101, 707, 1576, 1409, 1545, 354 /*PRN32*/, 1102, 578, 357, 1577, 1410, 1546, 1101, 707, 1576, 1409, 1545, 354 /*PRN32*/,
705}; 705};
const std::array<int32_t, 37> phase1 = {1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 8, 8, 8, 9, 9, 10}; const std::array<int32_t, 37> phase1 = {1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 8, 8, 8, 9, 9, 10};
const std::array<int32_t, 37> phase2 = {3, 4, 5, 6, 8, 9, 10, 11, 7, 4, 5, 6, 8, 9, 10, 11, 5, 6, 8, 9, 10, 11, 6, 8, 9, 10, 11, 8, 9, 10, 11, 9, 10, 11, 10, 11, 11}; const std::array<int32_t, 37> phase2 = {3, 4, 5, 6, 8, 9, 10, 11, 7, 4, 5, 6, 8, 9, 10, 11, 5, 6, 8, 9, 10, 11, 6, 8, 9, 10, 11, 8, 9, 10, 11, 9, 10, 11, 10, 11, 11};
std::bitset<_code_length> G1{}; std::bitset<code_length> G1{};
std::bitset<_code_length> G2{}; std::bitset<code_length> G2{};
std::bitset<11> G1_register(std::string("01010101010")); std::bitset<11> G1_register(std::string("01010101010"));
std::bitset<11> G2_register(std::string("01010101010")); std::bitset<11> G2_register(std::string("01010101010"));
@ -50,7 +50,7 @@ void beidou_b1i_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _c
int32_t prn_idx; int32_t prn_idx;
// compute delay array index for given PRN number // compute delay array index for given PRN number
prn_idx = _prn - 1; prn_idx = prn - 1;
// A simple error check // A simple error check
if ((prn_idx < 0) || (prn_idx > 32)) if ((prn_idx < 0) || (prn_idx > 32))
@ -59,7 +59,7 @@ void beidou_b1i_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _c
} }
// Generate G1 & G2 Register // Generate G1 & G2 Register
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
G1[lcv] = G1_register[0]; G1[lcv] = G1_register[0];
G2[lcv] = G2_register[-(phase1[prn_idx] - 11)] xor G2_register[-(phase2[prn_idx] - 11)]; G2[lcv] = G2_register[-(phase1[prn_idx] - 11)] xor G2_register[-(phase2[prn_idx] - 11)];
@ -78,53 +78,53 @@ void beidou_b1i_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _c
} }
// Set the delay // Set the delay
delay = _code_length - delays[prn_idx] * 0; //********************************** delay = code_length - delays[prn_idx] * 0; //**********************************
delay += _chip_shift; delay += chip_shift;
delay %= _code_length; delay %= code_length;
// Generate PRN from G1 and G2 Registers // Generate PRN from G1 and G2 Registers
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[(lcv + _chip_shift) % _code_length] xor G2[delay]; aux = G1[(lcv + chip_shift) % code_length] xor G2[delay];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = 1; dest[lcv] = 1;
} }
else else
{ {
_dest[lcv] = -1; dest[lcv] = -1;
} }
delay++; delay++;
delay %= _code_length; delay %= code_length;
} }
} }
void beidou_b1i_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b1i_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 2046; constexpr uint32_t code_length = 2046;
std::array<int32_t, _code_length> b1i_code_int{}; std::array<int32_t, code_length> b1i_code_int{};
beidou_b1i_code_gen_int(own::span<int32_t>(b1i_code_int.data(), _code_length), _prn, _chip_shift); beidou_b1i_code_gen_int(own::span<int32_t>(b1i_code_int.data(), code_length), prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = static_cast<float>(b1i_code_int[ii]); dest[ii] = static_cast<float>(b1i_code_int[ii]);
} }
} }
void beidou_b1i_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b1i_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 2046; constexpr uint32_t code_length = 2046;
std::array<int32_t, _code_length> b1i_code_int{}; std::array<int32_t, code_length> b1i_code_int{};
beidou_b1i_code_gen_int(own::span<int32_t>(b1i_code_int.data(), _code_length), _prn, _chip_shift); beidou_b1i_code_gen_int(own::span<int32_t>(b1i_code_int.data(), code_length), prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = std::complex<float>(static_cast<float>(b1i_code_int[ii]), 0.0F); dest[ii] = std::complex<float>(static_cast<float>(b1i_code_int[ii]), 0.0F);
} }
} }
@ -132,22 +132,22 @@ void beidou_b1i_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _
/* /*
* Generates complex BeiDou B1I code for the desired SV ID and sampled to specific sampling frequency * Generates complex BeiDou B1I code for the desired SV ID and sampled to specific sampling frequency
*/ */
void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift)
{ {
constexpr int32_t _codeFreqBasis = 2046000; // Hz constexpr int32_t codeFreqBasis = 2046000; // chips per second
constexpr int32_t _codeLength = 2046; constexpr int32_t codeLength = 2046;
constexpr float _tc = 1.0 / static_cast<float>(_codeFreqBasis); // B1I chip period in sec constexpr float tc = 1.0 / static_cast<float>(codeFreqBasis); // B1I chip period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
std::array<std::complex<float>, 2046> _code{}; std::array<std::complex<float>, 2046> code_aux{};
int32_t _codeValueIndex; int32_t codeValueIndex;
float aux; float aux;
beidou_b1i_code_gen_complex(_code, _prn, _chip_shift); // generate B1I code 1 sample per chip beidou_b1i_code_gen_complex(code_aux, prn, chip_shift); // generate B1I code 1 sample per chip
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
@ -156,20 +156,20 @@ void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, u
// number of samples per millisecond (because one B1I code period is // number of samples per millisecond (because one B1I code period is
// one millisecond). // one millisecond).
aux = (_ts * (static_cast<float>(i) + 1)) / _tc; aux = (ts * (static_cast<float>(i) + 1)) / tc;
_codeValueIndex = AUX_CEIL(aux) - 1; codeValueIndex = AUX_CEIL(aux) - 1;
// --- Make the digitized version of the B1I code ------------------ // --- Make the digitized version of the B1I code ------------------
// The "upsampled" code is made by selecting values form the B1I code // The upsampled code is made by selecting values from the B1I code
// chip array (caCode) for the time instances of each sample. // chip array for the time instances of each sample.
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // Correct the last index (due to number rounding issues)
_dest[i] = _code[_codeLength - 1]; dest[i] = code_aux[codeLength - 1];
} }
else else
{ {
_dest[i] = _code[_codeValueIndex]; // repeat the chip -> upsample dest[i] = code_aux[codeValueIndex]; // repeat the chip -> upsample
} }
} }
} }

View File

@ -41,19 +41,16 @@ namespace own = gsl;
//! Generates int32_t GPS L1 C/A code for the desired SV ID and code shift //! Generates int32_t GPS L1 C/A code for the desired SV ID and code shift
void beidou_b1i_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _chip_shift); void beidou_b1i_code_gen_int(own::span<int32_t> dest, int32_t prn, uint32_t chip_shift);
//! Generates float GPS L1 C/A code for the desired SV ID and code shift //! Generates float GPS L1 C/A code for the desired SV ID and code shift
void beidou_b1i_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift); void beidou_b1i_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void beidou_b1i_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift);
//! Generates N complex GPS L1 C/A codes for the desired SV ID and code shift
void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift //! Generates complex GPS L1 C/A code for the desired SV ID and code shift
void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); void beidou_b1i_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void beidou_b1i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -26,11 +26,11 @@
const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void beidou_b3i_code_gen_int(own::span<int> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b3i_code_gen_int(own::span<int> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 10230; constexpr uint32_t code_length = 10230;
std::bitset<_code_length> G1{}; std::bitset<code_length> G1{};
std::bitset<_code_length> G2{}; std::bitset<code_length> G2{};
auto G1_register = std::bitset<13>{}.set(); // All true auto G1_register = std::bitset<13>{}.set(); // All true
auto G2_register = std::bitset<13>{}.set(); // All true auto G2_register = std::bitset<13>{}.set(); // All true
auto G1_register_reset = std::bitset<13>{}.set(); auto G1_register_reset = std::bitset<13>{}.set();
@ -43,7 +43,7 @@ void beidou_b3i_code_gen_int(own::span<int> _dest, int32_t _prn, uint32_t _chip_
uint32_t lcv; uint32_t lcv;
uint32_t lcv2; uint32_t lcv2;
uint32_t delay; uint32_t delay;
int32_t prn_idx = _prn - 1; int32_t prn_idx = prn - 1;
const std::array<std::bitset<13>, 63> G2_register_shifted = const std::array<std::bitset<13>, 63> G2_register_shifted =
{std::bitset<13>(std::string("1010111111111")), {std::bitset<13>(std::string("1010111111111")),
@ -120,7 +120,7 @@ void beidou_b3i_code_gen_int(own::span<int> _dest, int32_t _prn, uint32_t _chip_
G2_register = G2_register_shifted[prn_idx]; G2_register = G2_register_shifted[prn_idx];
// Generate G1 and G2 Register // Generate G1 and G2 Register
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
G1[lcv] = G1_register[0]; G1[lcv] = G1_register[0];
G2[lcv] = G2_register[0]; G2[lcv] = G2_register[0];
@ -145,74 +145,74 @@ void beidou_b3i_code_gen_int(own::span<int> _dest, int32_t _prn, uint32_t _chip_
} }
} }
delay = _code_length; delay = code_length;
delay += _chip_shift; delay += chip_shift;
delay %= _code_length; delay %= code_length;
// Generate PRN from G1 and G2 Registers // Generate PRN from G1 and G2 Registers
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[(lcv + _chip_shift) % _code_length] xor G2[delay]; aux = G1[(lcv + chip_shift) % code_length] xor G2[delay];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = 1; dest[lcv] = 1;
} }
else else
{ {
_dest[lcv] = -1; dest[lcv] = -1;
} }
delay++; delay++;
delay %= _code_length; delay %= code_length;
} }
} }
void beidou_b3i_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b3i_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 10230; constexpr uint32_t code_length = 10230;
std::array<int, _code_length> b3i_code_int{}; std::array<int, code_length> b3i_code_int{};
beidou_b3i_code_gen_int(b3i_code_int, _prn, _chip_shift); beidou_b3i_code_gen_int(b3i_code_int, prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = static_cast<float>(b3i_code_int[ii]); dest[ii] = static_cast<float>(b3i_code_int[ii]);
} }
} }
void beidou_b3i_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift) void beidou_b3i_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 10230; constexpr uint32_t code_length = 10230;
std::array<int, _code_length> b3i_code_int{}; std::array<int, code_length> b3i_code_int{};
beidou_b3i_code_gen_int(b3i_code_int, _prn, _chip_shift); beidou_b3i_code_gen_int(b3i_code_int, prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = std::complex<float>(static_cast<float>(b3i_code_int[ii]), 0.0F); dest[ii] = std::complex<float>(static_cast<float>(b3i_code_int[ii]), 0.0F);
} }
} }
void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int _fs, uint32_t _chip_shift) void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int sampling_freq, uint32_t chip_shift)
{ {
constexpr int32_t _codeFreqBasis = 10230000; // Hz constexpr int32_t codeFreqBasis = 10230000; // chips per second
constexpr int32_t _codeLength = 10230; constexpr int32_t codeLength = 10230;
constexpr float _tc = 1.0 / static_cast<float>(_codeFreqBasis); // B3I chip period in sec constexpr float tc = 1.0 / static_cast<float>(codeFreqBasis); // B3I chip period in sec
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in secs const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in secs
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
std::array<std::complex<float>, 10230> _code{}; std::array<std::complex<float>, 10230> code_aux{};
int32_t _codeValueIndex; int32_t codeValueIndex;
float aux; float aux;
beidou_b3i_code_gen_complex(_code, _prn, _chip_shift); // generate B3I code 1 sample per chip beidou_b3i_code_gen_complex(code_aux, prn, chip_shift); // generate B3I code 1 sample per chip
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
@ -221,20 +221,20 @@ void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, u
// number of samples per millisecond (because one B3I code period is // number of samples per millisecond (because one B3I code period is
// one millisecond). // one millisecond).
aux = (_ts * (static_cast<float>(i) + 1)) / _tc; aux = (ts * (static_cast<float>(i) + 1)) / tc;
_codeValueIndex = AUX_CEIL(aux) - 1; codeValueIndex = AUX_CEIL(aux) - 1;
// --- Make the digitized version of the B3I code ------------------ // --- Make the digitized version of the B3I code ------------------
// The "upsampled" code is made by selecting values form the B3I code // The upsampled code is made by selecting values from the B3I code
// chip array (caCode) for the time instances of each sample. // chip array for the time instances of each sample.
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // Correct the last index (due to number rounding issues)
_dest[i] = _code[_codeLength - 1]; dest[i] = code_aux[codeLength - 1];
} }
else else
{ {
_dest[i] = _code[_codeValueIndex]; // repeat the chip -> upsample dest[i] = code_aux[codeValueIndex]; // repeat the chip -> upsample
} }
} }
} }

View File

@ -39,19 +39,16 @@ namespace own = gsl;
//! Generates int BeiDou B3I code for the desired SV ID and code shift //! Generates int BeiDou B3I code for the desired SV ID and code shift
void beidou_b3i_code_gen_int(own::span<int> _dest, int32_t _prn, uint32_t _chip_shift); void beidou_b3i_code_gen_int(own::span<int> dest, int32_t prn, uint32_t chip_shift);
//! Generates float BeiDou B3I code for the desired SV ID and code shift //! Generates float BeiDou B3I code for the desired SV ID and code shift
void beidou_b3i_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift); void beidou_b3i_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex BeiDou B3I code for the desired SV ID and code shift, and sampled to specific sampling frequency
void beidou_b3i_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift);
//! Generates N complex BeiDou B3I codes for the desired SV ID and code shift
void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int _fs, uint32_t _chip_shift, uint32_t _ncodes);
//! Generates complex BeiDou B3I code for the desired SV ID and code shift //! Generates complex BeiDou B3I code for the desired SV ID and code shift
void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int _fs, uint32_t _chip_shift); void beidou_b3i_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex BeiDou B3I code for the desired SV ID and code shift, and sampled to specific sampling frequency
void beidou_b3i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -30,216 +30,216 @@
#include <vector> #include <vector>
void galileo_e1_code_gen_int(own::span<int> _dest, const std::array<char, 3>& _Signal, int32_t _prn) void galileo_e1_code_gen_int(own::span<int> dest, const std::array<char, 3>& signal_id, int32_t prn)
{ {
const std::string _galileo_signal = _Signal.data(); const std::string galileo_signal = signal_id.data();
const int32_t prn = _prn - 1; const int32_t prn_ = prn - 1;
int32_t index = 0; int32_t index = 0;
// A simple error check // A simple error check
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
if (_galileo_signal.rfind("1B") != std::string::npos && _galileo_signal.length() >= 2) if (galileo_signal.rfind("1B") != std::string::npos && galileo_signal.length() >= 2)
{ {
for (size_t i = 0; i < GALILEO_E1_B_PRIMARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E1_B_PRIMARY_CODE_STR_LENGTH; i++)
{ {
hex_to_binary_converter(_dest.subspan(index, 4), GALILEO_E1_B_PRIMARY_CODE[prn][i]); hex_to_binary_converter(dest.subspan(index, 4), GALILEO_E1_B_PRIMARY_CODE[prn_][i]);
index += 4; index += 4;
} }
} }
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2) else if (galileo_signal.rfind("1C") != std::string::npos && galileo_signal.length() >= 2)
{ {
for (size_t i = 0; i < GALILEO_E1_C_PRIMARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E1_C_PRIMARY_CODE_STR_LENGTH; i++)
{ {
hex_to_binary_converter(_dest.subspan(index, 4), GALILEO_E1_C_PRIMARY_CODE[prn][i]); hex_to_binary_converter(dest.subspan(index, 4), GALILEO_E1_C_PRIMARY_CODE[prn_][i]);
index += 4; index += 4;
} }
} }
} }
void galileo_e1_sinboc_11_gen_int(own::span<int> _dest, own::span<const int> _prn) void galileo_e1_sinboc_11_gen_int(own::span<int> dest, own::span<const int> prn)
{ {
constexpr uint32_t _length_in = GALILEO_E1_B_CODE_LENGTH_CHIPS; constexpr uint32_t length_in = GALILEO_E1_B_CODE_LENGTH_CHIPS;
const auto _period = static_cast<uint32_t>(_dest.size() / _length_in); const auto period = static_cast<uint32_t>(dest.size() / length_in);
for (uint32_t i = 0; i < _length_in; i++) for (uint32_t i = 0; i < length_in; i++)
{ {
for (uint32_t j = 0; j < (_period / 2); j++) for (uint32_t j = 0; j < (period / 2); j++)
{ {
_dest[i * _period + j] = _prn[i]; dest[i * period + j] = prn[i];
} }
for (uint32_t j = (_period / 2); j < _period; j++) for (uint32_t j = (period / 2); j < period; j++)
{ {
_dest[i * _period + j] = -_prn[i]; dest[i * period + j] = -prn[i];
} }
} }
} }
void galileo_e1_sinboc_61_gen_int(own::span<int> _dest, own::span<const int> _prn) void galileo_e1_sinboc_61_gen_int(own::span<int> dest, own::span<const int> prn)
{ {
constexpr uint32_t _length_in = GALILEO_E1_B_CODE_LENGTH_CHIPS; constexpr uint32_t length_in = GALILEO_E1_B_CODE_LENGTH_CHIPS;
const auto _period = static_cast<uint32_t>(_dest.size() / _length_in); const auto period = static_cast<uint32_t>(dest.size() / length_in);
for (uint32_t i = 0; i < _length_in; i++) for (uint32_t i = 0; i < length_in; i++)
{ {
for (uint32_t j = 0; j < _period; j += 2) for (uint32_t j = 0; j < period; j += 2)
{ {
_dest[i * _period + j] = _prn[i]; dest[i * period + j] = prn[i];
} }
for (uint32_t j = 1; j < _period; j += 2) for (uint32_t j = 1; j < period; j += 2)
{ {
_dest[i * _period + j] = -_prn[i]; dest[i * period + j] = -prn[i];
} }
} }
} }
void galileo_e1_code_gen_sinboc11_float(own::span<float> _dest, const std::array<char, 3>& _Signal, uint32_t _prn) void galileo_e1_code_gen_sinboc11_float(own::span<float> dest, const std::array<char, 3>& signal_id, uint32_t prn)
{ {
const auto _codeLength = static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS); const auto codeLength = static_cast<uint32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS);
std::array<int32_t, 4092> primary_code_E1_chips{}; std::array<int32_t, 4092> primary_code_E1_chips{};
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); // generate Galileo E1 code, 1 sample per chip galileo_e1_code_gen_int(primary_code_E1_chips, signal_id, prn); // generate Galileo E1 code, 1 sample per chip
for (uint32_t i = 0; i < _codeLength; i++) for (uint32_t i = 0; i < codeLength; i++)
{ {
_dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]); dest[2 * i] = static_cast<float>(primary_code_E1_chips[i]);
_dest[2 * i + 1] = -_dest[2 * i]; dest[2 * i + 1] = -dest[2 * i];
} }
} }
void galileo_e1_gen_float(own::span<float> _dest, own::span<int> _prn, const std::array<char, 3>& _Signal) void galileo_e1_gen_float(own::span<float> dest, own::span<int> prn, const std::array<char, 3>& signal_id)
{ {
const auto _codeLength = _dest.size(); const auto codeLength = dest.size();
const float alpha = std::sqrt(10.0F / 11.0F); const float alpha = std::sqrt(10.0F / 11.0F);
const float beta = std::sqrt(1.0F / 11.0F); const float beta = std::sqrt(1.0F / 11.0F);
const std::string _galileo_signal = _Signal.data(); const std::string galileo_signal = signal_id.data();
std::vector<int32_t> sinboc_11(_codeLength); std::vector<int32_t> sinboc_11(codeLength);
std::vector<int32_t> sinboc_61(_codeLength); std::vector<int32_t> sinboc_61(codeLength);
galileo_e1_sinboc_11_gen_int(sinboc_11, _prn); // generate sinboc(1,1) 12 samples per chip galileo_e1_sinboc_11_gen_int(sinboc_11, prn); // generate sinboc(1,1) 12 samples per chip
galileo_e1_sinboc_61_gen_int(sinboc_61, _prn); // generate sinboc(6,1) 12 samples per chip galileo_e1_sinboc_61_gen_int(sinboc_61, prn); // generate sinboc(6,1) 12 samples per chip
if (_galileo_signal.rfind("1B") != std::string::npos && _galileo_signal.length() >= 2) if (galileo_signal.rfind("1B") != std::string::npos && galileo_signal.length() >= 2)
{ {
for (size_t i = 0; i < _codeLength; i++) for (size_t i = 0; i < codeLength; i++)
{ {
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) + dest[i] = alpha * static_cast<float>(sinboc_11[i]) +
beta * static_cast<float>(sinboc_61[i]); beta * static_cast<float>(sinboc_61[i]);
} }
} }
else if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2) else if (galileo_signal.rfind("1C") != std::string::npos && galileo_signal.length() >= 2)
{ {
for (size_t i = 0; i < _codeLength; i++) for (size_t i = 0; i < codeLength; i++)
{ {
_dest[i] = alpha * static_cast<float>(sinboc_11[i]) - dest[i] = alpha * static_cast<float>(sinboc_11[i]) -
beta * static_cast<float>(sinboc_61[i]); beta * static_cast<float>(sinboc_61[i]);
} }
} }
} }
void galileo_e1_code_gen_float_sampled(own::span<float> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_float_sampled(own::span<float> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift,
bool _secondary_flag) bool secondary_flag)
{ {
constexpr int32_t _codeFreqBasis = GALILEO_E1_CODE_CHIP_RATE_CPS; // Hz constexpr int32_t codeFreqBasis = GALILEO_E1_CODE_CHIP_RATE_CPS; // chips per second
const int32_t _samplesPerChip = (_cboc == true) ? 12 : 2; const int32_t samplesPerChip = (cboc == true) ? 12 : 2;
const uint32_t _codeLength = _samplesPerChip * GALILEO_E1_B_CODE_LENGTH_CHIPS; const uint32_t codeLength = samplesPerChip * GALILEO_E1_B_CODE_LENGTH_CHIPS;
const std::string _galileo_signal = _Signal.data(); const std::string galileo_signal = signal_id.data();
auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / GALILEO_E1_B_CODE_LENGTH_CHIPS)); auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / GALILEO_E1_B_CODE_LENGTH_CHIPS));
const uint32_t delay = ((static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) - _chip_shift) % static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * _samplesPerCode / GALILEO_E1_B_CODE_LENGTH_CHIPS; const uint32_t delay = ((static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS) - chip_shift) % static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS)) * samplesPerCode / GALILEO_E1_B_CODE_LENGTH_CHIPS;
std::vector<int32_t> primary_code_E1_chips(static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS)); std::vector<int32_t> primary_code_E1_chips(static_cast<int32_t>(GALILEO_E1_B_CODE_LENGTH_CHIPS));
galileo_e1_code_gen_int(primary_code_E1_chips, _Signal, _prn); // generate Galileo E1 code, 1 sample per chip galileo_e1_code_gen_int(primary_code_E1_chips, signal_id, prn); // generate Galileo E1 code, 1 sample per chip
std::vector<float> _signal_E1(_codeLength); std::vector<float> signal_E1(codeLength);
if (_cboc == true) if (cboc == true)
{ {
galileo_e1_gen_float(_signal_E1, primary_code_E1_chips, _Signal); // generate cboc 12 samples per chip galileo_e1_gen_float(signal_E1, primary_code_E1_chips, signal_id); // generate cboc 12 samples per chip
} }
else else
{ {
std::vector<int32_t> _signal_E1_int(static_cast<int32_t>(_codeLength)); std::vector<int32_t> signal_E1_int(static_cast<int32_t>(codeLength));
galileo_e1_sinboc_11_gen_int(_signal_E1_int, primary_code_E1_chips); // generate sinboc(1,1) 2 samples per chip galileo_e1_sinboc_11_gen_int(signal_E1_int, primary_code_E1_chips); // generate sinboc(1,1) 2 samples per chip
for (uint32_t ii = 0; ii < _codeLength; ++ii) for (uint32_t ii = 0; ii < codeLength; ++ii)
{ {
_signal_E1[ii] = static_cast<float>(_signal_E1_int[ii]); signal_E1[ii] = static_cast<float>(signal_E1_int[ii]);
} }
} }
if (_fs != _samplesPerChip * _codeFreqBasis) if (sampling_freq != samplesPerChip * codeFreqBasis)
{ {
std::vector<float> _resampled_signal(_samplesPerCode); std::vector<float> resampled_signal(samplesPerCode);
resampler(_signal_E1, _resampled_signal, static_cast<float>(_samplesPerChip * _codeFreqBasis), _fs); // resamples code to fs resampler(signal_E1, resampled_signal, static_cast<float>(samplesPerChip * codeFreqBasis), sampling_freq); // resamples code to fs
_signal_E1 = std::move(_resampled_signal); signal_E1 = std::move(resampled_signal);
} }
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag) if (galileo_signal.rfind("1C") != std::string::npos && galileo_signal.length() >= 2 && secondary_flag)
{ {
std::vector<float> _signal_E1C_secondary(static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH) * _samplesPerCode); std::vector<float> signal_E1C_secondary(static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH) * samplesPerCode);
for (uint32_t i = 0; i < static_cast<uint32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH); i++) for (uint32_t i = 0; i < static_cast<uint32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH); i++)
{ {
for (uint32_t k = 0; k < _samplesPerCode; k++) for (uint32_t k = 0; k < samplesPerCode; k++)
{ {
_signal_E1C_secondary[i * _samplesPerCode + k] = _signal_E1[k] * (GALILEO_E1_C_SECONDARY_CODE[i] == '0' ? 1.0F : -1.0F); signal_E1C_secondary[i * samplesPerCode + k] = signal_E1[k] * (GALILEO_E1_C_SECONDARY_CODE[i] == '0' ? 1.0F : -1.0F);
} }
} }
_samplesPerCode *= static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH); samplesPerCode *= static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH);
_signal_E1 = std::move(_signal_E1C_secondary); signal_E1 = std::move(signal_E1C_secondary);
} }
for (uint32_t i = 0; i < _samplesPerCode; i++) for (uint32_t i = 0; i < samplesPerCode; i++)
{ {
_dest[(i + delay) % _samplesPerCode] = _signal_E1[i]; dest[(i + delay) % samplesPerCode] = signal_E1[i];
} }
} }
void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift,
bool _secondary_flag) bool secondary_flag)
{ {
constexpr int32_t _codeFreqBasis = GALILEO_E1_CODE_CHIP_RATE_CPS; // Hz constexpr int32_t codeFreqBasis = GALILEO_E1_CODE_CHIP_RATE_CPS; // Hz
const std::string _galileo_signal = _Signal.data(); const std::string galileo_signal = signal_id.data();
auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) /
(static_cast<double>(_codeFreqBasis) / GALILEO_E1_B_CODE_LENGTH_CHIPS)); (static_cast<double>(codeFreqBasis) / GALILEO_E1_B_CODE_LENGTH_CHIPS));
if (_galileo_signal.rfind("1C") != std::string::npos && _galileo_signal.length() >= 2 && _secondary_flag) if (galileo_signal.rfind("1C") != std::string::npos && galileo_signal.length() >= 2 && secondary_flag)
{ {
_samplesPerCode *= static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH); samplesPerCode *= static_cast<int32_t>(GALILEO_E1_C_SECONDARY_CODE_LENGTH);
} }
std::vector<float> real_code(_samplesPerCode); std::vector<float> real_code(samplesPerCode);
galileo_e1_code_gen_float_sampled(real_code, _Signal, _cboc, _prn, _fs, _chip_shift, _secondary_flag); galileo_e1_code_gen_float_sampled(real_code, signal_id, cboc, prn, sampling_freq, chip_shift, secondary_flag);
for (uint32_t ii = 0; ii < _samplesPerCode; ++ii) for (uint32_t ii = 0; ii < samplesPerCode; ++ii)
{ {
_dest[ii] = std::complex<float>(real_code[ii], 0.0F); dest[ii] = std::complex<float>(real_code[ii], 0.0F);
} }
} }
void galileo_e1_code_gen_float_sampled(own::span<float> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_float_sampled(own::span<float> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift)
{ {
galileo_e1_code_gen_float_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false); galileo_e1_code_gen_float_sampled(dest, signal_id, cboc, prn, sampling_freq, chip_shift, false);
} }
void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift)
{ {
galileo_e1_code_gen_complex_sampled(_dest, _Signal, _cboc, _prn, _fs, _chip_shift, false); galileo_e1_code_gen_complex_sampled(dest, signal_id, cboc, prn, sampling_freq, chip_shift, false);
} }

View File

@ -43,39 +43,39 @@ namespace own = gsl;
* \brief This function generates Galileo E1 code (can select E1B or E1C sinboc). * \brief This function generates Galileo E1 code (can select E1B or E1C sinboc).
* *
*/ */
void galileo_e1_code_gen_sinboc11_float(own::span<float> _dest, const std::array<char, 3>& _Signal, uint32_t _prn); void galileo_e1_code_gen_sinboc11_float(own::span<float> dest, const std::array<char, 3>& signal_id, uint32_t prn);
/*! /*!
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc * \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
* and the sample frequency _fs). * and the sample frequency sampling_freq).
* *
*/ */
void galileo_e1_code_gen_float_sampled(own::span<float> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_float_sampled(own::span<float> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift,
bool _secondary_flag); bool secondary_flag);
/*! /*!
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc * \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
* and the sample frequency _fs). * and the sample frequency sampling_freq).
* *
*/ */
void galileo_e1_code_gen_float_sampled(own::span<float> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_float_sampled(own::span<float> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift);
/*! /*!
* \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc * \brief This function generates Galileo E1 code (can select E1B or E1C, cboc or sinboc
* and the sample frequency _fs). * and the sample frequency sampling_freq).
* *
*/ */
void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift,
bool _secondary_flag); bool secondary_flag);
/*! /*!
* \brief galileo_e1_code_gen_complex_sampled without _secondary_flag for backward compatibility. * \brief galileo_e1_code_gen_complex_sampled without secondary_flag for backward compatibility.
*/ */
void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> _dest, const std::array<char, 3>& _Signal, void galileo_e1_code_gen_complex_sampled(own::span<std::complex<float>> dest, const std::array<char, 3>& signal_id,
bool _cboc, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); bool cboc, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -31,189 +31,189 @@
#include <vector> #include <vector>
void galileo_e5_a_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e5_a_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn, int32_t prn,
const std::array<char, 3>& _Signal) const std::array<char, 3>& signal_id)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
if (_Signal[0] == '5' && _Signal[1] == 'Q') if (signal_id[0] == '5' && signal_id[1] == 'Q')
{ {
for (size_t i = 0; i < GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5A_Q_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5A_Q_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5A_Q_PRIMARY_CODE[prn][GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5A_Q_PRIMARY_CODE[prn_][GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
} }
else if (_Signal[0] == '5' && _Signal[1] == 'I') else if (signal_id[0] == '5' && signal_id[1] == 'I')
{ {
for (size_t i = 0; i < GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn][GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn_][GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
} }
else if (_Signal[0] == '5' && _Signal[1] == 'X') else if (signal_id[0] == '5' && signal_id[1] == 'X')
{ {
std::array<int32_t, 4> b{}; std::array<int32_t, 4> b{};
for (size_t i = 0; i < GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn_][i]);
hex_to_binary_converter(b, GALILEO_E5A_Q_PRIMARY_CODE[prn][i]); hex_to_binary_converter(b, GALILEO_E5A_Q_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0])); dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0]));
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1])); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1]));
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), static_cast<float>(b[2])); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), static_cast<float>(b[2]));
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), static_cast<float>(b[3])); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), static_cast<float>(b[3]));
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn][GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5A_I_PRIMARY_CODE[prn_][GALILEO_E5A_I_PRIMARY_CODE_STR_LENGTH - 1]);
hex_to_binary_converter(b, GALILEO_E5A_Q_PRIMARY_CODE[prn][GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(b, GALILEO_E5A_Q_PRIMARY_CODE[prn_][GALILEO_E5A_Q_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0])); dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0]));
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1])); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1]));
} }
} }
void galileo_e5_a_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e5_a_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
const std::array<char, 3>& _Signal, const std::array<char, 3>& signal_id,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift) uint32_t chip_shift)
{ {
constexpr uint32_t _codeLength = GALILEO_E5A_CODE_LENGTH_CHIPS; constexpr uint32_t codeLength = GALILEO_E5A_CODE_LENGTH_CHIPS;
constexpr int32_t _codeFreqBasis = GALILEO_E5A_CODE_CHIP_RATE_CPS; constexpr int32_t codeFreqBasis = GALILEO_E5A_CODE_CHIP_RATE_CPS;
const auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const uint32_t delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength; const uint32_t delay = ((codeLength - chip_shift) % codeLength) * samplesPerCode / codeLength;
std::vector<std::complex<float>> _code(_codeLength); std::vector<std::complex<float>> code_aux(codeLength);
galileo_e5_a_code_gen_complex_primary(_code, _prn, _Signal); galileo_e5_a_code_gen_complex_primary(code_aux, prn, signal_id);
if (_fs != _codeFreqBasis) if (sampling_freq != codeFreqBasis)
{ {
std::vector<std::complex<float>> _resampled_signal(_samplesPerCode); std::vector<std::complex<float>> resampled_signal_aux(samplesPerCode);
resampler(_code, _resampled_signal, _codeFreqBasis, _fs); // resamples code to fs resampler(code_aux, resampled_signal_aux, codeFreqBasis, sampling_freq); // resamples code to sampling_freq
_code = std::move(_resampled_signal); code_aux = std::move(resampled_signal_aux);
} }
for (uint32_t i = 0; i < _samplesPerCode; i++) for (uint32_t i = 0; i < samplesPerCode; i++)
{ {
_dest[(i + delay) % _samplesPerCode] = _code[i]; dest[(i + delay) % samplesPerCode] = code_aux[i];
} }
} }
void galileo_e5_b_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e5_b_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn, int32_t prn,
const std::array<char, 3>& _Signal) const std::array<char, 3>& signal_id)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
if (_Signal[0] == '7' && _Signal[1] == 'Q') if (signal_id[0] == '7' && signal_id[1] == 'Q')
{ {
for (size_t i = 0; i < GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5B_Q_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5B_Q_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5B_Q_PRIMARY_CODE[prn][GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5B_Q_PRIMARY_CODE[prn_][GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
} }
else if (_Signal[0] == '7' && _Signal[1] == 'I') else if (signal_id[0] == '7' && signal_id[1] == 'I')
{ {
for (size_t i = 0; i < GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn][GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn_][GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
} }
else if (_Signal[0] == '7' && _Signal[1] == 'X') else if (signal_id[0] == '7' && signal_id[1] == 'X')
{ {
std::array<int32_t, 4> b{}; std::array<int32_t, 4> b{};
for (size_t i = 0; i < GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn_][i]);
hex_to_binary_converter(b, GALILEO_E5B_Q_PRIMARY_CODE[prn][i]); hex_to_binary_converter(b, GALILEO_E5B_Q_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0])); dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0]));
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1])); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1]));
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), static_cast<float>(b[2])); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), static_cast<float>(b[2]));
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), static_cast<float>(b[3])); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), static_cast<float>(b[3]));
index = index + 4; index = index + 4;
} }
// last 2 bits are filled up zeros // last 2 bits are filled up zeros
hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn][GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E5B_I_PRIMARY_CODE[prn_][GALILEO_E5B_I_PRIMARY_CODE_STR_LENGTH - 1]);
hex_to_binary_converter(b, GALILEO_E5B_Q_PRIMARY_CODE[prn][GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(b, GALILEO_E5B_Q_PRIMARY_CODE[prn_][GALILEO_E5B_Q_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0])); dest[index] = std::complex<float>(static_cast<float>(a[0]), static_cast<float>(b[0]));
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1])); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), static_cast<float>(b[1]));
} }
} }
void galileo_e5_b_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e5_b_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
const std::array<char, 3>& _Signal, const std::array<char, 3>& signal_id,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift) uint32_t chip_shift)
{ {
constexpr uint32_t _codeLength = GALILEO_E5B_CODE_LENGTH_CHIPS; constexpr uint32_t codeLength = GALILEO_E5B_CODE_LENGTH_CHIPS;
constexpr int32_t _codeFreqBasis = GALILEO_E5B_CODE_CHIP_RATE_CPS; constexpr int32_t codeFreqBasis = GALILEO_E5B_CODE_CHIP_RATE_CPS;
const auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const uint32_t delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength; const uint32_t delay = ((codeLength - chip_shift) % codeLength) * samplesPerCode / codeLength;
std::vector<std::complex<float>> _code(_codeLength); std::vector<std::complex<float>> code_aux(codeLength);
galileo_e5_b_code_gen_complex_primary(_code, _prn, _Signal); galileo_e5_b_code_gen_complex_primary(code_aux, prn, signal_id);
if (_fs != _codeFreqBasis) if (sampling_freq != codeFreqBasis)
{ {
std::vector<std::complex<float>> _resampled_signal(_samplesPerCode); std::vector<std::complex<float>> resampled_signal_aux(samplesPerCode);
resampler(_code, _resampled_signal, _codeFreqBasis, _fs); // resamples code to fs resampler(code_aux, resampled_signal_aux, codeFreqBasis, sampling_freq); // resamples code to sampling_freq
_code = std::move(_resampled_signal); code_aux = std::move(resampled_signal_aux);
} }
for (uint32_t i = 0; i < _samplesPerCode; i++) for (uint32_t i = 0; i < samplesPerCode; i++)
{ {
_dest[(i + delay) % _samplesPerCode] = _code[i]; dest[(i + delay) % samplesPerCode] = code_aux[i];
} }
} }

View File

@ -44,39 +44,39 @@ namespace own = gsl;
/*! /*!
* \brief Generates Galileo E5a code at 1 sample/chip * \brief Generates Galileo E5a code at 1 sample/chip
*/ */
void galileo_e5_a_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e5_a_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn, int32_t prn,
const std::array<char, 3>& _Signal); const std::array<char, 3>& signal_id);
/*! /*!
* \brief Generates Galileo E5a complex code, shifted to the desired chip and * \brief Generates Galileo E5a complex code, shifted to the desired chip and
* sampled at a frequency fs * sampled at a frequency sampling_freq
*/ */
void galileo_e5_a_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e5_a_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
const std::array<char, 3>& _Signal, const std::array<char, 3>& signal_id,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift); uint32_t chip_shift);
/*! /*!
* \brief Generates Galileo E5b code at 1 sample/chip * \brief Generates Galileo E5b code at 1 sample/chip
*/ */
void galileo_e5_b_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e5_b_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn, int32_t prn,
const std::array<char, 3>& _Signal); const std::array<char, 3>& signal_id);
/*! /*!
* \brief Generates Galileo E5b complex code, shifted to the desired chip and * \brief Generates Galileo E5b complex code, shifted to the desired chip and
* sampled at a frequency fs * sampled at a frequency sampling_freq
*/ */
void galileo_e5_b_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e5_b_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
const std::array<char, 3>& _Signal, const std::array<char, 3>& signal_id,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift); uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -26,222 +26,222 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
void galileo_e6_b_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e6_b_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn) int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last bit is filled up with a zero // last bit is filled up with a zero
hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn][GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn_][GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
} }
void galileo_e6_b_code_gen_float_primary(own::span<float> _dest, int32_t _prn) void galileo_e6_b_code_gen_float_primary(own::span<float> dest, int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn_][i]);
_dest[index] = static_cast<float>(a[0]); dest[index] = static_cast<float>(a[0]);
_dest[index + 1] = static_cast<float>(a[1]); dest[index + 1] = static_cast<float>(a[1]);
_dest[index + 2] = static_cast<float>(a[2]); dest[index + 2] = static_cast<float>(a[2]);
_dest[index + 3] = static_cast<float>(a[3]); dest[index + 3] = static_cast<float>(a[3]);
index = index + 4; index = index + 4;
} }
// last bit is filled up with a zero // last bit is filled up with a zero
hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn][GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E6_B_PRIMARY_CODE[prn_][GALILEO_E6_B_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = static_cast<float>(a[0]); dest[index] = static_cast<float>(a[0]);
_dest[index + 1] = static_cast<float>(a[1]); dest[index + 1] = static_cast<float>(a[1]);
_dest[index + 2] = static_cast<float>(a[2]); dest[index + 2] = static_cast<float>(a[2]);
} }
void galileo_e6_b_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e6_b_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift) uint32_t chip_shift)
{ {
constexpr uint32_t _codeLength = GALILEO_E6_B_CODE_LENGTH_CHIPS; constexpr uint32_t codeLength = GALILEO_E6_B_CODE_LENGTH_CHIPS;
constexpr int32_t _codeFreqBasis = GALILEO_E6_B_CODE_CHIP_RATE_CPS; constexpr int32_t codeFreqBasis = GALILEO_E6_B_CODE_CHIP_RATE_CPS;
const auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const uint32_t delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength; const uint32_t delay = ((codeLength - chip_shift) % codeLength) * samplesPerCode / codeLength;
std::vector<std::complex<float>> _code(_codeLength); std::vector<std::complex<float>> code_aux(codeLength);
galileo_e6_b_code_gen_complex_primary(_code, _prn); galileo_e6_b_code_gen_complex_primary(code_aux, prn);
if (_fs != _codeFreqBasis) if (sampling_freq != codeFreqBasis)
{ {
std::vector<std::complex<float>> _resampled_signal(_samplesPerCode); std::vector<std::complex<float>> resampled_signal_aux(samplesPerCode);
resampler(_code, _resampled_signal, _codeFreqBasis, _fs); // resamples code to fs resampler(code_aux, resampled_signal_aux, codeFreqBasis, sampling_freq); // resamples code to sampling_freq
_code = std::move(_resampled_signal); code_aux = std::move(resampled_signal_aux);
} }
for (uint32_t i = 0; i < _samplesPerCode; i++) for (uint32_t i = 0; i < samplesPerCode; i++)
{ {
_dest[(i + delay) % _samplesPerCode] = _code[i]; dest[(i + delay) % samplesPerCode] = code_aux[i];
} }
} }
void galileo_e6_c_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e6_c_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn) int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
// last bit is filled up with a zero // last bit is filled up with a zero
hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn][GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn_][GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
} }
void galileo_e6_c_code_gen_float_primary(own::span<float> _dest, int32_t _prn) void galileo_e6_c_code_gen_float_primary(own::span<float> dest, int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1; i++) for (size_t i = 0; i < GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn_][i]);
_dest[index] = static_cast<float>(a[0]); dest[index] = static_cast<float>(a[0]);
_dest[index + 1] = static_cast<float>(a[1]); dest[index + 1] = static_cast<float>(a[1]);
_dest[index + 2] = static_cast<float>(a[2]); dest[index + 2] = static_cast<float>(a[2]);
_dest[index + 3] = static_cast<float>(a[3]); dest[index + 3] = static_cast<float>(a[3]);
index = index + 4; index = index + 4;
} }
// last bit is filled up with a zero // last bit is filled up with a zero
hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn][GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1]); hex_to_binary_converter(a, GALILEO_E6_C_PRIMARY_CODE[prn_][GALILEO_E6_C_PRIMARY_CODE_STR_LENGTH - 1]);
_dest[index] = static_cast<float>(a[0]); dest[index] = static_cast<float>(a[0]);
_dest[index + 1] = static_cast<float>(a[1]); dest[index + 1] = static_cast<float>(a[1]);
_dest[index + 2] = static_cast<float>(a[2]); dest[index + 2] = static_cast<float>(a[2]);
} }
void galileo_e6_c_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e6_c_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift) uint32_t chip_shift)
{ {
constexpr uint32_t _codeLength = GALILEO_E6_C_CODE_LENGTH_CHIPS; constexpr uint32_t codeLength = GALILEO_E6_C_CODE_LENGTH_CHIPS;
constexpr int32_t _codeFreqBasis = GALILEO_E6_C_CODE_CHIP_RATE_CPS; constexpr int32_t codeFreqBasis = GALILEO_E6_C_CODE_CHIP_RATE_CPS;
const auto _samplesPerCode = static_cast<uint32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<uint32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const uint32_t delay = ((_codeLength - _chip_shift) % _codeLength) * _samplesPerCode / _codeLength; const uint32_t delay = ((codeLength - chip_shift) % codeLength) * samplesPerCode / codeLength;
std::vector<std::complex<float>> _code(_codeLength); std::vector<std::complex<float>> code_aux(codeLength);
galileo_e6_c_code_gen_complex_primary(_code, _prn); galileo_e6_c_code_gen_complex_primary(code_aux, prn);
if (_fs != _codeFreqBasis) if (sampling_freq != codeFreqBasis)
{ {
std::vector<std::complex<float>> _resampled_signal(_samplesPerCode); std::vector<std::complex<float>> resampled_signal_aux(samplesPerCode);
resampler(_code, _resampled_signal, _codeFreqBasis, _fs); // resamples code to fs resampler(code_aux, resampled_signal_aux, codeFreqBasis, sampling_freq); // resamples code to sampling_freq
_code = std::move(_resampled_signal); code_aux = std::move(resampled_signal_aux);
} }
for (uint32_t i = 0; i < _samplesPerCode; i++) for (uint32_t i = 0; i < samplesPerCode; i++)
{ {
_dest[(i + delay) % _samplesPerCode] = _code[i]; dest[(i + delay) % samplesPerCode] = code_aux[i];
} }
} }
void galileo_e6_c_secondary_code_gen_complex(own::span<std::complex<float>> _dest, void galileo_e6_c_secondary_code_gen_complex(own::span<std::complex<float>> dest,
int32_t _prn) int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_C_SECONDARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_C_SECONDARY_CODE[prn_][i]);
_dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0); dest[index] = std::complex<float>(static_cast<float>(a[0]), 0.0);
_dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0); dest[index + 1] = std::complex<float>(static_cast<float>(a[1]), 0.0);
_dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0); dest[index + 2] = std::complex<float>(static_cast<float>(a[2]), 0.0);
_dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0); dest[index + 3] = std::complex<float>(static_cast<float>(a[3]), 0.0);
index = index + 4; index = index + 4;
} }
} }
void galileo_e6_c_secondary_code_gen_float(own::span<float> _dest, void galileo_e6_c_secondary_code_gen_float(own::span<float> dest,
int32_t _prn) int32_t prn)
{ {
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
std::array<int32_t, 4> a{}; std::array<int32_t, 4> a{};
if ((_prn < 1) || (_prn > 50)) if ((prn < 1) || (prn > 50))
{ {
return; return;
} }
for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++)
{ {
hex_to_binary_converter(a, GALILEO_E6_C_SECONDARY_CODE[prn][i]); hex_to_binary_converter(a, GALILEO_E6_C_SECONDARY_CODE[prn_][i]);
_dest[index] = static_cast<float>(a[0]); dest[index] = static_cast<float>(a[0]);
_dest[index + 1] = static_cast<float>(a[1]); dest[index + 1] = static_cast<float>(a[1]);
_dest[index + 2] = static_cast<float>(a[2]); dest[index + 2] = static_cast<float>(a[2]);
_dest[index + 3] = static_cast<float>(a[3]); dest[index + 3] = static_cast<float>(a[3]);
index = index + 4; index = index + 4;
} }
} }
std::string galileo_e6_c_secondary_code(int32_t _prn) std::string galileo_e6_c_secondary_code(int32_t prn)
{ {
std::string dest(static_cast<size_t>(GALILEO_E6_C_SECONDARY_CODE_LENGTH_CHIPS), '0'); std::string dest(static_cast<size_t>(GALILEO_E6_C_SECONDARY_CODE_LENGTH_CHIPS), '0');
const uint32_t prn = _prn - 1; const uint32_t prn_ = prn - 1;
uint32_t index = 0; uint32_t index = 0;
for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++) for (size_t i = 0; i < GALILEO_E6_C_SECONDARY_CODE_STR_LENGTH; i++)
{ {
std::string aux = hex_to_binary_string(GALILEO_E6_C_SECONDARY_CODE[prn][i]); std::string aux = hex_to_binary_string(GALILEO_E6_C_SECONDARY_CODE[prn_][i]);
dest[index] = aux[0]; dest[index] = aux[0];
dest[index + 1] = aux[1]; dest[index + 1] = aux[1];
dest[index + 2] = aux[2]; dest[index + 2] = aux[2];

View File

@ -43,67 +43,67 @@ namespace own = gsl;
/*! /*!
* \brief Generates Galileo E6B code at 1 sample/chip * \brief Generates Galileo E6B code at 1 sample/chip
*/ */
void galileo_e6_b_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e6_b_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn); int32_t prn);
/*! /*!
* \brief Generates Galileo E6B code at 1 sample/chip * \brief Generates Galileo E6B code at 1 sample/chip
*/ */
void galileo_e6_b_code_gen_float_primary(own::span<float> _dest, int32_t _prn); void galileo_e6_b_code_gen_float_primary(own::span<float> dest, int32_t prn);
/*! /*!
* \brief Generates Galileo E6B complex code, shifted to the desired chip and * \brief Generates Galileo E6B complex code, shifted to the desired chip and
* sampled at a frequency fs * sampled at a frequency sampling_freq
*/ */
void galileo_e6_b_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e6_b_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift); uint32_t chip_shift);
/*! /*!
* \brief Generates Galileo E6C codes at 1 sample/chip * \brief Generates Galileo E6C codes at 1 sample/chip
*/ */
void galileo_e6_c_code_gen_complex_primary(own::span<std::complex<float>> _dest, void galileo_e6_c_code_gen_complex_primary(own::span<std::complex<float>> dest,
int32_t _prn); int32_t prn);
/*! /*!
* \brief Generates Galileo E6C codes at 1 sample/chip * \brief Generates Galileo E6C codes at 1 sample/chip
*/ */
void galileo_e6_c_code_gen_float_primary(own::span<float> _dest, int32_t _prn); void galileo_e6_c_code_gen_float_primary(own::span<float> dest, int32_t prn);
/*! /*!
* \brief Generates Galileo E6C complex codes, shifted to the desired chip and * \brief Generates Galileo E6C complex codes, shifted to the desired chip and
* sampled at a frequency fs * sampled at a frequency sampling_freq
*/ */
void galileo_e6_c_code_gen_complex_sampled(own::span<std::complex<float>> _dest, void galileo_e6_c_code_gen_complex_sampled(own::span<std::complex<float>> dest,
uint32_t _prn, uint32_t prn,
int32_t _fs, int32_t sampling_freq,
uint32_t _chip_shift); uint32_t chip_shift);
/*! /*!
* \brief Generates Galileo E6C secondary codes at 1 sample/chip * \brief Generates Galileo E6C secondary codes at 1 sample/chip
*/ */
void galileo_e6_c_secondary_code_gen_complex(own::span<std::complex<float>> _dest, void galileo_e6_c_secondary_code_gen_complex(own::span<std::complex<float>> dest,
int32_t _prn); int32_t prn);
/*! /*!
* \brief Generates Galileo E6C secondary codes at 1 sample/chip * \brief Generates Galileo E6C secondary codes at 1 sample/chip
*/ */
void galileo_e6_c_secondary_code_gen_float(own::span<float> _dest, void galileo_e6_c_secondary_code_gen_float(own::span<float> dest,
int32_t _prn); int32_t prn);
/*! /*!
* \brief Generates a string with Galileo E6C secondary codes at 1 sample/chip * \brief Generates a string with Galileo E6C secondary codes at 1 sample/chip
*/ */
std::string galileo_e6_c_secondary_code(int32_t _prn); std::string galileo_e6_c_secondary_code(int32_t prn);
/** \} */ /** \} */

View File

@ -25,10 +25,10 @@
const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _chip_shift) void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> dest, uint32_t chip_shift)
{ {
const uint32_t _code_length = 511; const uint32_t code_length = 511;
std::bitset<_code_length> G1{}; std::bitset<code_length> G1{};
auto G1_register = std::bitset<9>{}.set(); // All true auto G1_register = std::bitset<9>{}.set(); // All true
bool feedback1; bool feedback1;
bool aux; bool aux;
@ -37,7 +37,7 @@ void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
uint32_t lcv2; uint32_t lcv2;
/* Generate G1 Register */ /* Generate G1 Register */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
G1[lcv] = G1_register[2]; G1[lcv] = G1_register[2];
@ -52,38 +52,38 @@ void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
} }
/* Generate PRN from G1 Register */ /* Generate PRN from G1 Register */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[lcv]; aux = G1[lcv];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = std::complex<float>(1, 0); dest[lcv] = std::complex<float>(1, 0);
} }
else else
{ {
_dest[lcv] = std::complex<float>(-1, 0); dest[lcv] = std::complex<float>(-1, 0);
} }
} }
/* Set the delay */ /* Set the delay */
delay = _code_length; delay = code_length;
delay += _chip_shift; delay += chip_shift;
delay %= _code_length; delay %= code_length;
/* Generate PRN from G1 and G2 Registers */ /* Generate PRN from G1 and G2 Registers */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[(lcv + _chip_shift) % _code_length]; aux = G1[(lcv + chip_shift) % code_length];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = std::complex<float>(1, 0); dest[lcv] = std::complex<float>(1, 0);
} }
else else
{ {
_dest[lcv] = std::complex<float>(-1, 0); dest[lcv] = std::complex<float>(-1, 0);
} }
delay++; delay++;
delay %= _code_length; delay %= code_length;
} }
} }
@ -91,44 +91,44 @@ void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
/* /*
* Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency * Generates complex GLONASS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
*/ */
void glonass_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift) void glonass_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, int32_t sampling_freq, uint32_t chip_shift)
{ {
constexpr int32_t _codeFreqBasis = 511000; // Hz constexpr int32_t codeFreqBasis = 511000; // chips per second
constexpr int32_t _codeLength = 511; constexpr int32_t codeLength = 511;
constexpr float _tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec constexpr float tc = 1.0 / static_cast<float>(codeFreqBasis); // C/A chip period in sec
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
std::array<std::complex<float>, 511> _code{}; std::array<std::complex<float>, 511> code_aux{};
int32_t _codeValueIndex; int32_t codeValueIndex;
float aux; float aux;
glonass_l1_ca_code_gen_complex(_code, _chip_shift); // generate C/A code 1 sample per chip glonass_l1_ca_code_gen_complex(code_aux, chip_shift); // generate C/A code 1 sample per chip
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
// --- Make index array to read C/A code values -------------------- // --- Make index array to read C/A code values --------------------
// The length of the index array depends on the sampling frequency - // The length of the index array depends on the sampling frequency -
// number of samples per millisecond (because one C/A code period is one // number of samples per millisecond (because one C/A code period is
// millisecond). // one millisecond).
aux = (_ts * (static_cast<float>(i) + 1)) / _tc; aux = (ts * (static_cast<float>(i) + 1)) / tc;
_codeValueIndex = AUX_CEIL(aux) - 1; codeValueIndex = AUX_CEIL(aux) - 1;
// --- Make the digitized version of the C/A code ------------------ // --- Make the digitized version of the C/A code ------------------
// The "upsampled" code is made by selecting values form the CA code // The "upsampled" code is made by selecting values form the CA code
// chip array (caCode) for the time instances of each sample. // chip array (caCode) for the time instances of each sample.
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // Correct the last index (due to number rounding issues)
_dest[i] = _code[_codeLength - 1]; dest[i] = code_aux[codeLength - 1];
} }
else else
{ {
_dest[i] = _code[_codeValueIndex]; // repeat the chip -> upsample dest[i] = code_aux[codeValueIndex]; // repeat the chip -> upsample
} }
} }
} }

View File

@ -38,14 +38,11 @@ namespace own = gsl;
* \{ */ * \{ */
//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _chip_shift);
//! Generates N complex GLONASS L1 C/A codes for the desired SV ID and code shift
void glonass_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift //! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift
void glonass_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift); void glonass_l1_ca_code_gen_complex(own::span<std::complex<float>> dest, uint32_t chip_shift);
//! Generates complex GLONASS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void glonass_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, int32_t sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -25,10 +25,10 @@
const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _chip_shift) void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> dest, uint32_t chip_shift)
{ {
const uint32_t _code_length = 511; const uint32_t code_length = 511;
std::bitset<_code_length> G1{}; std::bitset<code_length> G1{};
auto G1_register = std::bitset<9>{}.set(); // All true auto G1_register = std::bitset<9>{}.set(); // All true
bool feedback1; bool feedback1;
bool aux; bool aux;
@ -37,7 +37,7 @@ void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
uint32_t lcv2; uint32_t lcv2;
/* Generate G1 Register */ /* Generate G1 Register */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
G1[lcv] = G1_register[2]; G1[lcv] = G1_register[2];
@ -52,38 +52,38 @@ void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
} }
/* Generate PRN from G1 Register */ /* Generate PRN from G1 Register */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[lcv]; aux = G1[lcv];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = std::complex<float>(1, 0); dest[lcv] = std::complex<float>(1, 0);
} }
else else
{ {
_dest[lcv] = std::complex<float>(-1, 0); dest[lcv] = std::complex<float>(-1, 0);
} }
} }
/* Set the delay */ /* Set the delay */
delay = _code_length; delay = code_length;
delay += _chip_shift; delay += chip_shift;
delay %= _code_length; delay %= code_length;
/* Generate PRN from G1 and G2 Registers */ /* Generate PRN from G1 and G2 Registers */
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[(lcv + _chip_shift) % _code_length]; aux = G1[(lcv + chip_shift) % code_length];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = std::complex<float>(1, 0); dest[lcv] = std::complex<float>(1, 0);
} }
else else
{ {
_dest[lcv] = std::complex<float>(-1, 0); dest[lcv] = std::complex<float>(-1, 0);
} }
delay++; delay++;
delay %= _code_length; delay %= code_length;
} }
} }
@ -91,44 +91,44 @@ void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32
/* /*
* Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency * Generates complex GLONASS L2 C/A code for the desired SV ID and sampled to specific sampling frequency
*/ */
void glonass_l2_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift) void glonass_l2_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, int32_t sampling_freq, uint32_t chip_shift)
{ {
constexpr int32_t _codeFreqBasis = 511000; // Hz constexpr int32_t codeFreqBasis = 511000; // chips per second
constexpr int32_t _codeLength = 511; constexpr int32_t codeLength = 511;
constexpr float _tc = 1.0 / static_cast<float>(_codeFreqBasis); // C/A chip period in sec constexpr float tc = 1.0 / static_cast<float>(codeFreqBasis); // C/A chip period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
std::array<std::complex<float>, 511> _code{}; std::array<std::complex<float>, 511> code_aux{};
int32_t _codeValueIndex; int32_t codeValueIndex;
float aux; float aux;
glonass_l2_ca_code_gen_complex(_code, _chip_shift); // generate C/A code 1 sample per chip glonass_l2_ca_code_gen_complex(code_aux, chip_shift); // generate C/A code 1 sample per chip
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
// --- Make index array to read C/A code values -------------------- // --- Make index array to read C/A code values --------------------
// The length of the index array depends on the sampling frequency - // The length of the index array depends on the sampling frequency -
// number of samples per millisecond (because one C/A code period is one // number of samples per millisecond (because one C/A code period is
// millisecond). // one millisecond).
aux = (_ts * (static_cast<float>(i) + 1)) / _tc; aux = (ts * (static_cast<float>(i) + 1)) / tc;
_codeValueIndex = AUX_CEIL(aux) - 1; codeValueIndex = AUX_CEIL(aux) - 1;
// --- Make the digitized version of the C/A code ------------------ // --- Make the digitized version of the C/A code ------------------
// The "upsampled" code is made by selecting values form the CA code // The "upsampled" code is made by selecting values form the CA code
// chip array (caCode) for the time instances of each sample. // chip array (caCode) for the time instances of each sample.
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // Correct the last index (due to number rounding issues)
_dest[i] = _code[_codeLength - 1]; dest[i] = code_aux[codeLength - 1];
} }
else else
{ {
_dest[i] = _code[_codeValueIndex]; // repeat the chip -> upsample dest[i] = code_aux[codeValueIndex]; // repeat the chip -> upsample
} }
} }
} }

View File

@ -38,14 +38,11 @@ namespace own = gsl;
* \{ */ * \{ */
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _chip_shift);
//! Generates N complex GLONASS L2 C/A codes for the desired SV ID and code shift
void glonass_l2_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift //! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift
void glonass_l2_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, int32_t _fs, uint32_t _chip_shift); void glonass_l2_ca_code_gen_complex(own::span<std::complex<float>> dest, uint32_t chip_shift);
//! Generates complex GLONASS L2 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void glonass_l2_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, int32_t sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -27,121 +27,121 @@
const auto AUX_CEIL2 = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL2 = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void complex_exp_gen(own::span<std::complex<float>> _dest, double _f, double _fs) void complex_exp_gen(own::span<std::complex<float>> dest, double freq, double sampling_freq)
{ {
gr::fxpt_nco d_nco; gr::fxpt_nco d_nco;
d_nco.set_freq(static_cast<float>((TWO_PI * _f) / _fs)); d_nco.set_freq(static_cast<float>((TWO_PI * freq) / sampling_freq));
d_nco.sincos(_dest.data(), _dest.size(), 1); d_nco.sincos(dest.data(), dest.size(), 1);
} }
void complex_exp_gen_conj(own::span<std::complex<float>> _dest, double _f, double _fs) void complex_exp_gen_conj(own::span<std::complex<float>> dest, double freq, double sampling_freq)
{ {
gr::fxpt_nco d_nco; gr::fxpt_nco d_nco;
d_nco.set_freq(-static_cast<float>((TWO_PI * _f) / _fs)); d_nco.set_freq(-static_cast<float>((TWO_PI * freq) / sampling_freq));
d_nco.sincos(_dest.data(), _dest.size(), 1); d_nco.sincos(dest.data(), dest.size(), 1);
} }
void hex_to_binary_converter(own::span<int32_t> _dest, char _from) void hex_to_binary_converter(own::span<int32_t> dest, char from)
{ {
switch (_from) switch (from)
{ {
case '0': case '0':
_dest[0] = 1; dest[0] = 1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = 1; dest[3] = 1;
break; break;
case '1': case '1':
_dest[0] = 1; dest[0] = 1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = -1; dest[3] = -1;
break; break;
case '2': case '2':
_dest[0] = 1; dest[0] = 1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = 1; dest[3] = 1;
break; break;
case '3': case '3':
_dest[0] = 1; dest[0] = 1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = -1; dest[3] = -1;
break; break;
case '4': case '4':
_dest[0] = 1; dest[0] = 1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = 1; dest[3] = 1;
break; break;
case '5': case '5':
_dest[0] = 1; dest[0] = 1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = -1; dest[3] = -1;
break; break;
case '6': case '6':
_dest[0] = 1; dest[0] = 1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = 1; dest[3] = 1;
break; break;
case '7': case '7':
_dest[0] = 1; dest[0] = 1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = -1; dest[3] = -1;
break; break;
case '8': case '8':
_dest[0] = -1; dest[0] = -1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = 1; dest[3] = 1;
break; break;
case '9': case '9':
_dest[0] = -1; dest[0] = -1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = -1; dest[3] = -1;
break; break;
case 'A': case 'A':
_dest[0] = -1; dest[0] = -1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = 1; dest[3] = 1;
break; break;
case 'B': case 'B':
_dest[0] = -1; dest[0] = -1;
_dest[1] = 1; dest[1] = 1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = -1; dest[3] = -1;
break; break;
case 'C': case 'C':
_dest[0] = -1; dest[0] = -1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = 1; dest[3] = 1;
break; break;
case 'D': case 'D':
_dest[0] = -1; dest[0] = -1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = 1; dest[2] = 1;
_dest[3] = -1; dest[3] = -1;
break; break;
case 'E': case 'E':
_dest[0] = -1; dest[0] = -1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = 1; dest[3] = 1;
break; break;
case 'F': case 'F':
_dest[0] = -1; dest[0] = -1;
_dest[1] = -1; dest[1] = -1;
_dest[2] = -1; dest[2] = -1;
_dest[3] = -1; dest[3] = -1;
break; break;
default: default:
break; break;
@ -149,143 +149,145 @@ void hex_to_binary_converter(own::span<int32_t> _dest, char _from)
} }
std::string hex_to_binary_string(char _from) std::string hex_to_binary_string(char from)
{ {
std::string _dest("0000"); std::string dest("0000");
switch (_from) switch (from)
{ {
case '0': case '0':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '0'; dest[3] = '0';
break; break;
case '1': case '1':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '1'; dest[3] = '1';
break; break;
case '2': case '2':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '0'; dest[3] = '0';
break; break;
case '3': case '3':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '1'; dest[3] = '1';
break; break;
case '4': case '4':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '0'; dest[3] = '0';
break; break;
case '5': case '5':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '1'; dest[3] = '1';
break; break;
case '6': case '6':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '0'; dest[3] = '0';
break; break;
case '7': case '7':
_dest[0] = '0'; dest[0] = '0';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '1'; dest[3] = '1';
break; break;
case '8': case '8':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '0'; dest[3] = '0';
break; break;
case '9': case '9':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '1'; dest[3] = '1';
break; break;
case 'A': case 'A':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '0'; dest[3] = '0';
break; break;
case 'B': case 'B':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '0'; dest[1] = '0';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '1'; dest[3] = '1';
break; break;
case 'C': case 'C':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '0'; dest[3] = '0';
break; break;
case 'D': case 'D':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '0'; dest[2] = '0';
_dest[3] = '1'; dest[3] = '1';
break; break;
case 'E': case 'E':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '0'; dest[3] = '0';
break; break;
case 'F': case 'F':
_dest[0] = '1'; dest[0] = '1';
_dest[1] = '1'; dest[1] = '1';
_dest[2] = '1'; dest[2] = '1';
_dest[3] = '1'; dest[3] = '1';
break; break;
default: default:
break; break;
} }
return _dest; return dest;
} }
void resampler(const own::span<float> _from, own::span<float> _dest, float _fs_in, void resampler(const own::span<float> from, own::span<float> dest, float fs_in,
float _fs_out) float fs_out)
{ {
uint32_t _codeValueIndex; uint32_t codeValueIndex;
float aux; float aux;
const float _t_out = 1.0F / _fs_out; // Output sampling period const float t_out = 1.0F / fs_out; // Output sampling period
for (size_t i = 0; i < _dest.size() - 1; i++) const size_t dest_size = dest.size();
for (size_t i = 0; i < dest_size - 1; i++)
{ {
aux = (_t_out * (static_cast<float>(i) + 1.0F)) * _fs_in; aux = (t_out * (static_cast<float>(i) + 1.0F)) * fs_in;
_codeValueIndex = AUX_CEIL2(aux) - 1; codeValueIndex = AUX_CEIL2(aux) - 1;
_dest[i] = _from[_codeValueIndex]; dest[i] = from[codeValueIndex];
} }
// Correct the last index (due to number rounding issues) // Correct the last index (due to number rounding issues)
_dest[_dest.size() - 1] = _from[_from.size() - 1]; dest[dest_size - 1] = from[from.size() - 1];
} }
void resampler(own::span<const std::complex<float>> _from, own::span<std::complex<float>> _dest, float _fs_in, void resampler(own::span<const std::complex<float>> from, own::span<std::complex<float>> dest, float fs_in,
float _fs_out) float fs_out)
{ {
uint32_t _codeValueIndex; uint32_t codeValueIndex;
float aux; float aux;
const float _t_out = 1.0F / _fs_out; // Output sampling period const float t_out = 1.0F / fs_out; // Output sampling period
for (size_t i = 0; i < _dest.size() - 1; i++) const size_t dest_size = dest.size();
for (size_t i = 0; i < dest_size - 1; i++)
{ {
aux = (_t_out * (static_cast<float>(i) + 1.0F)) * _fs_in; aux = (t_out * (static_cast<float>(i) + 1.0F)) * fs_in;
_codeValueIndex = AUX_CEIL2(aux) - 1; codeValueIndex = AUX_CEIL2(aux) - 1;
_dest[i] = _from[_codeValueIndex]; dest[i] = from[codeValueIndex];
} }
// Correct the last index (due to number rounding issues) // Correct the last index (due to number rounding issues)
_dest[_dest.size() - 1] = _from[_from.size() - 1]; dest[dest_size - 1] = from[from.size() - 1];
} }

View File

@ -40,44 +40,44 @@ namespace own = gsl;
/*! /*!
* \brief This function generates a complex exponential in _dest. * \brief This function generates a complex exponential in dest.
* *
*/ */
void complex_exp_gen(own::span<std::complex<float>> _dest, double _f, double _fs); void complex_exp_gen(own::span<std::complex<float>> dest, double freq, double sampling_freq);
/*! /*!
* \brief This function generates a conjugate complex exponential in _dest. * \brief This function generates a conjugate complex exponential in dest.
* *
*/ */
void complex_exp_gen_conj(own::span<std::complex<float>> _dest, double _f, double _fs); void complex_exp_gen_conj(own::span<std::complex<float>> dest, double freq, double sampling_freq);
/*! /*!
* \brief This function makes a conversion from hex (the input is a char) * \brief This function makes a conversion from hex (the input is a char)
* to binary (the output are 4 ints with +1 or -1 values). * to binary (the output are 4 ints with +1 or -1 values).
* *
*/ */
void hex_to_binary_converter(own::span<int32_t> _dest, char _from); void hex_to_binary_converter(own::span<int32_t> dest, char from);
/*! /*!
* \brief This function makes a conversion from hex (the input is a char) * \brief This function makes a conversion from hex (the input is a char)
* to binary (the output is a string of 4 char with 0 or 1 values). * to binary (the output is a string of 4 char with 0 or 1 values).
* *
*/ */
std::string hex_to_binary_string(char _from); std::string hex_to_binary_string(char from);
/*! /*!
* \brief This function resamples a sequence of float values. * \brief This function resamples a sequence of float values.
* *
*/ */
void resampler(const own::span<float> _from, own::span<float> _dest, void resampler(const own::span<float> from, own::span<float> dest,
float _fs_in, float _fs_out); float fs_in, float fs_out);
/*! /*!
* \brief This function resamples a sequence of complex values. * \brief This function resamples a sequence of complex values.
* *
*/ */
void resampler(own::span<const std::complex<float>> _from, own::span<std::complex<float>> _dest, void resampler(own::span<const std::complex<float>> from, own::span<std::complex<float>> dest,
float _fs_in, float _fs_out); float fs_in, float fs_out);
/** \} */ /** \} */

View File

@ -31,43 +31,43 @@ uint32_t gps_l2c_m_shift(uint32_t x)
} }
void gps_l2c_m_code(own::span<int32_t> _dest, uint32_t _prn) void gps_l2c_m_code(own::span<int32_t> dest, uint32_t prn)
{ {
uint32_t x = GPS_L2C_M_INIT_REG[_prn - 1]; uint32_t x = GPS_L2C_M_INIT_REG[prn - 1];
for (int32_t n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++) for (int32_t n = 0; n < GPS_L2_M_CODE_LENGTH_CHIPS; n++)
{ {
_dest[n] = static_cast<int8_t>(x & 1U); dest[n] = static_cast<int32_t>(x & 1U);
x = gps_l2c_m_shift(x); x = gps_l2c_m_shift(x);
} }
} }
void gps_l2c_m_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn) void gps_l2c_m_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
gps_l2c_m_code(_code, _prn); gps_l2c_m_code(code_aux, prn);
} }
for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * _code[i]); dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * code_aux[i]);
} }
} }
void gps_l2c_m_code_gen_float(own::span<float> _dest, uint32_t _prn) void gps_l2c_m_code_gen_float(own::span<float> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
gps_l2c_m_code(_code, _prn); gps_l2c_m_code(code_aux, prn);
} }
for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L2_M_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]); dest[i] = 1.0 - 2.0 * static_cast<float>(code_aux[i]);
} }
} }
@ -75,37 +75,37 @@ void gps_l2c_m_code_gen_float(own::span<float> _dest, uint32_t _prn)
/* /*
* Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency * Generates complex GPS L2C M code for the desired SV ID and sampled to specific sampling frequency
*/ */
void gps_l2c_m_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs) void gps_l2c_m_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq)
{ {
constexpr int32_t _codeLength = GPS_L2_M_CODE_LENGTH_CHIPS; constexpr int32_t codeLength = GPS_L2_M_CODE_LENGTH_CHIPS;
constexpr float _tc = 1.0F / static_cast<float>(GPS_L2_M_CODE_RATE_CPS); // L2C chip period in sec constexpr float tc = 1.0F / static_cast<float>(GPS_L2_M_CODE_RATE_CPS); // L2C chip period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L2_M_CODE_RATE_CPS) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(GPS_L2_M_CODE_RATE_CPS) / static_cast<double>(codeLength)));
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
int32_t _codeValueIndex; int32_t codeValueIndex;
std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L2_M_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
gps_l2c_m_code(_code, _prn); gps_l2c_m_code(code_aux, prn);
} }
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
// --- Make index array to read L2C code values -------------------- // --- Make index array to read L2C code values --------------------
_codeValueIndex = std::ceil((_ts * (static_cast<float>(i) + 1.0F)) / _tc) - 1; codeValueIndex = std::ceil((ts * (static_cast<float>(i) + 1.0F)) / tc) - 1;
// --- Make the digitized version of the L2C code ------------------ // --- Make the digitized version of the L2C code ------------------
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // Correct the last index (due to number rounding issues)
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * _code[_codeLength - 1]); dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * code_aux[codeLength - 1]);
} }
else else
{ {
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * _code[_codeValueIndex]); // repeat the chip -> upsample dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * code_aux[codeValueIndex]); // repeat the chip -> upsample
} }
} }
} }

View File

@ -38,11 +38,13 @@ namespace own = gsl;
//! Generates complex GPS L2C M code for the desired SV ID //! Generates complex GPS L2C M code for the desired SV ID
void gps_l2c_m_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn); void gps_l2c_m_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn);
void gps_l2c_m_code_gen_float(own::span<float> _dest, uint32_t _prn);
//! Generates float GPS L2C M code for the desired SV ID
void gps_l2c_m_code_gen_float(own::span<float> dest, uint32_t prn);
//! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency //! Generates complex GPS L2C M code for the desired SV ID, and sampled to specific sampling frequency
void gps_l2c_m_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs); void gps_l2c_m_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq);
/** \} */ /** \} */

View File

@ -120,7 +120,7 @@ std::deque<bool> make_l5q_xb()
} }
void make_l5i(own::span<int32_t> _dest, int32_t prn) void make_l5i(own::span<int32_t> dest, int32_t prn)
{ {
const int32_t xb_offset = GPS_L5I_INIT_REG[prn]; const int32_t xb_offset = GPS_L5I_INIT_REG[prn];
@ -135,12 +135,12 @@ void make_l5i(own::span<int32_t> _dest, int32_t prn)
for (int32_t n = 0; n < GPS_L5I_CODE_LENGTH_CHIPS; n++) for (int32_t n = 0; n < GPS_L5I_CODE_LENGTH_CHIPS; n++)
{ {
_dest[n] = xa[n] xor xb_shift[n]; dest[n] = xa[n] xor xb_shift[n];
} }
} }
void make_l5q(own::span<int32_t> _dest, int32_t prn) void make_l5q(own::span<int32_t> dest, int32_t prn)
{ {
const int32_t xb_offset = GPS_L5Q_INIT_REG[prn]; const int32_t xb_offset = GPS_L5Q_INIT_REG[prn];
@ -155,37 +155,37 @@ void make_l5q(own::span<int32_t> _dest, int32_t prn)
for (int32_t n = 0; n < GPS_L5Q_CODE_LENGTH_CHIPS; n++) for (int32_t n = 0; n < GPS_L5Q_CODE_LENGTH_CHIPS; n++)
{ {
_dest[n] = xa[n] xor xb_shift[n]; dest[n] = xa[n] xor xb_shift[n];
} }
} }
void gps_l5i_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn) void gps_l5i_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5i(_code, _prn - 1); make_l5i(code_aux, prn - 1);
} }
for (int32_t i = 0; i < GPS_L5I_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L5I_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = std::complex<float>(1.0F - 2.0F * static_cast<float>(_code[i]), 0.0); dest[i] = std::complex<float>(1.0F - 2.0F * static_cast<float>(code_aux[i]), 0.0);
} }
} }
void gps_l5i_code_gen_float(own::span<float> _dest, uint32_t _prn) void gps_l5i_code_gen_float(own::span<float> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5i(_code, _prn - 1); make_l5i(code_aux, prn - 1);
} }
for (int32_t i = 0; i < GPS_L5I_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L5I_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = 1.0F - 2.0F * static_cast<float>(_code[i]); dest[i] = 1.0F - 2.0F * static_cast<float>(code_aux[i]);
} }
} }
@ -193,68 +193,68 @@ void gps_l5i_code_gen_float(own::span<float> _dest, uint32_t _prn)
/* /*
* Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency * Generates complex GPS L5i code for the desired SV ID and sampled to specific sampling frequency
*/ */
void gps_l5i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs) void gps_l5i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq)
{ {
constexpr int32_t _codeLength = GPS_L5I_CODE_LENGTH_CHIPS; constexpr int32_t codeLength = GPS_L5I_CODE_LENGTH_CHIPS;
constexpr float _tc = 1.0 / static_cast<float>(GPS_L5I_CODE_RATE_CPS); // L5I primary chip period in sec constexpr float tc = 1.0 / static_cast<float>(GPS_L5I_CODE_RATE_CPS); // L5I primary chip period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5I_CODE_RATE_CPS) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(GPS_L5I_CODE_RATE_CPS) / static_cast<double>(codeLength)));
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
int32_t _codeValueIndex; int32_t codeValueIndex;
std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5I_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5i(_code, _prn - 1); make_l5i(code_aux, prn - 1);
} }
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
// --- Make index array to read L5 code values --------------------- // --- Make index array to read L5 code values ---------------------
_codeValueIndex = static_cast<int32_t>(std::ceil(_ts * static_cast<float>(i + 1.0F) / _tc)) - 1; codeValueIndex = static_cast<int32_t>(std::ceil(ts * static_cast<float>(i + 1.0F) / tc)) - 1;
// --- Make the digitized version of the L5I code ------------------ // --- Make the digitized version of the L5I code ------------------
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // --- Correct the last index (due to number rounding issues) -----------
_dest[i] = std::complex<float>(1.0F - 2.0F * _code[_codeLength - 1], 0.0); dest[i] = std::complex<float>(1.0F - 2.0F * code_aux[codeLength - 1], 0.0);
} }
else else
{ {
_dest[i] = std::complex<float>(1.0F - 2.0F * _code[_codeValueIndex], 0.0); // repeat the chip -> upsample dest[i] = std::complex<float>(1.0F - 2.0F * code_aux[codeValueIndex], 0.0); // repeat the chip -> upsample
} }
} }
} }
void gps_l5q_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn) void gps_l5q_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5q(_code, _prn - 1); make_l5q(code_aux, prn - 1);
} }
for (int32_t i = 0; i < GPS_L5Q_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L5Q_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * static_cast<float>(_code[i])); dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * static_cast<float>(code_aux[i]));
} }
} }
void gps_l5q_code_gen_float(own::span<float> _dest, uint32_t _prn) void gps_l5q_code_gen_float(own::span<float> dest, uint32_t prn)
{ {
std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5q(_code, _prn - 1); make_l5q(code_aux, prn - 1);
} }
for (int32_t i = 0; i < GPS_L5Q_CODE_LENGTH_CHIPS; i++) for (int32_t i = 0; i < GPS_L5Q_CODE_LENGTH_CHIPS; i++)
{ {
_dest[i] = 1.0 - 2.0 * static_cast<float>(_code[i]); dest[i] = 1.0 - 2.0 * static_cast<float>(code_aux[i]);
} }
} }
@ -262,40 +262,40 @@ void gps_l5q_code_gen_float(own::span<float> _dest, uint32_t _prn)
/* /*
* Generates complex GPS L5Q code for the desired SV ID and sampled to specific sampling frequency * Generates complex GPS L5Q code for the desired SV ID and sampled to specific sampling frequency
*/ */
void gps_l5q_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs) void gps_l5q_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq)
{ {
std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> _code{}; std::array<int32_t, GPS_L5Q_CODE_LENGTH_CHIPS> code_aux{};
if (_prn > 0 and _prn < 51) if (prn > 0 and prn < 51)
{ {
make_l5q(_code, _prn - 1); make_l5q(code_aux, prn - 1);
} }
int32_t _codeValueIndex; int32_t codeValueIndex;
constexpr int32_t _codeLength = GPS_L5Q_CODE_LENGTH_CHIPS; constexpr int32_t codeLength = GPS_L5Q_CODE_LENGTH_CHIPS;
// --- Find number of samples per spreading code --------------------------- // --- Find number of samples per spreading code ---------------------------
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(GPS_L5Q_CODE_RATE_CPS) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(GPS_L5Q_CODE_RATE_CPS) / static_cast<double>(codeLength)));
// --- Find time constants ------------------------------------------------- // --- Find time constants -------------------------------------------------
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
constexpr float _tc = 1.0F / static_cast<float>(GPS_L5Q_CODE_RATE_CPS); // L5Q chip period in sec constexpr float tc = 1.0F / static_cast<float>(GPS_L5Q_CODE_RATE_CPS); // L5Q chip period in sec
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
// --- Make index array to read L5 code values --------------------- // --- Make index array to read L5 code values ---------------------
_codeValueIndex = static_cast<int32_t>(std::ceil(_ts * static_cast<float>(i + 1.0F) / _tc)) - 1; codeValueIndex = static_cast<int32_t>(std::ceil(ts * static_cast<float>(i + 1.0F) / tc)) - 1;
// --- Make the digitized version of the L5Q code ------------------ // --- Make the digitized version of the L5Q code ------------------
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) ----------- // --- Correct the last index (due to number rounding issues) -----------
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * _code[_codeLength - 1]); dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * code_aux[codeLength - 1]);
} }
else else
{ {
_dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * _code[_codeValueIndex]); // repeat the chip -> upsample dest[i] = std::complex<float>(0.0, 1.0F - 2.0F * code_aux[codeValueIndex]); // repeat the chip -> upsample
} }
} }
} }

View File

@ -38,22 +38,22 @@ namespace own = gsl;
//! Generates complex GPS L5I code for the desired SV ID //! Generates complex GPS L5I code for the desired SV ID
void gps_l5i_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn); void gps_l5i_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn);
//! Generates real GPS L5I code for the desired SV ID //! Generates real GPS L5I code for the desired SV ID
void gps_l5i_code_gen_float(own::span<float> _dest, uint32_t _prn); void gps_l5i_code_gen_float(own::span<float> dest, uint32_t prn);
//! Generates complex GPS L5Q code for the desired SV ID //! Generates complex GPS L5Q code for the desired SV ID
void gps_l5q_code_gen_complex(own::span<std::complex<float>> _dest, uint32_t _prn); void gps_l5q_code_gen_complex(own::span<std::complex<float>> dest, uint32_t prn);
//! Generates real GPS L5Q code for the desired SV ID //! Generates real GPS L5Q code for the desired SV ID
void gps_l5q_code_gen_float(own::span<float> _dest, uint32_t _prn); void gps_l5q_code_gen_float(own::span<float> dest, uint32_t prn);
//! Generates complex GPS L5I code for the desired SV ID, and sampled to specific sampling frequency //! Generates complex GPS L5I code for the desired SV ID, and sampled to specific sampling frequency
void gps_l5i_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs); void gps_l5i_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq);
//! Generates complex GPS L5Q code for the desired SV ID, and sampled to specific sampling frequency //! Generates complex GPS L5Q code for the desired SV ID, and sampled to specific sampling frequency
void gps_l5q_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs); void gps_l5q_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq);
/** \} */ /** \} */

View File

@ -25,11 +25,11 @@
const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); }; const auto AUX_CEIL = [](float x) { return static_cast<int32_t>(static_cast<int64_t>((x) + 1)); };
void gps_l1_ca_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _chip_shift) void gps_l1_ca_code_gen_int(own::span<int32_t> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 1023; constexpr uint32_t code_length = 1023;
std::bitset<_code_length> G1{}; std::bitset<code_length> G1{};
std::bitset<_code_length> G2{}; std::bitset<code_length> G2{};
auto G1_register = std::bitset<10>{}.set(); // All true auto G1_register = std::bitset<10>{}.set(); // All true
auto G2_register = std::bitset<10>{}.set(); // All true auto G2_register = std::bitset<10>{}.set(); // All true
uint32_t lcv; uint32_t lcv;
@ -47,13 +47,13 @@ void gps_l1_ca_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _ch
355, 1012, 176, 603, 130, 359, 595, 68, 386 /*PRN138*/}; 355, 1012, 176, 603, 130, 359, 595, 68, 386 /*PRN138*/};
// compute delay array index for given PRN number // compute delay array index for given PRN number
if (120 <= _prn && _prn <= 138) if (120 <= prn && prn <= 138)
{ {
prn_idx = _prn - 88; // SBAS PRNs are at array indices 31 to 50 (offset: -120+33-1 =-88) prn_idx = prn - 88; // SBAS PRNs are at array indices 31 to 50 (offset: -120+33-1 =-88)
} }
else else
{ {
prn_idx = _prn - 1; prn_idx = prn - 1;
} }
// A simple error check // A simple error check
@ -63,7 +63,7 @@ void gps_l1_ca_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _ch
} }
// Generate G1 & G2 Register // Generate G1 & G2 Register
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
G1[lcv] = G1_register[0]; G1[lcv] = G1_register[0];
G2[lcv] = G2_register[0]; G2[lcv] = G2_register[0];
@ -82,52 +82,52 @@ void gps_l1_ca_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _ch
} }
// Set the delay // Set the delay
delay = _code_length - delays[prn_idx]; delay = code_length - delays[prn_idx];
delay += _chip_shift; delay += chip_shift;
delay %= _code_length; delay %= code_length;
// Generate PRN from G1 and G2 Registers // Generate PRN from G1 and G2 Registers
for (lcv = 0; lcv < _code_length; lcv++) for (lcv = 0; lcv < code_length; lcv++)
{ {
aux = G1[(lcv + _chip_shift) % _code_length] xor G2[delay]; aux = G1[(lcv + chip_shift) % code_length] xor G2[delay];
if (aux == true) if (aux == true)
{ {
_dest[lcv] = 1; dest[lcv] = 1;
} }
else else
{ {
_dest[lcv] = -1; dest[lcv] = -1;
} }
delay++; delay++;
delay %= _code_length; delay %= code_length;
} }
} }
void gps_l1_ca_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift) void gps_l1_ca_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 1023; constexpr uint32_t code_length = 1023;
std::array<int32_t, _code_length> ca_code_int{}; std::array<int32_t, code_length> ca_code_int{};
gps_l1_ca_code_gen_int(ca_code_int, _prn, _chip_shift); gps_l1_ca_code_gen_int(ca_code_int, prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = static_cast<float>(ca_code_int[ii]); dest[ii] = static_cast<float>(ca_code_int[ii]);
} }
} }
void gps_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift) void gps_l1_ca_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift)
{ {
constexpr uint32_t _code_length = 1023; constexpr uint32_t code_length = 1023;
std::array<int32_t, _code_length> ca_code_int{}; std::array<int32_t, code_length> ca_code_int{};
gps_l1_ca_code_gen_int(ca_code_int, _prn, _chip_shift); gps_l1_ca_code_gen_int(ca_code_int, prn, chip_shift);
for (uint32_t ii = 0; ii < _code_length; ++ii) for (uint32_t ii = 0; ii < code_length; ++ii)
{ {
_dest[ii] = std::complex<float>(0.0F, static_cast<float>(ca_code_int[ii])); dest[ii] = std::complex<float>(0.0F, static_cast<float>(ca_code_int[ii]));
} }
} }
@ -136,22 +136,22 @@ void gps_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _p
* Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency * Generates complex GPS L1 C/A code for the desired SV ID and sampled to specific sampling frequency
* NOTICE: the number of samples is rounded towards zero (integer truncation) * NOTICE: the number of samples is rounded towards zero (integer truncation)
*/ */
void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift) void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift)
{ {
// This function is based on the GNU software GPS for MATLAB in the Kay Borre book // This function is based on the GNU software GPS for MATLAB in the Kay Borre book
constexpr int32_t _codeFreqBasis = 1023000; // Hz constexpr int32_t codeFreqBasis = 1023000; // chips per second
constexpr int32_t _codeLength = 1023; constexpr int32_t codeLength = 1023;
constexpr float _tc = 1.0F / static_cast<float>(_codeFreqBasis); // C/A chip period in sec constexpr float tc = 1.0F / static_cast<float>(codeFreqBasis); // C/A chip period in sec
const auto _samplesPerCode = static_cast<int32_t>(static_cast<double>(_fs) / (static_cast<double>(_codeFreqBasis) / static_cast<double>(_codeLength))); const auto samplesPerCode = static_cast<int32_t>(static_cast<double>(sampling_freq) / (static_cast<double>(codeFreqBasis) / static_cast<double>(codeLength)));
const float _ts = 1.0F / static_cast<float>(_fs); // Sampling period in sec const float ts = 1.0F / static_cast<float>(sampling_freq); // Sampling period in sec
std::array<std::complex<float>, 1023> _code{}; std::array<std::complex<float>, 1023> code_aux{};
int32_t _codeValueIndex; int32_t codeValueIndex;
float aux; float aux;
gps_l1_ca_code_gen_complex(_code, _prn, _chip_shift); // generate C/A code 1 sample per chip gps_l1_ca_code_gen_complex(code_aux, prn, chip_shift); // generate C/A code 1 sample per chip
for (int32_t i = 0; i < _samplesPerCode; i++) for (int32_t i = 0; i < samplesPerCode; i++)
{ {
// === Digitizing ================================================== // === Digitizing ==================================================
@ -160,20 +160,20 @@ void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, ui
// number of samples per millisecond (because one C/A code period is one // number of samples per millisecond (because one C/A code period is one
// millisecond). // millisecond).
aux = (_ts * (static_cast<float>(i) + 1)) / _tc; aux = (ts * (static_cast<float>(i) + 1)) / tc;
_codeValueIndex = AUX_CEIL(aux) - 1; codeValueIndex = AUX_CEIL(aux) - 1;
// --- Make the digitized version of the C/A code ------------------- // --- Make the digitized version of the C/A code -------------------
// The "upsampled" code is made by selecting values form the CA code // The "upsampled" code is made by selecting values form the CA code
// chip array (caCode) for the time instances of each sample. // chip array (caCode) for the time instances of each sample.
if (i == _samplesPerCode - 1) if (i == samplesPerCode - 1)
{ {
// --- Correct the last index (due to number rounding issues) // --- Correct the last index (due to number rounding issues)
_dest[i] = _code[_codeLength - 1]; dest[i] = code_aux[codeLength - 1];
} }
else else
{ {
_dest[i] = _code[_codeValueIndex]; // repeat the chip -> upsample dest[i] = code_aux[codeValueIndex]; // repeat the chip -> upsample
} }
} }
} }

View File

@ -39,19 +39,16 @@ namespace own = gsl;
//! Generates int GPS L1 C/A code for the desired SV ID and code shift //! Generates int GPS L1 C/A code for the desired SV ID and code shift
void gps_l1_ca_code_gen_int(own::span<int32_t> _dest, int32_t _prn, uint32_t _chip_shift); void gps_l1_ca_code_gen_int(own::span<int32_t> dest, int32_t prn, uint32_t chip_shift);
//! Generates float GPS L1 C/A code for the desired SV ID and code shift //! Generates float GPS L1 C/A code for the desired SV ID and code shift
void gps_l1_ca_code_gen_float(own::span<float> _dest, int32_t _prn, uint32_t _chip_shift); void gps_l1_ca_code_gen_float(own::span<float> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void gps_l1_ca_code_gen_complex(own::span<std::complex<float>> _dest, int32_t _prn, uint32_t _chip_shift);
//! Generates N complex GPS L1 C/A codes for the desired SV ID and code shift
void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift, uint32_t _ncodes);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift //! Generates complex GPS L1 C/A code for the desired SV ID and code shift
void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> _dest, uint32_t _prn, int32_t _fs, uint32_t _chip_shift); void gps_l1_ca_code_gen_complex(own::span<std::complex<float>> dest, int32_t prn, uint32_t chip_shift);
//! Generates complex GPS L1 C/A code for the desired SV ID and code shift, and sampled to specific sampling frequency
void gps_l1_ca_code_gen_complex_sampled(own::span<std::complex<float>> dest, uint32_t prn, int32_t sampling_freq, uint32_t chip_shift);
/** \} */ /** \} */

View File

@ -71,7 +71,7 @@ const uint32_t GPS_CNAV_PREAMBLE2 = 0x74U; /* (0b01110100u) */
* *
* \private * \private
*/ */
static uint32_t _cnav_compute_crc(cnav_v27_part_t *part) static uint32_t cnav_compute_crc_(cnav_v27_part_t *part)
{ {
uint32_t crc = crc24q_bits(0, part->decoded, GPS_CNAV_MSG_DATA_LENGTH, uint32_t crc = crc24q_bits(0, part->decoded, GPS_CNAV_MSG_DATA_LENGTH,
part->invert); part->invert);
@ -90,7 +90,7 @@ static uint32_t _cnav_compute_crc(cnav_v27_part_t *part)
* *
* \private * \private
*/ */
static uint32_t _cnav_extract_crc(const cnav_v27_part_t *part) static uint32_t cnav_extract_crc_(const cnav_v27_part_t *part)
{ {
uint32_t crc = getbitu(part->decoded, GPS_CNAV_MSG_DATA_LENGTH, uint32_t crc = getbitu(part->decoded, GPS_CNAV_MSG_DATA_LENGTH,
GPS_CNAV_MSG_CRC_LENGTH); GPS_CNAV_MSG_CRC_LENGTH);
@ -116,7 +116,7 @@ static uint32_t _cnav_extract_crc(const cnav_v27_part_t *part)
* *
* \private * \private
*/ */
static void _cnav_rescan_preamble(cnav_v27_part_t *part) static void cnav_rescan_preamble_(cnav_v27_part_t *part)
{ {
part->preamble_seen = false; part->preamble_seen = false;
@ -161,7 +161,7 @@ static void _cnav_rescan_preamble(cnav_v27_part_t *part)
* *
* \private * \private
*/ */
static void _cnav_add_symbol(cnav_v27_part_t *part, uint8_t ch) static void cnav_add_symbol_(cnav_v27_part_t *part, uint8_t ch)
{ {
part->symbols[part->n_symbols++] = ch; part->symbols[part->n_symbols++] = ch;
@ -224,14 +224,14 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, uint8_t ch)
if (!part->preamble_seen) if (!part->preamble_seen)
{ {
/* Rescan for preamble if possible. The first bit is ignored. */ /* Rescan for preamble if possible. The first bit is ignored. */
_cnav_rescan_preamble(part); cnav_rescan_preamble_(part);
} }
if (part->preamble_seen && GPS_CNAV_MSG_LENGTH <= part->n_decoded) if (part->preamble_seen && GPS_CNAV_MSG_LENGTH <= part->n_decoded)
{ {
/* We have collected 300 bits starting from message preamble. Now try /* We have collected 300 bits starting from message preamble. Now try
* to compute CRC-24Q */ * to compute CRC-24Q */
const uint32_t crc = _cnav_compute_crc(part); const uint32_t crc = cnav_compute_crc_(part);
const uint32_t crc2 = _cnav_extract_crc(part); const uint32_t crc2 = cnav_extract_crc_(part);
if (part->message_lock) if (part->message_lock)
{ {
@ -292,7 +292,7 @@ static void _cnav_add_symbol(cnav_v27_part_t *part, uint8_t ch)
* *
* \return None * \return None
*/ */
static void _cnav_msg_invert(cnav_v27_part_t *part) static void cnav_msg_invert_(cnav_v27_part_t *part)
{ {
size_t i = 0; size_t i = 0;
for (i = 0; i < sizeof(part->decoded); i++) for (i = 0; i < sizeof(part->decoded); i++)
@ -322,7 +322,7 @@ static void _cnav_msg_invert(cnav_v27_part_t *part)
* *
* \private * \private
*/ */
static bool _cnav_msg_decode(cnav_v27_part_t *part, cnav_msg_t *msg, uint32_t *delay) static bool cnav_msg_decode_(cnav_v27_part_t *part, cnav_msg_t *msg, uint32_t *delay)
{ {
bool res = false; bool res = false;
if (GPS_CNAV_MSG_LENGTH <= part->n_decoded) if (GPS_CNAV_MSG_LENGTH <= part->n_decoded)
@ -332,7 +332,7 @@ static bool _cnav_msg_decode(cnav_v27_part_t *part, cnav_msg_t *msg, uint32_t *d
/* CRC is OK */ /* CRC is OK */
if (part->invert) if (part->invert)
{ {
_cnav_msg_invert(part); cnav_msg_invert_(part);
} }
msg->prn = getbitu(part->decoded, 8, 6); msg->prn = getbitu(part->decoded, 8, 6);
@ -347,7 +347,7 @@ static bool _cnav_msg_decode(cnav_v27_part_t *part, cnav_msg_t *msg, uint32_t *d
if (part->invert) if (part->invert)
{ {
_cnav_msg_invert(part); cnav_msg_invert_(part);
} }
res = true; res = true;
} }
@ -388,7 +388,7 @@ void cnav_msg_decoder_init(cnav_msg_decoder_t *dec)
0); 0);
dec->part1.init = true; dec->part1.init = true;
dec->part2.init = true; dec->part2.init = true;
_cnav_add_symbol(&dec->part2, 0x80); cnav_add_symbol_(&dec->part2, 0x80);
} }
/** /**
@ -419,22 +419,22 @@ bool cnav_msg_decoder_add_symbol(cnav_msg_decoder_t *dec,
cnav_msg_t *msg, cnav_msg_t *msg,
uint32_t *pdelay) uint32_t *pdelay)
{ {
_cnav_add_symbol(&dec->part1, symbol); cnav_add_symbol_(&dec->part1, symbol);
_cnav_add_symbol(&dec->part2, symbol); cnav_add_symbol_(&dec->part2, symbol);
if (dec->part1.message_lock) if (dec->part1.message_lock)
{ {
/* Flush data in decoder. */ /* Flush data in decoder. */
dec->part2.n_decoded = 0; dec->part2.n_decoded = 0;
dec->part2.n_symbols = 0; dec->part2.n_symbols = 0;
return _cnav_msg_decode(&dec->part1, msg, pdelay); return cnav_msg_decode_(&dec->part1, msg, pdelay);
} }
if (dec->part2.message_lock) if (dec->part2.message_lock)
{ {
/* Flush data in decoder. */ /* Flush data in decoder. */
dec->part1.n_decoded = 0; dec->part1.n_decoded = 0;
dec->part1.n_symbols = 0; dec->part1.n_symbols = 0;
return _cnav_msg_decode(&dec->part2, msg, pdelay); return cnav_msg_decode_(&dec->part2, msg, pdelay);
} }
return false; return false;

View File

@ -56,10 +56,10 @@ TEST(CodeGenerationTest, CodeGenGPSL1SampledTest)
signed int _prn = 1; signed int _prn = 1;
unsigned int _chip_shift = 4; unsigned int _chip_shift = 4;
double _fs = 8000000.0; double _fs = 8000000.0;
const signed int _codeFreqBasis = 1023000; // Hz const signed int codeFreqBasis = 1023000; // Hz
const signed int _codeLength = 1023; const signed int codeLength = 1023;
int _samplesPerCode = round(_fs / static_cast<double>(_codeFreqBasis / _codeLength)); int samplesPerCode = round(_fs / static_cast<double>(codeFreqBasis / codeLength));
std::vector<std::complex<float>> _dest(_samplesPerCode); std::vector<std::complex<float>> _dest(samplesPerCode);
int iterations = 1000; int iterations = 1000;
@ -83,10 +83,10 @@ TEST(CodeGenerationTest, ComplexConjugateTest)
{ {
double _fs = 8000000.0; double _fs = 8000000.0;
double _f = 4000.0; double _f = 4000.0;
const signed int _codeFreqBasis = 1023000; // Hz const signed int codeFreqBasis = 1023000; // Hz
const signed int _codeLength = 1023; const signed int codeLength = 1023;
int _samplesPerCode = round(_fs / static_cast<double>(_codeFreqBasis / _codeLength)); int samplesPerCode = round(_fs / static_cast<double>(codeFreqBasis / codeLength));
std::vector<std::complex<float>> _dest(_samplesPerCode); std::vector<std::complex<float>> _dest(samplesPerCode);
int iterations = 1000; int iterations = 1000;