ardupilot/libraries/AP_GPS/GPS.h

229 lines
7.3 KiB
C++

// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
/// @file GPS.h
/// @brief Interface definition for the various GPS drivers.
#ifndef __GPS_H__
#define __GPS_H__
#include <AP_HAL.h>
#include <inttypes.h>
#include <AP_Progmem.h>
#include <AP_Math.h>
/// @class GPS
/// @brief Abstract base class for GPS receiver drivers.
class GPS
{
public:
GPS();
/// Update GPS state based on possible bytes received from the module.
///
/// This routine must be called periodically to process incoming data.
///
/// GPS drivers should not override this function; they should implement
/// ::read instead.
///
void update(void);
/// GPS status codes
///
/// \note Non-intuitive ordering for legacy reasons
///
enum GPS_Status {
NO_GPS = 0, ///< No GPS connected/detected
NO_FIX = 1, ///< Receiving valid GPS messages but no lock
GPS_OK_FIX_2D = 2, ///< Receiving valid messages and 2D lock
GPS_OK_FIX_3D = 3 ///< Receiving valid messages and 3D lock
};
/// Fix status codes
///
enum Fix_Status {
FIX_NONE = 0, ///< No fix
FIX_2D = 2, ///< 2d fix
FIX_3D = 3, ///< 3d fix
};
// GPS navigation engine settings. Not all GPS receivers support
// this
enum GPS_Engine_Setting {
GPS_ENGINE_NONE = -1,
GPS_ENGINE_PORTABLE = 0,
GPS_ENGINE_STATIONARY = 2,
GPS_ENGINE_PEDESTRIAN = 3,
GPS_ENGINE_AUTOMOTIVE = 4,
GPS_ENGINE_SEA = 5,
GPS_ENGINE_AIRBORNE_1G = 6,
GPS_ENGINE_AIRBORNE_2G = 7,
GPS_ENGINE_AIRBORNE_4G = 8
};
/// Query GPS status
///
/// The 'valid message' status indicates that a recognised message was
/// received from the GPS within the last 500ms.
///
/// @returns Current GPS status
///
GPS_Status status(void) const {
return _status;
}
/// Startup initialisation.
///
/// This routine performs any one-off initialisation required to set the
/// GPS up for use.
///
/// Must be implemented by the GPS driver.
///
virtual void init(AP_HAL::UARTDriver *s, enum GPS_Engine_Setting engine_setting = GPS_ENGINE_NONE) = 0;
// Properties
uint32_t time_week_ms; ///< GPS time (milliseconds from start of GPS week)
uint16_t time_week; ///< GPS week number
int32_t latitude; ///< latitude in degrees * 10,000,000
int32_t longitude; ///< longitude in degrees * 10,000,000
int32_t altitude_cm; ///< altitude in cm
uint32_t ground_speed_cm; ///< ground speed in cm/sec
int32_t ground_course_cd; ///< ground course in 100ths of a degree
int32_t speed_3d_cm; ///< 3D speed in cm/sec (not always available)
int16_t hdop; ///< horizontal dilution of precision in cm
uint8_t num_sats; ///< Number of visible satelites
/// 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;
Fix_Status fix; ///< 0 if we have no fix, 2 for 2D fix, 3 for 3D fix
bool valid_read; ///< true if we have seen data from the GPS (use ::status instead)
// Debug support
bool print_errors; ///< deprecated
// HIL support
virtual void setHIL(uint64_t time_epoch_ms, float latitude, float longitude, float altitude,
float ground_speed, float ground_course, float speed_3d, uint8_t num_sats);
// components of velocity in 2D, in m/s
float velocity_north(void) const {
return _status >= GPS_OK_FIX_2D ? _velocity_north : 0;
}
float velocity_east(void) const {
return _status >= GPS_OK_FIX_2D ? _velocity_east : 0;
}
float velocity_down(void) const {
return _status >= GPS_OK_FIX_3D ? _velocity_down : 0;
}
// GPS velocity vector as NED in m/s
Vector3f velocity_vector(void) const {
return Vector3f(_velocity_north, _velocity_east, _velocity_down);
}
// last ground speed in m/s. This can be used when we have no GPS
// lock to return the last ground speed we had with lock
float last_ground_speed(void) {
return static_cast<float>(_last_ground_speed_cm) * 0.01f;
}
// the expected lag (in seconds) in the position and velocity readings from the gps
virtual float get_lag() { return 1.0f; }
// the time we got our last fix in system milliseconds
uint32_t last_fix_time;
// the time we last processed a message in milliseconds
uint32_t last_message_time_ms(void) const { return _idleTimer; }
// return last fix time since the 1/1/1970 in microseconds
uint64_t time_epoch_usec(void);
// return true if the GPS supports raw velocity values
protected:
AP_HAL::UARTDriver *_port; ///< port the GPS is attached to
/// read from the GPS stream and update properties
///
/// Must be implemented by the GPS driver.
///
/// @returns true if a valid message was received from the GPS
///
virtual bool read(void) = 0;
/// 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
///
int32_t _swapl(const void *bytes) const;
/// 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
int16_t _swapi(const void *bytes) const;
/// 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
///
/// @note deprecated as-is due to the difficulty of hooking up to a working
/// printf vs. the potential benefits
///
void _error(const char *msg);
enum GPS_Engine_Setting _nav_setting;
void _write_progstr_block(AP_HAL::UARTDriver *_fs, const prog_char *pstr, uint8_t size);
void _send_progstr(AP_HAL::UARTDriver *_fs, const prog_char *pstr, uint8_t size);
void _update_progstr(void);
// velocities in cm/s if available from the GPS
int32_t _vel_north;
int32_t _vel_east;
int32_t _vel_down;
// does this GPS support raw velocity numbers?
bool _have_raw_velocity;
// detected baudrate
uint16_t _baudrate;
// the time we got the last GPS timestamp
uint32_t _last_gps_time;
// return time in seconds since GPS epoch given time components
void _make_gps_time(uint32_t bcd_date, uint32_t bcd_milliseconds);
private:
/// Last time that the GPS driver got a good packet from the GPS
///
uint32_t _idleTimer;
/// Our current status
GPS_Status _status;
// previous ground speed in cm/s
uint32_t _last_ground_speed_cm;
// components of the velocity, in m/s
float _velocity_north;
float _velocity_east;
float _velocity_down;
};
#endif // __GPS_H__