function [tk,plh,fq,nsat,hdop,dgpst,dgpsid]=nmeagpgga(str)
%NMEAGPGGA  Parse NMEA GPGGA string.
%   [TK,PLH]=NMEAGPGGA(STR) parses the NMEA fix data GPGGA string STR. Output
%   is the time TK in seconds since the start of the day and the array PLH with 
%   the lattitude (rad), longitude (rad) and ellipsoidal height (m). The routine 
%   will check the message type and checksum. If a problem is found NaN is
%   returned for TK.
%
%   [TK,PLH,FQ,NSAT,HDOP]=NMEAGPGGA(STR) also returns the fix quality FQ,
%   number of satellites NSAT involved in the fix, and the horizontal dillution
%   of precision HDOP. The fix quality FQ is: 0 = invalid, 1 = GPS fix (SPS),
%   2 = DGPS fix, 3 = PPS fix ,4 = Real Time Kinematic, 5 = Float RTK,
%   6 = estimated (dead reckoning) (2.3 feature), 7 = Manual input mode, and
% 	8 = Simulation mode.
%
%   [TK,PLH,FQ,NSAT,HDOP,DGPST,DGPSID]=NMEAGPGGA(STR) in addition returns  
%   the latency of the DGPS corrections DGPST and the DGPS station ID DGPSID.
%
%   See also NMEACHECKSUM and NMEAREAD.
%
%   Copyright 2010, TU Delft, DEOS.

%   Created:    4 March 2010 by Hans van der Marel
%   Modified:   

% Initialize output

tk=NaN;plh=[NaN NaN NaN];fq=NaN;nsat=NaN;hdop=NaN;dgpst=NaN;dgpsid=NaN;

% check the message type

if ~strcmp(str(1:6),'$GPGGA')
   disp('Warning NMEAGPGGA: Incorrect message type');
   return
end

% check the checksum

[ok,str]=nmeachecksum(str);
if ok ~= 1
   disp('Warning NMEAGPGGA: Checksum error');
   return
end

% parse the message contents

cdatas=textscan(str,'%s','delimiter',',');
cdata=cdatas{1};                             % don't know why this is needed ;-)

% GGA - essential fix data which provide 3D location and accuracy data.
% 
%  $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
% 
% Where:
%      GGA          Global Positioning System Fix Data
%      123519       Fix taken at 12:35:19 UTC
%      4807.038,N   Latitude 48 deg 07.038' N
%      01131.000,E  Longitude 11 deg 31.000' E
%      1            Fix quality: 0 = invalid
%                                1 = GPS fix (SPS)
%                                2 = DGPS fix
%                                3 = PPS fix
% 			       4 = Real Time Kinematic
% 			       5 = Float RTK
%                                6 = estimated (dead reckoning) (2.3 feature)
% 			       7 = Manual input mode
% 			       8 = Simulation mode
%      08           Number of satellites being tracked
%      0.9          Horizontal dilution of position
%      545.4,M      Altitude, Meters, above mean sea level
%      46.9,M       Height of geoid (mean sea level) above WGS84
%                       ellipsoid
%      (empty field) time in seconds since last DGPS update
%      (empty field) DGPS station ID number
%      *47          the checksum data, always begins with *
% 
% If the height of geoid is missing then the altitude should be suspect. Some 
% non-standard implementations report altitude with respect to the ellipsoid 
% rather than geoid altitude. Some units do not report negative altitudes at all. 
% This is the only sentence that reports altitude. 

% decode the time (in seconds)

hms=sscanf(cdata{2},'%2d%2d%f');
tk=hms(1)*3600+hms(2)*60+hms(3);

% decode the latitude and longitude in decimal degrees

tmp=sscanf(cdata{3},'%f');
lat=floor(tmp/100);
lat=lat+(tmp-lat*100)/60;
if strcmp(cdata{4},'S')
  lat=-1*lat;
end
lat=pi*lat/180;

tmp=sscanf(cdata{5},'%f');
lon=floor(tmp/100);
lon=lon+(tmp-lon*100)/60;
if strcmp(cdata{6},'W')
  lon=-1*lon;
end
lon=pi*lon/180;

% decode the fix quality, number of satellites and HDOP

fq=sscanf(cdata{7},'%d');
nsat=sscanf(cdata{8},'%d');
hdop=sscanf(cdata{9},'%f');

% decode the height above MSL and geoid height

hmsl=sscanf(cdata{10},'%f');
if ~strcmp(cdata{11},'M')
   disp('Warning NMEAGPGGA: Incorrect units for MSL height');
end
N=sscanf(cdata{12},'%f');
if ~strcmp(cdata{13},'M')
   disp('Warning NMEAGPGGA: Incorrect units for geoid height');
end
hell=N+hmsl;

% decode DGPS latency and station id

dgpst=sscanf(cdata{14},'%f');
dgpsid=cdata{15};

% store lattitude, longitude and height together in an array 

plh=[lat lon hell];

return
