mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 14:25:20 +03:00
Adds variations in GPS coordinate OSD element display: 1. Fractional degrees with 7 digits (default) - 000.0000000 2. Fractional degrees with 4 digits - 000.0000 3. Degrees, minutes, seconds - 000^00'00.0"E 4. Open Location Code (sometimed called Google Plus Code) - 23ABC4R8+M37 Uses Open Location Code library from: https://github.com/google/open-location-code Added support for `STATE(GPS_FIX_EVER)` to differentiate from having a fix now (`STATE(GPS_FIX)`) vs. ever having a fix. Logic change to only display coordinates from the GPS module once a fix has been initially established. This prevents displaying interim coordinates supplied by the GPS while the fix is still being establised as these coordinates can be inaccurate by hundreds of miles. Once a fix is established initially then the coordinates will continue to be displayed even if the fix is lost or degrades in quality. Add logic to "blink" the coordinates if the 3D fix is lost after initially being established. Alerts the user that the coordinate display may be inaccurate or no longer being updated. We want to keep the coordinates displayed to aid recovery if the user loses the fix (like crashing upside down). Replace GPS defines `LAT` and `LON` used throughout the code with the enumeration: ``` typedef enum { GPS_LATITUDE, GPS_LONGITUDE } gpsCoordinateType_e; ``` The Open Location Code option is bounded with `USE_GPS_PLUS_CODE` to allow it to be excluded if needed for targets with limited flash space. It currently fits for F411 but we may have to remove it in the future.
69 lines
2.9 KiB
C
69 lines
2.9 KiB
C
/*
|
|
* We place these static definitions on a separate header file so that we can
|
|
* include the file in both the library and the tests.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <float.h>
|
|
#include <math.h>
|
|
#include <memory.h>
|
|
|
|
#define OLC_kEncodingBase 20
|
|
#define OLC_kGridCols 4
|
|
#define OLC_kLatMaxDegrees 90
|
|
#define OLC_kLonMaxDegrees 180
|
|
|
|
// Separates the first eight digits from the rest of the code.
|
|
static const char kSeparator = '+';
|
|
// Used to indicate null values before the separator.
|
|
static const char kPaddingCharacter = '0';
|
|
// Digits used in the codes.
|
|
static const char kAlphabet[] = "23456789CFGHJMPQRVWX";
|
|
// Number of digits in the alphabet.
|
|
static const size_t kEncodingBase = OLC_kEncodingBase;
|
|
// The max number of digits returned in a plus code. Roughly 1 x 0.5 cm.
|
|
static const size_t kMaximumDigitCount = 15;
|
|
// The number of code characters that are lat/lng pairs.
|
|
static const size_t kPairCodeLength = 10;
|
|
// The number of characters that combine lat and lng into a grid.
|
|
// kMaximumDigitCount - kPairCodeLength
|
|
static const size_t kGridCodeLength = 5;
|
|
// The number of columns in each grid step.
|
|
static const size_t kGridCols = OLC_kGridCols;
|
|
// The number of rows in each grid step.
|
|
static const size_t kGridRows = OLC_kEncodingBase / OLC_kGridCols;
|
|
// The number of digits before the separator.
|
|
static const size_t kSeparatorPosition = 8;
|
|
// Inverse of the precision of the last pair digits (in degrees).
|
|
static const size_t kPairPrecisionInverse = 8000;
|
|
// Inverse (1/) of the precision of the final grid digits in degrees.
|
|
// Latitude is kEncodingBase^3 * kGridRows^kGridCodeLength
|
|
static const size_t kGridLatPrecisionInverse = 2.5e7;
|
|
// Longitude is kEncodingBase^3 * kGridColumns^kGridCodeLength
|
|
static const size_t kGridLonPrecisionInverse = 8.192e6;
|
|
// Latitude bounds are -kLatMaxDegrees degrees and +kLatMaxDegrees degrees
|
|
// which we transpose to 0 and 180 degrees.
|
|
static const double kLatMaxDegrees = OLC_kLatMaxDegrees;
|
|
static const double kLatMaxDegreesT2 = 2 * OLC_kLatMaxDegrees;
|
|
|
|
// Longitude bounds are -kLonMaxDegrees degrees and +kLonMaxDegrees degrees
|
|
// which we transpose to 0 and 360 degrees.
|
|
static const double kLonMaxDegrees = OLC_kLonMaxDegrees;
|
|
static const double kLonMaxDegreesT2 = 2 * OLC_kLonMaxDegrees;
|
|
|
|
// Lookup table of the alphabet positions of characters 'C' through 'X',
|
|
// inclusive. A value of -1 means the character isn't part of the alphabet.
|
|
static const int kPositionLUT['X' - 'C' + 1] = {
|
|
8, -1, -1, 9, 10, 11, -1, 12, -1, -1, 13,
|
|
-1, -1, 14, 15, 16, -1, -1, -1, 17, 18, 19,
|
|
};
|
|
|
|
// Returns the position of a char in the encoding alphabet, or -1 if invalid.
|
|
static int get_alphabet_position(char c) {
|
|
char uc = toupper(c);
|
|
// We use a lookup table for performance reasons.
|
|
if (uc >= 'C' && uc <= 'X') return kPositionLUT[uc - 'C'];
|
|
if (uc >= 'c' && uc <= 'x') return kPositionLUT[uc - 'c'];
|
|
if (uc >= '2' && uc <= '9') return uc - '2';
|
|
return -1;
|
|
}
|