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.
GPS.cpp@4:d911d7c4e09d, 2016-02-15 (annotated)
- Committer:
- chris215
- Date:
- Mon Feb 15 05:26:36 2016 +0000
- Revision:
- 4:d911d7c4e09d
- Parent:
- 2:72ac4d7044a7
- Child:
- 5:8a73e34b3978
Added gps message reception timeout.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
chris215 | 0:0c1aa5906cef | 1 | #include "GPS.h" |
chris215 | 0:0c1aa5906cef | 2 | #include "GPSUtils.hpp" |
chris215 | 0:0c1aa5906cef | 3 | |
chris215 | 0:0c1aa5906cef | 4 | GPS::GPS(PinName tx, PinName rx) : RawSerial(tx, rx) |
chris215 | 0:0c1aa5906cef | 5 | { |
chris215 | 4:d911d7c4e09d | 6 | _gpsTimer.start(); |
chris215 | 4:d911d7c4e09d | 7 | _gpsTimer.reset(); |
chris215 | 2:72ac4d7044a7 | 8 | RxQueueSize=0; |
chris215 | 2:72ac4d7044a7 | 9 | RxQueueWriteIndex=0; |
chris215 | 2:72ac4d7044a7 | 10 | RxQueueReadIndex=0; |
chris215 | 1:fade122a76a8 | 11 | RawSerial::baud(115200); |
chris215 | 0:0c1aa5906cef | 12 | attach(this, &GPS::RxIrqHandler); |
chris215 | 0:0c1aa5906cef | 13 | } |
chris215 | 0:0c1aa5906cef | 14 | |
chris215 | 0:0c1aa5906cef | 15 | void GPS::SetBaud(int rate){ |
chris215 | 0:0c1aa5906cef | 16 | RawSerial::baud(rate); |
chris215 | 0:0c1aa5906cef | 17 | } |
chris215 | 0:0c1aa5906cef | 18 | |
chris215 | 0:0c1aa5906cef | 19 | void GPS::RxIrqHandler(void) |
chris215 | 0:0c1aa5906cef | 20 | { |
chris215 | 0:0c1aa5906cef | 21 | char in; |
chris215 | 0:0c1aa5906cef | 22 | while(RawSerial::readable()) |
chris215 | 0:0c1aa5906cef | 23 | { |
chris215 | 0:0c1aa5906cef | 24 | in = RawSerial::getc(); |
chris215 | 0:0c1aa5906cef | 25 | if(in == START_CHAR) |
chris215 | 0:0c1aa5906cef | 26 | { |
chris215 | 0:0c1aa5906cef | 27 | insertIndex = 0; |
chris215 | 0:0c1aa5906cef | 28 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = in; |
chris215 | 2:72ac4d7044a7 | 29 | RxMessageBuffer.MessageIsNew = 1; |
chris215 | 0:0c1aa5906cef | 30 | } |
chris215 | 0:0c1aa5906cef | 31 | else if(in == END_CHAR) |
chris215 | 0:0c1aa5906cef | 32 | { |
chris215 | 2:72ac4d7044a7 | 33 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = 0; |
chris215 | 2:72ac4d7044a7 | 34 | //identify GPS message |
chris215 | 2:72ac4d7044a7 | 35 | int GPSMessageType = IdentifyGPSMessage(RxMessageBuffer); |
chris215 | 2:72ac4d7044a7 | 36 | if(GPSMessageType > 0) |
chris215 | 2:72ac4d7044a7 | 37 | { |
chris215 | 2:72ac4d7044a7 | 38 | if(GPSMessageType == GPS_GPGGAR) |
chris215 | 2:72ac4d7044a7 | 39 | memcpy(&GPSGGAMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 40 | if(GPSMessageType == GPS_GPGSAR) |
chris215 | 2:72ac4d7044a7 | 41 | memcpy(&GPSGSAMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 42 | if(GPSMessageType == GPS_GPVTGR) |
chris215 | 2:72ac4d7044a7 | 43 | memcpy(&GPSVTGMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 44 | if(GPSMessageType == GPS_GPRMCR) |
chris215 | 2:72ac4d7044a7 | 45 | memcpy(&GPSRMCMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 46 | } |
chris215 | 0:0c1aa5906cef | 47 | } |
chris215 | 0:0c1aa5906cef | 48 | else |
chris215 | 0:0c1aa5906cef | 49 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = in; |
chris215 | 0:0c1aa5906cef | 50 | } |
chris215 | 0:0c1aa5906cef | 51 | } |
chris215 | 2:72ac4d7044a7 | 52 | void GPS::PumpGpsMessages(void) |
chris215 | 2:72ac4d7044a7 | 53 | { |
chris215 | 2:72ac4d7044a7 | 54 | if(GPSRMCMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 55 | { |
chris215 | 2:72ac4d7044a7 | 56 | GPSRMCMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 57 | DecodeMessage(GPSRMCMessage,info); |
chris215 | 4:d911d7c4e09d | 58 | _gpsTimer.reset(); |
chris215 | 2:72ac4d7044a7 | 59 | } |
chris215 | 2:72ac4d7044a7 | 60 | if(GPSGGAMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 61 | { |
chris215 | 2:72ac4d7044a7 | 62 | GPSGGAMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 63 | DecodeMessage(GPSGGAMessage,info); |
chris215 | 4:d911d7c4e09d | 64 | _gpsTimer.reset(); |
chris215 | 2:72ac4d7044a7 | 65 | } |
chris215 | 2:72ac4d7044a7 | 66 | if(GPSVTGMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 67 | { |
chris215 | 2:72ac4d7044a7 | 68 | GPSVTGMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 69 | DecodeMessage(GPSVTGMessage,info); |
chris215 | 4:d911d7c4e09d | 70 | _gpsTimer.reset(); |
chris215 | 2:72ac4d7044a7 | 71 | } |
chris215 | 2:72ac4d7044a7 | 72 | if(GPSGSAMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 73 | { |
chris215 | 2:72ac4d7044a7 | 74 | GPSGSAMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 75 | DecodeMessage(GPSGSAMessage,info); |
chris215 | 4:d911d7c4e09d | 76 | _gpsTimer.reset(); |
chris215 | 4:d911d7c4e09d | 77 | } |
chris215 | 4:d911d7c4e09d | 78 | |
chris215 | 4:d911d7c4e09d | 79 | if(_gpsTimer.read_ms() > 5000) |
chris215 | 4:d911d7c4e09d | 80 | { |
chris215 | 4:d911d7c4e09d | 81 | info.fix = 1; |
chris215 | 2:72ac4d7044a7 | 82 | } |
chris215 | 2:72ac4d7044a7 | 83 | } |
chris215 | 0:0c1aa5906cef | 84 | |
chris215 | 0:0c1aa5906cef | 85 | ECEFPoint GPS::ReadPositionECEF(void) |
chris215 | 0:0c1aa5906cef | 86 | { |
chris215 | 0:0c1aa5906cef | 87 | return GeoDesicToECEF(ReadDecGeodLoc()); |
chris215 | 0:0c1aa5906cef | 88 | } |
chris215 | 0:0c1aa5906cef | 89 | ECEFDistance GPS::DistanceBetweenTwoWP(ECEFPoint p1,ECEFPoint p2) |
chris215 | 0:0c1aa5906cef | 90 | { |
chris215 | 0:0c1aa5906cef | 91 | return DistanceBetweenTwoECEFPoints(p1,p2); |
chris215 | 0:0c1aa5906cef | 92 | } |
chris215 | 0:0c1aa5906cef | 93 | |
chris215 | 0:0c1aa5906cef | 94 | geodPoint GPS::ReadDecGeodLoc(void){ |
chris215 | 0:0c1aa5906cef | 95 | geodPoint newLoc; |
chris215 | 0:0c1aa5906cef | 96 | newLoc.latitude = nmea_to_dec(info.latitude,info.latLoc); |
chris215 | 0:0c1aa5906cef | 97 | newLoc.longitude = nmea_to_dec(info.longitude,info.lonLoc); |
chris215 | 0:0c1aa5906cef | 98 | newLoc.altitude = info.GPSAltitude; |
chris215 | 0:0c1aa5906cef | 99 | return newLoc; |
chris215 | 0:0c1aa5906cef | 100 | } |
chris215 | 0:0c1aa5906cef | 101 | |
chris215 | 0:0c1aa5906cef | 102 | geodPoint GPS::ReadRawGeodLoc(void){ |
chris215 | 0:0c1aa5906cef | 103 | geodPoint newLoc; |
chris215 | 0:0c1aa5906cef | 104 | newLoc.latitude = info.latitude; |
chris215 | 0:0c1aa5906cef | 105 | newLoc.longitude = info.longitude; |
chris215 | 0:0c1aa5906cef | 106 | newLoc.altitude = info.GPSAltitude; |
chris215 | 0:0c1aa5906cef | 107 | return newLoc; |
chris215 | 0:0c1aa5906cef | 108 | } |
chris215 | 0:0c1aa5906cef | 109 | |
chris215 | 0:0c1aa5906cef | 110 | |
chris215 | 0:0c1aa5906cef | 111 | bool GPS::FixIs3d(void){ |
chris215 | 0:0c1aa5906cef | 112 | return (info.fix == 3); |
chris215 | 0:0c1aa5906cef | 113 | } |
chris215 | 0:0c1aa5906cef | 114 | bool GPS::FixIs2d(void){ |
chris215 | 0:0c1aa5906cef | 115 | return (FixIs3d() || (info.fix == 2)); |
chris215 | 0:0c1aa5906cef | 116 | } |
chris215 | 0:0c1aa5906cef | 117 | bool GPS::GPSFixValid(void){ |
chris215 | 0:0c1aa5906cef | 118 | return (info.GPSStatus == 'A'); |
chris215 | 0:0c1aa5906cef | 119 | } |
chris215 | 0:0c1aa5906cef | 120 | |
chris215 | 0:0c1aa5906cef | 121 |