• Stars
    star
    243
  • Rank 160,261 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A NMEA parser and GPS utility library

GPS.js

NPM Package Build Status MIT license

GPS.js is an extensible parser for NMEA sentences, given by any common GPS receiver. The output is tried to be as high-level as possible to make it more useful than simply splitting the information. The aim is, that you don't have to understand NMEA, just plug in your receiver and you're ready to go.

Usage

The interface of GPS.js is as simple as the following few lines. You need to add an event-listener for the completion of the task and invoke the update method with a sentence you want to process. There are much more examples in the examples folder.

const gps = new GPS;

// Add an event listener on all protocols
gps.on('data', parsed => {
    console.log(parsed);
});

// Call the update routine directly with a NMEA sentence, which would
// come from the serial port or stream-reader normally
gps.update("$GPGGA,224900.000,4832.3762,N,00903.5393,E,1,04,7.8,498.6,M,48.0,M,,0000*5E");

It's also possible to add event-listeners only on one of the following protocols, by stating gps.on('GGA', ...) for example.

State

The real advantage over other NMEA implementations is, that the GPS information is interpreted and normalized. The most high-level API is the state object, which changes with every new event. You can use this information with:

gps.on('data', () => {
  console.log(gps.state);
});

Installation

Installing GPS.js is as easy as cloning this repo or use the following command:

npm install gps

Find the serial device

On Linux serial devices typically have names like /dev/ttyS1, on OSX /dev/tty.usbmodem1411 after installing a USB to serial driver and on Windows, you're probably fine by using the highest COM device you can find in the device manager. Please note that if you have multiple USB ports on your computer and use them randomly, you have to lookup the path/device again.

Register device on a BeagleBone

If you find yourself on a BeagleBone, the serial device must be registered manually. Luckily, this can be done within node quite easily using octalbonescript:

const obs = require('octalbonescript');
obs.serial.enable('/dev/ttyS1', () => {  
    console.log('serial device activated');
});

Examples

GPS.js comes with some examples, like drawing the current latitude and longitude to Google Maps, displaying a persistent state and displaying the parsed raw data. In some cases you have to adjust the serial path to your own GPS receiver to make it work.

Simple serial example

const SerialPort = require('serialport');
const GPS = require('gps');

const port = new SerialPort('/dev/tty.usbmodem11401', { // change path
  baudRate: 9600,
  parser: new SerialPort.parsers.Readline({
    delimiter: '\r\n'
  })
});

const gps = new GPS;

gps.on('data', data => {
  console.log(data, gps.state);
})

port.on('data', data => {
  gps.updatePartial(data);
})

Dashboard

Go into the folder examples/dashboard and start the server with

node server

After that you can open the browser and go to http://localhost:3000. The result should look like the following, which in principle is just a visualization of the state object gps.state

GPS TU Dresden

Google Maps

Go into the folder examples/maps and start the server with

node server

After that you can open the browser and go to http://localhost:3000 The result should look like

GPS Google Maps Dresden

Confluence

Confluence is a project, which tries to travel to and document all integer GPS coordinates. GPS.js can assist on that goal. Go into the examples folder and run:

node confluence

You should see something like the following, updating as you move around

You are at (48.53, 9.05951),
The closest confluence point (49, 9) is in 51.36 km.
You have to go 355.2° N

Set Time

On systems without a RTC - like Raspberry PI - you need to update the time yourself at runtime. If the device has an internet connection, it's quite easy to use an NTP server. An alternative for disconnected projects with access to a GPS receiver can be the high-precision time signal, sent by satellites. Go to the examples folder and run the following to update the time:

node set-date

Available Methods

update(line)

The update method is the most important function, it parses a NMEA sentence and forces the callbacks to trigger

updatePartial(chunk)

Will call update() when a full NMEA sentence has been arrived

on(event, callback)

Adds an event listener for a protocol to occur (see implemented protocols, simply use the name - upper case) or for all sentences with data. Because GPS.js should be more general, it doesn't inherit EventEmitter, but simply invokes the callback.

off(event)

Removes an event listener

