gpsd
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.
How to run it
Run with: cargo run --release -- -D 3 -N -s 4800 /dev/ttyUSB0 (use your device and speed though)
The -D 3 specifies debugging level messages, which include device open and
close messages. If you just want info level, you can leave this off.
Current state
Currently it does just enough to make opencpn happy reading from it.
- 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.
As it turns out, though, nowait is the default in most distros.
So maybe this isn't so bad.
- There's no working auto speed detection for serial devices yet, so
you must specify a speed on the command line.
Hotlist of things to do next:
- Baudrate detection.
- Read NMEA 2000 messages and translate them to nmea 0183. In
particular, I'd like to generate AIS messages.
- Implement hotplug. This should actually be pretty easy once baud rate
detection is done.
Low priority stuff:
- SIRF devices aren't supported, but detection of them is implemented
- No support for json messages as expected by cgps and othere
- No support for polling
- No detection of GPS devices
- PPS devices aren't supported
- Several obscure devices aren't supported (Garmin TXT mode for example)
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.
Timing info
So I can't even get more than a second of CPU after running for a few hours now.
Compared to gpsd, which took about 1 minute of CPU every hour, I'm very
happy wih the performance. Timings, on my Dell i5, YMMV.