OFDM 过采样信号模型
在本例中,我们将研究一个过采样 OFDM(正交频分复用,一种使用大量紧密间隔的正交子载波或复用的数字调制技术)信号模型。通过该模型,您可以看到多种调制的耦合。另一个例子是使用 RMS 单元来测量叠加了噪声的 OFDM 调制信号,其缩放值与 FFT(快速傅立叶变换)大小中的有效子载波数成正比,以确认信号功率近似等于 1。
该模型根据以下原则构建。
1.生成随机整数数据集和先导输入符号。
2.2. 16-QAM 对数据和先导符号进行调制。
3. OFDM 对 QAM 调制信号进行调制。一对 OFDM 调制器和解调器处理三个符号,每个符号的先导信号子载波索引和循环前缀长度各不相同。OFDM 信号包含数据和先导信号,由模型以四倍采样率生成。
4.4. 接下来,我们对每个帧进行振幅失真,从而显著改变信号功率。
5.5. 然后,OFDM 对数据和先导信号分别进行解调和输出。
6.16-QAM 对数据和先导符号进行解调。
7.然后找出输入和输出之间的差值。
下图显示了实现的模型。

让我们初始化模型参数。
In [ ]:
M = 16; # Порядок модуляции
nfft = 64; # Длина FFT
NumSymbols=3; # Количество символов OFDM
osf=4; # Фактор передискретизации
ngbc = [9;8]; # Число носителей защитного диапазона
insertdcnull = true; # Наличие DC-нулевой поднесущей
addpilotport = true; # Присутствие пилота
Noise_power = 10; # Мощность шума
In [ ]:
# Индексы пилотных поднесущих
pscindx = [[12;26;40;54] [14;28;38;52] [12;26;40;54]];
cplen = [16; 32; 16]; # CyclicPrefixLength
# Выборки на кадр для данных
spf_data = NumSymbols * (nfft-sum(ngbc)-size(pscindx,1)-insertdcnull)
# Выборки на кадр для пилота
spf_pilot = NumSymbols * size(pscindx,1)
# Число активных поднесущих
nasc = nfft-sum(ngbc)+insertdcnull;
声明模型参数后,让我们初始化模型启动函数并启动模型本身。
In [ ]:
# Подключение вспомогательной функции запуска модели.
function run_model( name_model)
Path = (@__DIR__) * "/" * name_model * ".engee"
if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
model = engee.open( name_model ) # Открыть модель
model_output = engee.run( model, verbose=true ); # Запустить модель
else
model = engee.load( Path, force=true ) # Загрузить модель
model_output = engee.run( model, verbose=true ); # Запустить модель
engee.close( name_model, force=true ); # Закрыть модель
end
sleep(5)
return model_output
end
run_model("OFDM_Signal_and_QAM") # Запуск модели.
Out[0]:
现在我们来分析记录的数据。
In [ ]:
ErrorData = collect(ErrorData);
ErrorPilot = collect(ErrorPilot);
RMSinp = collect(RMSinp);
RMSout = collect(RMSout);
ErrorData = ErrorData.value;
ErrorPilot = ErrorPilot.value;
RMSinp = RMSinp.value;
RMSout = RMSout.value;
In [ ]:
plot([real(RMSinp),real(RMSout)], title="RMS", label=["До наложения шума" "После наложения шума"])
Out[0]:
我们可以看到,每一帧的信号功率都有所不同。现在我们来看看输入和输出数据之间的差异。
In [ ]:
plot([ErrorData,ErrorPilot], title="Разница между входами и выходами", label=["Данные" "Пилоты"])
Out[0]:
从图中可以看出,误差为零,但为了确保万无一失,我们还是要找出总误差。
In [ ]:
println("Суммарная разница между входными и выходными данными: " * string(sum(ErrorData)))
println("Суммарная разница между входными и выходными пилотами: " * string(sum(ErrorPilot)))
结论
在本例中,我们分解并演示了在通信系统中使用几种调制方式的可能性。这种方法在这一领域的应用非常广泛。