Implemented Protocols

GGA - Fix information

Gets the data, you're most probably looking for: latitude and longitude

The parsed object will have the following attributes:

  • type: "GGA"
  • time: The time given as a JavaScript Date object
  • lat: The latitude
  • lon: The longitude
  • alt: The altitude
  • quality: Fix quality (either invalid, fix or diff)
  • satellites: Number of satellites being tracked
  • hdop: Horizontal dilution of precision
  • geoidal: Height of geoid in meters (mean sea level)
  • age: time in seconds since last DGPS update
  • stationID: DGPS station ID number
  • valid: Indicates if the checksum is okay

RMC - NMEAs own version of essential GPS data

Similar to GGA but gives also delivers the velocity

The parsed object will have the following attributes:

  • type: "RMC"
  • time: The time given as a JavaScript Date object
  • status: Status active or void
  • lat: The latitude
  • lon: The longitude
  • speed: Speed over the ground in km/h
  • track: Track angle in degrees
  • variation: Magnetic Variation
  • faa: The FAA mode, introduced with NMEA 2.3
  • valid: Indicates if the checksum is okay

GSA - Active satellites

The parsed object will have the following attributes:

GLL - Geographic Position - Latitude/Longitude

The parsed object will have the following attributes:

  • type: "GLL"
  • lat: The latitude
  • lon: The longitude
  • status: Status active or void
  • time: The time given as a JavaScript Date object
  • valid: Indicates if the checksum is okay

GSV - List of Satellites in view

GSV messages are paginated. msgNumber indicates the current page and msgsTotal is the total number of pages.

The parsed object will have the following attributes:

  • type: "GSV"
  • msgNumber: Current page
  • msgsTotal: Number of pages
  • satellites: Array of satellite objects with the following attributes:
    • prn: Satellite PRN number
    • elevation: Elevation in degrees
    • azimuth: Azimuth in degrees
    • snr: Signal to Noise Ratio (higher is better)
  • valid: Indicates if the checksum is okay

VTG - vector track and speed over ground

The parsed object will have the following attributes:

  • type: "VTG"
  • track: Track in degrees
  • speed: Speed over ground in km/h
  • faa: The FAA mode, introduced with NMEA 2.3
  • valid: Indicates if the checksum is okay

ZDA - UTC day, month, and year, and local time zone offset

The parsed object will have the following attributes:

  • type: "ZDA"
  • time: The time given as a JavaScript Date object

HDT - Heading

The parsed object will have the following attributes:

  • type: "HDT"
  • heading: Heading in degrees
  • trueNorth: Indicates heading relative to True North
  • valid: Indicates if the checksum is okay

GST - Position error statistics

The parsed object will have the following attributes:

  • type: "GST"
  • time: The time given as a JavaScript Date object
  • rms: RMS value of the pseudorange residuals; includes carrier phase residuals during periods of RTK (float) and RTK (fixed)
  • ellipseMajor: Error ellipse semi-major axis 1 sigma error, in meters
  • ellipseMinor: Error ellipse semi-minor axis 1 sigma error, in meters
  • ellipseOrientation: Error ellipse orientation, degrees from true north
  • latitudeError: Latitude 1 sigma error, in meters
  • longitudeError: Longitude 1 sigma error, in meters
  • heightError: Height 1 sigma error, in meters
  • valid: Indicates if the checksum is okay

GPS State

If the streaming API is not needed, but a solid state of the system, the gps.state object can be used. It has the following properties:

  • time: Current time
  • lat: Latitude
  • lon: Longitude
  • alt: Altitude
  • satsActive: Array of active satellites
  • speed: Speed over ground in km/h
  • track: Track in degrees
  • satsVisible: Array of all visible satellites

Adding new protocols is a matter of minutes. If you need a protocol which isn't implemented, I'm happy to see a pull request or a new ticket.

Troubleshooting

If you don't get valid position information after turning on the receiver, chances are high you simply have to wait as it takes some time to first fix.

Functions

GPS.js comes with a few static functions, which helps working with geo-coordinates.

GPS.Parse(line)

