This is a rewrite of the C-based gpsd, which is pretty central to navigation. I use it to read packets from my NMEA2000 device as well as read from a backup GPS device; especially important to me is the NMEA 2000 canbus to GPS and AIS messages that opencpn can understand.
As it turns out, the C gpsd NMEA2000 driver doesn't currently parse AIS messages and translate them. It only seems to support GPS messages and some heading information. Looks like there is code there, it just doesn't seem to work. Worse yet, every now and then, it just quits. Restarting gpsd resolves the issue. The code is stricky, so it's just easier to start over in a memory safe language.
Currently does just enough to make opencpn happy reading from it. There are still a lot of things to do: - The GPS device is opened and messages are forwarded to the channel, even if there are no subscribers. This is a waste of power. It shouldn't even open the GPS device until there is at least one listener, like what gpsd does, unless you specify nowait. - 'speed' is currently ignored; it's hardcoded as 4800 baud - There's no auto speed detection for serial devices - SIRF devices aren't supported - PPS devices aren't supported - Other devices aren't supported
Next up: Read NMEA 2000 messages and translate them to nmea 0183. In particular, I'd like to generate AIS messages.
Low priority stuff: - No support for json messages as expected by cgps and othere - No support for polling - No detection of GPS devices - No hotplug support
Run with: cargo run -- -D 3 -N /dev/ttyUSB0
(or whatever your device is)
There are a few things we are already doing better than gpsd did: - Connecting and then issuing some commands, but not actually getting any output, puts you on a 60 second timer for disconnection. This is more aggressive than gpsd, which seems to have some complex rules for whether to disconnect you or not. This might matter for clients that POLL, but if they aren't polling at least once per minute, they should probably disconnect and reconnect. - Received requests don't have to come all at once. To see this error in gpsd, telnet to it, send ?W then hit CTRL-D which pushes that packet out to gpsd, without a newline, resulting in an "invalid command" error. This implementation parses "commands" which mean that partial commands will just wait for their completion. - Rather than making so many system calls and delays to change the speed during auto baud rate detection, just close the device and reopen it at the new speed.
Timings, on my Dell i5, calculated by just running the service for a while while connected to opencpn, show about a 10% CPU improvement in the main loop, and about a 50% reduction in RSS. The single-threaded version seems to use more memory but less CPU:
| Service | Runtime | Elapsed CPU | CPU to elapsed time | VmRSS | | gpsd | 02:48:00 | 00:02:38 | 1.567% | 4488 kB | | rgpsd-mt | 02:42:00 | 00:02:19 | 1.43% | 2300 kB | | rgpsd-st | 00:10:00 | 00:00:07 | 1.19% | 3368 kB |