PX4 Firmware
PX4 Autopilot Software http://px4.io
gps_helper.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2014 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file gps_helper.h
36  * @author Thomas Gubler <thomasgubler@student.ethz.ch>
37  * @author Julian Oes <julian@oes.ch>
38  */
39 
40 #pragma once
41 
42 #include <cstdint>
43 #include "../../definitions.h"
44 
45 #ifndef GPS_READ_BUFFER_SIZE
46 #define GPS_READ_BUFFER_SIZE 150 ///< buffer size for the read() call. Messages can be longer than that.
47 #endif
48 
49 enum class GPSCallbackType {
50  /**
51  * Read data from device. This is a blocking operation with a timeout.
52  * data1: points to a buffer to be written to. The first sizeof(int) bytes contain the
53  * timeout in ms when calling the method.
54  * data2: buffer length in bytes. Less bytes than this can be read.
55  * return: num read bytes, 0 on timeout (the method can actually also return 0 before
56  * the timeout happens).
57  */
58  readDeviceData = 0,
59 
60  /**
61  * Write data to device
62  * data1: data to be written
63  * data2: number of bytes to write
64  * return: num written bytes
65  */
67 
68  /**
69  * set Baudrate
70  * data1: ignored
71  * data2: baudrate
72  * return: 0 on success
73  */
75 
76  /**
77  * Got an RTCM message from the device.
78  * data1: pointer to the message
79  * data2: message length
80  * return: ignored
81  */
83 
84  /**
85  * message about current survey-in status
86  * data1: points to a SurveyInStatus struct
87  * data2: ignored
88  * return: ignored
89  */
91 
92  /**
93  * can be used to set the current clock accurately
94  * data1: pointer to a timespec struct
95  * data2: ignored
96  * return: ignored
97  */
98  setClock,
99 };
100 
101 enum class GPSRestartType {
102  None,
103 
104  /**
105  * In hot start mode, the receiver was powered down only for a short time (4 hours or less),
106  * so that its ephemeris is still valid. Since the receiver doesn't need to download ephemeris
107  * again, this is the fastest startup method.
108  */
109  Hot,
110 
111  /**
112  * In warm start mode, the receiver has approximate information for time, position, and coarse
113  * satellite position data (Almanac). In this mode, after power-up, the receiver normally needs
114  * to download ephemeris before it can calculate position and velocity data.
115  */
116  Warm,
117 
118  /**
119  * In cold start mode, the receiver has no information from the last position at startup.
120  * Therefore, the receiver must search the full time and frequency space, and all possible
121  * satellite numbers. If a satellite signal is found, it is tracked to decode the ephemeris,
122  * whereas the other channels continue to search satellites. Once there is a sufficient number
123  * of satellites with valid ephemeris, the receiver can calculate position and velocity data.
124  */
125  Cold
126 };
127 
128 /** Callback function for platform-specific stuff.
129  * data1 and data2 depend on type and user is the custom user-supplied argument.
130  * @return <0 on error, >=0 on success (depending on type)
131  */
132 typedef int (*GPSCallbackPtr)(GPSCallbackType type, void *data1, int data2, void *user);
133 
134 
136  double latitude; /**< NAN if unknown/not set [deg] */
137  double longitude; /**< NAN if unknown/not set [deg] */
138  float altitude; /**< NAN if unknown/not set [m] */
139  uint32_t mean_accuracy; /**< [mm] */
140  uint32_t duration; /**< [s] */
141  uint8_t flags; /**< bit 0: valid, bit 1: active */
142 };
143 
144 // TODO: this number seems wrong
145 #define GPS_EPOCH_SECS ((time_t)1234567890ULL)
146 
148 {
149 public:
150  enum class OutputMode : uint8_t {
151  GPS = 0, ///< normal GPS output
152  RTCM ///< request RTCM output. This is used for (fixed position) base stations
153  };
154 
155  enum class Interface : uint8_t {
156  UART = 0,
157  SPI
158  };
159 
160 
161  GPSHelper(GPSCallbackPtr callback, void *callback_user);
162  virtual ~GPSHelper() = default;
163 
164  /**
165  * configure the device
166  * @param baud Input and output parameter: if set to 0, the baudrate will be automatically detected and set to
167  * the detected baudrate. If not 0, a fixed baudrate is used.
168  * @return 0 on success, <0 otherwise
169  */
170  virtual int configure(unsigned &baud, OutputMode output_mode) = 0;
171 
172  /**
173  * receive & handle new data from the device
174  * @param timeout [ms]
175  * @return <0 on error, otherwise a bitset:
176  * bit 0 set: got gps position update
177  * bit 1 set: got satellite info update
178  */
179  virtual int receive(unsigned timeout) = 0;
180 
181  /**
182  * Reset GPS device
183  * @param restart_type
184  * @return <0 failure
185  * -1 not implemented
186  * 0 success
187  */
188  virtual int reset(GPSRestartType restart_type) { return -1; }
189 
190  float getPositionUpdateRate() { return _rate_lat_lon; }
191  float getVelocityUpdateRate() { return _rate_vel; }
192  void resetUpdateRates();
193  void storeUpdateRates();
194 
195 protected:
196 
197  /**
198  * read from device
199  * @param buf: pointer to read buffer
200  * @param buf_length: size of read buffer
201  * @param timeout: timeout in ms
202  * @return: 0 for nothing read, or poll timed out
203  * < 0 for error
204  * > 0 number of bytes read
205  */
206  int read(uint8_t *buf, int buf_length, int timeout)
207  {
208  *((int *)buf) = timeout;
209  return _callback(GPSCallbackType::readDeviceData, buf, buf_length, _callback_user);
210  }
211 
212  /**
213  * write to the device
214  * @param buf
215  * @param buf_length
216  * @return num written bytes, -1 on error
217  */
218  int write(const void *buf, int buf_length)
219  {
220  return _callback(GPSCallbackType::writeDeviceData, (void *)buf, buf_length, _callback_user);
221  }
222 
223  /**
224  * set the Baudrate
225  * @param baudrate
226  * @return 0 on success, <0 otherwise
227  */
229  {
230  return _callback(GPSCallbackType::setBaudrate, nullptr, baudrate, _callback_user);
231  }
232 
234  {
235  _callback(GPSCallbackType::surveyInStatus, &status, 0, _callback_user);
236  }
237 
238  /** got an RTCM message from the device */
239  void gotRTCMMessage(uint8_t *buf, int buf_length)
240  {
241  _callback(GPSCallbackType::gotRTCMMessage, buf, buf_length, _callback_user);
242  }
243 
244  void setClock(timespec &t)
245  {
246  _callback(GPSCallbackType::setClock, &t, 0, _callback_user);
247  }
248 
249  /**
250  * Convert an ECEF (Earth Centered Earth Fixed) coordinate to LLA WGS84 (Lat, Lon, Alt).
251  * Ported from: https://stackoverflow.com/a/25428344
252  * @param ecef_x ECEF X-coordinate [m]
253  * @param ecef_y ECEF Y-coordinate [m]
254  * @param ecef_z ECEF Z-coordinate [m]
255  * @param latitude [deg]
256  * @param longitude [deg]
257  * @param altitude [m]
258  */
259  static void ECEF2lla(double ecef_x, double ecef_y, double ecef_z, double &latitude, double &longitude, float &altitude);
260 
261  GPSCallbackPtr _callback{nullptr};
262  void *_callback_user{};
263 
264  uint8_t _rate_count_lat_lon{};
265  uint8_t _rate_count_vel{};
266 
267  float _rate_lat_lon{0.0f};
268  float _rate_vel{0.0f};
269 
270  uint64_t _interval_rate_start{0};
271 };
float getPositionUpdateRate()
Definition: gps_helper.h:190
void surveyInStatus(SurveyInStatus &status)
Definition: gps_helper.h:233
static struct vehicle_status_s status
Definition: Commander.cpp:138
GPSRestartType
Definition: gps_helper.h:101
Read data from device.
Definition: gps.cpp:89
int setBaudrate(int baudrate)
set the Baudrate
Definition: gps_helper.h:228
double latitude
NAN if unknown/not set [deg].
Definition: gps_helper.h:136
virtual int reset(GPSRestartType restart_type)
Reset GPS device.
Definition: gps_helper.h:188
int read(uint8_t *buf, int buf_length, int timeout)
read from device
Definition: gps_helper.h:206
double longitude
NAN if unknown/not set [deg].
Definition: gps_helper.h:137
int write(const void *buf, int buf_length)
write to the device
Definition: gps_helper.h:218
set Baudrate data1: ignored data2: baudrate return: 0 on success
void gotRTCMMessage(uint8_t *buf, int buf_length)
got an RTCM message from the device
Definition: gps_helper.h:239
int(* GPSCallbackPtr)(GPSCallbackType type, void *data1, int data2, void *user)
Callback function for platform-specific stuff.
Definition: gps_helper.h:132
Got an RTCM message from the device.
float altitude
NAN if unknown/not set [m].
Definition: gps_helper.h:138
In cold start mode, the receiver has no information from the last position at startup.
In warm start mode, the receiver has approximate information for time, position, and coarse satellite...
can be used to set the current clock accurately data1: pointer to a timespec struct data2: ignored re...
GPSCallbackType
Definition: gps_helper.h:49
uint8_t flags
bit 0: valid, bit 1: active
Definition: gps_helper.h:141
uint32_t mean_accuracy
[mm]
Definition: gps_helper.h:139
In hot start mode, the receiver was powered down only for a short time (4 hours or less)...
void setClock(timespec &t)
Definition: gps_helper.h:244
message about current survey-in status data1: points to a SurveyInStatus struct data2: ignored return...
float getVelocityUpdateRate()
Definition: gps_helper.h:191
Write data to device data1: data to be written data2: number of bytes to write return: num written by...
uint32_t duration
[s]
Definition: gps_helper.h:140