#include <ArGPS.h>
Inheritance diagram for ArGPS:
Connects to GPS device over a serial port or other device connection and reads data. Supports GPS devices sending standard NMEA format data (specifically the GPRMC, GPGGA, GPGSA, GPGRME, and optionally GPGSV, PGRMZ, PGRME, and HCHDG/T/M messages). If your GPS device supports several data formats or modes, select NMEA output in its configuration.
The preferred method of creating and setting up a new ArGPS object is to use ArGPSConnector, which creates an instance of ArGPS or a subclass, and creates and opens its device connection, based on command-line parameters. (To manually create an ArGPS object, create an ArDeviceConnection instance and call setDeviceConnection(), then open that device connection and call connect().
For either method, to get new data from the GPS, must call read() or readWithLock() periodically, ideally at a rate equal to or faster than your GPS sends data (usually one second). You can do this from a Sensor Intetrpretation Task in ArRobot, or a seperate thread. If you are calling read() from a loop in a new thread,
Here is an example of calling readWithLock() from a sensor interpretation task. The integer argument given to the functor constructor is a milisecond timeout that is passed to readWithLock() and prevents it from blocking too long if it doesn't read any data. It is important to do this in a robot task, or the robot task cycle will be blocked and cause problems.
ArRetFunctor1C<ArGPS, int, unsigned int> gpsReadFunc(myGPS, &ArGPS::readWithLock, 10); myRobot->addSensorInterpretationTask("GPS read", 100, &gpsReadFunc);
If you use your own loop or thread, then it ought to include a call to ArUtil::sleep() for at least several hundred miliseconds to avoid starving other threads, since read() will return immediately if there is no data to read rather than blocking.
For each piece of data provided by this class, there is a flag indicating whether it was received from the GPS and set. Not all GPS models return all kinds of information, or it may be disabled in some way in a GPS's internal configuration, or the GPS may not yet have started sending the data (e.g. still acquiring satellites). Also, not all data will be received by one call to read(), and especially immediately after connecting and starting to read data, it may take a few seconds for data to be obtained. Furthermore, it may take some time for the GPS to calculate data with full accuracy.
gpsRobotTaskExample::cpp
enum | FixType { NoFix, BadFix, GPSFix, DGPSFix, PPSFix, RTKinFix, FloatRTKinFix, DeadReckFix, ManualFix, SimulatedFix, UnknownFixType, OmnistarConverging = FloatRTKinFix, OmnistarConverged = RTKinFix } |
Access the last received data from the GPS. More... | |
double | getCompassHeadingMag () const |
Heading from magnetic north. | |
double | getCompassHeadingTrue () const |
Heading from true north. | |
const ArGPS::Data & | getCurrentDataRef () const |
unsigned short | getDGPSStationID () const |
FixType | getFixType () const |
const char * | getFixTypeName () const |
double | getGarminPositionError () const |
double | getGarminVerticalPositionError () const |
GPS device's error estimation in meters. | |
ArTime | getGPSPositionTimestamp () const |
double | getLatitude () const |
double | getLongitude () const |
int | getNumSatellitesTracked () const |
double | getSpeed () const |
ArTime | getTimeReceivedPosition () const |
bool | haveCompassHeadingMag () const |
Have a compass heading value relative to magnetic north. | |
bool | haveCompassHeadingTrue () const |
Have a compass heading value relative to true north (using device's configured declination). | |
bool | haveDGPSStation () const |
bool | haveGarminPositionError () const |
bool | haveGarminVerticalPositionError () const |
bool | haveLatitude () const |
bool | haveLongitude () const |
bool | havePosition () const |
bool | haveSpeed () const |
void | setCompassHeadingMag (double val) |
void | setCompassHeadingMagWithLock (double val) |
void | setCompassHeadingTrue (double val) |
void | setCompassHeadingTrueWithLock (double val) |
static const char * | getFixTypeName (FixType type) |
Public Types | |
enum | { ReadFinished = ArNMEAParser::ParseFinished, ReadError = ArNMEAParser::ParseError, ReadData = ArNMEAParser::ParseData, ReadUpdated = ArNMEAParser::ParseUpdated } |
Flags to indicates what the read() method did. i.e. If nothing was done, then the result will be 0. To check a read() return result result to see if data was updated, use (result & ReadUpdated). To check if there was an error, use (result & ReadError). More... | |
Public Member Functions | |
void | addNMEAHandler (const char *message, ArNMEAParser::Handler *handler) |
bool | blockingConnect (unsigned long connectTimeout=10000) |
virtual bool | connect (unsigned long connectTimeout=10000) |
Check that the device connection (e.g. serial port) is open, and that data is being received from GPS. | |
double | getAltimeter () const |
double | getAltitude () const |
Calculated from GPS. | |
ArDeviceConnection * | getDeviceConnection () const |
Return device connection in use (or NULL if none). | |
double | getHDOP () const |
double | getMeanSNR () const |
dB | |
double | getPDOP () const |
double | getVDOP () const |
bool | haveAltimeter () const |
bool | haveAltitude () const |
Calculated from GPS. | |
bool | haveHDOP () const |
bool | havePDOP () const |
bool | haveSNR () const |
bool | haveVDOP () const |
void | lock () |
void | logData () const |
Log last received data using ArLog. | |
void | printData (bool labels=true) const |
void | printDataLabelsHeader () const |
virtual int | read (unsigned long maxTime=0) |
Read some data from the device connection, and update stored data as complete messages are received. | |
int | readWithLock (unsigned int maxTime) |
void | removeNMEAHandler (const char *message) |
void | setDeviceConnection (ArDeviceConnection *deviceConn) |
Set device connection to use. | |
void | setIgnoreChecksum (bool ignore) |
Set whether checksum sent with NMEA messages is ignored. | |
void | unlock () |
double | getAltitudeError () const |
Standard deviation of altitude error, meters. | |
double | getInputsRMS () const |
double | getLatitudeError () const |
ArPose | getLatLonError () const |
double | getLongitudeError () const |
bool | haveAltitudeError () const |
bool | haveInputsRMS () const |
bool | haveLatLonError () const |
unsigned short | getBeaconChannel () const |
double | getBeaconFreq () const |
kHz | |
double | getBeaconSignalStrength () const |
dB | |
double | getBeaconSNR () const |
dB | |
unsigned short | getBecaonBPS () const |
bitrate (bits per second) | |
bool | haveBeaconInfo () const |
ArPose | getErrorEllipse () const |
bool | haveErrorEllipse () const |
Public Attributes | |
enum ArGPS:: { ... } | ReadFlags |
Flags to indicates what the read() method did. i.e. If nothing was done, then the result will be 0. To check a read() return result result to see if data was updated, use (result & ReadUpdated). To check if there was an error, use (result & ReadError). | |
Protected Member Functions | |
void | handleGPGGA (ArNMEAParser::Message msg) |
void | handleGPGSA (ArNMEAParser::Message msg) |
void | handleGPGST (ArNMEAParser::Message msg) |
void | handleGPGSV (ArNMEAParser::Message msg) |
void | handleGPMSS (ArNMEAParser::Message msg) |
void | handleGPRMC (ArNMEAParser::Message msg) |
void | handleHCHDx (ArNMEAParser::Message msg) |
void | handlePGRME (ArNMEAParser::Message msg) |
void | handlePGRMZ (ArNMEAParser::Message msg) |
virtual bool | initDevice () |
bool | readFloatFromString (std::string &str, double *target, double(*convf)(double)=NULL) const |
bool | readFloatFromStringVec (std::vector< std::string > *vec, size_t i, double *target, double(*convf)(double)=NULL) const |
bool | readUShortFromString (std::string &str, unsigned short *target, unsigned short(*convf)(unsigned short)=NULL) const |
bool | readUShortFromStringVec (std::vector< std::string > *vec, size_t i, unsigned short *target, unsigned short(*convf)(unsigned short)=NULL) const |
bool | waitForData (unsigned long timeout) |
Static Protected Member Functions | |
static double | feetToMeters (double f) |
static double | gpsDegminToDegrees (double degmin) |
static double | knotsToMPS (double knots) |
static double | metersToFeet (double m) |
static double | mpsToMph (double mps) |
Protected Attributes | |
ArArgumentParser * | myArgParser |
bool | myCreatedOwnDeviceCon |
Data | myData |
ArDeviceConnection * | myDevice |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPGGAHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPGSAHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPGSTHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPGSVHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPMSSHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myGPRMCHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myHCHDxHandler |
ArMutex | myMutex |
ArNMEAParser | myNMEAParser |
ArRetFunctorC< bool, ArGPS > | myParseArgsCallback |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myPGRMEHandler |
ArFunctor1C< ArGPS, ArNMEAParser::Message > | myPGRMZHandler |
unsigned short | mySNRNum |
unsigned int | mySNRSum |
anonymous enum |
Flags to indicates what the read() method did. i.e. If nothing was done, then the result will be 0. To check a read() return result result to see if data was updated, use (result & ReadUpdated). To check if there was an error, use (result & ReadError).
These happen to match the flags in ArNMEAParser.
enum ArGPS::FixType |
Access the last received data from the GPS.
Data accessors
void ArGPS::addNMEAHandler | ( | const char * | message, | |
ArNMEAParser::Handler * | handler | |||
) | [inline] |
Set a handler for an NMEA message. Mostly for internal use or to be used by related classes, but you could use for ususual or custom messages emitted by a device that you wish to be handled outside of the ArGPS class.
bool ArGPS::blockingConnect | ( | unsigned long | connectTimeout = 10000 |
) | [inline] |
virtual bool ArGPS::connect | ( | unsigned long | connectTimeout = 10000 |
) | [virtual] |
Check that the device connection (e.g. serial port) is open, and that data is being received from GPS.
Subclasses may override this method so that device-specific initialization commands may be sent.
double ArGPS::getGarminPositionError | ( | ) | const [inline] |
GPS device's error estimation in meters
double ArGPS::getLatitude | ( | ) | const [inline] |
double ArGPS::getLongitude | ( | ) | const [inline] |
double ArGPS::getSpeed | ( | ) | const [inline] |
ArTime ArGPS::getTimeReceivedPosition | ( | ) | const [inline] |
bool ArGPS::haveBeaconInfo | ( | ) | const [inline] |
DGPS stationary beacon info
bool ArGPS::haveErrorEllipse | ( | ) | const [inline] |
Standard deviation of position error, meters. Theta in ArPose is orientation of ellipse from true north, Y is the length of the major axis on that orientation, X the minor.
bool ArGPS::haveGarminPositionError | ( | ) | const [inline] |
bool ArGPS::haveGarminVerticalPositionError | ( | ) | const [inline] |
bool ArGPS::haveLatLonError | ( | ) | const [inline] |
Standard deviation of latitude and longitude error, meters. Theta value in ArPose is unused.
Values may be inf or NaN (if GPS supplies "Inf" or "NAN")
virtual bool ArGPS::initDevice | ( | ) | [inline, protected, virtual] |
Subclasses may override to send device initialization/configuration commands and set up device-specific message handlers. (Default behavior is to do nothing and return true.)
void ArGPS::lock | ( | ) | [inline] |
Locks a mutex object contained by this class. No other method (except readWithLock()) in ArGPS locks or unlocks this mutex, it is provided for you to use when accessing ArGPS from multiple threads.
void ArGPS::printData | ( | bool | labels = true |
) | const |
Print basic navigation data on one line to standard output, with no newline at end.
virtual int ArGPS::read | ( | unsigned long | maxTime = 0 |
) | [virtual] |
Read some data from the device connection, and update stored data as complete messages are received.
maxTime | If nonzero, return when this time limit is reached, even if there is still data available to read. If zero, then don't return until all available data has been exhausted or an error occurs. Be careful setting this parameter to 0: read() could block for an arbitrary amount of time, even forever if for some reason data is recieved from the device faster than read() can read and parse it. |
int ArGPS::readWithLock | ( | unsigned int | maxTime | ) | [inline] |
void ArGPS::setCompassHeadingMag | ( | double | val | ) | [inline] |
Manually set compass values.
void ArGPS::unlock | ( | ) | [inline] |
Unlocks a mutex object contained by this class. No other method (except readWithLock()) in ArGPS locks or unlocks this mutex, it is provided for you to use when accessing ArGPS from multiple threads.
bool ArGPS::waitForData | ( | unsigned long | timeout | ) | [protected] |
Block until data is read from GPS. Waits by calling read() every 100 ms for timeout ms.
enum { ... } ArGPS::ReadFlags |
Flags to indicates what the read() method did. i.e. If nothing was done, then the result will be 0. To check a read() return result result to see if data was updated, use (result & ReadUpdated). To check if there was an error, use (result & ReadError).
These happen to match the flags in ArNMEAParser.