Parses a single line and returns the resulting object, in case the callback system isn't needed/wanted

GPS.Distance(latFrom, lonFrom, latTo, lonTo)

Calculates the distance between two geo-coordinates using Haversine formula

GPS.TotalDistance(points)

Calculates the length of a traveled route, given as an array of {lat: x, lon: y} point objects

GPS.Heading(latFrom, lonFrom, latTo, lonTo)

Calculates the angle from one coordinate to another. Heading is represented as windrose coordinates (N=0, E=90, S=189, W=270). The result can be used as the argument of angles compass() method:

const angles = require('angles');
console.log(angles.compass(GPS.Heading(50, 10, 51, 9))); // will return x ∈ { N, S, E, W, NE, ... }

Using GPS.js with the browser

The use cases should be rare to parse NMEA directly inside the browser, but it works too.

<script src="gps.js"></script>
<script>
   var gps = new GPS;
   gps.update('...');
</script>

Testing

If you plan to enhance the library, make sure you add test cases and all the previous tests are passing. You can test the library with

npm test

Copyright and licensing

Copyright (c) 2016-2022, Robert Eisele Dual licensed under the MIT or GPL Version 2 licenses.

More Repositories

1

jQuery-webcam

A webcam wrapper plugin for jQuery
ActionScript
515
star
2

Fraction.js

Fraction is a rational numbers library written in JavaScript
JavaScript
422
star
3

node-dhcp

A DHCP server and client written in pure JavaScript
JavaScript
292
star
4

PHP-Facedetect

A simple OpenCV wrapper for PHP to detect faces on images
C++
263
star
5

jQuery-Paging

Probably the most advanced jQuery pagination plugin, no really!
HTML
233
star
6

Complex.js

A complex numbers library
JavaScript
224
star
7

BitSet.js

An arbitrary size Bit-Vector implementation in JavaScript
JavaScript
217
star
8

jQuery-xcolor

An easy to use color manipulation plugin for jQuery
JavaScript
157
star
9

PHP

A PHP improvement
C
137
star
10

udf_infusion

A MySQL functionality enhancement UDF
Shell
136
star
11

Polynomial.js

A JavaScript library to work with polynomials
JavaScript
121
star
12

Quaternion.js

A JavaScript Quaternion library
JavaScript
115
star
13

Fritzing

My fritzing sketches
C++
63
star
14

node-gamecontroller

A node.js driver for several gamecontrollers
JavaScript
51
star
15

HTML5-Tetris

A HTML5 Tetris Implementation
JavaScript
45
star
16

HTML5-Experiments

My HTML5 Experiments
HTML
34
star
17

Trackball.js

A library to add a virtual Trackball to your DOM
JavaScript
34
star
18

Kalman.js

A JavaScript Kalman filter library
JavaScript
30
star
19

PHP-Daemon

PHP
30
star
20

Stewart

Inverse kinematics for Stewart Platforms written in JavaScript
JavaScript
25
star
21

Rectangles.js

Rectangles.js is a collection of functions to work with rectangles
JavaScript
20
star
22

Angles.js

Angles.js is a collection of functions to work with angles
JavaScript
17
star
23

PHP-Classes

A collection of PHP classes
PHP
15
star
24

PHP-Defcon

A global constant management library for PHP
C
14
star
25

JavaScript-Files

A collection of JavaScript files
JavaScript
11
star
26

Circle.js

A function collection for working with circles
JavaScript
11
star
27

node-dsh

A full featured JavaScript shell
JavaScript
9
star
28

PHP-IDNA

A libidn wrapper for PHP
C
5
star
29

PHP-Infusion

A PHP functionality enhancement library
C
5
star
30

PHP-Sysload

A simple sysload monitoring extension for PHP
C
3
star
31

mod_mysql_accesslog

A lighttpd module to log directly into MySQL
C
3
star
32

UnitFormat.js

A human readable unit formatting tool in JavaScript
JavaScript
2
star
33

jQuery-borderstyle

A handy jQuery plugin to manipulate the border stlye CSS attributes
JavaScript
1
star