UWBIns/lib/gnss/read_rinex_obs.m

217 lines
6.9 KiB
Matlab

function [rinex,rec_xyz] = read_rinex_obs(fname,nlines)
%*******************************************************
% function [ rinex ] = read_rinex_obs(fname)
%
% DESCRIPTION:
% This function reads a RINEX format GPS data
% file and returns the data in an array.
%
% ARGUMENTS:
% fname (str) - RINEX file
%
% OUTPUT:
% rinex - rinex data (v3 struct)
%
% CALLED BY:
% process_rinex.m
%
% FUNCTIONS CALLED:
% read_rinex_header.m
%
% MODIFICATIONS:
% XX-XX-03 : Jan Weiss - Original
% 03-14-06 : Jan Weiss - Cleanup
% : See SVN log for further modifications
% 10-26-06 : simplified for class positioning project & allows for
% limited number of lines read (PA)
%
% Colorado Center for Astrodynamics Research
% Copyright 2006 University of Colorado, Boulder
%*******************************************************
if (nargin < 2)
nlines = 1e6;
end
% Initialize variables
rinex_data = [];
line_count = 1;
% Read header
[ fid, rec_xyz, observables ] = read_rinex_header(fname);
num_obs = length(observables);
% Get the first line of the observations.
current_line = fgetl(fid);
% If not at the end of the file, search for the desired information.
while current_line ~= -1 & line_count < nlines
% Get the time for this data epoch.
current_time = [ str2num(current_line(2:3)) ; str2num(current_line(5:6)) ; ...
str2num(current_line(8:9)) ; str2num(current_line(11:12)) ; ...
str2num(current_line(14:15)) ; str2num(current_line(17:27)) ]';
% How many SV's are there?
current_num_sv = str2num(current_line(30:32));
% Figure out which PRN's there are.
for ii=1:current_num_sv
current_prn(ii) = str2num(current_line(31 + 3*ii : 32 + 3*ii));
end
% Get the data for all SV's in this epoch.
for ii=1:current_num_sv
% Get the next line.
current_line = fgetl(fid);
line_count = line_count + 1;
% Check the length of the line and pad it with zeros to
% make sure it is 80 characters long.
current_line = check_rinex_line_length(current_line);
% Get the observables on this line.
current_obs = [ str2num(current_line(1:14)) ; str2num(current_line(17:30)) ; ...
str2num(current_line(33:46)) ; str2num(current_line(49:62)) ; str2num(current_line(65:78)) ];
% If there are > 5 observables, read another line to get the rest of the observables for this SV.
if num_obs > 5
% Get the next line.
current_line = fgetl(fid);
line_count = line_count + 1;
% Check the length of the line and pad it with zeros to
% make sure it is 80 characters long.
current_line = check_rinex_line_length(current_line);
% Append the data in this line to the data from previous line.
current_obs = [ current_obs ; str2num(current_line(1:14)) ; ...
str2num(current_line(17:30)) ; str2num(current_line(33:46)) ; ...
str2num(current_line(49:62)) ; str2num(current_line(65:78)) ];
end % if num_obs > 5
% Format the data for this PRN as Date/Time, PRN, Observations.
current_data = [ current_time , current_prn(ii) , current_obs' ];
% Keep only data for the specified PRNs
if nargin == 3 & PRN_list & isempty(find(PRN_list == current_prn(ii)))
continue
end
%Append to the master rinex data file.
rinex_data = [ rinex_data ; current_data ];
end % for ii=1:current_num_sv
% Get the next line.
current_line = fgetl(fid);
line_count = line_count + 1;
end % while current_line ~= -1
% Convert time format
[ gpswk, gpssec ] = cal2gpstime(rinex_data(:,1:6));
rinex.data = [ gpswk gpssec rinex_data(:, 7:end) ];
% Define columns
rinex = define_cols(rinex, observables);
% Convert CP to meters
rinex = convert_rinex_CP(rinex);
% =========================================================================
function rinex = define_cols(rinex, observables)
% Defaults
rinex.col.WEEK = 1;
rinex.col.TOW = 2;
rinex.col.PRN = 3;
col_offset = 3;
for ii=1:length(observables)
switch observables{ii}
case {'L1'}
rinex.col.L1 = ii + col_offset;
case {'L2'}
rinex.col.L2 = ii + col_offset;
case {'P1'}
rinex.col.P1 = ii + col_offset;
case {'P2'}
rinex.col.P2 = ii + col_offset;
case {'C1'}
rinex.col.C1 = ii + col_offset;
case {'D1'}
rinex.col.D1 = ii + col_offset;
case {'S1'}
rinex.col.S1 = ii + col_offset;
case {'S2'}
rinex.col.S2 = ii + col_offset;
end % switch
end % for ii=1:length(observables)
% =========================================================================
function [ rinex ] = convert_rinex_CP(rinex)
set_constants;
if rinex.col.L1 ~= 0
rinex.data(:, rinex.col.L1) = rinex.data(:, rinex.col.L1) * LAMBDA_L1;
end
% =========================================================================
function [ fid, rec_xyz, observables ] = read_rinex_header( file_name )
% Initialize the observables variable.
observables={};
% Assign a file ID and open the given header file.
fid=fopen(file_name);
% If the file does not exist, scream bloody murder!
if fid == -1
display('Error! Header file does not exist.');
else
% Set up a flag for when the header file is done.
end_of_header=0;
% Get the first line of the file.
current_line = fgetl(fid);
% If not at the end of the file, search for the desired information.
while end_of_header ~= 1
% Search for the approximate receiver location line.
if strfind(current_line,'APPROX POSITION XYZ')
% Read xyz coordinates into a matrix.
[rec_xyz] = sscanf(current_line,'%f');
end
% Search for the number/types of observables line.
if strfind(current_line,'# / TYPES OF OBSERV')
% Read the non-white space characters into a temp variable.
[observables_temp] = sscanf(current_line,'%s');
% Read the number of observables space and then create
% a matrix containing the actual observables.
for ii = 1:str2num(observables_temp(1))
observables{ii} = observables_temp( 2*ii : 2*ii+1 );
end
end
% Get the next line of the header file.
current_line = fgetl(fid);
%Check if this line is at the end of the header file.
if strfind(current_line,'END OF HEADER')
end_of_header=1;
end
end
end