Mbed library to handle GPS data reception and parsing
Dependents: GPS_U-blox_NEO-6M_Code
Features
- All positionning parameters are contained into a global data structure.
- Automatic nema string parsing and data structure update.
- GSA,GGA,VTG and RMC
- Convert latitude and longitude to decimal value.
- Converts latittude,longitude and altitude to ECEF coordinates.
Planed developement
- Test library for RTOS use.
- Complete the nema parsing decoders (couple of parameters are not parsed yet and not present in the data structure).
- Add conversion tool to get ENU coordinates.
utils/GPSUtils.hpp@0:0c1aa5906cef, 2014-08-06 (annotated)
- Committer:
- chris215
- Date:
- Wed Aug 06 01:37:39 2014 +0000
- Revision:
- 0:0c1aa5906cef
- Child:
- 1:fade122a76a8
Renamed library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
chris215 | 0:0c1aa5906cef | 1 | #ifndef _GPSUTILS_H_ |
chris215 | 0:0c1aa5906cef | 2 | #define _GPSUTILS_H_ |
chris215 | 0:0c1aa5906cef | 3 | |
chris215 | 0:0c1aa5906cef | 4 | #include "mbedGPSDefs.h" |
chris215 | 0:0c1aa5906cef | 5 | #include "GPGGAdecoder.hpp" |
chris215 | 0:0c1aa5906cef | 6 | #include "GPVTGdecoder.hpp" |
chris215 | 0:0c1aa5906cef | 7 | #include "GPGSAdecoder.hpp" |
chris215 | 0:0c1aa5906cef | 8 | #include "GPRMCdecoder.hpp" |
chris215 | 0:0c1aa5906cef | 9 | #include "WGS84.h" |
chris215 | 0:0c1aa5906cef | 10 | |
chris215 | 0:0c1aa5906cef | 11 | #define PI 3.141592653589793238462643383279502884 |
chris215 | 0:0c1aa5906cef | 12 | #define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / PI)) |
chris215 | 0:0c1aa5906cef | 13 | #define DEGREES_TO_RADIANS ( PI / 180.0) |
chris215 | 0:0c1aa5906cef | 14 | #define WGS84_A 6378137.000 |
chris215 | 0:0c1aa5906cef | 15 | //298.257223563 |
chris215 | 0:0c1aa5906cef | 16 | #define WGS84_E 0.081819190842621 |
chris215 | 0:0c1aa5906cef | 17 | |
chris215 | 0:0c1aa5906cef | 18 | |
chris215 | 0:0c1aa5906cef | 19 | /* |
chris215 | 0:0c1aa5906cef | 20 | Source of information about nema sentences : |
chris215 | 0:0c1aa5906cef | 21 | http://www.gpsinformation.org/dale/nmea.htm |
chris215 | 0:0c1aa5906cef | 22 | */ |
chris215 | 0:0c1aa5906cef | 23 | void DecodeMessage(message& msg,GPSInfo& data) |
chris215 | 0:0c1aa5906cef | 24 | { |
chris215 | 0:0c1aa5906cef | 25 | |
chris215 | 0:0c1aa5906cef | 26 | if(strstr(msg.data,GPS_CMD_GPGGA)){ |
chris215 | 0:0c1aa5906cef | 27 | DecodeGPGGA(msg.data,data); |
chris215 | 0:0c1aa5906cef | 28 | } |
chris215 | 0:0c1aa5906cef | 29 | |
chris215 | 0:0c1aa5906cef | 30 | if(strstr(msg.data,GPS_CMD_GPVTG)){ |
chris215 | 0:0c1aa5906cef | 31 | DecodeGPVTG(msg.data,data); |
chris215 | 0:0c1aa5906cef | 32 | } |
chris215 | 0:0c1aa5906cef | 33 | |
chris215 | 0:0c1aa5906cef | 34 | if(strstr(msg.data,GPS_CMD_GPGSA)){ |
chris215 | 0:0c1aa5906cef | 35 | DecodeGPGSA(msg.data,data); |
chris215 | 0:0c1aa5906cef | 36 | } |
chris215 | 0:0c1aa5906cef | 37 | if(strstr(msg.data,GPS_CMD_GPRMC)){ |
chris215 | 0:0c1aa5906cef | 38 | DecodeGPRMC(msg.data,data); |
chris215 | 0:0c1aa5906cef | 39 | } |
chris215 | 0:0c1aa5906cef | 40 | } |
chris215 | 0:0c1aa5906cef | 41 | |
chris215 | 0:0c1aa5906cef | 42 | ECEFPoint GeoDesicToECEF(geodPoint p) |
chris215 | 0:0c1aa5906cef | 43 | { |
chris215 | 0:0c1aa5906cef | 44 | ECEFPoint newECEFpoint; |
chris215 | 0:0c1aa5906cef | 45 | double lat = 0.0; |
chris215 | 0:0c1aa5906cef | 46 | double lon = 0.0; |
chris215 | 0:0c1aa5906cef | 47 | lat = p.latitude; |
chris215 | 0:0c1aa5906cef | 48 | lon = p.longitude; |
chris215 | 0:0c1aa5906cef | 49 | |
chris215 | 0:0c1aa5906cef | 50 | double clat = cos(lat * DEGREES_TO_RADIANS); |
chris215 | 0:0c1aa5906cef | 51 | double slat = sin(lat * DEGREES_TO_RADIANS); |
chris215 | 0:0c1aa5906cef | 52 | double clon = cos(lon * DEGREES_TO_RADIANS); |
chris215 | 0:0c1aa5906cef | 53 | double slon = sin(lon * DEGREES_TO_RADIANS); |
chris215 | 0:0c1aa5906cef | 54 | |
chris215 | 0:0c1aa5906cef | 55 | double N = WGS84_A / sqrt(1.0 - WGS84_E * WGS84_E * slat * slat); |
chris215 | 0:0c1aa5906cef | 56 | |
chris215 | 0:0c1aa5906cef | 57 | newECEFpoint.x = (N + p.altitude) * clat * clon; |
chris215 | 0:0c1aa5906cef | 58 | newECEFpoint.y = (N + p.altitude) * clat * slon; |
chris215 | 0:0c1aa5906cef | 59 | newECEFpoint.z = (N * (1.0 - WGS84_E * WGS84_E) + p.altitude) * slat; |
chris215 | 0:0c1aa5906cef | 60 | |
chris215 | 0:0c1aa5906cef | 61 | return newECEFpoint; |
chris215 | 0:0c1aa5906cef | 62 | } |
chris215 | 0:0c1aa5906cef | 63 | |
chris215 | 0:0c1aa5906cef | 64 | ECEFDistance DistanceBetweenTwoECEFPoints(ECEFPoint p1, ECEFPoint p2) |
chris215 | 0:0c1aa5906cef | 65 | { |
chris215 | 0:0c1aa5906cef | 66 | ECEFDistance newDistance; |
chris215 | 0:0c1aa5906cef | 67 | newDistance.dx = p1.x-p2.x; |
chris215 | 0:0c1aa5906cef | 68 | newDistance.dy = p1.y-p2.y; |
chris215 | 0:0c1aa5906cef | 69 | newDistance.dz = p1.z-p2.z; |
chris215 | 0:0c1aa5906cef | 70 | newDistance.d = sqrt((newDistance.dx*newDistance.dx) + (newDistance.dy*newDistance.dy) + (newDistance.dz*newDistance.dz)); |
chris215 | 0:0c1aa5906cef | 71 | return newDistance; |
chris215 | 0:0c1aa5906cef | 72 | } |
chris215 | 0:0c1aa5906cef | 73 | |
chris215 | 0:0c1aa5906cef | 74 | float nmea_to_dec(double nema_coor, char nsew) { |
chris215 | 0:0c1aa5906cef | 75 | int degree = (int)(nema_coor/100); |
chris215 | 0:0c1aa5906cef | 76 | double minutes = nema_coor - degree*100; |
chris215 | 0:0c1aa5906cef | 77 | double dec_deg = minutes / 60; |
chris215 | 0:0c1aa5906cef | 78 | double decimal = degree + dec_deg; |
chris215 | 0:0c1aa5906cef | 79 | if (nsew == 'S' || nsew == 'W') { // return negative |
chris215 | 0:0c1aa5906cef | 80 | decimal *= -1; |
chris215 | 0:0c1aa5906cef | 81 | } |
chris215 | 0:0c1aa5906cef | 82 | return decimal; |
chris215 | 0:0c1aa5906cef | 83 | } |
chris215 | 0:0c1aa5906cef | 84 | #endif |