SingleSource.m 5.82 KiB
function [positions, clockError] = SingleSource(pData, pSoundsourcePositions, pCombinationDetails, pStartEndPosition)
%SINGLESOURCE Estimates the trajectory by using only one soundsource.
%
% Parameters:
% pData (struct):
% Data structured by soundsource. The toa is already corrected
% (e.g. doppler correction etc.)
% pSoundsourcePositions (struct):
% The soundsource positions [deg].
% pCombinationDetails (table):
% Contains all information of the current soundsource
% combination.
% pStartEndPosition (double, logical):
% Set to false if it has not been passed by artoa. Contains the
% desired start and end position as a matrix of row vectors.
%
%
% Returns:
% positions (double):
% The calculated list of segment positions as a X x 2 column vector.
% clockError (double):
% The estimated clock error.
%% Check input
referencePositionStart = cellfun(@str2double, strsplit(pCombinationDetails.referencePosition{1}));
referencePositionEnd = cellfun(@str2double, strsplit(pCombinationDetails.referencePositionEnd{1}));
if any(isnan(referencePositionStart)) || any(isnan(referencePositionEnd))
error([mfilename ': SingleSource algorithm requires BOTH (Reference) Positions to be set!']);
end
%% Get required data
soundsourceName = strsplit(pCombinationDetails.soundsources{1});
soundsourceName = soundsourceName{1};
%% Prepare data for calculations
% get a date vector (does not matter which one)
dates = cell2mat(pData.(soundsourceName).date);
distances = cell2mat(pData.(soundsourceName).distance);
soundsourcePosition = pSoundsourcePositions.(soundsourceName);
% initialize return variables
positions = [ ...
referencePositionStart; ...
];
endPosition = str2num(pCombinationDetails.referencePositionEnd{:});
clockError = [];
%% Algorithm
dateLength = length(dates); % number of points to calculate trajectory for
timeStep = diff(dates(1:2))*86400; % time between position fixes %!!! needs genearlization accorind to float's RAFOS schedule
averageHorizontalVelocity = (distance(str2num(pCombinationDetails.referencePositionEnd{:}),...
str2num(pCombinationDetails.referencePosition{:}))*60*1852)...
/ ((pCombinationDetails.combinationEnd-pCombinationDetails.combinationBegin)*86400) % in meter per second
j = 0
figure(10)
for HorizontalVelocity = averageHorizontalVelocity:.05: 5*averageHorizontalVelocity
HorizontalVelocity
j = j+1
%clear positions
posi(j,:,1) = NaN*ones(1,dateLength,1);
posi(j,:,1) = NaN*ones(1,dateLength,1);
for i = 1:dateLength
currentDistance = distances(i); % get current distance [km] according to current toa
[lat1,lon1] = scircle1( ...
soundsourcePosition(1), ...
soundsourcePosition(2), ...
km2deg(currentDistance)); % calculate circle around soundsource
% plot(lon1,lat1,'r'); hold on % calculate circle around last float position
if i == 1
lastFloatPosition(1) = referencePositionStart(1);
lastFloatPosition(2) = referencePositionStart(2);
[dummy,oldbearing] = distance(referencePositionStart(1),referencePositionStart(2),referencePositionEnd(1),referencePositionEnd(2));
else
%continue
end
[lat2,lon2] = scircle1( ...
lastFloatPosition(1), ...
lastFloatPosition(2), ...
km2deg(HorizontalVelocity*timeStep/1000));
% plot(lon2,lat2,'b'); hold on; grid on
[lat,lon] = scxsc(soundsourcePosition(1),soundsourcePosition(2),km2deg(currentDistance),...
lastFloatPosition(1), lastFloatPosition(2),km2deg(HorizontalVelocity*timeStep/1000) );
%% so we have usually 2 solution, which one to select? --> the one closer towards the final point
% [helper] = distance(lat,lon,endPosition(1),endPosition(2)); %%%! besser: der punkt der sich auf der Verbindungsachse zwischen A und B in Richtung B bewegt
[helper,newbearing] = distance( lastFloatPosition(1), lastFloatPosition(2),lat,lon); %%%! besser: der punkt der sich auf der Verbindungsachse zwischen A und B in Richtung B bewegt
if ~isnan(helper(1)) % intersection found
% helperindi = find(helper == min(helper));
helper = abs(newbearing - oldbearing);
helperindi = find(helper == min(helper));
oldbearing = newbearing(helperindi);
lastFloatPosition(1) = lat(helperindi);
lastFloatPosition(2) = lon(helperindi);
posi(j,i,1) = lastFloatPosition(1);
posi(j,i,2) = lastFloatPosition(2);
plot(lastFloatPosition(2),lastFloatPosition(1),'xk')
plot(posi(j,:,2),posi(j,:,1),'-b'); hold on
else isnan(helper(1))
if size(posi,1) == 1
plot(posi(:,2),posi(:,1),'or'); hold on
else
plot(posi(j,:,2),posi(j,:,1),'-r'); hold on
end
% averageHorizontalVelocity = averageHorizontalVelocity + .01*averageHorizontalVelocity
break
end
end
drawnow
end
validdata = find(~isnan(posi(:,end,1)))
helper = distance(referencePositionEnd(1),referencePositionEnd(2),posi(validdata,end,1),posi(validdata,end,2))
jindi = find(helper == min(helper))
positions(1:dateLength,1) = posi(validdata(jindi),:,1)'
positions(1:dateLength,2) = posi(validdata(jindi),:,2)'
clockError = zeros(length(posi),1); % ich vermute mal das dies der Unterschied gemessene toa zu der "von der errechneten Position abgeleiteten toa". der ist null da wir ihn of 0 zwingen.
end