gps01.pl to HTML.

index -|- end

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

index -|- top

checked by tidy  Valid HTML 4.01 Transitional