水声信道MATLAB仿真程序

水声信道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 噪声模型

包含四种噪声分量:

  1. 热噪声:高斯白噪声
  2. 风成噪声:低频增强
  3. 船舶噪声:线谱+宽带
  4. 生物噪声:间歇性脉冲

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. 输出结果与分析

程序生成以下结果:

  1. 可视化输出

    • 声速剖面图
    • 射线追踪图
    • 信道冲激响应
    • 信号时频图
    • 匹配滤波输出
  2. 性能指标

    • 多径时延分布
    • RMS时延扩展
    • 相干带宽/时间
    • 接收信噪比(SNR)
    • 信道容量估计
  3. 数据文件

    • 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. 实际应用建议

  1. 验证与校准

    • 使用实测数据校准模型参数
    • 比较仿真结果与理论预测
    • 进行蒙特卡洛仿真获得统计特性
  2. 性能优化

    • 针对特定频段优化参数
    • 考虑季节性和地理变化
    • 添加平台运动效应
  3. 硬件在环

    • 将仿真信道集成到实际通信系统
    • 测试不同调制编码方案
    • 评估抗多径算法性能

这个程序提供了一个完整的水声信道仿真框架,你可以根据具体需求进行调整和扩展。如果需要特定应用(如水下通信、声呐探测、海洋监测等)的定制版本,我可以提供进一步的指导。

相关推荐
gcbjoy10 小时前
dbaseIII或foxplus的简化的弹出菜单实现方式
开发语言·经验分享
姓蔡小朋友10 小时前
LUA脚本
开发语言·junit·lua
悟能不能悟10 小时前
Java CheckFailedException会去获取message.properties的内容吗
java·开发语言
shang_xs10 小时前
Java 25 ScopedValue - 作用域内安全访问的一种实现
java·开发语言·安全
向量引擎10 小时前
[架构师级] 压榨GPT-5.2与Sora 2的极限性能:从单体调用到高并发多模态Agent集群的演进之路(附全套Python源码与性能调优方案)
开发语言·人工智能·python·gpt·ai·ai写作·api调用
小白学大数据10 小时前
Java 异步爬虫高效获取小红书短视频内容
java·开发语言·爬虫·python·音视频
solar应急响应10 小时前
域控宕机!如何强制夺取五大角色恢复业务?
开发语言·php
数据的世界0110 小时前
C# 获评2025年度编程语言-编程语言排行榜2026年1月
开发语言
2201_7578308710 小时前
Bean原理篇
java·开发语言
草原上唱山歌11 小时前
推荐学习的C++书籍
开发语言·c++·学习