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@2:72ac4d7044a7, 2016-02-14 (annotated)
- Committer:
- chris215
- Date:
- Sun Feb 14 05:55:38 2016 +0000
- Revision:
- 2:72ac4d7044a7
- Parent:
- 1:fade122a76a8
- Child:
- 4:d911d7c4e09d
Modified librairy to increase performance. Reduced interrupt overhead by removing most of the nema parsing.
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 | 2:72ac4d7044a7 | 6 | RxQueueSize=0; |
chris215 | 2:72ac4d7044a7 | 7 | RxQueueWriteIndex=0; |
chris215 | 2:72ac4d7044a7 | 8 | RxQueueReadIndex=0; |
chris215 | 1:fade122a76a8 | 9 | RawSerial::baud(115200); |
chris215 | 0:0c1aa5906cef | 10 | attach(this, &GPS::RxIrqHandler); |
chris215 | 0:0c1aa5906cef | 11 | } |
chris215 | 0:0c1aa5906cef | 12 | |
chris215 | 0:0c1aa5906cef | 13 | void GPS::SetBaud(int rate){ |
chris215 | 0:0c1aa5906cef | 14 | RawSerial::baud(rate); |
chris215 | 0:0c1aa5906cef | 15 | } |
chris215 | 0:0c1aa5906cef | 16 | |
chris215 | 0:0c1aa5906cef | 17 | void GPS::RxIrqHandler(void) |
chris215 | 0:0c1aa5906cef | 18 | { |
chris215 | 0:0c1aa5906cef | 19 | char in; |
chris215 | 0:0c1aa5906cef | 20 | while(RawSerial::readable()) |
chris215 | 0:0c1aa5906cef | 21 | { |
chris215 | 0:0c1aa5906cef | 22 | in = RawSerial::getc(); |
chris215 | 0:0c1aa5906cef | 23 | if(in == START_CHAR) |
chris215 | 0:0c1aa5906cef | 24 | { |
chris215 | 0:0c1aa5906cef | 25 | insertIndex = 0; |
chris215 | 0:0c1aa5906cef | 26 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = in; |
chris215 | 2:72ac4d7044a7 | 27 | RxMessageBuffer.MessageIsNew = 1; |
chris215 | 0:0c1aa5906cef | 28 | } |
chris215 | 0:0c1aa5906cef | 29 | else if(in == END_CHAR) |
chris215 | 0:0c1aa5906cef | 30 | { |
chris215 | 2:72ac4d7044a7 | 31 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = 0; |
chris215 | 2:72ac4d7044a7 | 32 | //identify GPS message |
chris215 | 2:72ac4d7044a7 | 33 | int GPSMessageType = IdentifyGPSMessage(RxMessageBuffer); |
chris215 | 2:72ac4d7044a7 | 34 | if(GPSMessageType > 0) |
chris215 | 2:72ac4d7044a7 | 35 | { |
chris215 | 2:72ac4d7044a7 | 36 | if(GPSMessageType == GPS_GPGGAR) |
chris215 | 2:72ac4d7044a7 | 37 | memcpy(&GPSGGAMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 38 | if(GPSMessageType == GPS_GPGSAR) |
chris215 | 2:72ac4d7044a7 | 39 | memcpy(&GPSGSAMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 40 | if(GPSMessageType == GPS_GPVTGR) |
chris215 | 2:72ac4d7044a7 | 41 | memcpy(&GPSVTGMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 42 | if(GPSMessageType == GPS_GPRMCR) |
chris215 | 2:72ac4d7044a7 | 43 | memcpy(&GPSRMCMessage,&RxMessageBuffer,sizeof(message)); |
chris215 | 2:72ac4d7044a7 | 44 | } |
chris215 | 0:0c1aa5906cef | 45 | } |
chris215 | 0:0c1aa5906cef | 46 | else |
chris215 | 0:0c1aa5906cef | 47 | RxMessageBuffer.data[(insertIndex++)%RX_BUFFER_SIZE] = in; |
chris215 | 0:0c1aa5906cef | 48 | } |
chris215 | 0:0c1aa5906cef | 49 | } |
chris215 | 2:72ac4d7044a7 | 50 | void GPS::PumpGpsMessages(void) |
chris215 | 2:72ac4d7044a7 | 51 | { |
chris215 | 2:72ac4d7044a7 | 52 | if(GPSRMCMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 53 | { |
chris215 | 2:72ac4d7044a7 | 54 | GPSRMCMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 55 | DecodeMessage(GPSRMCMessage,info); |
chris215 | 2:72ac4d7044a7 | 56 | } |
chris215 | 2:72ac4d7044a7 | 57 | if(GPSGGAMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 58 | { |
chris215 | 2:72ac4d7044a7 | 59 | GPSGGAMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 60 | DecodeMessage(GPSGGAMessage,info); |
chris215 | 2:72ac4d7044a7 | 61 | } |
chris215 | 2:72ac4d7044a7 | 62 | if(GPSVTGMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 63 | { |
chris215 | 2:72ac4d7044a7 | 64 | GPSVTGMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 65 | DecodeMessage(GPSVTGMessage,info); |
chris215 | 2:72ac4d7044a7 | 66 | } |
chris215 | 2:72ac4d7044a7 | 67 | if(GPSGSAMessage.MessageIsNew > 0) |
chris215 | 2:72ac4d7044a7 | 68 | { |
chris215 | 2:72ac4d7044a7 | 69 | GPSGSAMessage.MessageIsNew = 0; |
chris215 | 2:72ac4d7044a7 | 70 | DecodeMessage(GPSGSAMessage,info); |
chris215 | 2:72ac4d7044a7 | 71 | } |
chris215 | 2:72ac4d7044a7 | 72 | } |
chris215 | 0:0c1aa5906cef | 73 | |
chris215 | 0:0c1aa5906cef | 74 | ECEFPoint GPS::ReadPositionECEF(void) |
chris215 | 0:0c1aa5906cef | 75 | { |
chris215 | 0:0c1aa5906cef | 76 | return GeoDesicToECEF(ReadDecGeodLoc()); |
chris215 | 0:0c1aa5906cef | 77 | } |
chris215 | 0:0c1aa5906cef | 78 | ECEFDistance GPS::DistanceBetweenTwoWP(ECEFPoint p1,ECEFPoint p2) |
chris215 | 0:0c1aa5906cef | 79 | { |
chris215 | 0:0c1aa5906cef | 80 | return DistanceBetweenTwoECEFPoints(p1,p2); |
chris215 | 0:0c1aa5906cef | 81 | } |
chris215 | 0:0c1aa5906cef | 82 | |
chris215 | 0:0c1aa5906cef | 83 | geodPoint GPS::ReadDecGeodLoc(void){ |
chris215 | 0:0c1aa5906cef | 84 | geodPoint newLoc; |
chris215 | 0:0c1aa5906cef | 85 | newLoc.latitude = nmea_to_dec(info.latitude,info.latLoc); |
chris215 | 0:0c1aa5906cef | 86 | newLoc.longitude = nmea_to_dec(info.longitude,info.lonLoc); |
chris215 | 0:0c1aa5906cef | 87 | newLoc.altitude = info.GPSAltitude; |
chris215 | 0:0c1aa5906cef | 88 | return newLoc; |
chris215 | 0:0c1aa5906cef | 89 | } |
chris215 | 0:0c1aa5906cef | 90 | |
chris215 | 0:0c1aa5906cef | 91 | geodPoint GPS::ReadRawGeodLoc(void){ |
chris215 | 0:0c1aa5906cef | 92 | geodPoint newLoc; |
chris215 | 0:0c1aa5906cef | 93 | newLoc.latitude = info.latitude; |
chris215 | 0:0c1aa5906cef | 94 | newLoc.longitude = info.longitude; |
chris215 | 0:0c1aa5906cef | 95 | newLoc.altitude = info.GPSAltitude; |
chris215 | 0:0c1aa5906cef | 96 | return newLoc; |
chris215 | 0:0c1aa5906cef | 97 | } |
chris215 | 0:0c1aa5906cef | 98 | |
chris215 | 0:0c1aa5906cef | 99 | |
chris215 | 0:0c1aa5906cef | 100 | bool GPS::FixIs3d(void){ |
chris215 | 0:0c1aa5906cef | 101 | return (info.fix == 3); |
chris215 | 0:0c1aa5906cef | 102 | } |
chris215 | 0:0c1aa5906cef | 103 | bool GPS::FixIs2d(void){ |
chris215 | 0:0c1aa5906cef | 104 | return (FixIs3d() || (info.fix == 2)); |
chris215 | 0:0c1aa5906cef | 105 | } |
chris215 | 0:0c1aa5906cef | 106 | bool GPS::GPSFixValid(void){ |
chris215 | 0:0c1aa5906cef | 107 | return (info.GPSStatus == 'A'); |
chris215 | 0:0c1aa5906cef | 108 | } |
chris215 | 0:0c1aa5906cef | 109 | |
chris215 | 0:0c1aa5906cef | 110 |