To get the Explorer project off the ground, I decided to buy a GPS module, hook it up to an Arduino and shed some light on how these modules work. As soon as I had it all hooked up, my screen was flooded with strings similar to these:

These are NMEA 0183 strings. They are used by a lot of marine electronic systems for positioning and timing data. These are ASCII based "sentences" for serial communication, they are mean to have a one to many listener relationship.

As an example, a waypoint arrival alarm has the form:

$GPAAM,A,A,0.10,N,WPTNME*32

where: GP - Talker ID (GP for a GPS unit, GL for a GLONASS) AAM - Arrival alarm A - Arrival circle entered A - Perpendicular passed 0.10 - Circle radius N - Nautical miles WPTNME - Waypoint name *32 - Checksum data

Thus NMEAParser a C++ library for parsing NMEA sentences was born.

As one of the goals of the Explorer project is improving me C/C++ knowledge I decided to turn on Clang's -Weverything option. Doing so was an interesting experience, a lot of code I had written in the past had a lot of implicit conversion, weak tables, etc. It was a fun exercise to silence the warning, correcting the types and explicitly casting where needed. But since the project started it has almost always compiled with no warning after I turned off the following:

  • -Wno-c++98-compat
  • -Wno-c++98-compat-pedantic
  • -Wno-padded

Well, when compiling the library only. Warnings from the Google Test framework are pretty hideous (Warning: 2.5MB of warnings)

There is a C and a C++ API for the Library, parsing a message is as easy as:

const std::string RawMessage = "$GPDTM,W84,,0.0,N,0.0,E,0.0,W84*6F";

auto Parser = NMEAParser{};
auto Result = Parser.Parse(RawMessage);

In C it would look like:

const char *sentence = "$GPDTM,W84,,0.0,N,0.0,E,0.0,W84*6F";

HNMEAParser *Parser = HNMEAParser_Create();
NMEAMessage *Message = HNMEAParser_Parse(Parser, sentence);

On my MacBook Pro (Intel Core i5, 2.7 GHz) parsing 1 million GPDTM messages takes about 5.5s (5.5 microseconds per message). Since I don't really have a standard to compare this against, I am going say NMEAParser has reasonable performance.

Feel free to comment, review and criticise the library here or on GitHub. Ciao.

References:

  • https://en.wikipedia.org/wiki/NMEA_0183
  • http://www.gpsinformation.org/dale/nmea.htm
  • https://github.com/TinyROS/NMEAParser