这周最紧要任务,写多径效应的CIR估计,故将思路历程收集于一个 blog 中,以供今后参考

文章目录

  • 1 题目解读
  • 2 信道估计初探
  • Reference

1 题目解读

首先这个任务题目就看不懂,啥叫 CIR估计?
问了学姐,是信道脉冲响应,突然联想到之前一直听说的信道估计,百度百科对于信道估计的解释是:

所谓信道估计,就是从接收数据中将假定的某个信道模型的模型参数估计出来的过程。如果信道是线性的话,那么信道估计就是对系统冲激响应进行估计。需强调的是信道估计是信道对输入信号影响的一种数学表示,而“好”的信道估计则是使得某种估计误差最小化的估计算法。


2021-9-2更新
什么是CIR估计?

CIR包括两个纬度
CIR就是每个延时点上信号的强度
两个纬度:(1)每路信号的延时时间;(2)每路信号的强度

之前老师让看的两篇文章与CIR估计有什么关系?
【文献精读】【通信】Symphony: Localizing Multiple Acoustic Sources with a Single Microphone Array
【文献笔记】【通信】MAVL: Multiresolution Analysis of Voice Localization

DoA/AoA 的估计就是按信号时延来算的,而且用的也是互相关的的方法,因此在算角度的过程中已经把CIR算出来了

如果是多径信道,令 rx 与 tx 信号作互相关,肯定会在多个延时处有不同信号(这里的延时指tx相对rx的延时,不同路径信号延时不同)

不仅如此,对于多径信道来说,作自相关也能算出CIR,比如之前看的同一个source 的 LOS 和 ECHO两个信道,令 tx 作自相关,就能得到 LOS 和 ECHO 之间的时延


那么也就是说,我的任务可以转述为,对有多径效应的信道作信道估计

这其中有两个问题需要搞清楚:
(1)有多径效应的信道该如何用代码表示?
(2)信道估计算法怎么写?

首先,在开始调研之前,我对信道的理解如下:

一个通信系统有编码、调制、信道传输、解调、解码这几个过程
把要传送的数据编码,为的是增加复杂度,减小出错率
调制,是为了能够将数据嵌入一个carrier中,从而能够实现传输
而通信模型中的信道发挥存在感的就是加入噪声干扰,使解调和解码出现错误

由我当前对通信系统以及信道的理解,可以对题目引出如下几点疑问:
(1)信道脉冲响应的意义是什么?
(2)多径效应的信道和其他效应的信道相比有什么区别?或者说,不同的信道在哪些方面会有差别?


问题(1)隔天再看已经可以解答
学信号与系统的时候就知道,在线性时不变系统中,所有输入对应的输出都可以看成是一堆脉冲响应的线性组合,所以只要知道了这个系统的冲激响应,那么任意给一个输入就能算出输出


第二个问题有点深,在探究这个问题之前,我觉得可以先实现一个普通的信道估计算法来感受一下


8-30更新
通过阅读两篇声源定位的论文,可以初步下一个定义,所谓信道估计,就是得到信道传递函数 H 的过程,这个H就是一个关于衰减与延迟的函数


2 信道估计初探


根据 2 中的描述,为什么要作信道估计?
是为了在接收端进行信道补偿,从而提高整个的系统性能。


《MIMO-OFDM无线通信技术及MATLAB实现》有专门的一章来讲信道估计

信道估计一般使用前导 preamble 或者导频 pilot

导频结构有三种:
(1)块状类型:适用于频率选择性信道
(2)梳状类型:适用于快衰弱信道
(3)格状类型

基于训练符号的信道估计

训练符号估计需要发送前导或者导频信号,会产生额外负荷降低传输效率。
使用训练符号时,一般采用 最小二乘(LS)或者 最小均方误差(MMSE)技术来进行信道估计

LS方法,每个子载波上的LS信道估计可以表示为

其中,Y为输出,X为输入

LS方法会增强噪声,但是因为简单而被广泛使用

接下来的一堆公式推导看不懂

根据与导师的交流,对于多径信道来说 LS 和 MMSE根本不够用,并推荐我看了如下两篇论文:
【文献精读】【通信】Symphony: Localizing Multiple Acoustic Sources with a Single Microphone Array

