
簡介一份基于MATLAB的水聲OFDM通信系統(tǒng)仿真程序面向水下通信研究人員、算法工程師及相關(guān)專業(yè)學生重點解決多途信道下的可靠傳輸與功率效率問題。該m文件完整展示了OFDM符號映射、導頻插入、多途信道建模、接收端解調(diào)等流程并集中實現(xiàn)了信道估計與均峰功率比PAPR控制兩大關(guān)鍵技術(shù)可對比最小均方誤差、矩估計等信道估計算法以及裁剪、部分傳輸序列、多級編碼等降PAPR方案的效果。資源包為zip格式僅含1個m文件包體約3KB屬于輕量級單腳本仿真便于二次修改與參數(shù)掃描。目前已有570人學習下載適合作為水聲OFDM入門課題的驗證起點。通過運行該程序可以觀察信道估計精度對誤碼率的影響分析不同PAPR抑制方法在功放非線性和信號失真之間的權(quán)衡為后續(xù)采用更完整水聲信道模型或硬件實驗提供算法原型與參考。1. 水聲OFDM仿真別從零造輪子先拿這套MATLAB程序跑通鏈路做水聲OFDM仿真最容易卡死的不是調(diào)制解調(diào)而是多途信道下的信道估計和均峰功率比PAPR控制。很多同學一開始從零寫MATLAB代碼結(jié)果光一個循環(huán)前綴長度匹配就調(diào)了一星期。這份程序包把水聲OFDM通信系統(tǒng)的發(fā)送端、多途信道、信道估計和PAPR控制都串起來了適合兩類人一是做水聲通信物理層算法驗證的研究生想快速拿到一個能出誤碼率曲線的基線系統(tǒng)二是用MATLAB做課程設計、要展示OFDM在惡劣信道下表現(xiàn)的本科生。拿到手不建議整包重寫建議先跑通默認參數(shù)再按自己的信道環(huán)境替換關(guān)鍵參數(shù)。2. 多途信道模型與OFDM參數(shù)匹配時延、抽頭數(shù)、循環(huán)前綴的關(guān)系2.1 為什么水聲信道要用抽頭延遲線來建模水聲信道不像自由空間那樣可以看成高斯白噪聲信道。聲線在水中經(jīng)過海面、海底、溫度梯度反射到達接收端時形成一串不同時延、不同幅度的副本這就是多途效應。對OFDM來說多途直接決定頻率選擇性衰落的周期而這個周期又決定導頻的插入間隔和循環(huán)前綴的長度。所以建模第一步是確定信道時延擴展。常見做法是采用抽頭延遲線模型。每條路徑對應一個時延和一個復增益信道沖激響應寫成若干沖激之和。水聲OFDM仿真里我會用一個結(jié)構(gòu)體保存信道參數(shù)避免在多個腳本里復制數(shù)字。下面這段是程序包里典型的信道參數(shù)設置% 水聲多途信道參數(shù)抽頭延遲線模型 fs 12000; % 采樣率單位Hz N_subcarriers 1024; % OFDM子載波數(shù) Ng 256; % 循環(huán)前綴長度采樣點數(shù) Tcp Ng / fs; % 循環(huán)前綴時長 % 多途信道每條路徑 [時延s, 幅度, 相位] channel_paths [ 0.000, 1.000, 0.0 % 直達聲線 0.004, 0.650, 0.8 % 海底反射 0.009, 0.400, 1.4 % 海面反射 0.014, 0.250, -1.1 % 二次反射 0.021, 0.150, 2.0 ]; max_delay max(channel_paths(:, 1)); fprintf(最大時延 %.1f ms, CP時長 %.1f ms\n, ... max_delay*1000, Tcp*1000);這里采樣率是12kHz對應帶寬12kHz子載波間隔約11.7Hz一個OFDM符號不含CP約85msCP約21ms。最后一行打印的用意是讓你每次跑仿真前先問自己最大多途時延是否小于CP時長如果max_delay大于Tcp符號間干擾就會直接吃掉子載波正交性后面什么信道估計都白做。注意代碼里幅度列沒有歸一化實際程序包里會在生成信道沖激響應后做能量歸一化歸一化公式是h h / sqrt(sum(abs(h).^2))這樣不同路徑參數(shù)的仿真結(jié)果之間才有可比性。程序包里的信道生成函數(shù)通常把這段放在獨立函數(shù)里比如channel_baseband.m輸入channel_paths和fs輸出離散時域信道h。調(diào)參數(shù)時只需要改上面那個矩陣不需要翻主腳本。2.2 OFDM收發(fā)端的主流程和模塊邊界拿到程序包后主腳本會按以下順序執(zhí)行隨機二進制比特生成 - 映射成QAM符號 - 插入導頻 - IFFT調(diào)制 - 加循環(huán)前綴 - 調(diào)用PAPR控制 - 經(jīng)過多途信道疊加噪聲 - 接收端同步 - 去CP - FFT解調(diào) - 信道估計 - 均衡 - 解映射 - 計算誤碼率。下面是一段主流程的偽代碼程序包里實際就是這樣組織的% 主仿真循環(huán)一個SNR點跑若干幀 snr_dB 10; ber_total 0; for frame 1:100 data_bits randi([0 1], N_subcarriers*2, 1); % 16QAM映射每符號4bit這里簡化處理 data_symbols qammod(data_bits, 16, InputType, bit, UnitAveragePower, true); % 插入導頻子載波索引每隔6個放一個導頻 [tx_grid, pilot_idx] insert_pilots(data_symbols, N_subcarriers); % IFFT調(diào)制并加循環(huán)前綴 ifft_out ifft(tx_grid, N_subcarriers) * sqrt(N_subcarriers); tx_signal [ifft_out(end-Ng1:end); ifft_out]; % 通過多途信道并加噪聲注意snr換算 rx_signal conv(tx_signal, h, same) generate_noise(snr_dB, tx_signal); % 理想同步假設去CPFFT rx_ifft fft(rx_signal(Ng1:NgN_subcarriers)) / sqrt(N_subcarriers); % 導頻處LS信道估計并插值 h_est ls_channel_estimate(rx_ifft, pilot_idx, pilot_symbols); eq_symbols rx_ifft ./ h_est; % 解映射與誤碼率統(tǒng)計 rx_bits qamdemod(eq_symbols, 16, OutputType, bit, UnitAveragePower, true); ber_total ber_total sum(rx_bits ~ data_bits); end ber ber_total / (100 * numel(data_bits));這段代碼里的函數(shù)都是模塊化的insert_pilots負責導頻圖案ls_channel_estimate負責估計插值。我建議你拿到程序后先把這行改成實際調(diào)用的函數(shù)名再逐函數(shù)打開看輸入輸出。這里有兩個參數(shù)最值得調(diào)整導頻間隔示例是每隔6個子載波插一個和循環(huán)前綴Ng。水聲信道相干帶寬的估算公式是Bc ≈ 1/(5*max_delay)按上表最大時延21msBc大約只有9.5Hz而子載波間隔是11.7Hz已經(jīng)落入深度頻率選擇性衰落。這時導頻間隔必須足夠小否則插值重建會失真。程序包里還有一個容易被忽略的細節(jié)發(fā)送端在IFFT之前要對頻域符號做縮放。上面代碼里IFFT后乘以sqrt(N_subcarriers)是為了讓輸出的時域平均功率與頻域符號功率一致否則后面SNR計算全是偏的。我見過不少從網(wǎng)上抄的OFDM仿真少了這一步誤碼率曲線整體左移或右移好幾個dB查半天都查不到。所以跑陌生腳本時先打印一下發(fā)送信號的均方根功率確認它是1個單位的量級。還有一個不能漏的環(huán)節(jié)是噪聲生成。水聲OFDM仿真一般假設加性高斯白噪聲但SNR換算必須按照實際帶寬和過采樣來做。常見做法是把SNR定義在符號帶寬內(nèi)噪聲功率按采樣點數(shù)歸一化而不是直接用awgn函數(shù)因為awgn默認按信號向量能量計算容易和你的OFDM符號長度耦合。下面是一段我在MATLAB里常用的噪聲生成方式function noise generate_noise(snr_dB, signal) snr_linear 10^(snr_dB/10); signal_power mean(abs(signal).^2); noise_power signal_power / snr_linear; noise sqrt(noise_power/2) * (randn(size(signal)) 1j*randn(size(signal))); end這段代碼里的snr_dB是按復基帶信號功率定義的如果直接套到實信號上要注意前面那個sqrt(noise_power/2)的系數(shù)。程序包里如果用的是復數(shù)噪聲功率要拆到實部和虛部各一半否則實際噪聲功率會偏小3dBBER曲線也跟著偏移。3. 控制均峰功率比SLM與限幅的實現(xiàn)及取舍3.1 PAPR定義與CCDF評估OFDM時域信號是很多獨立子載波疊加相位相同時會出現(xiàn)很高的峰值這就是高峰均功率比。水聲發(fā)射機的功放線性區(qū)間通常很窄峰值過大會導致信號削頂產(chǎn)生帶外干擾和星座圖畸變。均峰功率比PAPR定義為時域信號峰值功率與平均功率之比通常用分貝表示。要評價一種PAPR控制方法好不好不能只看某個符號的PAPR值要看它的互補累計分布函數(shù)CCDF即PAPR超過某個門限的概率。程序包里一般會提供這樣一個計算函數(shù)用來統(tǒng)計不同方案的CCDF曲線function ccdf calculate_papr_ccdf(tx_signal_matrix, papr_thresholds) % tx_signal_matrix: 每列是一個OFDM符號的時域波形 % papr_thresholds: 你要評估的門限例如4:0.5:10 num_symbols size(tx_signal_matrix, 2); papr_values zeros(1, num_symbols); for k 1:num_symbols x tx_signal_matrix(:, k); peak_power max(abs(x).^2); avg_power mean(abs(x).^2); papr_values(k) 10 * log10(peak_power / avg_power); end ccdf zeros(size(papr_thresholds)); for t 1:length(papr_thresholds) ccdf(t) sum(papr_values papr_thresholds(t)) / num_symbols; end end注意采樣點數(shù)每一個OFDM符號的時域樣點數(shù)至少是子載波數(shù)的4倍否則峰值會被欠采樣漏掉。程序包里如果用了4倍過采樣PAPR和CCDF結(jié)果才比較接近真實射頻信號。如果只是基帶仿真不過采樣PAPR會偏低約1到2dB這一點在對比算法效果時影響不大但畫絕對數(shù)值時一定要說明是否過采樣。3.2 SLM方法多預編碼里挑最小的PAPR選擇性映射SLM的思想很簡單在IFFT之前用U組隨機相位序列分別乘頻域符號然后各自做IFFT選擇PAPR最小的那一路發(fā)送。接收端需要額外知道選擇了哪一組相位所以程序包里會用低速率邊帶信息傳索引。實現(xiàn)代碼如下function [tx_selected, phase_idx] slm_papr_reduce(ifft_input, U, N_subcarriers) % ifft_input: 頻域符號向量含導頻 % U: 候選相位序列數(shù)量常見16或32 best_papr Inf; for u 1:U % 隨機相位序列首子載波要保留直流相位固定為0 phase ones(N_subcarriers, 1); phase(2:end) exp(1j * 2 * pi * rand(N_subcarriers-1, 1)); candidate ifft_input .* phase; ifft_out ifft(candidate) * sqrt(N_subcarriers); papr 10 * log10( max(abs(ifft_out).^2) / mean(abs(ifft_out).^2) ); if papr best_papr best_papr papr; tx_selected ifft_out; phase_idx u; best_phase phase; end end % 實際發(fā)送時用best_phase去恢復頻域符號這里返回相位索引給邊帶 end這個函數(shù)的參數(shù)U是關(guān)鍵。U越大找到低PAPR候選的概率越高但每個符號的IFFT計算次數(shù)也線性增加。水聲OFDM數(shù)據(jù)率不高U取32在仿真里能壓到很低PAPR但實時實現(xiàn)基本不會這么干。我做實驗時一般先用U16對比U32看CCDF曲線在6dB門限處差的概率能不能接受。另外導頻子載波也會被相位序列乘到接收端做信道估計前需要先除以該符號的相位序列否則估計結(jié)果是錯的。程序包里正確處理了這一點但如果你自己改造時忽略它BER會直接崩掉。3.3 限幅濾波簡單粗暴但要有后處理限幅是另一種常用方法IFFT之后把超過某個門限A的時域采樣值直接截斷到A。這樣做PAPR立竿見影地降下來但代價是非線性失真帶內(nèi)失真抬高BER帶外泄漏影響頻譜。通常做法是限幅后再過一個低通濾波器也就是所謂限幅濾波。程序包里的實現(xiàn)一般是這樣的function tx_limited clipping_filter(tx_signal, clip_level) % clip_level: 限幅門限通常取平均幅度的2~4倍 peak_limit clip_level * sqrt(mean(abs(tx_signal).^2)); tx_limited tx_signal; % 限幅 over_idx abs(tx_signal) peak_limit; tx_limited(over_idx) peak_limit * exp(1j * angle(tx_signal(over_idx))); % 低通濾波濾掉限幅產(chǎn)生的帶外分量 b fir1(64, 0.8); % 截止頻率按帶寬留一定余量 tx_limited filter(b, 1, tx_limited); end這里的clip_level是相對平均幅度的倍數(shù)不是絕對功率值。比如clip_level3意味著把超過3倍平均幅度的峰值拉回3倍幅度。倍數(shù)取2.5到4之間是常見選擇取小了BER明顯惡化取大了PAPR改善又很小。低通濾波器會引入群時延導致符號定時偏移所以程序包里會在接收端重新做一次粗同步或者把濾波器的延遲在發(fā)送端用delay compensate提前補掉否則從第幾個采樣點開始去CP都會差一個常量。我自己的習慣是先跑不加PAPR控制的版本把BER基線確認好再疊加SLM或限幅否則限幅的BER惡化會被誤判成信道估計的問題。兩種方法各有各的適用場景下面這張對比表是我在報告里常用的方法實現(xiàn)難度計算量對BER的影響適用場景SLM中等隨U線性增加基本無損對誤碼率敏感允許邊帶開銷限幅濾波簡單很低有失真需調(diào)門限硬件資源緊張快速驗證4. LS信道估計與插值從導頻提取到均衡器重建4.1 導頻圖案和LS估計算法OFDM系統(tǒng)做相干解調(diào)必須先從接收信號中估計出每個子載波上的信道頻響。常用的最小二乘LS估計是在導頻子載波上直接計算接收值除以本地已知導頻值得到該子載波的信道系數(shù)。不需要任何信道統(tǒng)計先驗因此也是程序包默認的估計器。熱搜里常說的ls信道估計就是這個東西。水聲信道多途時延大相干帶寬小導頻必須足夠密。程序包使用梳狀導頻每隔幾個子載波插一個導頻。導頻間隔的選擇依據(jù)是采樣定理導頻間隔對應的頻域周期要小于信道相干帶寬。對于多途信道路徑最大時延越長頻域起伏越快導頻就要越密。比如最大時延21ms頻域起伏周期大約47.6Hz1/21ms子載波間隔11.7Hz那么每隔4個子載波插一個導頻就能覆蓋程序包默認6個在低信噪比時可能不夠。插導頻的代碼一般長這樣function [tx_grid, pilot_idx, pilot_symbols] insert_pilots(data_symbols, N_subcarriers, pilot_spacing) if nargin 3, pilot_spacing 6; end tx_grid zeros(N_subcarriers, 1); pilot_idx 1:pilot_spacing:N_subcarriers; % 導頻子載波下標 data_mask true(N_subcarriers, 1); data_mask(pilot_idx) false; data_idx find(data_mask); tx_grid(data_idx) data_symbols(1:length(data_idx)); % 導頻值用BPSK序列功率比數(shù)據(jù)符號高一些 pilot_symbols (2 * randi([0 1], length(pilot_idx), 1) - 1); tx_grid(pilot_idx) pilot_symbols; end這里的pilot_spacing就是導頻間隔單位是子載波數(shù)。程序包里建議把它做成可調(diào)參數(shù)而不是寫死在腳本里。導頻符號用BPSK而不是QAM是為了抗噪聲和簡化接收端生成副本。導頻功率可以比數(shù)據(jù)高比如高3dB這樣在低信噪比下估計誤差小很多但代價是數(shù)據(jù)子載波功率相應降低誤碼率曲線不一定整體變好需要自己權(quán)衡。4.2 LS估計與線性插值的完整實現(xiàn)接收端拿到導頻子載波上的接收值后先做LS除法再對導頻間缺失的子載波做線性插值。程序包里的實現(xiàn)大概分三步提取導頻位置、求初始估計、插值到全部子載波。代碼如下function h_est ls_channel_estimate(rx_signal_fft, pilot_idx, pilot_symbols, N_subcarriers) % 第一步導頻位置的LS估計 rx_pilot rx_signal_fft(pilot_idx); h_pilot rx_pilot ./ pilot_symbols; % 第二步對估計結(jié)果做頻域平滑減小噪聲影響 % 平滑窗長度取3~5水聲信道頻域變化慢時有效 h_pilot_smooth filter(ones(5,1)/5, 1, h_pilot); % 第三步線性插值到所有子載波 h_est interp1(pilot_idx, h_pilot_smooth, 1:N_subcarriers, linear, extrap); h_est h_est(:); end這段代碼里有兩個地方容易改出問題。第一是平滑窗filter的用法MATLAB的filter(ones(5,1)/5,1,...)是因果濾波會讓插值結(jié)果帶一個群時延偏移。嚴格的做法是使用零相位濾波比如filtfilt或者把導頻序列前后做循環(huán)擴展后再filter。如果只是驗算法性能用filtfilt最省事。第二是interp1的extrap如果第一個導頻不在子載波1上線性外推會在邊緣子載波上給出離譜的值所以程序包通常會讓第一個導頻放在第1個子載波末位導頻放在最后或者干脆用nearest處理邊緣。我通常會在均衡后打印一條診斷取數(shù)據(jù)子載波的平均誤差向量幅度EVM如果EVM超過20%先懷疑插值邊緣再懷疑同步。為了量化估計性能和判斷插值是否正常程序包里還常算信道估計的MSE??梢赃@樣做% 已知真實信道h_true時估計MSE h_true_fft fft(h_true, N_subcarriers); mse mean(abs(h_est - h_true_fft).^2); fprintf(信道估計MSE %.6f\n, mse);如果看到MSE沒有隨SNR提高而單調(diào)下降大概率是插值或平滑環(huán)節(jié)出了問題。這個診斷比只看BER更直接尤其在多途信道下BER受均衡和解調(diào)雙重影響而MSE能單獨鎖定信道估計環(huán)節(jié)。4.3 為什么先LS后LMMSE而不是一步到位有些同學拿到程序包后第一件事是想把LS換成LMMSE。LMMSE確實在低信噪比下比LS好但它需要知道信道的二階統(tǒng)計量也就是頻域相關(guān)矩陣而水聲信道統(tǒng)計特性很難精確獲得算錯了反而比LS差。程序包保留LS作為默認不是偷懶而是給后續(xù)擴展留一個干凈的基線。我在做對比實驗時通常會在同一個多途信道下先用LS跑出一條BER曲線再跑LMMSE兩者差距如果超過1dB說明導頻圖案或信道模型有問題如果差距不到0.5dB說明LS已經(jīng)足夠用沒必要增加復雜度。LMMSE的典型實現(xiàn)需要對導頻位置的信道頻響做維納濾波公式是H_lmmse R_hp * (R_pp sigma^2*I)^(-1) * H_ls。程序包里如果要擴展會單獨放一個lmmse_channel_estimate.m輸入導頻LS估計、噪聲方差和信道頻域自相關(guān)矩陣。噪聲方差可以從接收端空子載波能量估計這個細節(jié)比LMMSE公式本身更容易寫錯。如果是在課程設計里展示效果我建議保留LS然后額外畫一張LMMSE的BER對比圖這樣工作量增加不大內(nèi)容卻深一層。5. 避坑手冊多途信道仿真最容易翻車的五個問題5.1 循環(huán)前綴、定時同步與濾波器延遲的坑現(xiàn)象1誤碼率曲線在低信噪比時正常到高信噪比反而出現(xiàn)地板無論如何加大SNR都降不下去。我遇到過一次最后發(fā)現(xiàn)是循環(huán)前綴長度不夠最大多途時延21msCP時長只有21ms因為采樣率和點數(shù)取整實際CP只有20.8ms剛好差一點。多途的尾部和下一個OFDM符號頭部疊上破壞了正交性。原因CP只是用來吸收多途時延的如果路徑最大時延大于或等于CP時長符號間干擾就進入有效數(shù)據(jù)區(qū)。很多仿真腳本里寫的是接近而不是嚴格小于差幾個采樣點在高SNR下就會暴露。解決把max_delay和Tcp的比較放到信道參數(shù)定義之后強制用斷言檢查。程序包里可以加一行assert(max_delay Tcp, 多途時延超過CP請增大Ng或減小多途)。另外同步偏差也會造成等效時延擴展保守做法是讓CP比最大時延大10%~20%。現(xiàn)象2用限幅濾波后BER比沒限幅前還差很多星座圖整體旋轉(zhuǎn)了一個角度。這個坑我在自己實驗里踩過原因是低通濾波器fir1引入固定群時延接收端還沒有來得及補償FFT窗口起點偏移導致所有子載波相位線性旋轉(zhuǎn)。原因filter是有因果延時的符號經(jīng)過濾波器后整體延遲了約filter_order/2個采樣點。如果不提前補償就會把這種相位旋轉(zhuǎn)算進信道估計里。LS估計理論上能把線性相位估出來但邊緣子載波插值誤差大局部星座發(fā)散。解決要么在發(fā)送端對濾波延遲做delay compensation要么接收端做循環(huán)相關(guān)粗同步在FFT前重新定準窗口起點。程序包里的做法是把延遲寫成一個全局常量delay_comp在去CP前直接rx_signal circshift(rx_signal, -delay_comp)。每次運行前先打印delay_comp數(shù)值確認它等于濾波器階數(shù)的一半而不是隨便給的數(shù)。5.2 信道估計和PAPR評估的坑現(xiàn)象3LS信道估計得到的頻響像毛刺一樣上下亂跳均衡后星座點散成一團但加大SNR也沒有明顯改善。原因?qū)ьl間隔太大頻域采樣不滿足奈奎斯特條件。具體來說導頻間隔對應的采樣頻域間隔必須小于信道相干帶寬的一半。多途時延越大信道頻響變化越快導頻必須越密。當信道有能量極小的長時延尾跡時容易被忽視但它足以讓插值重建失真。解決先用程序包的默認信道參數(shù)跑一遍然后依次把導頻間隔從12降到6、4看BER在高SNR下是否顯著下降。同時檢查channel_paths里最弱路徑的時延是否也參與建模。如果只是為了驗證算法可以去掉能量低于0.05的弱路徑因為它們的貢獻低于噪聲卻會讓估計器更難插值。注意這里的取舍要記錄在仿真報告里否則別人復現(xiàn)時會對不上?,F(xiàn)象4PAPR的CCDF曲線在6dB門限處概率忽高忽低跑兩次結(jié)果差20%完全沒法判斷SLM有沒有用。原因蒙特卡洛樣本數(shù)太少。OFDM符號的PAPR是隨機變量低于1萬次統(tǒng)計尾部概率根本穩(wěn)不住。很多腳本為了速度快只跑256個符號畫出來的曲線鋸齒非常嚴重。解決把CCDF統(tǒng)計的符號數(shù)提到10000以上如果是驗證算法建議20000。程序包里可以單獨寫一個CCDF測試腳本不跑完整誤碼率鏈路只生成隨機數(shù)據(jù)、做IFFT、測PAPR這樣20000個符號在幾秒內(nèi)就能跑完。我在調(diào)SLM的U參數(shù)時就是用這個方法先把CCDF曲線確定下來再去跑完整鏈路省掉大量時間。現(xiàn)象5把PAPR控制放在信道之前和之后結(jié)果不一樣。有同學把SLM放到接收處理鏈路上以為是發(fā)送端算法結(jié)果把信道噪聲的PAPR也降了誤碼率曲線出現(xiàn)異常。原因PAPR控制是所有OFDM發(fā)送端算法必須在經(jīng)過信道之前完成。接收端的任何非線性都會破壞信道的線性疊加關(guān)系不能再叫PAPR控制。解決檢查主腳本調(diào)用順序發(fā)送端tx_signal slm_papr_reduce(...)必須在conv(tx_signal, h)之前接收端只能做線性均衡。如果發(fā)現(xiàn)程序的PAPR控制函數(shù)出現(xiàn)在信道之后直接認為是腳本寫錯了。這個錯誤在新手自改代碼時尤其常見因為SLM的返回值里有頻域符號容易隨手接到接收端變量名上。給函數(shù)起名時加上tx_前綴比如tx_slm_output能減少這種低級錯誤。6. 驗收與擴展用BER和CCDF把仿真程序變成可復用工具6.1 驗收基線與兩個擴展方向拿到程序包先別急著改算法先用它自帶的參數(shù)跑出三張圖BER曲線、CCDF曲線、均衡后的星座圖。只有基線穩(wěn)定后面加入自己的改動才有意義。我習慣的驗收流程是這樣先固定信噪比10dB跑200幀輸出一個BER數(shù)值再把這200幀拆成前100幀和后100幀分別統(tǒng)計如果兩半的BER差超過一倍說明幀數(shù)不夠先加大幀數(shù)再繼續(xù)。等BER穩(wěn)定后再掃描0:2:20dB共11個信噪比點每個點不少于200幀得到完整曲線。程序包里可以加一個簡單的多信噪比掃描腳本snr_list 0:2:20; ber_list zeros(size(snr_list)); for s 1:length(snr_list) ber_list(s) run_one_snr(snr_list(s), frames_per_snr200); fprintf(SNR %.1f dB, BER %.3e\n, snr_list(s), ber_list(s)); end semilogy(snr_list, ber_list, o-); grid on; xlabel(SNR (dB)); ylabel(BER);跑完這條曲線就能判斷程序包的默認信道估計是否正常工作在8dB以下BER應該緩慢下降8dB以上開始陡降如果曲線在某個SNR處出現(xiàn)平臺回第五章檢查CP和導頻間隔。擴展方向我會優(yōu)先做兩件事一是把限幅法和SLM的CCDF曲線畫進同一張圖用虛線原信號、實線SLM、點線限幅對比寫報告時很有說服力二是把LS估計換成LMMSE在同一個SNR點看BER改善幅度。這兩個擴展都不需要改動主流程只改接口參數(shù)。從那以后我每次拿到一個水聲OFDM仿真程序都先強制走一遍最大時延小于CP、導頻間隔小于相干帶寬的一半、CCDF樣本數(shù)超過一萬這三件事再談優(yōu)化算法。這次這套程序包也是按這個順序驗證的至少在新手手里能少走一半彎路。希望幫到你。本文還有配套的精品資源點擊獲取