麻烦帮我我看看我的水声时变信道的建模和结果行得通不
%% 水声时变稀疏信道仿真
clc; clear; close all;
%% 参数设置
% 基本参数
fc = 10e3; % 载波频率 10kHz
B = 5e3; % 带宽 5kHz
fs = 2*B; % 采样率
Ts = 1/fs; % 采样间隔
T_total = 2; % 总仿真时间(s)
t = 0:Ts:T_total-Ts; % 时间向量
Nt = length(t); % 时间点数
% 信道参数
Np = 15; % 总多径数
N_cluster = 3; % 簇的数量
paths_per_cluster = 5; % 每簇的路径数
% 簇参数(每组对应一个簇)
cluster_delay_centers = [0.02, 0.05, 0.1]; % 簇的中心时延(s)
cluster_delay_spread = [0.005, 0.008, 0.01]; % 簇的时延扩展(s)
cluster_doppler_spread = [1, 2, 3]; % 各簇的多普勒扩展(Hz)
% 信号参数
N_sym = 100; % 减少符号数以加快仿真
T_sym = 1/B; % 符号周期
mod_order = 4; % QPSK调制
%% 生成簇状稀疏多径信道参数
fprintf('生成簇状稀疏多径信道...\n');
% 初始化路径参数
A_i = zeros(Np, Nt); % 时变幅度
tau_i = zeros(Np, 1); % 初始时延
a_i = zeros(Np, 1); % 多普勒扩展因子
path_idx = 1;
for c = 1:N_cluster
% 为当前簇生成路径
for p = 1:paths_per_cluster
% 时延:簇中心 + 随机偏移(瑞利分布)
tau_i(path_idx) = cluster_delay_centers(c) + ...
raylrnd(cluster_delay_spread(c)/3);
% 多普勒扩展因子:与簇的多普勒扩展相关
a_i(path_idx) = cluster_doppler_spread(c) * (0.5 + randn(1)*0.2);
% 初始幅度(考虑水下传播衰减)
A0 = exp(-10 * tau_i(path_idx)); % 指数衰减模型
phase = 2*pi*rand(1); % 随机相位
% 时变幅度(包含多普勒频移和幅度波动)
fd = a_i(path_idx) * randn(1); % 随机多普勒频移
amplitude_fluctuation = 0.1; % 幅度波动
A_i(path_idx, :) = A0 * exp(1i*phase) .* ...
(1 + amplitude_fluctuation*sin(2*pi*fd*t)) .* ...
exp(1i*2*pi*fd*t);
path_idx = path_idx + 1;
end
end
%% 生成信道冲激响应 h(t, tau)
fprintf('计算时变信道冲激响应...\n');
% 时延网格
tau_max = max(tau_i) + 0.02; % 最大时延
N_tau = ceil(tau_max/Ts); % 时延点数
tau_grid = (0:N_tau-1)*Ts; % 时延轴
% 初始化信道冲激响应矩阵
h = zeros(Nt, N_tau);
% 对每个时间点和每个路径计算
for i = 1:Nt
for p = 1:Np
% 计算当前时刻的时延
tau_current = tau_i(p) - a_i(p) * t(i);
% 确保时延非负
if tau_current < 0
tau_current = 0;
end
% 找到最近的时延网格点(简化处理,实际应使用插值)
[~, idx] = min(abs(tau_grid - tau_current));
% 添加该路径的贡献
if idx <= N_tau
h(i, idx) = h(i, idx) + A_i(p, i);
end
end
end
%% 可视化1:信道冲激响应的三维图
figure('Position', [100, 100, 1200, 500]);
% 三维图
subplot(1,2,1);
surf(tau_grid*1000, t, abs(h), 'EdgeColor', 'none');
xlabel('时延 (ms)');
ylabel('时间 (s)');
zlabel('幅度');
title('时变信道冲激响应 (三维视图)');
colorbar;
view(45, 30);
grid on;
% 二维投影(热力图)
subplot(1,2,2);
imagesc(tau_grid*1000, t, abs(h));
xlabel('时延 (ms)');
ylabel('时间 (s)');
title('时变信道冲激响应 (热力图)');
colorbar;
axis xy;
colormap(jet);
%% 可视化2:不同时间点的信道冲激响应
figure('Position', [100, 100, 1200, 400]);
% 选择几个时间点展示
time_samples = [0.1, 0.5, 1.0, 1.5];
t_idx = round(time_samples/Ts) + 1;
t_idx(t_idx > Nt) = Nt;
for i = 1:length(time_samples)
subplot(2,2,i);
stem(tau_grid*1000, abs(h(t_idx(i), :)), 'filled', 'LineWidth', 1);
xlabel('时延 (ms)');
ylabel('幅度');
title(sprintf('t = %.1f s 时的信道冲激响应', time_samples(i)));
grid on;
xlim([0, tau_max*1000]);
end
%% 可视化3:信道的频率响应(随时间变化)
figure('Position', [100, 100, 1200, 400]);
% 计算频率响应
N_fft = 1024;
H = zeros(Nt, N_fft);
for i = 1:Nt
% 补零后做FFT
h_padded = [h(i, :), zeros(1, N_fft - N_tau)];
H(i, :) = fft(h_padded, N_fft);
end
f_axis = (-N_fft/2:N_fft/2-1) * (fs/N_fft) / 1000; % kHz
% 频率响应幅度图
subplot(1,2,1);
imagesc(f_axis, t, 20*log10(abs(H)));
xlabel('频率 (kHz)');
ylabel('时间 (s)');
title('信道频率响应幅度 (dB)');
colorbar;
axis xy;
caxis([-60, 0]); % 设置颜色范围
% 频率响应相位图
subplot(1,2,2);
imagesc(f_axis, t, angle(H));
xlabel('频率 (kHz)');
ylabel('时间 (s)');
title('信道频率响应相位');
colorbar;
axis xy;
colormap(hsv);
%% 可视化4:信道的稀疏性和簇状特性
figure('Position', [100, 100, 1000, 800]);
% 时延-多普勒扩展图
subplot(2,2,1);
scatter(tau_i*1000, a_i, 50, 'filled');
xlabel('初始时延 (ms)');
ylabel('多普勒扩展因子 a_i');
title('多径的时延-多普勒分布');
grid on;
% 路径幅度分布
subplot(2,2,2);
histogram(mean(abs(A_i), 2), 20);
xlabel('平均幅度');
ylabel('路径数');
title('路径幅度分布');
grid on;
% 簇状结构可视化
subplot(2,2,3);
hold on;
colors = ['r', 'g', 'b', 'm', 'c'];
for c = 1:N_cluster
start_idx = (c-1)*paths_per_cluster + 1;
end_idx = c*paths_per_cluster;
scatter(tau_i(start_idx:end_idx)*1000, a_i(start_idx:end_idx), ...
100, colors(c), 'filled', 'DisplayName', sprintf('簇 %d', c));
end
xlabel('时延 (ms)');
ylabel('多普勒扩展因子');
title('簇状结构分布');
legend('show');
grid on;
% 信道能量时延谱
subplot(2,2,4);
PDP = mean(abs(h).^2, 1); % 功率时延谱
bar(tau_grid*1000, 10*log10(PDP));
xlabel('时延 (ms)');
ylabel('功率 (dB)');
title('平均功率时延谱');
grid on;
%% 生成测试信号并通过信道(修复版本)
fprintf('\n生成测试信号并通过信道...\n');
% 生成QPSK测试信号
data = randi([0 mod_order-1], N_sym, 1);
tx_signal = qammod(data, mod_order, 'UnitAveragePower', true);
% 选择信道的一个时间切片进行测试(简化:使用固定信道)
test_time_idx = 1; % 使用第一个时间点的信道
test_h = h(test_time_idx, :); % 固定信道冲激响应
% 对信道冲激响应进行归一化
test_h = test_h / norm(test_h);
% 信号通过信道(卷积)
tx_signal_upsampled = interp(tx_signal, 10); % 上采样以便更好观察多径效应
rx_signal_conv = conv(tx_signal_upsampled, test_h, 'same');
% 添加噪声
SNR_dB = 20;
noise_power = 10^(-SNR_dB/10);
noise = sqrt(noise_power/2) * (randn(size(rx_signal_conv)) + 1i*randn(size(rx_signal_conv)));
rx_noisy = rx_signal_conv + noise;
% 下采样回原始速率
rx_signal_down = decimate(rx_noisy, 10);
%% 可视化5:发送和接收信号对比
figure('Position', [100, 100, 1200, 400]);
% 发送信号星座图
subplot(1,3,1);
scatter(real(tx_signal), imag(tx_signal), 30, 'b', 'filled');
xlabel('同相分量');
ylabel('正交分量');
title('发送信号星座图 (QPSK)');
axis equal;
grid on;
% 接收信号星座图(无均衡)
subplot(1,3,2);
scatter(real(rx_signal_down(1:length(tx_signal))), ...
imag(rx_signal_down(1:length(tx_signal))), 30, 'r', 'filled');
xlabel('同相分量');
ylabel('正交分量');
title('接收信号星座图 (受多径影响)');
axis equal;
grid on;
% 信号幅度对比
subplot(1,3,3);
plot(1:min(50, length(tx_signal)), abs(tx_signal(1:min(50, length(tx_signal)))), ...
'b-o', 'LineWidth', 1.5, 'MarkerSize', 4);
hold on;
plot(1:min(50, length(tx_signal)), abs(rx_signal_down(1:min(50, length(tx_signal)))), ...
'r-s', 'LineWidth', 1.5, 'MarkerSize', 4);
xlabel('符号序号');
ylabel('幅度');
title('发送与接收信号幅度对比');
legend('发送信号', '接收信号');
grid on;
%% 可视化6:信道估计结果(理想情况)
figure('Position', [100, 100, 1000, 400]);
% 理想信道与实际信道对比
subplot(1,2,1);
plot(tau_grid*1000, abs(test_h), 'b-', 'LineWidth', 2);
xlabel('时延 (ms)');
ylabel('幅度');
title('信道冲激响应(时域)');
grid on;
% 频率响应
subplot(1,2,2);
H_freq = fft(test_h, 1024);
freq_axis = linspace(-fs/2, fs/2, 1024) / 1000;
plot(freq_axis, fftshift(20*log10(abs(H_freq))), 'r-', 'LineWidth', 2);
xlabel('频率 (kHz)');
ylabel('幅度 (dB)');
title('信道频率响应');
grid on;
xlim([-5, 5]);
%% 计算信道特性统计量
fprintf('\n信道特性统计量:\n');
fprintf('==================\n');
% 平均时延扩展
tau_mean = mean(tau_i);
tau_rms = sqrt(mean((tau_i - tau_mean).^2));
fprintf('平均时延: %.3f ms\n', tau_mean*1000);
fprintf('RMS时延扩展: %.3f ms\n', tau_rms*1000);
% 相干带宽
coherence_bandwidth = 1/(2*pi*tau_rms);
fprintf('相干带宽: %.2f Hz\n', coherence_bandwidth);
% 多普勒扩展
doppler_spread = max(abs(a_i));
fprintf('最大多普勒扩展: %.2f Hz\n', doppler_spread);
% 相干时间
coherence_time = 1/(2*pi*doppler_spread);
fprintf('相干时间: %.3f s\n', coherence_time);
% 稀疏度
sparsity_threshold = 0.1 * max(abs(h(:)));
sparse_ratio = sum(abs(h(:)) > sparsity_threshold) / numel(h);
fprintf('信道稀疏度 (阈值 %.2f%%): %.2f%%\n', ...
sparsity_threshold/max(abs(h(:)))*100, sparse_ratio*100);
% 簇分离度
cluster_separation = [];
for c1 = 1:N_cluster
for c2 = c1+1:N_cluster
sep = abs(cluster_delay_centers(c1) - cluster_delay_centers(c2));
cluster_separation = [cluster_separation, sep];
end
end
fprintf('平均簇间时延间隔: %.3f ms\n', mean(cluster_separation)*1000);
% 信道容量估计(香农公式)
fprintf('\n信道容量估计:\n');
fprintf('信噪比: %.1f dB\n', SNR_dB);
SNR_linear = 10^(SNR_dB/10);
channel_capacity = B * log2(1 + SNR_linear);
fprintf('理论信道容量: %.2f Mbps\n', channel_capacity/1e6);
%% 保存仿真结果
save('underwater_channel_simulation_fixed.mat', 'h', 'tau_i', 'a_i', 'A_i', ...
't', 'tau_grid', 'tx_signal', 'rx_signal_down', 'fs', 'test_h');
fprintf('\n仿真完成!\n');
disp('所有图形窗口已生成,请查看可视化结果。');
%% 额外功能:信道冲激响应的动画(可选)
fprintf('\n是否生成信道冲激响应动画?(y/n): ');
user_input = input('', 's');
if strcmpi(user_input, 'y') || strcmpi(user_input, 'yes')
figure('Position', [100, 100, 800, 600]);
% 创建动画
fps = 10; % 帧率
num_frames = min(100, Nt); % 最大100帧
for frame = 1:num_frames
% 计算当前帧对应的时间索引
idx = round((frame-1) * (Nt-1) / (num_frames-1)) + 1;
% 绘制当前时刻的信道冲激响应
subplot(2,1,1);
stem(tau_grid*1000, abs(h(idx, :)), 'filled', 'LineWidth', 1.5);
xlabel('时延 (ms)');
ylabel('幅度');
title(sprintf('时变信道冲激响应 (t = %.2f s)', t(idx)));
grid on;
xlim([0, tau_max*1000]);
ylim([0, max(abs(h(:)))]);
% 绘制频率响应
subplot(2,1,2);
H_frame = fft(h(idx, :), 512);
f_axis_frame = linspace(-fs/2, fs/2, 512) / 1000;
plot(f_axis_frame, fftshift(20*log10(abs(H_frame))), 'r-', 'LineWidth', 1.5);
xlabel('频率 (kHz)');
ylabel('幅度 (dB)');
title('信道频率响应');
grid on;
xlim([-10, 10]);
ylim([-50, 0]);
% 暂停以显示动画
pause(1/fps);
% 清除图形以便下一帧
if frame < num_frames
clf;
end
end
fprintf('动画播放完成!\n');
end