gpt4 book ai didi

c++ - 在 GNU Radio 中使用有限状态机实现 Manchester-L (Biphase-L)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:38 25 4
gpt4 key购买 nike

我正在实现线路编码 block ,因为 GnuRadio 中的选择有限。我已经使用有限状态机 (FSM) 完成了 NRZ (L\M\S) 的实现和测试,它们似乎工作正常。现在,我正在尝试以 L 作为基线开始实现曼彻斯特 (L\M\S)。波形见下图摘自NASA深空网络遥测数据解码(208)

Modulation waveforms

有限状态机的构造如下所示。我决定使用 FSM,因为在我看来,它是实现线路代码的一种非常标准化的方式。 Manchester-L FSM

下面是用于测试实现的 gnuradio 流程图。测试是通过将 BPSK 信号(使用 CCSDS Reed-Solomon + 扰码器)发送到能够接收信号和处理遥测数据的外部设备来进行的。此实现已通过 NRZ-L\M\S 成功测试。 CCSDS 帧从文件中读取、解压缩并发送到 OOT block debug_linecode_bp 以进行曼彻斯特编码(曼彻斯特-L 的代码 0)。曼彻斯特编码之后是 OOT block debug_pulseshape_pam_2 block ,它将滤波器抽头和每个符号的样本数作为参数。接下来是一个 OOT block debug_bpsk_modulator,它执行简单的 BPSK 映射(Inphase = in[i],quadrature = 0)。 enter image description here头文件的代码如下所示

#ifndef INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H
#define INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H

#include <baseband/debug_linecode_bp.h>

namespace gr {
namespace baseband {

class debug_linecode_bp_impl : public debug_linecode_bp
{
private:
char last_state;
int d_code;
void fsm_decode_state(char state, unsigned char &bit0, unsigned char &bit1);
void fsm_encode_state(int code, unsigned char input, char last_state, char &next_state);
public:
debug_linecode_bp_impl(int code);
~debug_linecode_bp_impl();

// Where all the action really happens
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
};

} // namespace baseband
} // namespace gr

#endif /* INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H */

这是实现文件

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "debug_linecode_bp_impl.h"
#include <iostream>
using namespace std;
namespace gr {
namespace baseband {

debug_linecode_bp::sptr
debug_linecode_bp::make(int code)
{
return gnuradio::get_initial_sptr
(new debug_linecode_bp_impl(code));
}

/*
* The private constructor
*/
debug_linecode_bp_impl::debug_linecode_bp_impl(int code)
: gr::sync_interpolator("debug_linecode_bp",
gr::io_signature::make(1, 1, sizeof(unsigned char)),
gr::io_signature::make(1, 1, sizeof(unsigned char)), 2),
d_code(code),last_state('a')
{}

/*
* Our virtual destructor.
*/
debug_linecode_bp_impl::~debug_linecode_bp_impl()
{
}
void
debug_linecode_bp_impl::fsm_decode_state(char state, unsigned char &bit0, unsigned char &bit1)
{
switch(state)
{
case 'a':
bit0 = 0x00;
bit1 = 0x00;
break;
case 'b':
bit0 = 0x00;
bit1 = 0x01;
break;
case 'c':
bit0 = 0x01;
bit1 = 0x01;
break;
case 'd':
bit0 = 0x01;
bit1 = 0x00;
break;
}
}

void
debug_linecode_bp_impl::fsm_encode_state(int code, unsigned char input, char last_state, char &next_state)
{
switch(code)
{
case 0://Biphae-L
switch(last_state)
{
case 'a': //Illegal state
next_state = 'b';
cout << "Illegal state [a] encountered" << endl;
break;
case 'b':
next_state = (input & 0x01) ? 'd' : 'b';
break;
case 'c': //Illegal state
next_state = 'b';
cout << "Illegal state [b] encountered" << endl;
break;
case 'd':
next_state = (input & 0x01) ? 'd' : 'b';
break;
}
break;
case 1://Biphase-S
switch(last_state)
{
case 'a':
next_state = (input & 0x01) ? 'c' : 'd';
break;
case 'b':
next_state = (input & 0x01) ? 'a' : 'b';
break;
case 'c':
next_state = (input & 0x01) ? 'a' : 'b';
break;
case 'd':
next_state = (input & 0x01) ? 'c' : 'd';
break;
}
break;
case 2://Biphase-M
switch(last_state)
{
case 'a':
next_state = (input & 0x01) ? 'd' : 'c';
break;
case 'b':
next_state = (input & 0x01) ? 'b' : 'a';
break;
case 'c':
next_state = (input & 0x01) ? 'b' : 'a';
break;
case 'd':
next_state = (input & 0x01) ? 'd' : 'c';
break;
}
break;
}
}

int
debug_linecode_bp_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const unsigned char *in = (const unsigned char *) input_items[0];
unsigned char *out = (unsigned char *) output_items[0];

char next_state;
unsigned char bit0;
unsigned char bit1;
for (int i = 0; i < noutput_items/2; i++) {
fsm_encode_state(d_code,in[i],last_state, next_state);
fsm_decode_state(next_state, bit0, bit1);
for (int j = 0; j < 2; j++) {
out[i + j] = bit0;
out[i + j + 1] = bit1;
}
last_state = next_state;
}

// Tell runtime system how many output items we produced.
return noutput_items;
}

} /* namespace baseband */
} /* namespace gr */

到目前为止,测试还没有成功。我用来从这个流程图接收信号的设备甚至无法挑选一个数据包。我的结论是错误来自曼彻斯特编码器。非常欢迎对上述代码的任何想法。

谢谢。

最佳答案

一段时间后,我找到了代码中的错误。实际上,问题出在我复制输出的方式上。我所要做的就是删除内部 for 循环并使用 memcpy 直接复制输出。这就是功函数现在的样子

 int
debug_linecode_bp_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const unsigned char *in = (const unsigned char *) input_items[0];
unsigned char *out = (unsigned char *) output_items[0];

char next_state;
unsigned char bit0;
unsigned char bit1;
vector<unsigned char> bits;
for (int i = 0; i < noutput_items/2; i++) {
fsm_encode_state(d_code,in[i],last_state, next_state);
fsm_decode_state(next_state, bit0, bit1);
bits.push_back(bit0);
bits.push_back(bit1);
memcpy(out,bits.data(),2);
bits.clear();
out+=2;
last_state = next_state;
}

// Tell runtime system how many output items we produced.
return noutput_items;
}

这是调制器输出的波形 Manchester Pulse

关于c++ - 在 GNU Radio 中使用有限状态机实现 Manchester-L (Biphase-L),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49030085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com