Collect and Parse GPS (NMEA0183) Data in R
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
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.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.