Generated: Tue Feb 2 17:54:41 2010 from gps01.pl 2005/06/27 6.8 KB.
#!/usr/bin/perl # nmea.perl # Convert generic NMEA output into something more spreadsheet-friendly. # Understands some Garmin-specific sentences. # # Note: we depend on the $GPRMC sentence appearing once in every # "data burst" from the GPS, preferably as the first sentence. # If this is not true for a particular GPS, the code that calls # output() must be moved to a more appropriate place. # # Dave Martindale, May 2000 # $maxtrack = 12; $dbgon = 1; # 0 for runtime if ($dbgon == 1) { $infile = 'gps01.txt'; $outfile = 'tempgps1.csv'; } else { $infile = shift or die "No input file given ...\n"; $outfile = shift or die "No output file given ...\n"; } ###$infile = "<-"; ###$outfile = ">-"; ###open (INFILE, $infile) or die "couldn't open input file $infile\n"; ###open (OUTFILE, $outfile) or die "couldn't open output file $outfile\n"; open (INFILE, "<$infile") or die "couldn't open input file $infile\n"; open (OUTFILE, ">$outfile") or die "couldn't open output file $outfile\n"; print OUTFILE "GPRMC,,,,,,,,"; print OUTFILE "GPGGA,,,,,,,,,,"; print OUTFILE "GPGSA,,,,,,,,,,,,,,,,,"; print OUTFILE "GPGSV,", "," x (4 * $maxtrack); print OUTFILE "GPVTG,,,,"; print OUTFILE "GPGLL,,,,"; print OUTFILE "PGRME,,,"; print OUTFILE "PGRMZ,,"; print OUTFILE "PGRMM"; print OUTFILE "\n"; print OUTFILE "Time,Valid,Lat,Long,SOG,CMG,Date,MVar,"; # GPRMC print OUTFILE "Time,Lat,Long,Qual,Sats,HDOP,Alt,GeoH,DGPSAge,DGPSID,"; # GPGGA print OUTFILE "Auto,Dim,PRN,,,,,,,,,,,,PDOP,HDOP,VDOP,"; # GPGSA print OUTFILE "View,"; # GPGSV for ($sat = 1; $sat <= $maxtrack; $sat++) { print OUTFILE "PRN ", $sat, ",Elev,Azim,S/N,"; } print OUTFILE "CRS (T),CRS (M),SOG (Kt),SOG (km/h),"; # GPVTG print OUTFILE "Lat,Long,Time,Valid,"; # GPGLL print OUTFILE "HPE,VPE,SPE,"; # PGRME print OUTFILE "Alt,Dim,"; # PGRMZ print OUTFILE "Datum"; # PGRMM print OUTFILE "\n"; sub output { print OUTFILE $time_rmc, ',', $ok_rmc, ',', $lat_rmc, ',', $long_rmc, ',', $speed, ',', $cmg, ',', $date, ',', $mvar, ','; print OUTFILE $time_gga, ',', $lat_gga, ',', $long_gga, ',', $fixqual, ',', $nsat, ',', $hdop_gga, ',', $alt_gga, ',', $gheight, ',', $DGPS_age, ',', $DGPS_ID, ','; print OUTFILE $fixsel, ',', $fixdeg, ',', join(',', @satsused), ',', $pdop, ',', $hdop, ',', $vdop, ','; print OUTFILE $nsiv, ','; for ($sat = 0; $sat < $maxtrack; $sat++) { if ($sat < $nsiv) { print OUTFILE $prn[$sat], ',', $elev[$sat], ',', $azim[$sat], ',', $signal[$sat], ','; } else { print OUTFILE ",,,,"; } } print OUTFILE $crs_t, ',', $crs_m, ',', $sog_kt, ',', $sog_km, ','; print OUTFILE $lat_gll, ',', $long_gll, ',', $time_gll, ',', $ok_gll, ','; print OUTFILE $hpe, ',', $vpe, ',', $epe, ','; print OUTFILE $alt_rmz, ',', $alt_type, ','; print OUTFILE $datum; print OUTFILE "\n"; } sub latitude { my ($deg, $min) = unpack "a2a*", $_[0]; my $lat = $deg + $min / 60; $lat = - $lat if $_[1] =~ /[Ss]/; return $lat; } sub longitude { my ($deg, $min) = unpack "a3a*", $_[0]; my $long = $deg + $min / 60; $long = - $long if $_[1] =~ /[Ww]/; return $long; } $first = 1; while ($line = <INFILE>) { chomp($line); @field = split /[,*]/, $line; # split on comma, and * (checksum) SWITCH: { # recommended minimum specific GPS/Transit data if ($field[0] eq '$GPRMC') { # We don't know exactly what sentences to expect # from an arbitrary GPS, but we assume that RMC # will always be included. Each time we see this # sentence, print out the accumulated information # from the previous burst. output() unless ($first) ; $first = 0; # Now process the new RMC record $time_rmc = join ':', unpack "a2" x 3, $field[1]; $ok_rmc = $field[2]; $lat_rmc = latitude(@field[3..4]); $long_rmc = longitude(@field[5..6]); $speed = $field[7]; $cmg = $field[8]; $date = join '/', unpack "a2" x 3, $field[9]; $mvar = $field[10] . $field[11]; # field[12] is checksum last SWITCH; } # GPS fix data if ($field[0] eq '$GPGGA') { $time_gga = join ':', unpack "a2" x 3, $field[1]; $lat_gga = latitude(@field[2..3]); $long_gga = longitude(@field[4..5]); $fixqual = $field[6]; $nsat = $field[7]; $hdop_gga = $field[8]; $alt_gga = $field[9]; # $field[10] is altitude units (always M) $gheight = $field[11]; # $field[12] is geoid height units (always M) $DGPS_age = $field[13]; $DGPS_ID = $field[14]; # field[15] is checksum; last SWITCH; } # GPS DOP and active satellites if ($field[0] eq '$GPGSA') { $fixsel = $field[1]; # A for auto selection, M for manual $fixdeg = $field[2]; # 2 or 3 for 2D or 3D fix @satsused = @field[3..14]; $pdop = $field[15]; $hdop = $field[16]; $vdop = $field[17]; # field[18] is checksum; last SWITCH; } # satellites in view if ($field[0] eq '$GPGSV') { # $field[1] is total number of sentences for full data # $field[2] is current sentence number $nsiv = $field[3]; # # Unpack next 16 fields as PRN, elevation, azimuth, and # signal quality for next 4 satellites # $sat = ($field[2] - 1) * 4; $lim = $sat + 4; if ($nsiv < $lim) { $lim = $nsiv; } $f = 4; while ($sat < $lim) { $prn[$sat] = $field[$f++]; $elev[$sat] = $field[$f++]; $azim[$sat] = $field[$f++]; $sig = $field[$f++]; $sig = '' if $sig == 0; $signal[$sat] = $sig; $sat++; } # field[20] is checksum; last SWITCH; } # track/ground speed if ($field[0] eq '$GPVTG') { $crs_t = $field[1]; # $field[2] is reference (always T); $crs_m = $field[3]; # $field[4] is reference (always M); $sog_kt = $field[5]; # $field[6] is units (always N); $sog_km = $field[7]; # $field[8] is units (always K); # $field[9] is checksum; last SWITCH; } # position error info if ($field[0] eq '$PGRME') { $hpe = $field[1]; # $field[2] is units (always M) $vpe = $field[3]; # $field[4] is units (always M) $epe = $field[5]; # $field[6] is units (always M) # field[7] is checksum; last SWITCH; } # latitude/longitude if ($field[0] eq '$GPGLL') { $lat_gll = latitude(@field[1..2]); $long_gll = longitude(@field[3..4]); $time_gll = join ':', unpack "a2" x 3, $field[5]; $ok_gll = $field[6]; # field[7] is checksum; last SWITCH; } # altitude if ($field[0] eq '$PGRMZ') { $alt_rmz = $field[1]; # $field[2] is units (always F) $alt_type = $field[3]; # 2: user alt, 3: 3D fix # field[4] is checksum; last SWITCH; } # datum if ($field[0] eq '$PGRMM') { $datum = $field[1]; # field[2] is checksum; last SWITCH; } } } close INFILE; close OUTFILE; if ($dbgon == 1) { system($outfile) ### = 'tempgps1.csv'; } #eof