1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-26 01:35:41 +03:00

Add GPS Lap Timer (#11856)

* Add gps lap timer

* change timing to GPS time instead of local time

* rebase and minor changes

* implement KarateBrot's suggestions

* follow ledvinap's suggestions, some OSD symbol changes

* move platform.h include to the top

Co-authored-by: Jan Post <Rm2k-Freak@web.de>

* fix osd elements not showing, remove useless block

* cleanup, move pg stuff to pg folder

* cleanup from review

* minor mods to gps lap timer update, add number of laps tracked

* rename time variable

* add const to timeMs

Co-authored-by: Jan Post <Rm2k-Freak@web.de>

* Update licenses, add is_sys_element macro

* update licenses

* round to nearest centisecond

Co-authored-by: Jan Post <Rm2k-Freak@web.de>

---------

Co-authored-by: Jan Post <Rm2k-Freak@web.de>
This commit is contained in:
SpencerGraffunder 2023-05-24 20:31:22 -04:00 committed by GitHub
parent 23a416b431
commit aad197f791
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 660 additions and 10 deletions

View file

@ -138,6 +138,7 @@
#include "fc/controlrate_profile.h"
#include "fc/core.h"
#include "fc/gps_lap_timer.h"
#include "fc/rc_adjustments.h"
#include "fc/rc_controls.h"
#include "fc/runtime_config.h"
@ -234,6 +235,9 @@ static uint32_t blinkBits[(OSD_ITEM_COUNT + 31) / 32];
#define IS_BLINK(item) (blinkBits[(item) / 32] & (1 << ((item) % 32)))
#define BLINK(item) (IS_BLINK(item) && blinkState)
// Return whether element is a SYS element and needs special handling
#define IS_SYS_OSD_ELEMENT(item) (item >= OSD_SYS_GOGGLE_VOLTAGE) && (item <= OSD_SYS_FAN_SPEED)
enum {UP, DOWN};
static int osdDisplayWrite(osdElementParms_t *element, uint8_t x, uint8_t y, uint8_t attr, const char *s)
@ -1040,8 +1044,14 @@ static void osdElementGpsHomeDirection(osdElementParms_t *element)
{
if (STATE(GPS_FIX) && STATE(GPS_FIX_HOME)) {
if (GPS_distanceToHome > 0) {
const int h = DECIDEGREES_TO_DEGREES(GPS_directionToHome - attitude.values.yaw);
element->buff[0] = osdGetDirectionSymbolFromHeading(h);
int direction = GPS_directionToHome;
#ifdef USE_GPS_LAP_TIMER
// Override the "home" point to the start/finish location if the lap timer is running
if (gpsLapTimerData.timerRunning) {
direction = lrintf(gpsLapTimerData.dirToPoint * 0.1f); // Convert from centidegree to degree and round to nearest
}
#endif
element->buff[0] = osdGetDirectionSymbolFromHeading(DECIDEGREES_TO_DEGREES(direction - attitude.values.yaw));
} else {
element->buff[0] = SYM_OVER_HOME;
}
@ -1057,7 +1067,14 @@ static void osdElementGpsHomeDirection(osdElementParms_t *element)
static void osdElementGpsHomeDistance(osdElementParms_t *element)
{
if (STATE(GPS_FIX) && STATE(GPS_FIX_HOME)) {
osdFormatDistanceString(element->buff, GPS_distanceToHome, SYM_HOMEFLAG);
int distance = GPS_distanceToHome;
#ifdef USE_GPS_LAP_TIMER
// Change the "home" point to the start/finish location if the lap timer is running
if (gpsLapTimerData.timerRunning) {
distance = lrintf(gpsLapTimerData.distToPointCM * 0.01f); // Round to nearest natural number
}
#endif
osdFormatDistanceString(element->buff, distance, SYM_HOMEFLAG);
} else {
element->buff[0] = SYM_HOMEFLAG;
// We use this symbol when we don't have a FIX
@ -1129,6 +1146,35 @@ static void osdElementEfficiency(osdElementParms_t *element)
}
#endif // USE_GPS
#ifdef USE_GPS_LAP_TIMER
static void osdFormatLapTime(osdElementParms_t *element, uint32_t timeMs, uint8_t symbol)
{
timeMs += 5; // round to nearest centisecond (+/- 5ms)
uint32_t seconds = timeMs / 1000;
uint32_t decimals = (timeMs % 1000) / 10;
tfp_sprintf(element->buff, "%c%3u.%02u", symbol, seconds, decimals);
}
static void osdElementGpsLapTimeCurrent(osdElementParms_t *element)
{
if (gpsLapTimerData.timerRunning) {
osdFormatLapTime(element, gpsSol.time - gpsLapTimerData.timeOfLastLap, SYM_TOTAL_DISTANCE);
} else {
osdFormatLapTime(element, 0, SYM_TOTAL_DISTANCE);
}
}
static void osdElementGpsLapTimePrevious(osdElementParms_t *element)
{
osdFormatLapTime(element, gpsLapTimerData.previousLaps[0], SYM_PREV_LAP_TIME);
}
static void osdElementGpsLapTimeBest3(osdElementParms_t *element)
{
osdFormatLapTime(element, gpsLapTimerData.best3Consec, SYM_CHECKERED_FLAG);
}
#endif // GPS_LAP_TIMER
static void osdBackgroundHorizonSidebars(osdElementParms_t *element)
{
// Draw AH sides
@ -1852,6 +1898,11 @@ const osdElementDrawFn osdElementDrawFunction[OSD_ITEM_COUNT] = {
#ifdef USE_GPS
[OSD_EFFICIENCY] = osdElementEfficiency,
#endif
#ifdef USE_GPS_LAP_TIMER
[OSD_GPS_LAP_TIME_CURRENT] = osdElementGpsLapTimeCurrent,
[OSD_GPS_LAP_TIME_PREVIOUS] = osdElementGpsLapTimePrevious,
[OSD_GPS_LAP_TIME_BEST3] = osdElementGpsLapTimeBest3,
#endif // GPS_LAP_TIMER
#ifdef USE_PERSISTENT_STATS
[OSD_TOTAL_FLIGHTS] = osdElementTotalFlights,
#endif
@ -1932,6 +1983,14 @@ void osdAddActiveElements(void)
}
#endif
#ifdef USE_GPS_LAP_TIMER
if (sensors(SENSOR_GPS)) {
osdAddActiveElement(OSD_GPS_LAP_TIME_CURRENT);
osdAddActiveElement(OSD_GPS_LAP_TIME_PREVIOUS);
osdAddActiveElement(OSD_GPS_LAP_TIME_BEST3);
}
#endif // GPS_LAP_TIMER
#ifdef USE_PERSISTENT_STATS
osdAddActiveElement(OSD_TOTAL_FLIGHTS);
#endif
@ -1962,7 +2021,7 @@ static void osdDrawSingleElement(displayPort_t *osdDisplayPort, uint8_t item)
element.attr = DISPLAYPORT_SEVERITY_NORMAL;
// Call the element drawing function
if ((item >= OSD_SYS_GOGGLE_VOLTAGE) && (item < OSD_ITEM_COUNT)) {
if (IS_SYS_OSD_ELEMENT(item)) {
displaySys(osdDisplayPort, elemPosX, elemPosY, (displayPortSystemElement_e)(item - OSD_SYS_GOGGLE_VOLTAGE + DISPLAYPORT_SYS_GOGGLE_VOLTAGE));
} else {
osdElementDrawFunction[item](&element);