www.gusucode.com > MATLAB编程伽利略和北斗的BOC捕获跟踪和解算程序 > MATLAB编程伽利略和北斗的BOC捕获跟踪和解算程序/gnss_sw_radio2/BitSynchronization.m
classdef BitSynchronization < Signal properties (SetAccess = private) SVID; SecondaryPRNCodeObjs; CorrelatorOutBuffer; FrequencyShiftBuffer; CarrierPhaseShiftBuffer; TimeShiftBuffer; CorrelatorOutBufferSize; NumberOfCorrelatorOutInBuffer; BitSoftInformationFileName; BitSoftInformationFile; Replica; ProbabilityOfFalseAlarm; SufficientStatistics; Threshold; end % end of properties properties (SetAccess = private, GetAccess = private) checkBitSynchronizationHandle; end % end of properties methods function obj = BitSynchronization(Name, SVID, BitSoftInformationFileName) obj = obj@Signal(Name); obj.SVID = SVID; obj.BitSoftInformationFileName = BitSoftInformationFileName; obj.BitSoftInformationFile = fopen(obj.BitSoftInformationFileName, 'w'); obj.NumberOfCorrelatorOutInBuffer = 0; obj.ProbabilityOfFalseAlarm = 1e-9; SVID = obj.SVID; switch (obj.Name) case 'E5' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5aI'); obj.SecondaryPRNCodeObjs{2} = SecondaryPRNCode('E5aQ'); obj.SecondaryPRNCodeObjs{3} = SecondaryPRNCode('E5bI'); obj.SecondaryPRNCodeObjs{4} = SecondaryPRNCode('E5bQ'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Replica(2,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{2}.getCode(SVID, 0), N); obj.Replica(3,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{3}.getCode(1, 0), N); obj.Replica(4,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{4}.getCode(SVID, 0), N); obj.Threshold = zeros(1, 4); obj.SufficientStatistics = zeros(1, 4); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5; case 'E5a' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5aI'); obj.SecondaryPRNCodeObjs{2} = SecondaryPRNCode('E5aQ'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Replica(2,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{2}.getCode(SVID, 0), N); obj.Threshold = zeros(1, 2); obj.SufficientStatistics = zeros(1, 2); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5a; case 'E5aI' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5aI'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5aI; case 'E5aQ' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5aQ'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(SVID, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5aQ; case 'E5b' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5bI'); obj.SecondaryPRNCodeObjs{2} = SecondaryPRNCode('E5bQ'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Replica(2,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{2}.getCode(SVID, 0), N); obj.Threshold = zeros(1, 2); obj.SufficientStatistics = zeros(1, 2); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5b; case 'E5bI' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5bI'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5bI; case 'E5bQ' obj.CorrelatorOutBufferSize = 100; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E5bQ'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(SVID, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE5bQ; case 'E1' obj.CorrelatorOutBufferSize = 25; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = []; obj.SecondaryPRNCodeObjs{2} = SecondaryPRNCode('E1c'); obj.Replica(1,:) = ones(1, N); obj.Replica(2,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{2}.getCode(1, 0), N); obj.Threshold = zeros(1, 2); obj.SufficientStatistics = zeros(1, 2); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE1; case 'E1c' obj.CorrelatorOutBufferSize = 25; N = obj.CorrelatorOutBufferSize; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('E1c'); obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationE1c; case 'B1' obj.CorrelatorOutBufferSize = 100; obj.SecondaryPRNCodeObjs{1} = SecondaryPRNCode('B1'); N = obj.CorrelatorOutBufferSize; obj.Replica(1,:) = BitSynchronization.extendCode(... obj.SecondaryPRNCodeObjs{1}.getCode(1, 0), N); obj.Threshold = zeros(1, 1); obj.SufficientStatistics = zeros(1, 1); obj.checkBitSynchronizationHandle = @obj.checkBitSynchronizationB1; otherwise error('Unknown signal') end end function obj = set.CorrelatorOutBufferSize(obj, val) obj.CorrelatorOutBufferSize = val; obj.TimeShiftBuffer = zeros(1, obj.CorrelatorOutBufferSize); obj.FrequencyShiftBuffer = zeros(1, obj.CorrelatorOutBufferSize); obj.CarrierPhaseShiftBuffer = zeros(1, obj.CorrelatorOutBufferSize); switch (obj.Name) case 'E5' obj.CorrelatorOutBuffer = zeros(4, obj.CorrelatorOutBufferSize); case 'E5a' obj.CorrelatorOutBuffer = zeros(2, obj.CorrelatorOutBufferSize); case 'E5aI' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); case 'E5aQ' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); case 'E5b' obj.CorrelatorOutBuffer = zeros(2, obj.CorrelatorOutBufferSize); case 'E5bI' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); case 'E5bQ' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); case 'E1' obj.CorrelatorOutBuffer = zeros(2, obj.CorrelatorOutBufferSize); case 'E1c' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); case 'B1' obj.CorrelatorOutBuffer = zeros(1, obj.CorrelatorOutBufferSize); otherwise error('Unknown signal') end end function obj = addToBuffer(obj, CorrelatorOut, FrequencyShift, ... TimeShift, CarrierPhaseShift) if (obj.NumberOfCorrelatorOutInBuffer < obj.CorrelatorOutBufferSize) obj.NumberOfCorrelatorOutInBuffer = obj.NumberOfCorrelatorOutInBuffer+1; i = obj.NumberOfCorrelatorOutInBuffer; else i = obj.CorrelatorOutBufferSize; obj.CorrelatorOutBuffer = circshift(obj.CorrelatorOutBuffer.',-1).'; obj.FrequencyShiftBuffer = circshift(obj.FrequencyShiftBuffer.',-1).'; obj.TimeShiftBuffer = circshift(obj.TimeShiftBuffer.',-1).'; obj.CarrierPhaseShiftBuffer =... circshift(obj.CarrierPhaseShiftBuffer.',-1).'; end obj.CorrelatorOutBuffer(:, i) = CorrelatorOut; obj.FrequencyShiftBuffer(:, i) = FrequencyShift; obj.TimeShiftBuffer(:, i) = TimeShift; obj.CarrierPhaseShiftBuffer(:, i) = CarrierPhaseShift; end function out = getFrequencyShiftStd(obj) out = obj.getStd(obj.FrequencyShiftBuffer, 2); end function out = getTimeShiftStd(obj) out = obj.getStd(obj.TimeShiftBuffer, 2); end function out = getCarrierPhaseShiftStd(obj) if (sum(obj.CarrierPhaseShiftBuffer == 0) > ... floor(obj.CorrelatorOutBufferSize/10)) out = Inf; else out = obj.getStd(obj.CarrierPhaseShiftBuffer, 2); end end function out = getStd(obj, Buffer, Degree) if (obj.NumberOfCorrelatorOutInBuffer ~= obj.CorrelatorOutBufferSize) error('Not enough correlator out in buffer') else x = 1:obj.NumberOfCorrelatorOutInBuffer; y = Buffer; [p S] = polyfit(x, y, Degree); y_interpolated = polyval(p, x); out = sqrt(var(y - y_interpolated)); end end function out = checkFrequencyTimeShiftStd(obj, FrequencyShiftStdThreshold,... TimeShiftStdThreshold) if (obj.NumberOfCorrelatorOutInBuffer ~= obj.CorrelatorOutBufferSize) error('Not enough correlator out in buffer') else if ((obj.getFrequencyShiftStd() < FrequencyShiftStdThreshold) && ... (obj.getTimeShiftStd() < TimeShiftStdThreshold)) out = 1; else out = 0; end end end function out = checkCarrierPhaseShiftStdThreshold(obj,... CarrierPhaseShiftStdThreshold) if (obj.NumberOfCorrelatorOutInBuffer ~= obj.CorrelatorOutBufferSize) error('Not enough correlator out in buffer') else if (obj.getCarrierPhaseShiftStd() < CarrierPhaseShiftStdThreshold) out = 1; else out = 0; end end end function out = checkBitSynchronization(obj) if (obj.NumberOfCorrelatorOutInBuffer ~= obj.CorrelatorOutBufferSize) error('Not enough correlator out in buffer') else out = obj.checkBitSynchronizationHandle(); end end function out = getThreshold(obj, Std) out = Std * sqrt( -2*log(obj.ProbabilityOfFalseAlarm)); end function out = getSufficientStatistics(obj, Observation,... Replica, NumberOfPeriods) out = 0; N = NumberOfPeriods; M = length(Observation)/N; for i = 1:N out = out + abs(Observation((1 + (i-1)*M):(i*M)) *... Replica((1 + (i-1)*M):(i*M)).'); end end function out = Decide(obj, SufficientStatistics, Threshold) if (SufficientStatistics > Threshold) out = 1; else out = 0; end end function out = checkBitSynchronizationIndex(obj, Index) M = obj.CorrelatorOutBufferSize; N = M/obj.SecondaryPRNCodeObjs{Index}.NumberOfChips; Std = obj.getStd(obj.CorrelatorOutBuffer(Index,:), 1) * sqrt(M/N) * sqrt(N); SuffStat = obj.getSufficientStatistics(obj.CorrelatorOutBuffer(Index,:),... obj.Replica(Index,:), N); Threshold = obj.getThreshold(Std); out = obj.Decide(SuffStat, Threshold); obj.Threshold(Index) = Threshold; obj.SufficientStatistics(Index) = SuffStat; end function out = getBitSoftInformation(obj) switch (obj.Name) case 'E5' for i=1:4 out(i,:) = obj.getBitSoftInformationIndex(i); end case 'E5a' out(1,:) = obj.getBitSoftInformationIndex(1); %out(2,:) = obj.getBitSoftInformationIndex(2); case 'E5aI' out(1,:) = obj.getBitSoftInformationIndex(1); case 'E5aQ' %out(1,:) = obj.getBitSoftInformationIndex(1); case 'E5b' out(1,:) = obj.getBitSoftInformationIndex(1); %out(2,:) = obj.getBitSoftInformationIndex(2); case 'E5bI' out(1,:) = obj.getBitSoftInformationIndex(1); case 'E5bQ' %out(1,:) = obj.getBitSoftInformationIndex(1); case 'E1' out(1,:) = obj.getBitSoftInformationIndex(1); case 'E1c' %out(1,:) = obj.getBitSoftInformationIndex(1); case 'B1' out(1,:) = obj.getBitSoftInformationIndex(1); otherwise error('Unknown signal') end end function obj = storeBitSoftInformation(obj) SI = obj.getBitSoftInformation(); switch (obj.Name) case 'E5' SIToStore(1,:) = SI(1,:); SIToStore(2,:) = SI(3,:); case 'E5a' SIToStore(1,:) = SI(1,:); case 'E5aI' SIToStore(1,:) = SI(1,:); case 'E5aQ' case 'E5b' SIToStore(1,:) = SI(1,:); case 'E5bI' SIToStore(1,:) = SI(1,:); case 'E5bQ' case 'E1' SIToStore(1,:) = SI(1,:); case 'E1c' case 'B1' SIToStore(1,:) = SI(1,:); otherwise error('Unknown signal') end [m n] = size(SIToStore); File = obj.BitSoftInformationFile; for i=1:n for k=1:m fprintf(File, '%f', SIToStore(k, i)); end fprintf(File, '\n'); end end function out = getBitSoftInformationIndex(obj, Index) M = obj.CorrelatorOutBufferSize; try N = M/obj.SecondaryPRNCodeObjs{Index}.NumberOfChips; catch N = M; end Observation = obj.CorrelatorOutBuffer(Index,:); K = M/N; Replica = obj.Replica(Index, :); for i = 1:N tmp(i) = Observation((1 + (i-1)*K):(i*K)) *... Replica((1 + (i-1)*K):(i*K)).'; end out = real(tmp(N)); %CarrierPhaseVec = atan(imag(tmp)./real(tmp)); % insensitive to 180 degree %CarrierPhase = mean(CarrierPhaseVec); %tmp = tmp .* exp(-j*CarrierPhase); %out = real(tmp(N)); %CarrierPhaseVec = atan2(imag(tmp), real(tmp)); % insensitive to 180 degree %angle_old = CarrierPhaseVec(N-1); %angle_new = CarrierPhaseVec(N); %out = angle_new - angle_old; %if (out < (-3*pi/2)) % out = out + 2*pi; %elseif ( (out >= (-3*pi/2)) && (out < -pi)) % out = out + pi; %elseif ( (out >= -pi) && (out < (-pi/2))) % out = out + pi/2; %elseif ( (out >= -pi/2) && (out < 0)) % out = out + pi/2; %elseif ( (out >= pi/2) && (out < pi)) % out = out - pi; %elseif ( (out >= pi) && (out < 3*pi/2)) % out = out - 3*pi/2; %elseif ( (out >= 3*pi/2) && (out < 2*pi)) % out = out - 3*pi/2; %end %tmp2 = tmp(N)/tmp(N-1); %phi = atan2(imag(tmp2), real(tmp2)); %out = abs(phi) - pi/2; end function delete(obj) if (~isempty(obj.BitSoftInformationFile)) fclose(obj.BitSoftInformationFile); end end end % end of methods methods (Access = private) function out = checkBitSynchronizationE5(obj) for i=1:4 out(i) = obj.checkBitSynchronizationIndex(i); end end function out = checkBitSynchronizationE5a(obj) out(1) = obj.checkBitSynchronizationIndex(1); out(2) = obj.checkBitSynchronizationIndex(2); end function out = checkBitSynchronizationE5aI(obj) out(1) = obj.checkBitSynchronizationIndex(1); end function out = checkBitSynchronizationE5aQ(obj) out(1) = obj.checkBitSynchronizationIndex(1); end function out = checkBitSynchronizationE5b(obj) out(1) = obj.checkBitSynchronizationIndex(1); out(2) = obj.checkBitSynchronizationIndex(2); end function out = checkBitSynchronizationE5bI(obj) out(1) = obj.checkBitSynchronizationIndex(1); end function out = checkBitSynchronizationE5bQ(obj) out(1) = obj.checkBitSynchronizationIndex(1); end function out = checkBitSynchronizationE1(obj) out(1) = obj.checkBitSynchronizationIndex(2); end function out = checkBitSynchronizationE1c(obj) out(1) = obj.checkBitSynchronizationIndex(1); end function out = checkBitSynchronizationB1(obj) out(1) = obj.checkBitSynchronizationIndex(1); end end % end of methods methods (Static) function out = extendCode(Code, NumberOfChips) CodeLength = length(Code); NumberOfPeriods = floor(NumberOfChips/CodeLength); for i=1:NumberOfPeriods out((1 + (i-1)*CodeLength) : (i*CodeLength) ) = -2*Code +1; end if (NumberOfChips > (NumberOfPeriods*CodeLength) ) ChipsToEnd = NumberOfChips -NumberOfPeriods*CodeLength; out((1 + NumberOfPeriods*CodeLength) : end) = -2*Code(1:ChipsToEnd) +1; end end end % end of methods end % end of class