Files
WirelessNetworkingTechnologies/lab_5/HelperNTNPositionEstimate.m
T
2026-06-22 22:03:28 +02:00

152 lines
5.7 KiB
Matlab
Executable File

classdef HelperNTNPositionEstimate
%HelperNTNPositionEstimate Class defining the supporting functions used
%in the receiver position estimation in NTN example
%
% Note: This is an undocumented class and its API and/or
% functionality may change in subsequent releases.
% Copyright 2024-2025 The MathWorks, Inc.
methods (Static)
function out = instantposition(s, v, r, rDot)
% OUT = instantposition(S,V,R,RDOT) returns the possible
% position OUT using satellite position S, satellite velocity
% V, range R, and range-rate RDOT. S and V are in Earth
% Centered Earth Fixed (ECEF) coordinate system. R is in m and
% RDOT is in m/s. OUT is a 3-by-2 matrix with each column
% corresponding to a possible position in LLA (Latitude,
% Longitude, Altitude).
tolerance = 1e-4;
max_iter_refine = 1000;
% Earth Parameters
r_E = 6378137; % Equatorial radius (meters)
r_p = 6356752; % Polar radius (meters)
% Initialize two r_c values with random values
r_c_1 = (r_E - r_p) * rand();
r_c_2 = r_c_1; % Starting both from the same value (can be different if needed)
% Refinement loop for two solutions
for iter = 1:max_iter_refine
prev_r_c_1 = r_c_1;
prev_r_c_2 = r_c_2;
% Compute geometric parameters
r_s2 = dot(s,s); % Squared norm of position vector
% Linear system for refinement
A = [s(1) s(2); v(1) v(2)];
b_1 = 0.5*(r_s2 + r_c_1^2 - r^2);
b_2 = 0.5*(r_s2 + r_c_2^2 - r^2);
c = dot(s,v) - r*rDot;
% Solve the parameters for r_c_1 and r_c_2
mat_1 = [b_1, s(3); c, v(3)];
mat_2 = [b_2, s(3); c, v(3)];
params_1 = A \ mat_1;
params_2 = A \ mat_2;
% Extract parameters for the first solution
alpha_1 = params_1(1);
beta_1 = params_1(3);
gamma_1 = params_1(2);
delta_1 = params_1(4);
% Extract parameters for the second solution
alpha_2 = params_2(1);
beta_2 = params_2(3);
gamma_2 = params_2(2);
delta_2 = params_2(4);
% Calculate discriminant for both solutions
numerator_1 = alpha_1 * beta_1 + gamma_1 * delta_1;
discriminant_1 = numerator_1^2 - (1 + delta_1^2 + beta_1^2) * (alpha_1^2 + gamma_1^2 - r_c_1^2);
numerator_2 = alpha_2 * beta_2 + gamma_2 * delta_2;
discriminant_2 = numerator_2^2 - (1 + delta_2^2 + beta_2^2) * (alpha_2^2 + gamma_2^2 - r_c_2^2);
% Handle negative discriminant by regenerating r_c
if discriminant_1 < 0
r_c_1 = r_p + (r_E - r_p) * rand();
continue;
end
if discriminant_2 < 0
r_c_2 = r_p + (r_E - r_p) * rand();
continue;
end
% Compute z-coordinates for both solutions
z_hat_1 = (numerator_1 + sqrt(discriminant_1)) / (1 + delta_1^2 + beta_1^2);
z_hat_2 = (numerator_2 - sqrt(discriminant_2)) / (1 + delta_2^2 + beta_2^2);
% Compute x and y coordinates for both solutions
x_hat_1 = alpha_1 - beta_1 * z_hat_1;
y_hat_1 = gamma_1 - delta_1 * z_hat_1;
x_hat_2 = alpha_2 - beta_2 * z_hat_2;
y_hat_2 = gamma_2 - delta_2 * z_hat_2;
% Convert to LLA
lla_1 = ecef2llaLocal([x_hat_1; y_hat_1; z_hat_1]);
lla_2 = ecef2llaLocal([x_hat_2; y_hat_2; z_hat_2]);
% Recalculate r_c for refined solutions
dr_1 = sind(lla_1(1))^2 + cosd(lla_1(1))^2 * (r_p / r_E)^2;
r_c_1 = sqrt(r_p^2 / dr_1);
dr_2 = sind(lla_2(1))^2 + cosd(lla_2(1))^2 * (r_p / r_E)^2;
r_c_2 = sqrt(r_p^2 / dr_2);
% Check convergence for both solutions
if abs(r_c_1 - prev_r_c_1) < tolerance && abs(r_c_2 - prev_r_c_2) < tolerance
break;
end
end
out = [];
if discriminant_1 > 0
out = lla_1(:);
end
if discriminant_2 > 0
out = [out(:) lla_2(:)];
end
end
function error = positionerror(originalPos,estimatedPos)
% ERR = positionerror(ORIGINALPOS,ESTIMATEDPOS) computes the
% position errors ERR for given original position ORIGINALPOS
% and estimated positions ESTIMATEDPOS. Original position and
% estimated positions are in LLA. ESTIMATEDPOS is 3-by-N matrix
% with N being the number of positions.
% Convert the positions to ECEF
posECEF = lla2ecefLocal([originalPos estimatedPos]);
error = vecnorm(posECEF(:,1)-posECEF(:,2:end));
end
end
end
function lla = ecef2llaLocal(ecef)
% Output Latitude (degrees), Longitude (degrees), and Altitude (meters)
tmp = matlabshared.orbit.internal.Transforms.itrf2geographic(ecef);
% Convert to degrees and get the LLA coordinates
lla = [rad2deg(tmp(1,1:end)); ...
rad2deg(tmp(2,1:end)); ...
tmp(3,1:end)];
end
function ecef = lla2ecefLocal(lla)
% Output ECEF: X (meters), Y (meters), and Z (meters)
% Convert to radians
lla = [deg2rad(lla(1,1:end)); ...
deg2rad(lla(2,1:end)); ...
lla(3,1:end)];
% Get ECEF coordinates
ecef = matlabshared.orbit.internal.Transforms.geographic2itrf(lla);
end