2018-03-30 10:04:14 +00:00
|
|
|
% Function plots variations of coordinates over time and a 3D position
|
|
|
|
% plot. It plots receiver coordinates in UTM system or coordinate offsets if
|
|
|
|
% the true UTM receiver coordinates are provided.
|
|
|
|
%
|
|
|
|
% plotNavigation(navSolutions, settings)
|
|
|
|
%
|
|
|
|
% Inputs:
|
|
|
|
% navSolutions - Results from navigation solution function. It
|
|
|
|
% contains measured pseudoranges and receiver
|
|
|
|
% coordinates.
|
|
|
|
% settings - Receiver settings. The true receiver coordinates
|
|
|
|
% are contained in this structure.
|
|
|
|
% plot_skyplot - If ==1 then use satellite coordinates to plot the
|
|
|
|
% the satellite positions
|
|
|
|
|
|
|
|
% Darius Plausinaitis
|
|
|
|
% Modified by Javier Arribas, 2011. jarribas(at)cttc.es
|
|
|
|
% -------------------------------------------------------------------------
|
|
|
|
%
|
2020-12-30 12:35:06 +00:00
|
|
|
% GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
2018-03-30 10:04:14 +00:00
|
|
|
% This file is part of GNSS-SDR.
|
|
|
|
%
|
2020-12-30 12:35:06 +00:00
|
|
|
% Copyright (C) 2010-2019 (see AUTHORS file for a list of contributors)
|
2020-02-08 00:20:02 +00:00
|
|
|
% SPDX-License-Identifier: GPL-3.0-or-later
|
2018-03-30 10:04:14 +00:00
|
|
|
%
|
|
|
|
% -------------------------------------------------------------------------
|
|
|
|
%
|
|
|
|
|
|
|
|
function plotNavigation(navSolutions, settings,plot_skyplot)
|
|
|
|
|
|
|
|
|
|
|
|
%% Plot results in the necessary data exists ==============================
|
|
|
|
if (~isempty(navSolutions))
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%% If reference position is not provided, then set reference position
|
2018-04-03 17:15:25 +00:00
|
|
|
%% to the average position
|
2018-03-30 10:04:14 +00:00
|
|
|
if isnan(settings.truePosition.E) || isnan(settings.truePosition.N) ...
|
|
|
|
|| isnan(settings.truePosition.U)
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%=== Compute mean values ==========================================
|
|
|
|
% Remove NaN-s or the output of the function MEAN will be NaN.
|
|
|
|
refCoord.E = mean(navSolutions.E(~isnan(navSolutions.E)));
|
|
|
|
refCoord.N = mean(navSolutions.N(~isnan(navSolutions.N)));
|
|
|
|
refCoord.U = mean(navSolutions.U(~isnan(navSolutions.U)));
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%Also convert geodetic coordinates to deg:min:sec vector format
|
|
|
|
meanLongitude = dms2mat(deg2dms(...
|
|
|
|
mean(navSolutions.longitude(~isnan(navSolutions.longitude)))), -5);
|
|
|
|
meanLatitude = dms2mat(deg2dms(...
|
|
|
|
mean(navSolutions.latitude(~isnan(navSolutions.latitude)))), -5);
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
LatLong_str=[num2str(meanLatitude(1)), '??', ...
|
|
|
|
num2str(meanLatitude(2)), '''', ...
|
|
|
|
num2str(meanLatitude(3)), '''''', ...
|
|
|
|
',', ...
|
|
|
|
num2str(meanLongitude(1)), '??', ...
|
|
|
|
num2str(meanLongitude(2)), '''', ...
|
|
|
|
num2str(meanLongitude(3)), '''''']
|
2020-12-30 12:35:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
refPointLgText = ['Mean Position\newline Lat: ', ...
|
|
|
|
num2str(meanLatitude(1)), '{\circ}', ...
|
|
|
|
num2str(meanLatitude(2)), '{\prime}', ...
|
|
|
|
num2str(meanLatitude(3)), '{\prime}{\prime}', ...
|
|
|
|
'\newline Lng: ', ...
|
|
|
|
num2str(meanLongitude(1)), '{\circ}', ...
|
|
|
|
num2str(meanLongitude(2)), '{\prime}', ...
|
|
|
|
num2str(meanLongitude(3)), '{\prime}{\prime}', ...
|
|
|
|
'\newline Hgt: ', ...
|
|
|
|
num2str(mean(navSolutions.height(~isnan(navSolutions.height))), '%+6.1f')];
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
else
|
|
|
|
% compute the mean error for static receiver
|
|
|
|
mean_position.E = mean(navSolutions.E(~isnan(navSolutions.E)));
|
|
|
|
mean_position.N = mean(navSolutions.N(~isnan(navSolutions.N)));
|
|
|
|
mean_position.U = mean(navSolutions.U(~isnan(navSolutions.U)));
|
|
|
|
refCoord.E = settings.truePosition.E;
|
|
|
|
refCoord.N = settings.truePosition.N;
|
|
|
|
refCoord.U = settings.truePosition.U;
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
error_meters=sqrt((mean_position.E-refCoord.E)^2+(mean_position.N-refCoord.N)^2+(mean_position.U-refCoord.U)^2);
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
refPointLgText = ['Reference Position, Mean 3D error = ' num2str(error_meters) ' [m]'];
|
|
|
|
end
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
figureNumber = 300;
|
|
|
|
% The 300 is chosen for more convenient handling of the open
|
|
|
|
% figure windows, when many figures are closed and reopened. Figures
|
|
|
|
% drawn or opened by the user, will not be "overwritten" by this
|
|
|
|
% function if the auto numbering is not used.
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%=== Select (or create) and clear the figure ==========================
|
|
|
|
figure(figureNumber);
|
|
|
|
clf (figureNumber);
|
|
|
|
set (figureNumber, 'Name', 'Navigation solutions');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%--- Draw axes --------------------------------------------------------
|
|
|
|
handles(1, 1) = subplot(4, 2, 1 : 4);
|
|
|
|
handles(3, 1) = subplot(4, 2, [5, 7]);
|
|
|
|
handles(3, 2) = subplot(4, 2, [6, 8]);
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%% Plot all figures =======================================================
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%--- Coordinate differences in UTM system -----------------------------
|
|
|
|
plot(handles(1, 1), [(navSolutions.E - refCoord.E)', ...
|
|
|
|
(navSolutions.N - refCoord.N)',...
|
|
|
|
(navSolutions.U - refCoord.U)']);
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
title (handles(1, 1), 'Coordinates variations in UTM system');
|
|
|
|
legend(handles(1, 1), 'E', 'N', 'U');
|
|
|
|
xlabel(handles(1, 1), ['Measurement period: ', ...
|
|
|
|
num2str(settings.navSolPeriod), 'ms']);
|
|
|
|
ylabel(handles(1, 1), 'Variations (m)');
|
|
|
|
grid (handles(1, 1));
|
|
|
|
axis (handles(1, 1), 'tight');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%--- Position plot in UTM system --------------------------------------
|
|
|
|
plot3 (handles(3, 1), navSolutions.E - refCoord.E, ...
|
|
|
|
navSolutions.N - refCoord.N, ...
|
|
|
|
navSolutions.U - refCoord.U, '+');
|
|
|
|
hold (handles(3, 1), 'on');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
%Plot the reference point
|
|
|
|
plot3 (handles(3, 1), 0, 0, 0, 'r+', 'LineWidth', 1.5, 'MarkerSize', 10);
|
|
|
|
hold (handles(3, 1), 'off');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
view (handles(3, 1), 0, 90);
|
|
|
|
axis (handles(3, 1), 'equal');
|
|
|
|
grid (handles(3, 1), 'minor');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
legend(handles(3, 1), 'Measurements', refPointLgText);
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
title (handles(3, 1), 'Positions in UTM system (3D plot)');
|
|
|
|
xlabel(handles(3, 1), 'East (m)');
|
|
|
|
ylabel(handles(3, 1), 'North (m)');
|
|
|
|
zlabel(handles(3, 1), 'Upping (m)');
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
if (plot_skyplot==1)
|
|
|
|
%--- Satellite sky plot -----------------------------------------------
|
|
|
|
skyPlot(handles(3, 2), ...
|
|
|
|
navSolutions.channel.az, ...
|
|
|
|
navSolutions.channel.el, ...
|
|
|
|
navSolutions.channel.PRN(:, 1));
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
title (handles(3, 2), ['Sky plot (mean PDOP: ', ...
|
|
|
|
num2str(mean(navSolutions.DOP(2,:))), ')']);
|
|
|
|
end
|
2020-12-30 12:35:06 +00:00
|
|
|
|
2018-03-30 10:04:14 +00:00
|
|
|
else
|
|
|
|
disp('plotNavigation: No navigation data to plot.');
|
|
|
|
end % if (~isempty(navSolutions))
|