声波作为目前已知在水下能够远距离传播的媒介,因此其在水下的通信、导航、探测等领域得到了广泛的应用。虽然电磁波在水下也能传播,但是其在水下衰减非常的严重,一般只能传播几米远,但是声波却可以传播几百甚至是上千公里。因此可以使用声波在水下进行通信,然而在水下通信时的信道要远比电磁波在空气中通信是的信道复杂的多,为了有效的在水下进行通信需要对水下的信道进行建模。
声波在水下传播时一般会受到来自水面和水底的反射,这就导致多途效应非常的明显,此外如果是在河道或者是水库里通信其还会受到来自河道岸边和水库堤坝的反射声波影响。为了有效的对这一现象进行建模,我们只考虑水面和水底的反射,并假设声源(也即发射换能器)的位置距离水面为H1,接收处(也即水听器)的位置距离水面距离为H2,水深为H,两者的水平距离为D,如下图所示:
下面我们来考虑一次反射的情况:
从水面反射的情况 从水底反射的情况
则有
其有两种情况,即一个是首先从发射换能器出发第一次从水面反射的(左边的情况),另一个是首先从发射换能器出发第一次从水底反射的(右边的情况),而且我们可发现左边情况的d_1和d_2的表达式和右边的表达式是对称的,即将左边表达式中的H_1和H_2分别换成H-H_1和H-H_2即可得到右边的表达式,这一规律在后面的二次反射、三次反射等更高次反射都是成立的,因此我们只考虑首先从发射换能器出发第一次从水面反射的情况,得到表达式后只需要将式中的H_1和H_2分别换成H-H_1和H-H_2即可得到另一种情况的表达式。
对于二次反射如下图所示:
则有
对于三次反射
则有
总结一下有如下规律,对于n次反射(第一次从水面反射的)有
其中
至此有关第一次从水面反射的所有次数的反射规律已被找出,为了得到第一次从水底反射的所有反射次数的情况我们只需将式中的H_1和H_2分别换成H-H_1和H-H_2即可得到相应的结果。
有了上面的各段距离我们就可以得到不同反射次数的声波到达时刻,根据上面的公式我们可以编写matlab程序来生成所需的仿真数据。为了得到切确的结果我们还做了如下假设:
(1)基于射线声学理论
(2)几何衰减按球面波衰减规律衰减,不考虑吸收衰减
(3)考虑水面和水底的反射
(4)考虑在高斯白噪声背景下
(5)整个空间声速分布均匀
给出如下的Matlab代码
function receive_signal = Com_Sonar_data_generation(c,fs,f0,Tao,Sample_time,SNR,H,H1,H2,D,Re_coef_surf,Re_coef_bottom,Reflex_num)
%**********************************通信声呐水听器数据生成函数************************************
%几点假设:
%(1)基于射线声学理论
%(2)几何衰减按球面波传播衰减规律衰减,不考虑吸收衰减
%(3)考虑水面和水底的反射(浅海声信道?)
%(4)考虑在高斯白噪声背景下
%(5)整个空间声速分布均匀
%***************************************输入参数说明******************************************
% c 声速 Unit:m/s
% fs 采样率 Unit:Hz
% f0 信号频率 Unit:Hz
% Tao 信号脉宽 Unit:s
% Sample_time 采样时长 Unit:s 假设信号发射的时刻为零时刻
% SNR 信噪比 Unit:dB
% H 水深 Unit:m
% H1 发射换能器水深 Unit:m
% H2 接收换能器水深 Unit:m
% D 接收与发射换能器水平距离 Unit:m
% Re_coef_surf 水面反射系数
% Re_coef_bottom 水底反射系数 存在半波损失
% Reflex_num 考虑最大的反射次数
%***************************************输出参数说明******************************************
% receive_signal 以信号发射为起始采样点的水听器接收信号
%**************最后更新 20171019
%***更新内容
%*首次编写
%%
%**********************************************************************************************************************
H1b = H - H1; %发射换能器到水底的距离 Unit:m
H2b = H - H2; %接收换能器到水底的距离 Unit:m
Ts = 1/fs; %采样时间间隔
sample_num = fix(Sample_time*fs); %采样总点数
nTs = (0:sample_num-1)/fs; %离散的采样时刻
sample_num1 = fix(Tao*fs); %信号的采样点数
nTs1 = (0:sample_num1-1)/fs; %信号的离散的采样时刻
receive_signal = zeros(size(nTs)); %用于存储水听器接收的信号
d0 = sqrt((H1-H2)^2+D^2); %两个换能器的直线距离
S0 = 1/d0; %直达波的声压幅值
Noise_var = 10^(-SNR/20)*S0; %白噪声的方差
%% 计算到达回波信号
real_time = d0/c; %信号的实际到达时刻
signal_start_time = fix(real_time*fs)+1; %信号第一个采样点的时刻
phase = (signal_start_time*Ts-real_time)/Ts*2*pi; %得到信号的第一个采样点的相位
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) = S0*sin(2*pi*f0*nTs1+phase); %模拟采样
receive_signal = receive_signal + Noise_var*randn(size(nTs)); %加入噪声
if Reflex_num>0 %考虑反射时
for i = 1:Reflex_num %考虑i次反射的情况
if mod(i,2) == 0 %偶数次时
%---------------------------------------------------第一次从水面反射时---------------------------------------------------
M = i*H+H1-H2; %中间系数
k1 = sqrt(1+(D/M)^2); %中间系数
d1 = k1*H1; %发射换能器距离水面第一个反射点的距离
d2 = k1*H; %界面相邻两点间的距离
d3 = k1*(H-H2); %水听器距离边界最后一个反射点最近的距离
di = d1+d2*(i-1)+d3; %反射波总路程
Si = 1/di*Re_coef_surf^(i/2)*Re_coef_bottom^(i/2); %反射波的声压幅值
real_time = di/c; %信号的实际到达时刻
signal_start_time = fix(real_time*fs)+1; %信号第一个采样点的时刻
phase = (signal_start_time*Ts-real_time)/Ts*2*pi; %得到信号的第一个采样点的相位
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) =...
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) + Si*sin(2*pi*f0*nTs1 + phase); %模拟采样
%---------------------------------------------------第一次从水底反射时---------------------------------------------------
Mb = i*H+H1b-H2b; %中间系数
k1b = sqrt(1+(D/Mb)^2); %中间系数
d1b = k1b*H1b; %发射换能器距离水底第一个反射点的距离
d2b = k1b*H; %界面相邻两点间的距离
d3b = k1b*(H-H2b); %水听器距离边界最后一个反射点最近的距离
dib = d1b+d2b*(i-1)+d3b; %反射波总路程
Sib = 1/dib*Re_coef_surf^(i/2)*Re_coef_bottom^(i/2); %反射波的声压幅值
real_time = dib/c; %信号的实际到达时刻
signal_start_time = fix(real_time*fs)+1; %信号第一个采样点的时刻
phase = (signal_start_time*Ts-real_time)/Ts*2*pi; %得到信号的第一个采样点的相位
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) =...
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) + Sib*sin(2*pi*f0*nTs1 + phase); %模拟采样
else %奇数次时
%---------------------------------------------------第一次从水面反射时---------------------------------------------------
M = (i-1)*H+H1+H2; %中间系数
k1 = sqrt(1+(D/M)^2); %中间系数
d1 = k1*H1; %发射换能器距离水面第一个反射点的距离
d2 = k1*H; %界面相邻两点间的距离
d3 = k1*H2; %水听器距离边界最后一个反射点最近的距离
di = d1+d2*(i-1)+d3; %反射波总路程
Si = 1/di*Re_coef_surf^((i-1)/2+1)*Re_coef_bottom^((i-1)/2); %反射波的声压幅值
real_time = di/c; %信号的实际到达时刻
signal_start_time = fix(real_time*fs)+1; %信号第一个采样点的时刻
phase = (signal_start_time*Ts-real_time)/Ts*2*pi; %得到信号的第一个采样点的相位
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) =...
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) + Si*sin(2*pi*f0*nTs1 + phase); %模拟采样
%---------------------------------------------------第一次从水底反射时---------------------------------------------------
Mb = (i-1)*H+H1b+H2b; %中间系数
k1b = sqrt(1+(D/Mb)^2); %中间系数
d1b = k1b*H1b; %发射换能器距离水底第一个反射点的距离
d2b = k1b*H; %界面相邻两点间的距离
d3b = k1b*H2b; %水听器距离边界最后一个反射点最近的距离
dib = d1b+d2b*(i-1)+d3b; %反射波总路程
Sib = 1/di*Re_coef_surf^((i-1)/2)*Re_coef_bottom^((i-1)/2+1); %反射波的声压幅值
real_time = dib/c; %信号的实际到达时刻
signal_start_time = fix(real_time*fs)+1; %信号第一个采样点的时刻
phase = (signal_start_time*Ts-real_time)/Ts*2*pi; %得到信号的第一个采样点的相位
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) =...
receive_signal(signal_start_time:(signal_start_time+sample_num1-1)) + Sib*sin(2*pi*f0*nTs1 + phase); %模拟采样
end
end
end
receive_signal = receive_signal/S0; %将直达波的幅值归一化
这是一段通信声呐水听器数据生成函数,我们将在下面这段Matlab代码中调用它用于生成特定参数下的数据。
close all;
clear all;
clc;
c = 1500; %声速 Unit:m/s
f0 = 15e3; %信号频率 Unit:Hz
fs = f0*10; %采样率 最高频率的5倍 Unit:Hz
Tao = 5/f0; %信号脉宽 Unit:s
Sample_time = 0.1; %采样时长 Unit:s 假设信号发射的时刻为零时刻
SNR = 60; %信噪比 Unit:dB
H = 10; %水深 Unit:m
H1 = 5; %发射换能器水深 Unit:m
H2 = 4; %接收换能器水深 Unit:m
D = 10; %接收与发射换能器水平距离 Unit:m
Re_coef_surf = -1; %水面反射系数
Re_coef_bottom = 0.5; %水底反射系数
Reflex_num = 10; %考虑最大的反射次数
%%
sample_num = fix(Sample_time*fs); %采样总点数
nTs = (0:sample_num-1)/fs; %离散的采样时刻
%生成水听器接收数据
receive_signal0 = Com_Sonar_data_generation(c,fs,f0,Tao,Sample_time,SNR,H,H1,H2,D,Re_coef_surf,Re_coef_bottom,Reflex_num);
figure;
plot(nTs,receive_signal0);
xlabel('时间s');
ylabel('幅度');
string = ['水听器接收的仿真数据,信噪比SNR=',num2str(SNR),'dB,考虑的最大反射次数',num2str(Reflex_num)];
title(string);
运行一下上述程序得到如下图
仿真的结果与理论推导的一致,说明程序没有问题。有了这段仿真数据生成代码我们就可以对参数不同的情况进行仿真,从而预先验证一下相关的算法,为后续的实际调试提供一定的理论支撑。