这两篇论文看完后还是懵逼,因为这两篇paper的主题是声源定位,所以只是简要介绍了多径信道的模型,并没有讲信道估计算法

这篇帖子详细贴了 OFDM系统的信道估计代码
OFDM中信道估计技术分析与实现

我亲手打了一遍这个帖子的代码,有一两个小bug,但是过程非常清晰,亲手 coding 之后感觉酣畅淋漓,我自己写的详细注释版如下:

close all;
clear;
clc;% 单纯打印在命令行窗口
fprintf('OFDM信道估计仿真\n');%% 参数设置 carrier_count = 64;  % 单个OFDM符号中的载波数目
num_symbol = 50;     % OFDM符号数量,不包括导频
guard = 8;           % 循环前缀 CP, 即每个OFDM的最后8个子载波作为CP加在开头
pilot_inter = 8;     % 导频间隔,即每隔几个OFDM符号插入一个导频
modulation_mode = 16;% 调制方式, QAM调制的order
SNR = 0:2:20;        % 信噪比取值
num_loop = 15;       % 循环次数% 每种信噪比做15次实验
num_bit_err = zeros(length(SNR), num_loop);
num_bit_err_dft = zeros(length(SNR), num_loop);
num_bit_err_ls = zeros(length(SNR), num_loop);
MSE = zeros(length(SNR), num_loop);
MSE_dft = zeros(length(SNR), num_loop);
MSE_ls = zeros(length(SNR), num_loop);%% 主程序for c1 = 1:length(SNR)fprintf('\n\n\n仿真信噪比为%f\n\n', SNR(c1));for num1 = 1:num_loop%---------------产生发送的随机序列-----------------------bits_len = carrier_count * num_symbol;bits_tx = randi([0 1], 1, bits_len); % 1行bits_len列矩阵%---------------符号调制-----------------------modulated_sequence = qammod(bits_tx, modulation_mode);%---------------导频格式-----------------------pilot_len = carrier_count; % 导频与OFDM符号同级别% rand 默认区间(0,1)% round 四舍五入% 结束后 pilot_symbols只有0和1,是一个1行pilot_len列矩阵pilot_symbols = round(rand(1, pilot_len));% 将导频信号中的0变为-1,所以目前导频有两种,-1和1for i = 1:pilot_lenif pilot_symbols(1, i) == 0pilot_symbols(1, i) = pilot_symbols(1, i) - 1;elsepilot_symbols(1, i) = pilot_symbols(1, i);endend% 行向量变列向量pilot_symbols = pilot_symbols';%---------------计算导频和数据数目-----------------------% ceil 向上取整num_pilot = ceil(num_symbol / pilot_inter);% rem 取余,返回 num_symbol除以pilot_inter后的余数 % 每组符号开头一个导频,结尾还要再加一个导频if rem(num_symbol, pilot_inter)==0num_pilot = num_pilot + 1;endnum_data = num_symbol + num_pilot;%---------------导频位置计算-----------------------pilot_index = zeros(1, num_pilot);% +1 是算上了导频的位置,此时data_index容量大于 num_symboldata_index = zeros(1, num_pilot * (pilot_inter + 1));for i = 1:num_pilot-1pilot_index(1, i) = (i-1) * (pilot_inter + 1) + 1;end% 最后一个导频的位置从开头数起要看具体情况% 但反正是在最后一个pilot_index(1, num_pilot) = num_data;% 为了插入导频,第一个、最后一个以及每隔8个位的索引都空了出来% 缺少的索引值在 pilot_indexfor j = 0:num_pilotdata_index(1, (1 + j * pilot_inter) : (j + 1) * pilot_inter) = (2 + j * (pilot_inter + 1)) : ((j + 1) * (pilot_inter + 1));end% 将多余的容量去掉data_index = data_index(1, 1:num_symbol);%---------------导频插入-----------------------% 和之前不一样,每一列为一个OFDM调制符号piloted_ofdm_syms = zeros(carrier_count, num_data);% piloted_ofdm_syms 与 modulated_sequence的列数不一样% piloted_ofdm_syms 的列数增加了 导频数% 而modulated_sequence的列数只有 OFDM符号数% 先将 modulated_sequence 中应该是 OFDM符号 的列数依次插入 modulated_sequence 的列% data_index 和 modulated_sequence 的列数都是 num_symbolpiloted_ofdm_syms(:, data_index) = reshape(modulated_sequence, carrier_count, num_symbol);% 再将 pilot 插入其索引位% pilot_symbols 只是一个列向量,横向扩充 num_pilot 倍成为一个数组piloted_ofdm_syms(:, pilot_index) = repmat(pilot_symbols, 1, num_pilot);%---------------IFFT变换-----------------------% OFDM调制后默认是频域信号% 为什么要乘以 sqrt(carrier_count)time_signal = sqrt(carrier_count) * ifft(piloted_ofdm_syms);%---------------加循环前缀-----------------------% CP 与子载波同级别add_cyclic_signal = [time_signal((carrier_count - guard + 1 : carrier_count), :); time_signal];% 将矩阵变为一个行向量再传输tx_data_trans = reshape(add_cyclic_signal, 1, (carrier_count + guard) * num_data);%---------------信道处理-----------------------% AWGN 信道% 计算信号功率tx_signal_power = sum(abs(tx_data_trans(:)) .^ 2) / length(tx_data_trans(:));% 为啥这么算?noise_var = tx_signal_power / (10 ^ (SNR(c1) / 10));rx_data = awgn(tx_data_trans, SNR(c1), 'measured');%---------------信号接收、去循环前缀、FFT变换-----------------------% 信号接收rx_signal = reshape(rx_data, (carrier_count + guard), num_data);% 去除CPrx_signal_matrix = zeros(carrier_count, num_data);rx_signal_matrix = rx_signal(guard + 1:end, :);% FFT变换% 因为接下来要提取导频,导频自然得回到频域才能提取rx_carriers = fft(rx_signal_matrix) / sqrt(carrier_count);%---------------导频和数据提取-----------------------% 提取导频rx_pilot = rx_carriers(:, pilot_index);% 提取数据(频域)rx_fre_data = rx_carriers(:, data_index);%---------------导频位置信道响应LS估计-----------------------% pilot_patt 就是发送端插入的 pilotpilot_patt = repmat(pilot_symbols, 1, num_pilot);% LS算法的 y/xpilot_esti = rx_pilot ./ pilot_patt;%---------------LS估计的线性插值-----------------------% 使用信道估计,其实就已经默认了rx的data是不可信的% 所以需要使用导频来恢复 dataint_len = pilot_index;len = 1:num_data;channel_H_ls = zeros(carrier_count, num_data);% 每个符号/导频的子载波数量是固定的% 现在是要通过 num_pilot 个 导频来估算 num_data 个导频+data% 因此子载波一个一个来for ii = 1:carrier_count% 在 int_len(pilot_index)这些点(点的数量为 num_pilot)% 函数取值分别为 pilot_esti(ii, 1:(num_pilot))% 那么同样的函数,将点扩充为 len(num_data)个,各点的估计值是多少?channel_H_ls(ii, :) = interp1(int_len, pilot_esti(ii, 1:(num_pilot)), len, 'linear');endchannel_H_data_ls = channel_H_ls(:, data_index);%---------------LS估计中发送数据的估计值-----------------------% 这个公式从何而来还不懂tx_data_estimate_ls = rx_fre_data .* conj(channel_H_data_ls) ./ (abs(channel_H_data_ls) .^ 2);%---------------DFT估计------------% DFT估计是为了再ls基础上消除时域噪声% 但是以下代码没看懂为什么能达到消除时域噪声的效果% 或许是在时域作超过子载波长度点数的FFT能够消除噪声?% 先将 pilot_esti 换为时域% 补充子载波padding后(symbol纬度不变)% 再换回频域% 加padding 其实就是做了 carrier_count+1024 点 FFT 变换tx_pilot_estimate_ifft = ifft(pilot_esti);padding_zero = zeros(1024, num_pilot);tx_pilot_estimate_ifft_padding_zero = [tx_pilot_estimate_ifft; padding_zero];% 对于矩阵来说,fft分别对各列作ffttx_pilot_estimate_dft = fft(tx_pilot_estimate_ifft_padding_zero);%---------------DFT估计的线性插值------------% 插值操作与 ls 一样int_len = pilot_index;len = 1:num_data;channel_H_dft = zeros(carrier_count, num_data);for ii = 1:carrier_countchannel_H_dft(ii, :) = interp1(int_len, tx_pilot_estimate_dft(ii, 1:(num_pilot)), len, 'linear');endchannel_H_data_dft = channel_H_dft(:, data_index);%---------------DFT估计中发送数据的估计值------------tx_data_estimate_dft = rx_fre_data .* conj(channel_H_data_dft) ./ (abs(channel_H_data_dft) .^ 2);%---------------DFT符号解调------------% 原矩阵每一列向量变为行向量% 并且按顺序铺成 sequencedemod_in_dft = tx_data_estimate_dft(:).';demod_out_dft = qamdemod(demod_in_dft, modulation_mode);%---------------LS符号解调------------demod_in_ls = tx_data_estimate_ls(:).';demod_out_ls = qamdemod(demod_in_ls, modulation_mode);%---------------误码率计算------------for i = 1:length(bits_tx)if demod_out_dft(i) ~= bits_tx(i)num_bit_err_dft(c1, num1) = num_bit_err_dft(c1, num1) + 1;endif demod_out_ls(i) ~= bits_tx(i)num_bit_err_ls(c1, num1) = num_bit_err_ls(c1, num1) + 1;endendend
end% num_bit_err_dft.'表示原来的行变列
% 原先是每行代表一个 SNR 的所有 loop 结果
% 现在变成每列
% 与num_bit_err_dft(:).'展开不同,num_bit_err_dft.'仍是矩阵
% 因为 mean 是按列来算平均值的
BER_dft = mean(num_bit_err_dft.') / length(bits_tx);
BER_ls = mean(num_bit_err_ls.') / length(bits_tx);%% 绘图
figure
semilogy(SNR, BER_dft, '-mp', SNR, BER_ls, '-k+');
title('OFDM系统的LS和DFT信道估计');
xlabel('SNR');
ylabel('BER');
legend('DFT信道估计','LS信道估计');

通过这次coding 主要明白了以下的几个重要知识点:
(1)pilot, CP 的真面目
导频 pilot 与 符号 symbol 同级别 ,每隔几个 symbol 插入一个 pilot


更新,pilot也可以与子载波同级别,导频有很多种插入法


循环前缀 CP 与 子载波 同级别,每个symbol的最后n个子载波复制了然后插入到开头作为CP
比如一个 symbol [1, 2, 3, 4, 5], 假设 CP 为2,那么加入CP后变为 [4, 5, 1, 2, 3, 4, 5]

(2)明白了pilot的真正用途
使用信道估计,其实就已经默认了rx的data是不可信的,所以需要使用不易被干扰的导频来获取信道对信号的影响,即得到H,然后再通过 rx与 H 的运算来获得可信 data

(3)DFT估计,就是在LS基础上将导频ifft换回时域然后再作N点fft换回频域(N大于载波数量)

并且,通过此次coding 明确了我搞不懂的问题到底在哪里


要做XXX信道估计,要解决两个问题
(1)建立这个信道的模型
加多少噪音、衰弱、延时?以什么方式加?
(2)选择合适的估计算法
如果 y = hx + n,那就 ls, mmse, dft

卡壳点:
(1)微信论文中有给出多径信道模型,代码如何实现?
看起来还是 y = hx + n的形式,为什么 ls 不行了?
(2)不知道该上哪找合适的估计算法


Reference

[1] 移动无线信道脉冲响应的计算机模拟

[2] Matlab关于信道估计的一个描述

【实践】多径效应CIR估计相关推荐

  1. 软工实践原型设计——PaperRepositories

    软工实践原型设计--PaperRepositories 写在前面 本次作业链接 队友(031602237吴杰婷)博客链接 pdf文件地址 原型设计地址(加载有点慢...) 结对成员:031602237 ...

  2. 软工实践第一次作业-自我审视和规划

    软工实践第一次作业-自我审视和规划 题目地址:https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homework/2060? ...

  3. 【文献笔记】【部分精读】【CIR】Angle of Arrival Estimation based on Channel Impulse Response Measurements

    文章地址:https://ieeexplore.ieee.org/document/8967562 机器人顶会iros的一篇文章,我主要关注其关于CIR估计的部分 文章目录 我的理解 CIR估计与AO ...

  4. 做一名优秀的软件开发qa_如何成为一名优秀的开发人员

    做一名优秀的软件开发qa As a PHP developer, or any kind of developer as a matter of fact, you need to constantl ...

  5. Automatic Noise Modeling for Ghost-free HDR Reconstruction 阅读笔记

    Automatic Noise Modeling for Ghost-free HDR Reconstruction 阅读笔记 摘要 1. 简介 2. HDR去鬼影方法 2.1 图像噪声估计 2.2 ...

  6. 计算机审计上机试题,《计算机审计》上机实验报告.doc

    学生学号 实验课成绩 学 生 实 验 报 告 书 实验课程名称 开 课 学 院 指导教师姓名 学 生 姓 名 学生专业班级 20 -- 20 学年 第 学期 实验教学管理基本规范 实验是培养学生动手能 ...

  7. 超宽带(UWB)学习笔记——消除多径误差的第一径检测算法

    文章目录 前言 1. 第一径检测算法描述 1.1 问题的提出 1.2 实现过程 1.3 参数配置 2. 总结 参考文献 前言 使用超宽带进行测距,对抗多径是一个非常重要的问题,其本质是在最强径不是第一 ...

  8. 读计算机操作系统的读后感,《计算机操作系统》读后感锦集

    <计算机操作系统>是一本由汤子瀛 / 哲凤屏 / 汤小丹著作,西安电子科技大学出版社出版的平装图书,本书定价:27.00,页数:393,特精心从网络上整理的一些读者的读后感,希望对大家能有 ...

  9. Win10下ME511刷安卓2.3.7(CM7)

    一.网上搜索下载必备软件和ME511的ROM 这里已经全部整理好了,下载地址(百度云盘):http://pan.baidu.com/s/1nuSMF0H 二.ME511刷安卓2.3.7相关文件说明 [ ...

最新文章

  1. 文件资源路径(相对路径和绝对路径)
  2. golang interface{} 转 struct结构体
  3. Jmeter自定义函数和引入外部文件的几种方法
  4. 自动安装 Java Access Bridge 2.0.2 的批处理脚本
  5. PyTorch基础-softmax函数mnist数据集识别-03
  6. 当一名程序员喝醉之后......
  7. java blowfish ecb,node.js – 使用nodejs crypto和php的mcrypt解密blowfish-ecb
  8. Mysql 最最最基本语句(大全)
  9. 【第十届“泰迪杯”数据挖掘挑战赛】B题:电力系统负荷预测分析 ARIMA、AutoARIMA、LSTM、Prophet、多元Prophet 实现
  10. 锐浪报表 Grid++Report PrintPreview 显示模式
  11. C语言华氏度转换摄氏度
  12. 如何用python做兼职_python学会后可以干什么副业#做什么兼职副业好
  13. win7系统(64/32位)安装office2010时提示需要msxml6.10.1129,问题的解决记录
  14. 阿里云招聘 | 遇见offer之就要圆你的大厂梦
  15. ubuntu ufw firewall防火墙端口设置 (防火墙的的开启、禁用、开放端口、关闭端口、重置、重启...)
  16. 【翻译】Real Shading in Unreal Engine 4
  17. 如何优化物联网边缘设备的能源使用
  18. ShardingSphere 学习
  19. 中科爱讯双频串口WiFi探针TZ5001 产品介绍
  20. 单个按键,实现单击+双击+长按

热门文章

  1. 龙猫数据:服务AI产业,筑基智慧生态
  2. AI智能化测试——各大厂质量保障实践分享汇总(上)
  3. android 异形button,C++:C++Builder中异形按钮的实现
  4. [分享]牛牛图片查看器[仿QQ图片查看器]及大致原理说明
  5. c51按键控制灯亮汇编语言,用一个按键控制LED灯亮/暗的汇编程序
  6. 微信小程序 评论留言功能实现 仿知乎
  7. GNU Make 使用手册(于凤昌中译版)
  8. 全世界公认最美的地方
  9. 人工智能AI带来的福利越来越真实了
  10. 从金本位到法定货币:银行家世界观的