Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2189 | - | 1 | // -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*- |
2 | |||
3 | /// @file GPS.h |
||
4 | /// @brief Interface definition for the various GPS drivers. |
||
5 | |||
6 | #ifndef GPS_h |
||
7 | #define GPS_h |
||
8 | |||
9 | #include <inttypes.h> |
||
10 | //#include "Stream.h" |
||
11 | |||
12 | /// @class GPS |
||
13 | /// @brief Abstract base class for GPS receiver drivers. |
||
14 | class GPS |
||
15 | { |
||
16 | public: |
||
17 | |||
18 | /// Update GPS state based on possible bytes received from the module. |
||
19 | /// |
||
20 | /// This routine must be called periodically to process incoming data. |
||
21 | /// |
||
22 | /// GPS drivers should not override this function; they should implement |
||
23 | /// ::read instead. |
||
24 | /// |
||
25 | void update(void); |
||
26 | |||
27 | void (*callback)(unsigned long t); |
||
28 | |||
29 | /// GPS status codes |
||
30 | /// |
||
31 | /// \note Non-intuitive ordering for legacy reasons |
||
32 | /// |
||
33 | enum GPS_Status { |
||
34 | NO_GPS = 0, ///< No GPS connected/detected |
||
35 | NO_FIX = 1, ///< Receiving valid GPS messages but no lock |
||
36 | GPS_OK = 2 ///< Receiving valid messages and locked |
||
37 | }; |
||
38 | |||
39 | /// Query GPS status |
||
40 | /// |
||
41 | /// The 'valid message' status indicates that a recognised message was |
||
42 | /// received from the GPS within the last 500ms. |
||
43 | /// |
||
44 | /// @returns Current GPS status |
||
45 | /// |
||
46 | GPS_Status status(void) { |
||
47 | return _status; |
||
48 | } |
||
49 | |||
50 | /// GPS time epoch codes |
||
51 | /// |
||
52 | enum GPS_Time_Epoch { |
||
53 | TIME_OF_DAY = 0, ///< |
||
54 | TIME_OF_WEEK = 1, ///< Ublox |
||
55 | TIME_OF_YEAR = 2, ///< MTK, NMEA |
||
56 | UNIX_EPOCH = 3 ///< If available |
||
57 | }; ///< SIFR? |
||
58 | |||
59 | |||
60 | /// Query GPS time epoch |
||
61 | /// |
||
62 | /// @returns Current GPS time epoch code |
||
63 | /// |
||
64 | GPS_Time_Epoch epoch(void) { |
||
65 | return _epoch; |
||
66 | } |
||
67 | |||
68 | /// Startup initialisation. |
||
69 | /// |
||
70 | /// This routine performs any one-off initialisation required to set the |
||
71 | /// GPS up for use. |
||
72 | /// |
||
73 | /// Must be implemented by the GPS driver. |
||
74 | /// |
||
75 | virtual void init(void) = 0; |
||
76 | |||
77 | // Properties |
||
78 | long time; ///< GPS time (milliseconds from epoch) |
||
79 | long date; ///< GPS date (FORMAT TBD) |
||
80 | long latitude; ///< latitude in degrees * 10,000,000 |
||
81 | long longitude; ///< longitude in degrees * 10,000,000 |
||
82 | long altitude; ///< altitude in cm |
||
83 | long ground_speed; ///< ground speed in cm/sec |
||
84 | long ground_course; ///< ground course in 100ths of a degree |
||
85 | long speed_3d; ///< 3D speed in cm/sec (not always available) |
||
86 | int hdop; ///< horizontal dilution of precision in cm |
||
87 | uint8_t num_sats; ///< Number of visible satelites |
||
88 | |||
89 | /// Set to true when new data arrives. A client may set this |
||
90 | /// to false in order to avoid processing data they have |
||
91 | /// already seen. |
||
92 | bool new_data; |
||
93 | |||
94 | // Deprecated properties |
||
95 | bool fix; ///< true if we have a position fix (use ::status instead) |
||
96 | bool valid_read; ///< true if we have seen data from the GPS (use ::status instead) |
||
97 | |||
98 | // Debug support |
||
99 | bool print_errors; ///< deprecated |
||
100 | |||
101 | // HIL support |
||
102 | virtual void setHIL(long time, float latitude, float longitude, float altitude, |
||
103 | float ground_speed, float ground_course, float speed_3d, uint8_t num_sats); |
||
104 | |||
105 | /// Time in milliseconds after which we will assume the GPS is no longer |
||
106 | /// sending us updates and attempt a re-init. |
||
107 | /// |
||
108 | /// 1200ms allows a small amount of slack over the worst-case 1Hz update |
||
109 | /// rate. |
||
110 | /// |
||
111 | uint32_t idleTimeout; |
||
112 | |||
113 | // our approximate linear acceleration in m/s/s |
||
114 | float acceleration(void) { return _acceleration; } |
||
115 | |||
116 | // the time we got our last fix in system milliseconds |
||
117 | uint32_t last_fix_time; |
||
118 | |||
119 | protected: |
||
120 | /// Stream *_port; ///< port the GPS is attached to |
||
121 | /// Constructor |
||
122 | /// |
||
123 | /// @note The stream is expected to be set up and configured for the |
||
124 | /// correct bitrate before ::init is called. |
||
125 | /// |
||
126 | /// @param s Stream connected to the GPS module. |
||
127 | /// |
||
128 | GPS(void *s) {}; |
||
129 | |||
130 | /// read from the GPS stream and update properties |
||
131 | /// |
||
132 | /// Must be implemented by the GPS driver. |
||
133 | /// |
||
134 | /// @returns true if a valid message was received from the GPS |
||
135 | /// |
||
136 | virtual bool read(void) = 0; |
||
137 | |||
138 | /// perform an endian swap on a long |
||
139 | /// |
||
140 | /// @param bytes pointer to a buffer containing bytes representing a |
||
141 | /// long in the wrong byte order |
||
142 | /// @returns endian-swapped value |
||
143 | /// |
||
144 | long _swapl(const void *bytes); |
||
145 | |||
146 | /// perform an endian swap on an int |
||
147 | /// |
||
148 | /// @param bytes pointer to a buffer containing bytes representing an |
||
149 | /// int in the wrong byte order |
||
150 | /// @returns endian-swapped value |
||
151 | int16_t _swapi(const void *bytes); |
||
152 | |||
153 | /// emit an error message |
||
154 | /// |
||
155 | /// based on the value of print_errors, emits the printf-formatted message |
||
156 | /// in msg,... to stderr |
||
157 | /// |
||
158 | /// @param fmt printf-like format string |
||
159 | /// |
||
160 | /// @note deprecated as-is due to the difficulty of hooking up to a working |
||
161 | /// printf vs. the potential benefits |
||
162 | /// |
||
163 | void _error(const char *msg); |
||
164 | |||
165 | /// Time epoch code for the gps in use |
||
166 | GPS_Time_Epoch _epoch; |
||
167 | |||
168 | private: |
||
169 | |||
170 | |||
171 | /// Last time that the GPS driver got a good packet from the GPS |
||
172 | /// |
||
173 | uint32_t _idleTimer; |
||
174 | |||
175 | /// Our current status |
||
176 | GPS_Status _status; |
||
177 | |||
178 | // previous ground speed in cm/s |
||
179 | uint32_t _last_ground_speed; |
||
180 | |||
181 | // smoothed estimate of our acceleration |
||
182 | float _acceleration; |
||
183 | }; |
||
184 | |||
185 | inline long |
||
186 | GPS::_swapl(const void *bytes) |
||
187 | { |
||
188 | const uint8_t *b = (const uint8_t *)bytes; |
||
189 | union { |
||
190 | long v; |
||
191 | uint8_t b[4]; |
||
192 | } u; |
||
193 | |||
194 | u.b[0] = b[3]; |
||
195 | u.b[1] = b[2]; |
||
196 | u.b[2] = b[1]; |
||
197 | u.b[3] = b[0]; |
||
198 | |||
199 | return(u.v); |
||
200 | } |
||
201 | |||
202 | inline int16_t |
||
203 | GPS::_swapi(const void *bytes) |
||
204 | { |
||
205 | const uint8_t *b = (const uint8_t *)bytes; |
||
206 | union { |
||
207 | int16_t v; |
||
208 | uint8_t b[2]; |
||
209 | } u; |
||
210 | |||
211 | u.b[0] = b[1]; |
||
212 | u.b[1] = b[0]; |
||
213 | |||
214 | return(u.v); |
||
215 | } |
||
216 | |||
217 | #endif |