From c72ab2f068a44e065a74b9b826acbecd6adb28fd Mon Sep 17 00:00:00 2001 From: Lewin Probst <info@emirror.de> Date: Mon, 21 Oct 2019 18:16:04 +0200 Subject: [PATCH] Updated trajectory output window. --- .../+trajectoryOutput/clearTrajectoryPlot.m | 9 +- .../+track/+trajectoryOutput/plot.m | 13 +- .../+track/+trajectoryOutput/plotTrajectory.m | 31 +++- lib/+artoa/+controller/+track/run.m | 5 +- lib/+artoa/+convert/rd2dmy.m | 2 +- .../calculateCombinationSegmentLeastSquares.m | 5 +- lib/+artoa/+float/calculateTrajectory.m | 167 +----------------- .../+float/calculateTrajectoryLeastSquares.m | 8 +- lib/+artoa/+float/scatterSatDataPositions.m | 6 +- lib/+artoa/+gui/+track/trajectoryOutput.m | 13 +- lib/+artoa/+soundsources/scatterPositions.m | 4 +- .../plotTrajectoryReferencePositions.m | 10 +- 12 files changed, 87 insertions(+), 186 deletions(-) diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m b/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m index dd04086..8234647 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/clearTrajectoryPlot.m @@ -35,8 +35,13 @@ end for i = 1:length(trajectories) fnames = fieldnames(trajectories{i}); for k = 1:length(fnames) - if isvalid(trajectories{i}.(fnames{k})) - delete(trajectories{i}.(fnames{k})); + switch fnames{k} + case {'textReferencePoints', 'textPositions'} + cellfun(@delete, trajectories{i}.(fnames{k})); + otherwise + if isvalid(trajectories{i}.(fnames{k})) + delete(trajectories{i}.(fnames{k})); + end end end end diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m b/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m index 5d19370..e29cb8d 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/plot.m @@ -40,11 +40,17 @@ for i = 1:length(trajectories) if trajectories{i}.hidden continue; end + trajectoryColor = artoaWorkspace.soundsourceColors(mod(trajectories{i}.id, size(artoaWorkspace.soundsourceColors, 1)), :); % plot the trajectory itself - [artoaGui.trajectoryOutput.trajectoryHandles{i}.scatterPositions] = ... + [ ... + artoaGui.trajectoryOutput.trajectoryHandles{i}.scatterPositions, ... + artoaGui.trajectoryOutput.trajectoryHandles{i}.linePositions, ... + artoaGui.trajectoryOutput.trajectoryHandles{i}.textPositions ... + ] = ... artoa.controller.track.trajectoryOutput.plotTrajectory( ... artoaGui.trajectoryOutput.axesTrajectoryOutput, ... - trajectories{i} ... + trajectories{i}, ... + trajectoryColor ... ); % plot trajectory reference point [ ... @@ -52,7 +58,8 @@ for i = 1:length(trajectories) artoaGui.trajectoryOutput.trajectoryHandles{i}.textReferencePoints ... ] = artoa.trajectory.plotTrajectoryReferencePositions( ... artoaGui.trajectoryOutput.axesTrajectoryOutput, ... - trajectories{i} ... + trajectories{i}, ... + trajectoryColor ... ); end diff --git a/lib/+artoa/+controller/+track/+trajectoryOutput/plotTrajectory.m b/lib/+artoa/+controller/+track/+trajectoryOutput/plotTrajectory.m index 7ddec19..dab4895 100644 --- a/lib/+artoa/+controller/+track/+trajectoryOutput/plotTrajectory.m +++ b/lib/+artoa/+controller/+track/+trajectoryOutput/plotTrajectory.m @@ -1,18 +1,43 @@ -function [scatterHandle] = plotTrajectory(pAxesHandle, pTrajectory) +function [scatterHandle, lineHandle, textHandles] = plotTrajectory(pAxesHandle, pTrajectory, pColor) %PLOTTRAJECTORY Summary of this function goes here % Detailed explanation goes here %% Update track gui content hold(pAxesHandle, 'on'); -% plot trajectory positions +%% Plot trajectory positions scatterHandle = ... scatter( ... pAxesHandle, ... pTrajectory.longitude, ... - pTrajectory.latitude ... + pTrajectory.latitude, ... + 6, ... + pColor, ... + 'filled' ... ); +%% Plot trajectory line +lineHandle = line( ... + pAxesHandle, ... + pTrajectory.longitude, ... + pTrajectory.latitude, ... + 'Color', pColor ... +); + +%% Plot text next to trajectory +t = artoa.convert.rd2dmy(pTrajectory.date); + +textHandles = cell(1, length(t)); +for i = 1:15:length(t) + textHandles{i} = text( ... + pTrajectory.longitude(i), ... + pTrajectory.latitude(i), ... + {' '; [num2str(t(i, 3)) '-' pad(num2str(t(i, 2)), 2, 'left', '0') '-' pad(num2str(t(i, 1)), 2, 'left', '0')]}, ... + 'FontSize', 6, ... + 'Color', pColor ... + ); +end + hold(pAxesHandle, 'off'); diff --git a/lib/+artoa/+controller/+track/run.m b/lib/+artoa/+controller/+track/run.m index fcb6ace..228595e 100644 --- a/lib/+artoa/+controller/+track/run.m +++ b/lib/+artoa/+controller/+track/run.m @@ -21,7 +21,7 @@ end %% Calculate and append track -trajectory = artoa.float.calculateTrajectory( ... +[trajectory, trajectoryDates] = artoa.float.calculateTrajectory( ... artoaWorkspace.float, ... artoaWorkspace.toaData, ... artoaWorkspace.filteredSoundsources, ... @@ -45,7 +45,8 @@ trajectoryObject.trackParameter = artoaWorkspace.trackParameter; % trajectory contains [lat lon] trajectoryObject.latitude = trajectory(:, 1); trajectoryObject.longitude = trajectory(:, 2); -trajectoryObject.id = length(artoaWorkspace.trajectoryOutput.trajectories) + 1; +trajectoryObject.date = trajectoryDates; +trajectoryObject.id = artoaWorkspace.trajectoryOutput.trajectories{end}.id + 1; trajectoryObject.hidden = false; % store to workspace diff --git a/lib/+artoa/+convert/rd2dmy.m b/lib/+artoa/+convert/rd2dmy.m index f4cd8ee..f855975 100644 --- a/lib/+artoa/+convert/rd2dmy.m +++ b/lib/+artoa/+convert/rd2dmy.m @@ -13,6 +13,6 @@ rjul = rjul(:); % redifined RAFOS day %date = greg_0h(rjul+2440000); -date = greg_0h(rjul+2451545); +date = artoa.vendor.greg_0h(rjul+2451545); dmy = [date(:,3) date(:,2) date(:,1)]; diff --git a/lib/+artoa/+data/calculateCombinationSegmentLeastSquares.m b/lib/+artoa/+data/calculateCombinationSegmentLeastSquares.m index 832cf29..d66ccf3 100644 --- a/lib/+artoa/+data/calculateCombinationSegmentLeastSquares.m +++ b/lib/+artoa/+data/calculateCombinationSegmentLeastSquares.m @@ -1,4 +1,4 @@ -function [segmentPositions] = calculateCombinationSegmentLeastSquares(pCorrectedData, pCombinationDetails, pFloatReferenceTime, pSoundVelocity) +function [segmentPositions, segmentDates] = calculateCombinationSegmentLeastSquares(pCorrectedData, pCombinationDetails, pFloatReferenceTime, pSoundVelocity) %CALCULATECOMBINATIONSEGMENTLEASTSQUARES Summary of this function goes here % Detailed explanation goes here @@ -80,6 +80,9 @@ for oDates = 1:length(intersectedToaDates) ]; end +%% Store toa dates +segmentDates = intersectedToaDates; + %% Remove reference position from trajectory segmentPositions = segmentPositions(2:end, :); diff --git a/lib/+artoa/+float/calculateTrajectory.m b/lib/+artoa/+float/calculateTrajectory.m index 5a17b24..c92b94e 100644 --- a/lib/+artoa/+float/calculateTrajectory.m +++ b/lib/+artoa/+float/calculateTrajectory.m @@ -1,4 +1,4 @@ -function [trajectory] = calculateTrajectory(pFloatDetails, pToaData, pSoundsources, pTrackingParameter, pLeapsecondsMatrix) +function [trajectory, trajectoryDates] = calculateTrajectory(pFloatDetails, pToaData, pSoundsources, pTrackingParameter, pLeapsecondsMatrix) %CALCULATETRAJECTORY Summary of this function goes here % Detailed explanation goes here @@ -178,12 +178,15 @@ trajectory = []; switch (trackingMethod) case 'least square' - trajectory = artoa.float.calculateTrajectoryLeastSquares( ... + [trajectory, trajectoryDates] = artoa.float.calculateTrajectoryLeastSquares( ... preparedData, ... soundsourceCombinations, ...startPosition, ... floatReferenceTime, ... soundVelocity ... ); + case 'exclusive least square' + trajectory = artoa.float.calculateTrajectoryExclusiveLeastSquares( ... + ); end return @@ -211,162 +214,4 @@ end % clkerror = NaN; -return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -%% Get required data -soundsourceCombinations = pTrackingParameter.soundsourceCombinations; -trackingMethod = pTrackingParameter.trackingMethodString; -startPosition = [pSatData.lat_sat(1) pSatData.lon_sat(1)]; - - -%% Run through all combinations - -% get the current combination -currentCombination = soundsourceCombinations(1, :); -% isolate the sound source data of this combination -currentSources = artoa.data.extractSoundsourcesFromStruct( ... - strsplit(currentCombination{3}), pSoundsources ... -); -% get the rafos date boundaries for this combination -beginRafosDate = str2double(currentCombination{1}); -endRafosDate = str2double(currentCombination{2}); -% create a selection based on the information above - -% equals to true if the dates are in range -selectionOfDates = (pToaData.toaDate >= beginRafosDate) & (pToaData.toaDate <= endRafosDate); - -soundsourceData = struct(); -soundsourcePositions = []; -for oSoundsource = 1:length(currentSources) - % collect the toa points that have been applied to the sound source and - % is in date range - selectionSoundsource = ... - strcmp(pToaData.soundSource, {currentSources{oSoundsource}.sourcename}) ... - & selectionOfDates; - [soundsourceData(oSoundsource).rafosDate, sortIndices] = sort(pToaData.toaDate(selectionSoundsource)); - soundsourceData(oSoundsource).toa = pToaData.toa(selectionSoundsource); - % sort toa - soundsourceData(oSoundsource).toa = soundsourceData(oSoundsource).toa(sortIndices); - % get position - soundsourcePositions = [soundsourcePositions; currentSources{oSoundsource}.position]; -end - -% search all correspondences -sameDateIndices = []; -for oDate = 1:length(soundsourceData(1).rafosDate) - tmpDate = soundsourceData(1).rafosDate(oDate); - tmpDateExists = true; - tmpIndices = oDate; - for oSoundsource = 2:length(currentSources) - tmpDateExists = tmpDateExists & any(soundsourceData(oSoundsource).rafosDate == tmpDate); - tmpIndices = [tmpIndices, find(soundsourceData(oSoundsource).rafosDate == tmpDate)]; - end - if tmpDateExists - sameDateIndices(end + 1, :) = tmpIndices; - end -end - - -for oSoundsource = 1:length(currentSources) - soundsourceData(oSoundsource).distanceToSoundsource = ... - (soundsourceData(oSoundsource).toa ... - + (pFloatDetails.phasereftime(1)*60 + pFloatDetails.phasereftime(2)) * 60 ... - - (currentSources{oSoundsource}.reftime(:, 1)*3600 + currentSources{oSoundsource}.reftime(:, 2) * 60) ... % - leapseconds missing - ) * 1464; -end - -calculatedPositions = startPosition; - -for oIndex = 1:size(sameDateIndices, 1) - sv = 1.464; - calculatedPositions = [ ... - calculatedPositions; ... - artoa.vendor.ls_converge( ... - calculatedPositions(end, :), ... - length(currentSources), ... - soundsourcePositions, ... - [soundsourceData(1).distanceToSoundsource(sameDateIndices(oIndex));soundsourceData(2).distanceToSoundsource(sameDateIndices(oIndex))], ... - sv ... - )* 180 / pi ... - ]; -end - -% run through all dates -indicesDates = find(selectionOfDates); -for oDates = 1:length(indicesDates) - % get the toa - currentToa = pToaData.toa(indicesDates(oDates)); - -end - - - - -switch (trackingMethod) - case 'Least Square' -% gpsRafosDates(o) = artoa.convert.dmy2rd( ... -% gpsData(o, pRfb.SAT_FORMAT.day_sat), ... -% gpsData(o, pRfb.SAT_FORMAT.month_sat), ... -% gpsData(o, pRfb.SAT_FORMAT.year_sat) ... -% ); - %distanceSoundSourceToFloat = artoa.data.calculateGeodist(currentGpsPosition, soundSourcePosition); -end - - -trajectory = []; - -end \ No newline at end of file +return \ No newline at end of file diff --git a/lib/+artoa/+float/calculateTrajectoryLeastSquares.m b/lib/+artoa/+float/calculateTrajectoryLeastSquares.m index 7bb2874..dc36489 100644 --- a/lib/+artoa/+float/calculateTrajectoryLeastSquares.m +++ b/lib/+artoa/+float/calculateTrajectoryLeastSquares.m @@ -1,21 +1,23 @@ -function [trajectory] = calculateTrajectoryLeastSquares(pPreparedData, pSoundsourceCombinations, pFloatReferenceTime, pSoundVelocity) +function [trajectory, trajectoryDates] = calculateTrajectoryLeastSquares(pPreparedData, pSoundsourceCombinations, pFloatReferenceTime, pSoundVelocity) %CALCULATETRAJECTORYLEASTSQUARES Summary of this function goes here % Detailed explanation goes here trajectory = []; +trajectoryDates = []; %trajectory = pStartPosition; for oCombination = 1:size(pSoundsourceCombinations, 1) - segmentPositions = artoa.data.calculateCombinationSegmentLeastSquares( ... + [segmentPositions, segmentDates] = artoa.data.calculateCombinationSegmentLeastSquares( ... pPreparedData, ... pSoundsourceCombinations(oCombination, :), ...%trajectory(end, :), ... pFloatReferenceTime, ... - pSoundVelocity{1, oCombination} ... + pSoundVelocity.soundspeed1(oCombination) ... ); trajectory = [ ... trajectory; ... segmentPositions ... ]; + trajectoryDates = [trajectoryDates; segmentDates]; end end diff --git a/lib/+artoa/+float/scatterSatDataPositions.m b/lib/+artoa/+float/scatterSatDataPositions.m index 631fee1..cc50645 100644 --- a/lib/+artoa/+float/scatterSatDataPositions.m +++ b/lib/+artoa/+float/scatterSatDataPositions.m @@ -16,13 +16,13 @@ steps = 1:3:(floor(length(x)/3)*3); %% Prepare text cell textCell = {}; for i = steps - textCell{end + 1} = {'', [' ' num2str(year(i)) '-' num2str(month(i)) '-' num2str(day(i))]}; + textCell{end + 1} = {'', [' ' num2str(year(i)) '-' pad(num2str(month(i)), 2, 'left', '0') '-' pad(num2str(day(i)), 2, 'left', '0')]}; end %% Plot hold(pAxesHandle, 'on'); -scatterHandle = scatter(pAxesHandle, x, y); -textHandles = text(pAxesHandle, x(steps), y(steps), textCell, 'FontSize', 7); +scatterHandle = scatter(pAxesHandle, x, y, [], [.5 .5 .5]); +textHandles = text(pAxesHandle, x(steps), y(steps), textCell, 'FontSize', 7, 'Color', [.5 .5 .5]); hold(pAxesHandle, 'off'); end diff --git a/lib/+artoa/+gui/+track/trajectoryOutput.m b/lib/+artoa/+gui/+track/trajectoryOutput.m index 6ecf440..b74ac84 100644 --- a/lib/+artoa/+gui/+track/trajectoryOutput.m +++ b/lib/+artoa/+gui/+track/trajectoryOutput.m @@ -16,7 +16,8 @@ availableCallbacks = { ... 'checkboxTrackVisible', ... 'buttonTrackInfos', ... 'buttonVelocities', ... - 'tableGeneratedTracksSelect' ... + 'tableGeneratedTracksSelect', ... + 'buttonGenerateNewTrajectoryId' ... }; @@ -162,6 +163,16 @@ artoaGui.trajectoryOutput.checkboxMercator = uicontrol( ... 'CallBack', pCallbacks.checkboxMercator ... ); +artoaGui.trajectoryOutput.buttonGenerateNewTrajectoryId = uicontrol( ... + 'Parent', artoaGui.trajectoryOutput.frameDisplayOptions, ... + 'String', 'Generate new trajectory id', ... + 'Style', 'PushButton', ... + 'FontSize', 8, ... + 'Units', 'normalized', ... + 'Position', [.1 .6 .8 .175], ... + 'CallBack', pCallbacks.buttonGenerateNewTrajectoryId ... +); + artoaGui.trajectoryOutput.buttonTrackInfos = uicontrol( ... 'Parent', artoaGui.trajectoryOutput.frameDisplayOptions, ... 'String', 'Track infos', ... diff --git a/lib/+artoa/+soundsources/scatterPositions.m b/lib/+artoa/+soundsources/scatterPositions.m index 716c1b1..82177be 100644 --- a/lib/+artoa/+soundsources/scatterPositions.m +++ b/lib/+artoa/+soundsources/scatterPositions.m @@ -19,8 +19,8 @@ end %% Plot positions hold(pAxesHandle, 'on'); -scatterHandle = scatter(pAxesHandle, lon, lat); -textHandles = text(lon, lat, plot_names); +scatterHandle = scatter(pAxesHandle, lon, lat, [], [0 0 0]); +textHandles = text(lon, lat, plot_names, 'Color', [0 0 0]); hold(pAxesHandle, 'off'); end diff --git a/lib/+artoa/+trajectory/plotTrajectoryReferencePositions.m b/lib/+artoa/+trajectory/plotTrajectoryReferencePositions.m index 1cd95d2..7577493 100644 --- a/lib/+artoa/+trajectory/plotTrajectoryReferencePositions.m +++ b/lib/+artoa/+trajectory/plotTrajectoryReferencePositions.m @@ -1,4 +1,4 @@ -function [scatterHandles, textHandles] = plotTrajectoryReferencePositions(pAxesHandle, pTrajectory) +function [scatterHandles, textHandles] = plotTrajectoryReferencePositions(pAxesHandle, pTrajectory, pColor) %PLOTTRAJECTORYREFERENCEPOSITIONS Summary of this function goes here % Detailed explanation goes here @@ -15,12 +15,14 @@ y = referencePositions(:, 1); hold(pAxesHandle, 'on'); -scatterHandles = scatter(pAxesHandle, x, y, 'x'); +scatterHandles = scatter(pAxesHandle, x, y, [], pColor, 'x'); % Plot text +textHandles = cell(1, length(x)); for i = 1:length(x) - textHandles = text( ... - pAxesHandle, x(i), y(i), {'', [' ' num2str(pTrajectory.id) '.' num2str(i)]} ... + textHandles{i} = text( ... + pAxesHandle, x(i), y(i), {'', [' ' num2str(pTrajectory.id) '.' num2str(i)]}, ... + 'Color', pColor ... ); end -- GitLab