关于水下定位,目前最常用的莫过于超短基线(USBL),其小巧轻便,部署方便,成为了水下定位装备的首选。传统的超短基线主要是由基阵和信标构成,基阵发送询问信号,相应的信标接收到信号后并作出应答,基阵根据信号的飞行时间来计算信标的直线距离,同时根据信号到达基阵各基元的时延差或者相位差来计算水平方位角和垂直方位角,进而得到信标相对于基阵的坐标。但是采用该种方案定位的结果只能在基阵端获取,而信标端没办法知道。当然为了让信标也知道自己相对于基阵的位置,通常会使用声通讯将基阵端的定位信息打包发送至信标,此种方案固然可行,但是其有一个很头疼的缺点,当水下的定位节点增多时,例如多名潜水员一起下水作业,他们都希望知道彼此的相对位置,该方法会非常的低效,超过10各节点整个系统将会变得异常复杂。
为了解决上述问题,笔者突发奇想,想出了一种能够平衡节点增多和效率问题,具体是将水下的定位节点都设计成基阵的形式,所有的节点时间同步,当某一个节点A发射信号时其会将自身的发射时刻通过声通讯打包发送出去,当其它节点(B,C,D,...)接收到信号时,首先计算出信号的达到时间,然后再根据通信包的发射时间从而计算出飞行时间和距离,同时根据时延差计算出方位角,进而在节点(B,C,D,...)得到A的相对位置。如果A,B,C,D,...所有节点按照某种规律发射信号,那么任意节点都可以同时获取其它节点的相对位置。也就是所有的节点都是平等关系,即去中心化。那么这某种规律又是什么规律呢?笔者想到了一种随机发射方案,即将时间划分成若干个时间周期,在该时间周期内任意节点的发射时间服从均匀分布。该方法不求每个节点在每个周期内都100%接收到其它节点的发射信号,而是尽量让每个节点的接收概率超过一定比例即可。
根据这一思想,笔者设计了一个仿真程序,如下:
Matlab
close all;
clear all
clc;
%%
% -------------- 新一代去中心化超短基线定位仿真 --------------------
% --- 定位单元都是一个基阵
% --- 各基阵本地时间同步
% --- 在定位周期内随机发射
% --- 去中心化定位
% --- 对于单个基阵,在定位周期内,其可以同时检测所有的基阵发射信号
c=1500;
R_max = 1000;
tar_num = 10;
Pos_xy = (rand(2,tar_num)-0.5)*2*R_max;
T_period = 3; %定位周期
T = T_period/2; %发射时间区间
T0 = 0.02; %信号脉冲长度
circle = 1000; %定位轮次
detect_num = zeros(1,tar_num);
for k = 1:circle
launch_t = rand(1,tar_num)*T; %模拟各基阵发射时刻
for i = 1:tar_num %不同的基阵
now_xy = Pos_xy(:,i);
other_xy = Pos_xy; other_xy(:,i) = [];
other_t = launch_t; other_t(i) = [];
dt = launch_t(i);
for j = 1:tar_num-1
dis = other_xy(:,j)-now_xy;
dt(j+1) = sqrt(dis'*dis)/c + other_t(j); %求当前基阵的接收其它基阵发射过来信号的时间
end
for j = 1:tar_num-1
dtt = dt; dtt(j+1) = [];
if tell_kick(dt(j+1),dtt,T0) == 0 %没有碰撞,说明可以被检测到
detect_num(i) = detect_num(i) + 1;
end
end
end
end
detect_ratio = detect_num/((tar_num-1)*circle); %检测率
figure;
plot(detect_ratio*100,'r*-'); grid on; xlabel('基阵编号'); ylabel('检测率%'); title({['目标数',num2str(tar_num)],['定位周期',num2str(T_period),'s,脉宽',num2str(T0*1000),'ms']});
%%
% 检测在时刻t0时的信号与已知的信号时间序列是否碰撞
function out = tell_kick(t0,t_array,T)
len = length(t_array);
T0 = [0,T]+t0;
T_array = zeros(len,2);
T_array(:,2) = T_array(:,2) + T;
T_array = T_array + t_array';
out = 0;
for i = 1:len
if(T_array(i,1) < T0(1)) && (T0(1) < T_array(i,2))
out = 1; break;
elseif(T_array(i,1) < T0(2)) && (T0(2) < T_array(i,2))
out = 1; break;
end
end
end
上述程序中仿真了10个节点,在信号脉宽20ms,定位周期3秒的情况下个节点的接收概率结果,结果如下,可见任意节点的检测概率84%左右。

如果想让检测概率提高,可以将定位周期增大到5s,其它条件不变,运行结果如下,检测概率提高到了89%左右。

如果定位节点有20个,其它情况与上述情况一致,运行一下结果如下,检测概率为78%左右。

如果信号脉宽为10ms,其它情况与上述情况一致,运行一下结果如下,检测概率为94.5%左右。

将目标数量调整到100,定位周期为20s,信号脉宽10ms,运行结果如下,检测概率82.7%

通过上述仿真我们可以发现,当目标数量增多时,目标的检测概率会下降,这是应该将定位周期调大或者定位信号脉宽调低,即可提高检测概率。