Collect and Parse GPS (NMEA0183) Data in R

May 11, 2010
By

(This article was first published on BioStatMatt » R, and kindly contributed to R-bloggers)

I recently wrote a serial connection for R-2.11.0 so that I can communicate with serial devices, for example an old Garmin eTrex Legend. This GPS device is able to output NMEA0183 sentences to a standard serial port (4800,8,1,N). I hooked up the device and used the serial connection to collect some data using some R commands similar to the following

> con <- serial("/dev/ttyUSB0", baudrate=4800L)
> testdata <- rawToChar(readBin(con, "raw", 10000))
> close(con)
> testdata
[1] "5801,W,1,04,2.1,57.7,M,-32.3,M,,*4E\r\n$GPGSA,A,2,
03,06,,16,23,,,,,,,,2.3,2.1,1.0*33\r\n$GPGSV,2,2,07,23,
...
E\r\n$GPBOD,,T,,M,,*47\r\n$GPVTG,0.0,T,7.2,M,0.0,N,0.0,
K*4B\r\n$PGR"

The particular NMEA0183 sentence I want begins with $GPRMC, the recommended minimum navigation information. This sentence includes UTC time and date, latitude, longitude, heading, ground speed and others. I’ve attached a copy of an unofficial description of the NMEA0183 protocol. I wrote the following two R functions to parse the $GPRMC sentences.

getGPRMC <- function(data) {
  ans <- list(rmc=NULL, rest=data)
  rxp <- "\\$GPRMC(,[^,]*){12}\\*[0-9,A-F]{2}\r\n"
  beg <- regexpr(rxp, data)
  if(beg == -1) return(ans)
  end <- beg + attr(beg, "match.length")
  sub <- substr(data, beg, end - 6)
  ans$rmc <- strsplit(sub, ",")[[1]]
  names(ans$rmc) <- c("id","utc","status","lat","N/S",
                      "long","E/W","knots","cog","date",
                      "mag","E/W","mode")
  ans$rest <- substr(data, end, nchar(data))
  return(ans)
}

getAllGPRMC <- function(data) {
  res <- getGPRMC(data)
  ans <- res$rmc
  while(!is.null(res$rmc)) {
    ans <- rbind(ans, res$rmc)
    res <- getGPRMC(res$rest)
  }
  return(ans)
}

The functions and test data may be found here NMEA0183Parse.R. The regular expression used to identify the $GPRMC sentence is somewhat rudimentary, I welcome any insights in this regard. Also, these functions may be easily modified to parse other NMEA0183 sentences. The following may be reproduced in R verbatim without any additional setup.

> source("http://biostatmatt.com/R/NMEA0183Parse.R")
> ls()
[1] "getAllGPRMC" "getGPRMC"    "testdata"
> getAllGPRMC(testdata)
    id       utc      status lat         N/S long         E/W knots cog
ans "$GPRMC" "230320" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    "$GPRMC" "230320" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    "$GPRMC" "230322" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    "$GPRMC" "230324" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    "$GPRMC" "230326" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    "$GPRMC" "230328" "A"    "3246.1080" "N" "07955.4646" "W" "0.0" "0.0"
    date     mag   E/W mode
ans "110510" "7.2" "W" "A"
    "110510" "7.2" "W" "A"
    "110510" "7.2" "W" "A"
    "110510" "7.2" "W" "A"
    "110510" "7.2" "W" "A"
    "110510" "7.2" "W" "A"

According to Google Maps, this location is (long/lat) is at the Charleston Battery Park, Charleston Battery Park.

To leave a comment for the author, please follow the link and comment on his blog: BioStatMatt » R.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Tags: , , ,

Comments are closed.