2010-09-06 06:20:44 -03:00
|
|
|
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*-
|
|
|
|
|
|
|
|
/// @file GPS.h
|
|
|
|
/// @brief Interface definition for the various GPS drivers.
|
|
|
|
|
2010-08-29 19:58:22 -03:00
|
|
|
#ifndef GPS_h
|
|
|
|
#define GPS_h
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
2010-09-06 06:20:44 -03:00
|
|
|
#include <Stream.h>
|
2010-08-29 19:58:22 -03:00
|
|
|
|
2010-09-06 06:20:44 -03:00
|
|
|
/// @class GPS
|
|
|
|
/// @brief Abstract base class for GPS receiver drivers.
|
2010-08-29 19:58:22 -03:00
|
|
|
class GPS
|
|
|
|
{
|
2010-09-06 06:20:44 -03:00
|
|
|
public:
|
|
|
|
|
|
|
|
/// Update GPS state based on possible bytes received from the module.
|
|
|
|
///
|
|
|
|
/// This routine must be called periodically to process incoming data.
|
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
/// GPS drivers should not override this function; they should implement
|
|
|
|
/// ::read instead.
|
2010-10-17 17:13:53 -03:00
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
void update(void);
|
2010-12-19 09:24:29 -04:00
|
|
|
|
2010-12-24 02:35:09 -04:00
|
|
|
/// GPS status codes
|
|
|
|
///
|
|
|
|
/// \note Non-intuitive ordering for legacy reasons
|
|
|
|
///
|
|
|
|
enum GPS_Status {
|
2011-01-09 20:44:09 -04:00
|
|
|
NO_GPS = 0, ///< No GPS connected/detected
|
|
|
|
NO_FIX = 1, ///< Receiving valid GPS messages but no lock
|
2010-12-24 02:35:09 -04:00
|
|
|
GPS_OK = 2 ///< Receiving valid messages and locked
|
|
|
|
};
|
2010-08-29 19:58:22 -03:00
|
|
|
|
2010-10-17 17:13:53 -03:00
|
|
|
/// Query GPS status
|
|
|
|
///
|
|
|
|
/// The 'valid message' status indicates that a recognised message was
|
|
|
|
/// received from the GPS within the last 500ms.
|
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
/// @returns Current GPS status
|
|
|
|
///
|
|
|
|
GPS_Status status(void) { return _status; }
|
|
|
|
|
2011-02-01 19:50:36 -04:00
|
|
|
/// GPS time epoch codes
|
|
|
|
///
|
|
|
|
enum GPS_Time_Epoch {
|
2011-06-16 13:33:08 -03:00
|
|
|
TIME_OF_DAY = 0, ///<
|
2011-02-01 19:50:36 -04:00
|
|
|
TIME_OF_WEEK = 1, ///< Ublox
|
|
|
|
TIME_OF_YEAR = 2, ///< MTK, NMEA
|
|
|
|
UNIX_EPOCH = 3 ///< If available
|
2011-06-16 13:33:08 -03:00
|
|
|
}; ///< SIFR?
|
|
|
|
|
2011-02-01 19:50:36 -04:00
|
|
|
|
|
|
|
/// Query GPS time epoch
|
|
|
|
///
|
|
|
|
/// @returns Current GPS time epoch code
|
|
|
|
///
|
|
|
|
GPS_Time_Epoch epoch(void) { return _epoch; }
|
|
|
|
|
2010-12-24 02:35:09 -04:00
|
|
|
/// Startup initialisation.
|
|
|
|
///
|
|
|
|
/// This routine performs any one-off initialisation required to set the
|
|
|
|
/// GPS up for use.
|
2010-10-17 17:13:53 -03:00
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
/// Must be implemented by the GPS driver.
|
2010-10-17 17:13:53 -03:00
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
virtual void init(void) = 0;
|
2010-10-17 17:13:53 -03:00
|
|
|
|
2010-08-29 19:58:22 -03:00
|
|
|
// Properties
|
2011-02-01 19:50:36 -04:00
|
|
|
long time; ///< GPS time (milliseconds from epoch)
|
2011-01-09 20:44:09 -04:00
|
|
|
long date; ///< GPS date (FORMAT TBD)
|
2010-09-06 06:20:44 -03:00
|
|
|
long latitude; ///< latitude in degrees * 10,000,000
|
|
|
|
long longitude; ///< longitude in degrees * 10,000,000
|
|
|
|
long altitude; ///< altitude in cm
|
|
|
|
long ground_speed; ///< ground speed in cm/sec
|
|
|
|
long ground_course; ///< ground course in 100ths of a degree
|
|
|
|
long speed_3d; ///< 3D speed in cm/sec (not always available)
|
2010-12-24 02:35:09 -04:00
|
|
|
int hdop; ///< horizontal dilution of precision in cm
|
2010-09-06 06:20:44 -03:00
|
|
|
uint8_t num_sats; ///< Number of visible satelites
|
2010-10-17 17:13:53 -03:00
|
|
|
|
2010-09-06 06:20:44 -03:00
|
|
|
/// Set to true when new data arrives. A client may set this
|
|
|
|
/// to false in order to avoid processing data they have
|
|
|
|
/// already seen.
|
|
|
|
bool new_data;
|
2010-10-17 01:07:46 -03:00
|
|
|
|
2010-10-17 17:13:53 -03:00
|
|
|
// Deprecated properties
|
|
|
|
bool fix; ///< true if we have a position fix (use ::status instead)
|
|
|
|
bool valid_read; ///< true if we have seen data from the GPS (use ::status instead)
|
2010-09-06 06:20:44 -03:00
|
|
|
|
2010-10-17 17:13:53 -03:00
|
|
|
// Debug support
|
2010-11-27 04:46:41 -04:00
|
|
|
bool print_errors; ///< deprecated
|
2011-06-16 13:33:08 -03:00
|
|
|
|
2011-02-16 14:19:07 -04:00
|
|
|
// HIL support
|
|
|
|
virtual void setHIL(long time, float latitude, float longitude, float altitude,
|
|
|
|
float ground_speed, float ground_course, float speed_3d, uint8_t num_sats);
|
2010-09-06 06:20:44 -03:00
|
|
|
|
2011-06-20 22:38:31 -03:00
|
|
|
/// Time in milliseconds after which we will assume the GPS is no longer
|
|
|
|
/// sending us updates and attempt a re-init.
|
|
|
|
///
|
|
|
|
/// 1200ms allows a small amount of slack over the worst-case 1Hz update
|
|
|
|
/// rate.
|
|
|
|
///
|
|
|
|
unsigned long idleTimeout;
|
|
|
|
|
2010-09-06 06:20:44 -03:00
|
|
|
protected:
|
2010-12-24 02:35:09 -04:00
|
|
|
Stream *_port; ///< port the GPS is attached to
|
2010-10-17 17:13:53 -03:00
|
|
|
|
2010-12-28 23:32:37 -04:00
|
|
|
/// Constructor
|
|
|
|
///
|
|
|
|
/// @note The stream is expected to be set up and configured for the
|
|
|
|
/// correct bitrate before ::init is called.
|
|
|
|
///
|
2011-01-09 20:44:09 -04:00
|
|
|
/// @param s Stream connected to the GPS module.
|
2010-12-28 23:32:37 -04:00
|
|
|
///
|
|
|
|
GPS(Stream *s) : _port(s) {};
|
|
|
|
|
2010-12-24 02:35:09 -04:00
|
|
|
/// read from the GPS stream and update properties
|
|
|
|
///
|
|
|
|
/// Must be implemented by the GPS driver.
|
2010-10-17 17:13:53 -03:00
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
/// @returns true if a valid message was received from the GPS
|
|
|
|
///
|
|
|
|
virtual bool read(void) = 0;
|
2010-09-06 06:20:44 -03:00
|
|
|
|
|
|
|
/// perform an endian swap on a long
|
|
|
|
///
|
|
|
|
/// @param bytes pointer to a buffer containing bytes representing a
|
|
|
|
/// long in the wrong byte order
|
|
|
|
/// @returns endian-swapped value
|
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
long _swapl(const void *bytes);
|
2010-09-06 06:20:44 -03:00
|
|
|
|
|
|
|
/// perform an endian swap on an int
|
|
|
|
///
|
|
|
|
/// @param bytes pointer to a buffer containing bytes representing an
|
|
|
|
/// int in the wrong byte order
|
|
|
|
/// @returns endian-swapped value
|
2010-12-24 02:35:09 -04:00
|
|
|
int _swapi(const void *bytes);
|
2010-09-06 06:20:44 -03:00
|
|
|
|
|
|
|
/// emit an error message
|
|
|
|
///
|
|
|
|
/// based on the value of print_errors, emits the printf-formatted message
|
|
|
|
/// in msg,... to stderr
|
|
|
|
///
|
|
|
|
/// @param fmt printf-like format string
|
|
|
|
///
|
2010-11-27 04:46:41 -04:00
|
|
|
/// @note deprecated as-is due to the difficulty of hooking up to a working
|
|
|
|
/// printf vs. the potential benefits
|
|
|
|
///
|
2010-12-24 02:35:09 -04:00
|
|
|
void _error(const char *msg);
|
2011-06-16 13:33:08 -03:00
|
|
|
|
2011-02-01 19:50:36 -04:00
|
|
|
/// Time epoch code for the gps in use
|
|
|
|
GPS_Time_Epoch _epoch;
|
2010-12-24 02:35:09 -04:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
|
|
/// Last time that the GPS driver got a good packet from the GPS
|
|
|
|
///
|
|
|
|
unsigned long _idleTimer;
|
|
|
|
|
|
|
|
/// Our current status
|
|
|
|
GPS_Status _status;
|
2011-06-16 13:33:08 -03:00
|
|
|
|
2010-08-29 19:58:22 -03:00
|
|
|
};
|
|
|
|
|
2010-09-06 06:20:44 -03:00
|
|
|
inline long
|
2010-09-06 17:00:57 -03:00
|
|
|
GPS::_swapl(const void *bytes)
|
2010-09-06 06:20:44 -03:00
|
|
|
{
|
2010-09-06 17:00:57 -03:00
|
|
|
const uint8_t *b = (const uint8_t *)bytes;
|
2010-09-06 06:20:44 -03:00
|
|
|
union {
|
|
|
|
long v;
|
|
|
|
uint8_t b[4];
|
|
|
|
} u;
|
|
|
|
|
2010-09-06 17:00:57 -03:00
|
|
|
u.b[0] = b[3];
|
|
|
|
u.b[1] = b[2];
|
|
|
|
u.b[2] = b[1];
|
|
|
|
u.b[3] = b[0];
|
2010-09-06 06:20:44 -03:00
|
|
|
|
|
|
|
return(u.v);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int16_t
|
2010-09-06 17:00:57 -03:00
|
|
|
GPS::_swapi(const void *bytes)
|
2010-09-06 06:20:44 -03:00
|
|
|
{
|
2010-09-06 17:00:57 -03:00
|
|
|
const uint8_t *b = (const uint8_t *)bytes;
|
2010-09-06 06:20:44 -03:00
|
|
|
union {
|
|
|
|
int16_t v;
|
|
|
|
uint8_t b[2];
|
|
|
|
} u;
|
|
|
|
|
2010-09-06 17:00:57 -03:00
|
|
|
u.b[0] = b[1];
|
|
|
|
u.b[1] = b[0];
|
2010-09-06 06:20:44 -03:00
|
|
|
|
|
|
|
return(u.v);
|
|
|
|
}
|
|
|
|
|
2010-08-29 19:58:22 -03:00
|
|
|
#endif
|