盲源分离matlab代码% 整合版 TDOA 定位算法实现
classdef dense_TDOA
properties
target % 目标真实坐标
BS_NUM % 基站数量
C_speed % 声速(米/秒)
distance_flag % 远/近场标识
whole_coord_array % 所有基站坐标数组
G_array % G 矩阵
signal_array % 信号数组
H_array % H 矩阵
B_array % B 矩阵
Q_array % Q 矩阵
sigma_array % sigma 矩阵
wls_result1 % 第一次 WLS 结果
wls_result2 % 第二次 WLS 结果
freq_array % 频率数组
MSE_value % 均方误差值
end
methods
% 构造函数
function obj = dense_TDOA(whole_coord_list, delta_list, target)
obj.target = target;
obj.BS_NUM = length(whole_coord_list);
obj.C_speed = 340; % 声速默认值
obj.distance_flag = [];
% 转换坐标列表为矩阵
obj.whole_coord_array = zeros(obj.BS_NUM, 3);
for i = 1:obj.BS_NUM
obj.whole_coord_array(i, :) = whole_coord_list{i};
end
obj.G_array = delta_list;
obj.signal_array = [];
obj.H_array = [];
obj.B_array = [];
obj.Q_array = [];
obj.sigma_array = [];
obj.wls_result1 = [];
obj.wls_result2 = [];
obj.freq_array = [];
obj.MSE_value = [];
end
% 计算 K 值 (x²+y²+z²)
function K = form_K(obj, order)
K = obj.whole_coord_array(order, 1)^2 + ...
obj.whole_coord_array(order, 2)^2 + ...
obj.whole_coord_array(order, 3)^2;
end
% 构造 H 矩阵
function form_array_H(obj)
H_temp_list = zeros(obj.BS_NUM - 1, 1);
for i = 2:obj.BS_NUM % MATLAB 从 1 开始索引,对应 Python 的 1 到 BS_NUM-1
part1 = (obj.signal_array(i) * obj.C_speed)^2;
part2 = obj.form_K(1) - obj.form_K(i);
H_temp_list(i - 1) = (part1 + part2) / 2;
end
obj.H_array = H_temp_list;
end
% 构造 Q 矩阵
function form_array_Q(obj)
obj.Q_array = eye(obj.BS_NUM - 1);
end
% 构造 B 矩阵
function form_array_B(obj, r1_list)
obj.B_array = diag(r1_list);
end
% 计算均方误差
function MSE_calculate(obj)
target_array = obj.target';
obj.MSE_value = sum((target_array - obj.wls_result1(1:3)) .^ 2) / 3;
end
% 构造 sigma 矩阵
function form_array_sigma(obj)
temp1 = (obj.C_speed^2) * obj.B_array;
temp2 = obj.Q_array * obj.B_array';
obj.sigma_array = temp1 * temp2;
end
% 评估距离并判断远近场
function evaluate_distance(obj, r)
obj.distance_flag = 1;
[~, freq_idx] = max(obj.freq_array);
freq = freq_idx * 39 + 1;
wave_length = obj.C_speed / freq;
% 计算平均距离
L = mean(obj.C_speed * abs(obj.signal_array(2:obj.BS_NUM)));
Ra = (L^2) / wave_length; % 判断半径
% 更新远近场标识
if r <= Ra
obj.distance_flag = 0; % 近场
else
obj.distance_flag = 1; % 远场
end
end
% 第一次 WLS 计算
function WLS_1(obj)
% 计算第一次 WLS
temp1 = obj.G_array' * pinv(obj.Q_array) * obj.G_array;
temp2 = obj.G_array' * pinv(obj.Q_array) * obj.H_array;
obj.wls_result1 = pinv(temp1) * temp2;
% 判断远近场
r = abs(obj.wls_result1(4));
obj.evaluate_distance(r);
% 近场情况重新计算
if obj.distance_flag == 0
xyz_1 = obj.wls_result1(1:3)';
r1_list = zeros(1, obj.BS_NUM - 1);
for i = 2:obj.BS_NUM
r1_list(i - 1) = lenth_calculate(xyz_1, obj.whole_coord_array(i, :));
end
obj.form_array_B(r1_list);
obj.form_array_sigma();
temp1 = obj.G_array' * pinv(obj.sigma_array) * obj.G_array;
temp2 = obj.G_array' * pinv(obj.sigma_array) * obj.H_array;
obj.wls_result1 = pinv(temp1) * temp2;
end
end
% 第二次 WLS 计算
function WLS_2(obj)
% 构造 WLS2 所需矩阵
temp_list = [obj.wls_result1(1) - obj.whole_coord_array(1, 1);
obj.wls_result1(2) - obj.whole_coord_array(1, 2);
obj.wls_result1(3) - obj.whole_coord_array(1, 3);
obj.wls_result1(4)];
WLS2_B = diag(temp_list);
WLS2_H = temp_list .^ 2;
WLS2_G = [eye(3); ones(1, 3)];
% 根据远近场计算第二次 WLS
if obj.distance_flag == 1
% 远场情况
part1 = WLS2_G' * pinv(WLS2_B) * obj.G_array' * pinv(obj.Q_array) * obj.G_array * pinv(WLS2_B) * WLS2_G;
part2 = WLS2_G' * pinv(WLS2_B) * obj.G_array' * pinv(obj.Q_array) * obj.G_array * pinv(WLS2_B) * WLS2_H;
WLS2_xyz = pinv(part1) * part2;
else
% 近场情况
part1 = WLS2_G' * pinv(WLS2_B) * obj.G_array' * pinv(obj.B_array) * pinv(obj.Q_array) * pinv(obj.B_array) * obj.G_array * pinv(WLS2_B) * WLS2_G;
part2 = WLS2_G' * pinv(WLS2_B) * obj.G_array' * pinv(obj.B_array) * pinv(obj.Q_array) * pinv(obj.B_array) * obj.G_array * pinv(WLS2_B) * WLS2_H;
WLS2_xyz = pinv(part1) * part2;
end
% 计算最终结果
try
obj.wls_result2 = [sqrt(WLS2_xyz(1) + obj.whole_coord_array(1, 1));
sqrt(WLS2_xyz(2) + obj.whole_coord_array(1, 2));
sqrt(WLS2_xyz(3) + obj.whole_coord_array(1, 3))];
catch
% 处理无效数据
obj.wls_result2 = [sqrt(abs(WLS2_xyz(1)) + obj.whole_coord_array(1, 1));
sqrt(abs(WLS2_xyz(2)) + obj.whole_coord_array(1, 2));
sqrt(abs(WLS2_xyz(3)) + obj.whole_coord_array(1, 3))];
end
end
% 坐标检测主函数
function [xyz, mse] = coord_detect(obj, signal_array, freq_array)
obj.signal_array = signal_array;
obj.freq_array = freq_array;
obj.form_array_H();
obj.form_array_Q();
obj.WLS_1();
obj.WLS_2();
obj.MSE_calculate();
% 输出结果
fprintf('\n预测结果:\n均方误差: %.8f \n远/近场标识: %d \n定位结果: [%.4f, %.4f, %.4f]\n', ...
obj.MSE_value, obj.distance_flag, ...
obj.wls_result2(1), obj.wls_result2(2), obj.wls_result2(3));
xyz = obj.wls_result2;
mse = obj.MSE_value;
end
end
end
% 辅助函数:计算 delta 列表
function delta_list = form_delta(coord_set, target)
% 这里是占位实现,实际应用中需要根据坐标集合和目标计算真实的 delta 值
n = size(coord_set, 1);
delta_list = zeros(n - 1, 3); % 假设 G 矩阵维度为(BS_NUM-1)×3
for i = 1:n - 1
delta_list(i, :) = coord_set(i + 1, :) - coord_set(1, :);
end
end
% 辅助函数:生成信号数组
function signal_array = form_signal(coord_set, target)
% 这里是占位实现,实际应用中需要根据真实信号模型生成
n = size(coord_set, 1);
signal_array = zeros(1, n);
for i = 1:n
% 简单模拟:距离越远信号越弱
dist = lenth_calculate(target, coord_set(i, :));
signal_array(i) = 1 / (1 + dist);
end
end
% 辅助函数:计算两点间距离
function len = lenth_calculate(xyz1, xyz2)
len = sqrt(sum((xyz1 - xyz2) .^ 2));
end
% 辅助函数:数据可视化
function draw_data(mse_list, freq_array, ~)
figure;
subplot(2, 1, 1);
plot(mse_list);
title('均方误差变化');
xlabel('测试次数');
ylabel('MSE');
subplot(2, 1, 2);
histogram(freq_array);
title('频率分布');
xlabel('频率(Hz)');
ylabel('计数');
end
% 主程序
clear;
clc;
result_list = [];
mse_list = [];
test_epoch = 1000; % 测试次数
% 生成随机目标坐标
target = cell(test_epoch, 1);
for i = 1:test_epoch
target{i} = rand(1, 3) * 5; % 生成 0-5 范围内的随机坐标
end
% 生成频率数组
freq_array = randi([500, 8000], test_epoch, 1);
% 基站坐标(可根据实际情况修改)
coord_set = [0, 0, 0; % 基站 1
5, 0, 0; % 基站 2
0, 5, 0; % 基站 3
5, 5, 0]; % 基站 4
% 转换为 cell 数组
whole_coord_list = cell(size(coord_set, 1), 1);
for i = 1:size(coord_set, 1)
whole_coord_list{i} = coord_set(i, :);
end
% 循环测试
for i = 1:test_epoch
delta_list = form_delta(coord_set, target{i});
d_TDOA = dense_TDOA(whole_coord_list, delta_list, target{i});
signal_array = form_signal(coord_set, target{i});
% 进行坐标检测
[xyz, mse] = d_TDOA.coord_detect(signal_array, freq_array);
% 保存结果
result_list = [result_list; xyz'];
mse_list = [mse_list; mse];
% 显示进度
if mod(i, 100) == 0
fprintf('已完成 %d/%d 次测试\n', i, test_epoch);
end
end
% 输出统计结果
fprintf("\n测试完成,均方误差均值: %.8f\n", mean(mse_list));
% 绘制数据可视化结果
draw_data(mse_list, freq_array, 10);修正语法错误
最新发布