水声信道MATLAB仿真程序,包含射线追踪、Bellhop模型、统计模型和多径效应模拟。
matlab
%% 水声信道仿真MATLAB程序
% 功能:水声信道建模与仿真,包含射线追踪、多径效应、时变特性等
clear; close all; clc;
warning('off', 'all');
fprintf('=== 水声信道仿真程序 ===\n');
%% 1. 仿真参数设置
fprintf('1. 设置仿真参数...\n');
% 1.1 基本参数
sim_params.fs = 50e3; % 采样频率 (Hz)
sim_params.duration = 2; % 仿真时长 (s)
sim_params.c = 1500; % 声速 (m/s),默认值
sim_params.fc = 10e3; % 载频 (Hz)
sim_params.B = 5e3; % 带宽 (Hz)
% 1.2 环境参数
env_params.depth = 100; % 水深 (m)
env_params.tx_depth = 30; % 发射机深度 (m)
env_params.rx_depth = 50; % 接收机深度 (m)
env_params.horizontal_range = 1000; % 水平距离 (m)
% 1.3 声速剖面(简化模型)
env_params.ssp_type = 'constant'; % 'constant', 'linear', 'munk'
env_params.ssp_gradient = -0.017; % 声速梯度 (s^-1)
% 1.4 海面/海底参数
env_params.surface_roughness = 0.5; % 海面粗糙度 (m)
env_params.bottom_type = 'sand'; % 海底类型
env_params.bottom_loss = 0.8; % 海底反射损失系数
% 1.5 多径参数
env_params.max_rays = 20; % 最大射线数
env_params.max_reflections = 5; % 最大反射次数
% 1.6 噪声参数
env_params.noise_level = -80; % 环境噪声 (dB re 1μPa/Hz)
env_params.shipping_noise = -70; % 船舶噪声 (dB)
env_params.wind_speed = 5; % 风速 (m/s)
%% 2. 核心函数定义
% 2.1 声速剖面计算函数
function c = calculate_ssp(z, params)
% 计算不同深度的声速
% z: 深度数组 (m)
% params: 声速剖面参数
switch params.ssp_type
case 'constant'
% 常数声速剖面
c = params.c * ones(size(z));
case 'linear'
% 线性声速剖面
c0 = params.c;
gradient = params.ssp_gradient;
c = c0 + gradient * z;
c = max(c, 1450); % 最小值限制
case 'munk'
% Munk声速剖面(典型深海剖面)
z_ref = 1300; % 参考深度
c_ref = 1490; % 参考声速
eps = 0.00737;
eta = 2*(z - z_ref)/z_ref;
c = c_ref * (1 + eps * (eta - 1 + exp(-eta)));
otherwise
c = params.c * ones(size(z));
end
end
% 2.2 射线追踪函数
function rays = ray_tracing(params, env_params)
% 基于Snell定律的射线追踪
fprintf(' 进行射线追踪...\n');
% 发射机和接收机位置
tx_pos = [0, env_params.tx_depth];
rx_pos = [env_params.horizontal_range, env_params.rx_depth];
% 创建深度网格
z_grid = 0:1:env_params.depth;
c_profile = calculate_ssp(z_grid, env_params);
% 初始化射线结构
rays = struct();
ray_count = 0;
% 射线出射角度范围
launch_angles = linspace(-80, 80, env_params.max_rays);
for i = 1:length(launch_angles)
angle = launch_angles(i);
% 当前射线的起点和角度
current_pos = tx_pos;
current_angle = angle;
% 射线路径
ray_path = current_pos;
reflections = 0;
valid_ray = true;
% 跟踪射线
while current_pos(1) < env_params.horizontal_range && reflections <= env_params.max_reflections
% 计算当前深度的声速
[~, depth_idx] = min(abs(z_grid - current_pos(2)));
current_c = c_profile(depth_idx);
% 根据Snell定律计算射线曲率
R = current_c / (abs(sind(current_angle)) * env_params.ssp_gradient);
% 计算射线下一段
step_size = 10; % 步长(m)
dx = step_size * cosd(current_angle);
dz = step_size * sind(current_angle);
% 考虑声速变化对角度的影响
if env_params.ssp_gradient ~= 0
new_depth = current_pos(2) + dz;
[~, new_depth_idx] = min(abs(z_grid - new_depth));
new_c = c_profile(new_depth_idx);
% Snell定律: sin(theta)/c = 常数
new_angle = asind(sind(current_angle) * new_c / current_c);
else
new_angle = current_angle;
end
% 更新位置
new_pos = [current_pos(1) + dx, current_pos(2) + dz];
% 检查边界条件
% 海面反射
if new_pos(2) < 0
new_pos(2) = -new_pos(2); % 镜像反射
new_angle = -new_angle; % 反射定律
reflections = reflections + 1;
% 海面反射损失
surface_loss = calculate_surface_loss(env_params, current_angle);
end
% 海底反射
if new_pos(2) > env_params.depth
new_pos(2) = 2*env_params.depth - new_pos(2); % 镜像反射
new_angle = -new_angle; % 反射定律
reflections = reflections + 1;
% 海底反射损失
bottom_loss = calculate_bottom_loss(env_params, current_angle);
end
% 添加到路径
ray_path = [ray_path; new_pos];
% 更新当前状态
current_pos = new_pos;
current_angle = new_angle;
% 检查是否超出范围
if current_pos(1) > env_params.horizontal_range * 1.2
break;
end
end
% 检查是否接近接收机
distance_to_rx = norm(current_pos - rx_pos);
if distance_to_rx < 50 % 50m容差
ray_count = ray_count + 1;
% 计算射线参数
path_length = sum(sqrt(sum(diff(ray_path).^2, 2)));
travel_time = path_length / mean(c_profile);
arrival_angle = atan2d(rx_pos(2) - current_pos(2), ...
rx_pos(1) - current_pos(1));
% 计算传播损失
propagation_loss = calculate_propagation_loss(...
path_length, reflections, env_params);
% 存储射线信息
rays(ray_count).path = ray_path;
rays(ray_count).angle = angle;
rays(ray_count).travel_time = travel_time;
rays(ray_count).arrival_angle = arrival_angle;
rays(ray_count).path_length = path_length;
rays(ray_count).reflections = reflections;
rays(ray_count).propagation_loss = propagation_loss;
fprintf(' 射线%d: 角度=%.1f°, 时延=%.3fs, 反射=%d, 损失=%.1fdB\n', ...
ray_count, angle, travel_time, reflections, propagation_loss);
end
end
fprintf(' 找到 %d 条有效射线\n', ray_count);
end
% 2.3 计算传播损失
function loss = calculate_propagation_loss(distance, reflections, env_params)
% 计算总传播损失
% 几何扩展损失 (柱面扩展)
geometric_loss = 10 * log10(distance);
% 吸收损失 (Thorp公式)
f_kHz = 10; % 10kHz
absorption = 0.11 * f_kHz^2 / (1 + f_kHz^2) + ...
44 * f_kHz^2 / (4100 + f_kHz^2) + ...
3.0e-4 * f_kHz^2 + 3.3e-6;
absorption_loss = absorption * distance / 1000; % dB/km
% 边界反射损失
reflection_loss = reflections * 3; % 每次反射约3dB损失
% 总损失
loss = geometric_loss + absorption_loss + reflection_loss;
end
% 2.4 计算海面损失
function loss = calculate_surface_loss(params, angle)
% 海面反射损失模型
% 基于海面粗糙度
roughness = params.surface_roughness;
% 掠射角 (相对于水平面)
grazing_angle = abs(90 - abs(angle));
if grazing_angle < 5
% 小掠射角时损失较大
loss = 10 + 2 * roughness;
else
% 大掠射角时近似完全反射
loss = 0.5 * roughness;
end
end
% 2.5 计算海底损失
function loss = calculate_bottom_loss(params, angle)
% 海底反射损失模型
switch params.bottom_type
case 'sand'
base_loss = 2;
case 'mud'
base_loss = 1;
case 'rock'
base_loss = 3;
case 'clay'
base_loss = 1.5;
otherwise
base_loss = 2;
end
% 掠射角影响
grazing_angle = abs(90 - abs(angle));
angle_factor = exp(-grazing_angle/30);
loss = base_loss * (1 + params.bottom_loss * angle_factor);
end
% 2.6 生成噪声
function noise = generate_noise(fs, duration, params)
% 生成环境噪声
t = 0:1/fs:duration-1/fs;
N = length(t);
% 1. 热噪声 (高斯白噪声)
thermal_noise = randn(1, N);
% 2. 风成噪声 (低频增强)
wind_cutoff = 500; % Hz
wind_bw = 1000;
[b_wind, a_wind] = butter(3, wind_cutoff/(fs/2), 'low');
wind_noise = filter(b_wind, a_wind, randn(1, N));
% 3. 船舶噪声 (线谱+宽带)
shipping_lines = [100, 200, 300, 400]; % 线谱频率
shipping_noise = zeros(1, N);
for f_line = shipping_lines
shipping_noise = shipping_noise + ...
0.1 * sin(2*pi*f_line*t + 2*pi*rand);
end
shipping_noise = shipping_noise + 0.05 * randn(1, N);
% 4. 生物噪声 (间歇性)
bio_prob = 0.01; % 生物噪声出现概率
bio_noise = zeros(1, N);
bio_events = find(rand(1, N) < bio_prob);
for idx = bio_events
if idx+1000 <= N
% 模拟海豚叫声或虾群噪声
f_bio = 5000 + 1000*randn;
bio_noise(idx:idx+999) = ...
0.02 * sin(2*pi*f_bio*(0:999)/fs) .* ...
exp(-(0:999)/200);
end
end
% 组合噪声并调整功率
noise = thermal_noise + ...
0.3 * wind_noise * params.wind_speed/10 + ...
0.2 * shipping_noise * 10^(params.shipping_noise/20) + ...
bio_noise;
% 调整总噪声功率
target_power = 10^(params.noise_level/20);
current_power = rms(noise);
noise = noise * (target_power / current_power);
end
% 2.7 多径信道模型
function [h, delays, gains, dopplers] = multipath_channel_model(rays, params)
% 生成多径信道冲激响应
fprintf(' 生成多径信道模型...\n');
% 对射线按到达时间排序
if isempty(rays)
h = 0;
delays = 0;
gains = 0;
dopplers = 0;
return;
end
travel_times = [rays.travel_time];
[sorted_times, sort_idx] = sort(travel_times);
rays = rays(sort_idx);
% 提取多径参数
n_paths = min(length(rays), 10); % 取前10条最强路径
delays = zeros(1, n_paths);
gains = zeros(1, n_paths);
dopplers = zeros(1, n_paths);
for i = 1:n_paths
delays(i) = rays(i).travel_time;
% 路径增益 (考虑传播损失)
path_loss_db = rays(i).propagation_loss;
gains(i) = 10^(-path_loss_db/20);
% 多普勒频移 (简化模型)
% 假设平台运动速度为1-3 m/s
v = 2 + randn * 0.5; % 相对速度
dopplers(i) = v / params.c * params.fc;
fprintf(' 路径%d: 时延=%.3fs, 增益=%.4f, 多普勒=%.1fHz\n', ...
i, delays(i), gains(i), dopplers(i));
end
% 创建离散信道冲激响应
max_delay = max(delays);
num_taps = ceil(max_delay * params.fs) + 100;
h = zeros(1, num_taps);
for i = 1:n_paths
tap_idx = round(delays(i) * params.fs) + 1;
if tap_idx <= num_taps
h(tap_idx) = gains(i) * exp(1j * 2*pi*dopplers(i)*delays(i));
end
end
% 添加抽头间干扰 (莱斯/瑞利衰落)
K_factor = 3; % 莱斯因子
for i = 1:length(h)
if abs(h(i)) > 0
% 主径
direct = h(i);
% 散射分量
scatter = (randn + 1j*randn)/sqrt(2);
% 组合
h(i) = sqrt(K_factor/(K_factor+1)) * direct + ...
sqrt(1/(K_factor+1)) * scatter;
end
end
end
% 2.8 Bellhop兼容接口(简化版)
function [rays, eigenrays] = bellhop_model(params, env_params)
% 简化的Bellhop模型实现
% 注意:完整Bellhop需要外部工具,这里实现核心逻辑
fprintf(' 运行简化Bellhop模型...\n');
% 这里调用实际的Bellhop或使用内置算法
% 为了简化,我们使用射线追踪结果
rays = ray_tracing(params, env_params);
% 计算本征射线(直接到达接收机的射线)
eigenrays = [];
for i = 1:length(rays)
if rays(i).reflections <= 2 % 只考虑反射次数少的
eigenrays = [eigenrays, rays(i)];
end
end
fprintf(' 找到 %d 条本征射线\n', length(eigenrays));
end
%% 3. 主仿真程序
% 3.1 环境设置与可视化
fprintf('\n2. 初始化仿真环境...\n');
% 生成声速剖面
z = 0:1:env_params.depth;
c_profile = calculate_ssp(z, env_params);
% 显示环境参数
figure('Position', [100, 100, 1200, 800]);
subplot(2, 3, 1);
plot(c_profile, z, 'b-', 'LineWidth', 2);
set(gca, 'YDir', 'reverse');
xlabel('声速 (m/s)');
ylabel('深度 (m)');
title('声速剖面');
grid on;
% 绘制环境布局
subplot(2, 3, 2);
hold on;
fill([0, env_params.horizontal_range, env_params.horizontal_range, 0], ...
[0, 0, env_params.depth, env_params.depth], [0.7, 0.5, 0.3]); % 海底
plot([0, env_params.horizontal_range], [0, 0], 'b-', 'LineWidth', 2); % 海面
plot(0, env_params.tx_depth, 'ro', 'MarkerSize', 10, 'LineWidth', 2, ...
'DisplayName', '发射机');
plot(env_params.horizontal_range, env_params.rx_depth, 'go', ...
'MarkerSize', 10, 'LineWidth', 2, 'DisplayName', '接收机');
xlabel('水平距离 (m)');
ylabel('深度 (m)');
title('环境布局');
legend('Location', 'best');
grid on;
axis equal;
% 3.2 运行射线追踪
fprintf('\n3. 进行射线追踪...\n');
rays = ray_tracing(sim_params, env_params);
% 绘制射线图
subplot(2, 3, 3);
hold on;
% 绘制海底和海面
fill([0, env_params.horizontal_range, env_params.horizontal_range, 0], ...
[0, 0, -10, -10], [0.2, 0.4, 0.8]); % 海面以上
fill([0, env_params.horizontal_range, env_params.horizontal_range, 0], ...
[env_params.depth, env_params.depth, env_params.depth+10, env_params.depth+10], ...
[0.5, 0.3, 0.1]); % 海底以下
% 绘制射线
colors = lines(length(rays));
for i = 1:length(rays)
path = rays(i).path;
plot(path(:,1), path(:,2), 'Color', colors(i,:), 'LineWidth', 1);
end
% 标记发射机和接收机
plot(0, env_params.tx_depth, 'ro', 'MarkerSize', 12, 'LineWidth', 3);
plot(env_params.horizontal_range, env_params.rx_depth, 'go', ...
'MarkerSize', 12, 'LineWidth', 3);
set(gca, 'YDir', 'reverse');
xlabel('水平距离 (m)');
ylabel('深度 (m)');
title(sprintf('射线追踪结果 (%d条射线)', length(rays)));
grid on;
xlim([0, env_params.horizontal_range*1.1]);
ylim([-10, env_params.depth+10]);
% 3.3 生成多径信道
fprintf('\n4. 生成多径信道响应...\n');
[h_channel, delays, gains, dopplers] = multipath_channel_model(rays, sim_params);
% 绘制信道冲激响应
subplot(2, 3, 4);
stem((0:length(h_channel)-1)/sim_params.fs, abs(h_channel), 'filled');
xlabel('时延 (s)');
ylabel('幅度');
title('信道冲激响应');
grid on;
xlim([0, max(delays)*1.1]);
% 绘制多径到达图
subplot(2, 3, 5);
for i = 1:length(delays)
if gains(i) > 0
stem(delays(i), 20*log10(gains(i)), 'filled', 'LineWidth', 2);
hold on;
text(delays(i), 20*log10(gains(i))+2, sprintf('%.1fHz', dopplers(i)), ...
'FontSize', 8, 'HorizontalAlignment', 'center');
end
end
xlabel('到达时延 (s)');
ylabel('路径增益 (dB)');
title('多径到达图');
grid on;
% 3.4 生成测试信号
fprintf('\n5. 生成测试信号...\n');
t = 0:1/sim_params.fs:sim_params.duration-1/sim_params.fs;
% LFM信号(线性调频)
pulse_width = 0.1; % 脉冲宽度
t_pulse = 0:1/sim_params.fs:pulse_width-1/sim_params.fs;
f_start = sim_params.fc - sim_params.B/2;
f_end = sim_params.fc + sim_params.B/2;
chirp_signal = chirp(t_pulse, f_start, pulse_width, f_end);
tx_signal = [chirp_signal, zeros(1, length(t)-length(chirp_signal))];
% 绘制信号
subplot(2, 3, 6);
spectrogram(tx_signal, 256, 250, 256, sim_params.fs, 'yaxis');
title('发射信号时频图');
colorbar;
sgtitle('水声信道仿真环境设置', 'FontSize', 14, 'FontWeight', 'bold');
%% 4. 信道传输仿真
fprintf('\n6. 模拟信道传输...\n');
% 4.1 通过信道传输信号
rx_signal = conv(tx_signal, h_channel, 'same');
% 4.2 添加噪声
noise = generate_noise(sim_params.fs, sim_params.duration, env_params);
rx_signal_noisy = rx_signal + noise(1:length(rx_signal));
% 4.3 计算信噪比
signal_power = mean(abs(rx_signal).^2);
noise_power = mean(abs(noise(1:length(rx_signal))).^2);
SNR = 10*log10(signal_power/noise_power);
fprintf(' 接收信号SNR: %.1f dB\n', SNR);
% 4.4 绘制传输结果
figure('Position', [100, 100, 1400, 800]);
% 发射信号
subplot(3, 3, 1);
plot(t(1:min(5000, length(t))), real(tx_signal(1:min(5000, length(t)))));
xlabel('时间 (s)');
ylabel('幅度');
title('发射信号 (实部)');
grid on;
% 信道冲激响应
subplot(3, 3, 2);
plot((0:length(h_channel)-1)/sim_params.fs, abs(h_channel));
xlabel('时延 (s)');
ylabel('幅度');
title('信道冲激响应');
grid on;
% 接收信号(无噪)
subplot(3, 3, 3);
plot(t(1:min(5000, length(t))), real(rx_signal(1:min(5000, length(t)))));
xlabel('时间 (s)');
ylabel('幅度');
title('接收信号 - 无噪声 (实部)');
grid on;
% 噪声信号
subplot(3, 3, 4);
plot(t(1:min(5000, length(t))), noise(1:min(5000, length(t))));
xlabel('时间 (s)');
ylabel('幅度');
title('环境噪声');
grid on;
% 含噪接收信号
subplot(3, 3, 5);
plot(t(1:min(5000, length(t))), real(rx_signal_noisy(1:min(5000, length(t)))));
xlabel('时间 (s)');
ylabel('幅度');
title(sprintf('接收信号 - 含噪 (SNR=%.1fdB)', SNR));
grid on;
% 发射信号频谱
subplot(3, 3, 6);
N_fft = 2^nextpow2(length(tx_signal));
f = (-N_fft/2:N_fft/2-1)*sim_params.fs/N_fft;
TX_fft = fftshift(abs(fft(tx_signal, N_fft)));
plot(f/1000, 20*log10(TX_fft/max(TX_fft)));
xlabel('频率 (kHz)');
ylabel('幅度 (dB)');
title('发射信号频谱');
xlim([-20, 20]);
grid on;
% 接收信号频谱
subplot(3, 3, 7);
RX_fft = fftshift(abs(fft(rx_signal_noisy, N_fft)));
plot(f/1000, 20*log10(RX_fft/max(RX_fft)));
xlabel('频率 (kHz)');
ylabel('幅度 (dB)');
title('接收信号频谱');
xlim([-20, 20]);
grid on;
% 时频分析
subplot(3, 3, 8);
[s, f_spec, t_spec] = spectrogram(rx_signal_noisy, 256, 250, 256, sim_params.fs);
imagesc(t_spec, f_spec/1000, 20*log10(abs(s)));
axis xy;
xlabel('时间 (s)');
ylabel('频率 (kHz)');
title('接收信号时频图');
colorbar;
clim([-60, 0]);
% 匹配滤波处理
subplot(3, 3, 9);
% 匹配滤波器(发射信号的共轭反转)
matched_filter = conj(fliplr(chirp_signal));
mf_output = conv(rx_signal_noisy, matched_filter, 'same');
mf_output = mf_output / max(abs(mf_output)); % 归一化
plot(t, abs(mf_output).^2, 'b-', 'LineWidth', 1.5);
hold on;
% 标记多径到达
for i = 1:length(delays)
if delays(i) < sim_params.duration
line([delays(i), delays(i)], [0, 1], ...
'Color', 'r', 'LineStyle', '--', 'LineWidth', 1);
text(delays(i), 0.8, sprintf('路径%d', i), ...
'Rotation', 90, 'FontSize', 8, 'Color', 'r');
end
end
xlabel('时延 (s)');
ylabel('归一化能量');
title('匹配滤波输出 (多径检测)');
grid on;
xlim([0, max(delays)*1.5]);
sgtitle('水声信道传输仿真结果', 'FontSize', 14, 'FontWeight', 'bold');
%% 5. 信道特性分析
fprintf('\n7. 分析信道特性...\n');
% 5.1 计算信道参数
if ~isempty(delays)
% 平均时延扩展
mean_delay = sum(delays .* gains.^2) / sum(gains.^2);
% RMS时延扩展
delay_spread = sqrt(sum(((delays - mean_delay).^2) .* gains.^2) / sum(gains.^2));
% 相干带宽
coherence_bandwidth = 1 / (2 * pi * delay_spread);
% 多普勒扩展
doppler_spread = std(dopplers);
% 相干时间
coherence_time = 1 / (2 * pi * doppler_spread);
fprintf(' 信道参数:\n');
fprintf(' 平均时延: %.3f s\n', mean_delay);
fprintf(' RMS时延扩展: %.3f s\n', delay_spread);
fprintf(' 相干带宽: %.1f Hz\n', coherence_bandwidth);
fprintf(' 多普勒扩展: %.1f Hz\n', doppler_spread);
fprintf(' 相干时间: %.3f s\n', coherence_time);
% 信道容量估算
B_effective = min(sim_params.B, coherence_bandwidth);
capacity = B_effective * log2(1 + 10^(SNR/10));
fprintf(' 信道容量估算: %.2f bps/Hz\n', capacity/B_effective);
end
% 5.2 绘制信道相干函数
figure('Position', [100, 100, 1000, 400]);
% 频率相干函数
subplot(1, 2, 1);
freq_corr = abs(ifft(abs(fft(h_channel)).^2));
freq_axis = (0:length(freq_corr)-1) * sim_params.fs / length(freq_corr);
plot(freq_axis(1:1000)/1000, freq_corr(1:1000)/max(freq_corr));
xlabel('频率差 (kHz)');
ylabel('归一化相关性');
title('频率相干函数');
grid on;
xlim([0, 10]);
% 时间相干函数
subplot(1, 2, 2);
time_corr = abs(fft(ifft(abs(h_channel)).^2));
time_axis = (0:length(time_corr)-1) / sim_params.fs;
plot(time_axis(1:1000), time_corr(1:1000)/max(time_corr));
xlabel('时间差 (s)');
ylabel('归一化相关性');
title('时间相干函数');
grid on;
xlim([0, 1]);
sgtitle('水声信道相干特性', 'FontSize', 12, 'FontWeight', 'bold');
%% 6. 不同环境条件对比
fprintf('\n8. 对比不同环境条件...\n');
figure('Position', [100, 100, 1200, 500]);
% 测试不同水深
depths = [50, 100, 200, 500];
n_depths = length(depths);
channel_responses = cell(1, n_depths);
for i = 1:n_depths
% 临时修改参数
temp_env = env_params;
temp_env.depth = depths(i);
% 重新计算
temp_rays = ray_tracing(sim_params, temp_env);
[temp_h, temp_delays, temp_gains, ~] = multipath_channel_model(temp_rays, sim_params);
channel_responses{i} = struct('h', temp_h, 'delays', temp_delays, 'gains', temp_gains);
end
% 绘制对比
subplot(1, 2, 1);
hold on;
colors = lines(n_depths);
for i = 1:n_depths
h_temp = channel_responses{i}.h;
t_temp = (0:length(h_temp)-1)/sim_params.fs;
plot(t_temp, abs(h_temp)/max(abs(h_temp)), ...
'Color', colors(i,:), 'LineWidth', 1.5, ...
'DisplayName', sprintf('%dm', depths(i)));
end
xlabel('时延 (s)');
ylabel('归一化幅度');
title('不同水深下的信道响应');
legend('Location', 'best');
grid on;
xlim([0, 0.5]);
% 测试不同距离
ranges = [500, 1000, 2000, 5000];
n_ranges = length(ranges);
subplot(1, 2, 2);
hold on;
for i = 1:n_ranges
temp_env = env_params;
temp_env.horizontal_range = ranges(i);
temp_rays = ray_tracing(sim_params, temp_env);
[temp_h, temp_delays, temp_gains, ~] = multipath_channel_model(temp_rays, sim_params);
% 计算平均增益
avg_gain = mean(temp_gains(temp_gains > 0));
plot(ranges(i), 20*log10(avg_gain), 'o', ...
'MarkerSize', 10, 'LineWidth', 2, ...
'DisplayName', sprintf('%dm', ranges(i)));
end
xlabel('传输距离 (m)');
ylabel('平均路径增益 (dB)');
title('距离对路径增益的影响');
grid on;
%% 7. 保存结果
fprintf('\n9. 保存仿真结果...\n');
% 保存仿真数据
simulation_results = struct();
simulation_results.params = sim_params;
simulation_results.env_params = env_params;
simulation_results.rays = rays;
simulation_results.channel_response = h_channel;
simulation_results.delays = delays;
simulation_results.gains = gains;
simulation_results.dopplers = dopplers;
simulation_results.tx_signal = tx_signal;
simulation_results.rx_signal = rx_signal_noisy;
simulation_results.SNR = SNR;
save('underwater_channel_simulation.mat', 'simulation_results', '-v7.3');
% 保存信道参数
channel_info = struct();
if ~isempty(delays)
channel_info.mean_delay = mean_delay;
channel_info.delay_spread = delay_spread;
channel_info.coherence_bandwidth = coherence_bandwidth;
channel_info.doppler_spread = doppler_spread;
channel_info.coherence_time = coherence_time;
end
save('channel_characteristics.mat', 'channel_info');
% 生成报告
fid = fopen('simulation_report.txt', 'w');
fprintf(fid, '水声信道仿真报告\n');
fprintf(fid, '生成时间: %s\n\n', datestr(now));
fprintf(fid, '仿真参数:\n');
fprintf(fid, ' 采样频率: %.0f Hz\n', sim_params.fs);
fprintf(fid, ' 载频: %.0f Hz\n', sim_params.fc);
fprintf(fid, ' 带宽: %.0f Hz\n', sim_params.B);
fprintf(fid, ' 声速: %.0f m/s\n\n', sim_params.c);
fprintf(fid, '环境参数:\n');
fprintf(fid, ' 水深: %.0f m\n', env_params.depth);
fprintf(fid, ' 发射深度: %.0f m\n', env_params.tx_depth);
fprintf(fid, ' 接收深度: %.0f m\n', env_params.rx_depth);
fprintf(fid, ' 水平距离: %.0f m\n\n', env_params.horizontal_range);
fprintf(fid, '信道特性:\n');
fprintf(fid, ' 多径数量: %d\n', length(delays));
fprintf(fid, ' 最大时延: %.3f s\n', max(delays));
fprintf(fid, ' 接收SNR: %.1f dB\n', SNR);
if ~isempty(delays)
fprintf(fid, ' RMS时延扩展: %.3f s\n', delay_spread);
fprintf(fid, ' 相干带宽: %.1f Hz\n', coherence_bandwidth);
end
fclose(fid);
fprintf(' 仿真结果已保存\n');
fprintf(' 报告已生成: simulation_report.txt\n');
%% 8. 使用说明
fprintf('\n=== 使用说明 ===\n');
fprintf('1. 主要功能:\n');
fprintf(' - 射线追踪与多径建模\n');
fprintf(' - 时变信道仿真\n');
fprintf(' - 噪声环境模拟\n');
fprintf(' - 信号传输与接收\n');
fprintf('2. 参数调整:\n');
fprintf(' - 修改 env_params 调整环境参数\n');
fprintf(' - 修改 sim_params 调整仿真参数\n');
fprintf(' - 测试不同声速剖面 (ssp_type)\n');
fprintf('3. 输出结果:\n');
fprintf(' - 信道冲激响应\n');
fprintf(' - 多径参数\n');
fprintf(' - 传输信号波形\n');
fprintf(' - 性能分析报告\n');
fprintf('\n=== 仿真完成 ===\n');
说明
1. 核心模块架构
| 模块 | 功能描述 | 关键技术 |
|---|---|---|
| 射线追踪 | 计算声波传播路径 | Snell定律、边界反射 |
| 声速剖面 | 模拟不同深度的声速变化 | 常数/线性/Munk剖面 |
| 多径建模 | 生成多径信道冲激响应 | 时延、增益、多普勒计算 |
| 噪声生成 | 模拟水下噪声环境 | 热噪声、风成噪声、船舶噪声 |
| 信号传输 | 模拟信号通过信道 | 卷积运算、匹配滤波 |
| 性能分析 | 计算信道特性参数 | 时延扩展、相干带宽、信道容量 |
2. 信道建模方法
2.1 射线追踪模型
matlab
% 基于Snell定律的射线追踪
for 每条射线:
计算当前声速和梯度
应用Snell定律: n1*sinθ1 = n2*sinθ2
检查边界反射(海面/海底)
计算传播损失
end
2.2 多径信道模型
信道冲激响应表示为:
h(t) = Σ a_p * δ(t-τ_p) * exp(j2πf_d,p t)
其中:
a_p:第p条路径的复增益τ_p:路径时延f_d,p:多普勒频移
2.3 噪声模型
包含四种噪声分量:
- 热噪声:高斯白噪声
- 风成噪声:低频增强
- 船舶噪声:线谱+宽带
- 生物噪声:间歇性脉冲
3. 关键参数与调整
环境参数调整:
matlab
% 修改这些参数模拟不同环境
env_params.depth = 200; % 水深 (m)
env_params.horizontal_range = 5000; % 传输距离 (m)
env_params.ssp_type = 'linear'; % 声速剖面类型
env_params.wind_speed = 10; % 风速 (m/s)
信道参数调整:
matlab
sim_params.fc = 25e3; % 载频 (Hz)
sim_params.B = 10e3; % 带宽 (Hz)
env_params.max_reflections = 10; % 最大反射次数
仿真精度调整:
matlab
sim_params.fs = 100e3; % 提高采样率
env_params.max_rays = 50; % 增加射线数
4. 输出结果与分析
程序生成以下结果:
-
可视化输出:
- 声速剖面图
- 射线追踪图
- 信道冲激响应
- 信号时频图
- 匹配滤波输出
-
性能指标:
- 多径时延分布
- RMS时延扩展
- 相干带宽/时间
- 接收信噪比(SNR)
- 信道容量估计
-
数据文件:
underwater_channel_simulation.mat:完整仿真数据channel_characteristics.mat:信道特征参数simulation_report.txt:文本报告
参考代码 水声信道仿真程序 www.3dddown.com/csa/96839.html
5. 应用场景扩展
通信系统设计:
matlab
% 添加OFDM调制解调
ofdm_params = struct(...
'N_subcarriers', 64, ...
'cp_length', 16, ...
'modulation', 'QPSK');
声呐系统仿真:
matlab
% 添加声呐脉冲设计
sonar_pulse = generate_sonar_pulse(...
'type', 'hyperbolic', ...
'bandwidth', 20e3, ...
'duration', 0.1);
信道均衡测试:
matlab
% 测试均衡算法性能
equalizer_types = {'ZF', 'MMSE', 'RLS', 'LMS'};
for eq_type = equalizer_types
test_equalizer(eq_type, channel_response, rx_signal);
end
6. 实际应用建议
-
验证与校准:
- 使用实测数据校准模型参数
- 比较仿真结果与理论预测
- 进行蒙特卡洛仿真获得统计特性
-
性能优化:
- 针对特定频段优化参数
- 考虑季节性和地理变化
- 添加平台运动效应
-
硬件在环:
- 将仿真信道集成到实际通信系统
- 测试不同调制编码方案
- 评估抗多径算法性能
这个程序提供了一个完整的水声信道仿真框架,你可以根据具体需求进行调整和扩展。如果需要特定应用(如水下通信、声呐探测、海洋监测等)的定制版本,我可以提供进一步的指导。