Skip to content

Commit

Permalink
uplink sequence burst detection
Browse files Browse the repository at this point in the history
  • Loading branch information
marenz2569 committed Jul 3, 2023
1 parent 9ef1196 commit 5e91c93
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 20 deletions.
31 changes: 31 additions & 0 deletions include/fixed_queue.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <deque>
#include <iostream>
#include <queue>

template <typename T, int MaxLen, typename Container = std::deque<T>>
class FixedQueue : public std::queue<T, Container> {
public:
FixedQueue() {
for (auto i = 0; i < MaxLen; i++) {
T default_value{};
std::queue<T, Container>::push(default_value);
}
}

void push(const T& value) {
if (this->size() == MaxLen) {
this->c.pop_front();
}
std::queue<T, Container>::push(value);
}

void pop(const T& value) { std::logic_error("Function not implemented"); }

typename Container::iterator begin() { return this->c.begin(); }

typename Container::reverse_iterator rbegin() { return this->c.rbegin(); }

typename Container::iterator end() { return this->c.end(); }

typename Container::reverse_iterator rend() { return this->c.rend(); }
};
22 changes: 22 additions & 0 deletions include/iq_stream_decoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <complex>

#include <bit_stream_decoder.hpp>
#include <fixed_queue.hpp>

/**
* Tetra downlink decoder for PI/4-DQPSK modulation
Expand All @@ -28,6 +29,27 @@ class IQStreamDecoder {
void process_complex(std::complex<float> symbol) noexcept;

private:
std::complex<float> hard_decision(std::complex<float> symbol);

std::vector<std::complex<float>> convolve_valid(std::vector<std::complex<float>> const& a,
std::vector<std::complex<float>> const& b);

FixedQueue<std::complex<float>, 300> symbol_buffer_;
FixedQueue<std::complex<float>, 300> symbol_buffer_hard_decision_;

// 9.4.4.3.2 Normal training sequence
const std::vector<std::complex<float>> training_seq_n_ = {{-1, -1}, {-1, 1}, {1, 1}, {1, 1}, {-1, -1}, {1, -1},
{1, -1}, {-1, 1}, {-1, -1}, {-1, 1}, {1, 1}};
const std::vector<std::complex<float>> training_seq_p_ = {{-1.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0}, {1.0, -1.0},
{-1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {-1.0, -1.0},
{-1.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0}};
// 9.4.4.3.3 Extended training sequence
const std::vector<std::complex<float>> training_seq_x_ = {
{1.0, -1.0}, {-1.0, 1.0}, {-1.0, -1.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0},
{1.0, -1.0}, {-1.0, 1.0}, {-1.0, -1.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {-1.0, -1.0}};

const float SEQUENCE_DETECTION_THRESHOLD = 1.5;

std::shared_ptr<BitStreamDecoder> bit_stream_decoder_{};

bool is_uplink_{};
Expand Down
112 changes: 92 additions & 20 deletions src/iq_stream_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,102 @@

#include <iq_stream_decoder.hpp>

void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
// Simple hard decission symbol mapper for now...
auto real = symbol.real();
auto imag = symbol.imag();

if (real > 0.0) {
if (imag > 0.0) {
// I
bit_stream_decoder_->process_bit(0);
bit_stream_decoder_->process_bit(0);
std::complex<float> IQStreamDecoder::hard_decision(std::complex<float> symbol) {
if (symbol.real() > 0) {
if (symbol.imag() > 0) {
return std::complex<float>(1, 1);
} else {
return std::complex<float>(1, -1);
}
} else {
if (symbol.imag() > 0) {
return std::complex<float>(-1, 1);
} else {
// IV
bit_stream_decoder_->process_bit(1);
bit_stream_decoder_->process_bit(0);
return std::complex<float>(-1, -1);
}
}
}

std::vector<std::complex<float>> IQStreamDecoder::convolve_valid(std::vector<std::complex<float>> const& a,
std::vector<std::complex<float>> const& b) {
std::vector<std::complex<float>> res;

// make shure a is longer equal than b
if (b.size() > a.size()) {
return convolve_valid(b, a);
}

for (int i = 0; i < a.size() - b.size() + 1; i++) {
std::complex<float> v{};
auto ita = a.begin();
std::advance(ita, i);
auto itb = b.rbegin();
for (; itb != b.rend(); ita++, itb++) {
v += *ita * *itb;
}
res.push_back(v);
}

return res;
}

void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
if (is_uplink_) {
// Control Uplink Burst or Normal Uplink Burst
symbol_buffer_.push(symbol);
symbol_buffer_hard_decision_.push(hard_decision(symbol));

// convolve hard_decision with flipped conjugate of n, p and x and check if abs > SEQUENCE_DETECTION_THRESHOLD
// to find potential correlation peaks
auto find_n =
convolve_valid({symbol_buffer_hard_decision_.begin(), symbol_buffer_hard_decision_.end()}, training_seq_n_);
auto find_p =
convolve_valid({symbol_buffer_hard_decision_.begin(), symbol_buffer_hard_decision_.end()}, training_seq_p_);
auto find_x =
convolve_valid({symbol_buffer_hard_decision_.begin(), symbol_buffer_hard_decision_.end()}, training_seq_x_);

// find CUB
// 2 tail + 42 coded symbols + middle of 15 training sequence (8) = 52
if (std::abs(find_x[51]) > SEQUENCE_DETECTION_THRESHOLD) {
// potentially found CUB
std::cout << "Potential CUB found" << std::endl;
}

// find NUB
// 2 tail + 108 coded symbols + middle of 11 training sequence (6) = 116
if (std::abs(find_p[115]) > SEQUENCE_DETECTION_THRESHOLD) {
std::cout << "Potential NUB_Split found" << std::endl;
}

if (std::abs(find_n[115]) > SEQUENCE_DETECTION_THRESHOLD &&
std::abs(find_x[115]) <= SEQUENCE_DETECTION_THRESHOLD) {
std::cout << "Potential NUB found" << std::endl;
}
} else {
if (imag > 0.0) {
// II
bit_stream_decoder_->process_bit(0);
bit_stream_decoder_->process_bit(1);
// Simple hard decission symbol mapper for now...
auto real = symbol.real();
auto imag = symbol.imag();

if (real > 0.0) {
if (imag > 0.0) {
// I
bit_stream_decoder_->process_bit(0);
bit_stream_decoder_->process_bit(0);
} else {
// IV
bit_stream_decoder_->process_bit(1);
bit_stream_decoder_->process_bit(0);
}
} else {
// III
bit_stream_decoder_->process_bit(1);
bit_stream_decoder_->process_bit(1);
if (imag > 0.0) {
// II
bit_stream_decoder_->process_bit(0);
bit_stream_decoder_->process_bit(1);
} else {
// III
bit_stream_decoder_->process_bit(1);
bit_stream_decoder_->process_bit(1);
}
}
}
}

0 comments on commit 5e91c93

Please sign in to comment.