From 586ca6a72058c48b640af36a7d3b31cdd44fbf59 Mon Sep 17 00:00:00 2001 From: Mr D - RC Date: Sun, 23 Feb 2025 22:38:13 +0000 Subject: [PATCH 1/7] Initial coding - Added overriding min ground speed to the programming framework. - Added reading min ground speed to the programming framework. - Updated nav functions to get the min ground speed via the programming framework. This handles if the override is enabled or not. - Added min ground speed element to the OSD. This involved re-formatting `osdFormatVelocityStr` to take a `osd_speedTypes_e` value. Instead or adding another boolean to define speed types. Moved Airspeed variants in to the function too. **Todo** - [ ] Add getting wind speed to programming framework - [ ] Test --- src/main/common/maths.h | 64 ++++----- src/main/io/osd.c | 154 +++++++++++++++------ src/main/io/osd.h | 10 +- src/main/navigation/navigation_fixedwing.c | 4 +- src/main/programming/logic_condition.c | 22 +++ src/main/programming/logic_condition.h | 6 +- 6 files changed, 186 insertions(+), 74 deletions(-) diff --git a/src/main/common/maths.h b/src/main/common/maths.h index 2dbb53c0a1d..675ff56c2ca 100644 --- a/src/main/common/maths.h +++ b/src/main/common/maths.h @@ -35,49 +35,51 @@ #define RAD (M_PIf / 180.0f) -#define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100) -#define CENTIDEGREES_TO_DEGREES(angle) ((angle) * 0.01f) +#define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100) +#define CENTIDEGREES_TO_DEGREES(angle) ((angle) * 0.01f) -#define CENTIDEGREES_TO_DECIDEGREES(angle) ((angle) / 10.0f) -#define DECIDEGREES_TO_CENTIDEGREES(angle) ((angle) * 10) +#define CENTIDEGREES_TO_DECIDEGREES(angle) ((angle) / 10.0f) +#define DECIDEGREES_TO_CENTIDEGREES(angle) ((angle) * 10) -#define DEGREES_TO_DECIDEGREES(angle) ((angle) * 10) -#define DECIDEGREES_TO_DEGREES(angle) ((angle) / 10.0f) +#define DEGREES_TO_DECIDEGREES(angle) ((angle) * 10) +#define DECIDEGREES_TO_DEGREES(angle) ((angle) / 10.0f) -#define DEGREES_PER_DEKADEGREE 10 -#define DEGREES_TO_DEKADEGREES(angle) ((angle) / DEGREES_PER_DEKADEGREE) -#define DEKADEGREES_TO_DEGREES(angle) ((angle) * DEGREES_PER_DEKADEGREE) +#define DEGREES_PER_DEKADEGREE 10 +#define DEGREES_TO_DEKADEGREES(angle) ((angle) / DEGREES_PER_DEKADEGREE) +#define DEKADEGREES_TO_DEGREES(angle) ((angle) * DEGREES_PER_DEKADEGREE) -#define DEGREES_TO_RADIANS(angle) ((angle) * RAD) -#define RADIANS_TO_DEGREES(angle) ((angle) / RAD) -#define DECIDEGREES_TO_RADIANS(angle) (((angle) / 10.0f) * RAD) -#define RADIANS_TO_DECIDEGREES(angle) (((angle) * 10.0f) / RAD) +#define DEGREES_TO_RADIANS(angle) ((angle) * RAD) +#define RADIANS_TO_DEGREES(angle) ((angle) / RAD) +#define DECIDEGREES_TO_RADIANS(angle) (((angle) / 10.0f) * RAD) +#define RADIANS_TO_DECIDEGREES(angle) (((angle) * 10.0f) / RAD) -#define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD) -#define CENTIDEGREES_TO_RADIANS(angle) (((angle) * 0.01f) * RAD) +#define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD) +#define CENTIDEGREES_TO_RADIANS(angle) (((angle) * 0.01f) * RAD) -#define MILLIMETERS_TO_CENTIMETERS(mm) (mm / 10.0f) +#define MILLIMETERS_TO_CENTIMETERS(mm) (mm / 10.0f) -#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f) -#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f) -#define CENTIMETERS_TO_METERS(cm) (cm * 0.01f) +#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f) +#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f) +#define CENTIMETERS_TO_METERS(cm) (cm * 0.01f) -#define METERS_TO_CENTIMETERS(m) (m * 100) -#define METERS_TO_KILOMETERS(m) (m / 1000.0f) -#define METERS_TO_MILES(m) (m / 1609.344f) -#define METERS_TO_NAUTICALMILES(m) (m / 1852.00f) +#define METERS_TO_CENTIMETERS(m) (m * 100) +#define METERS_TO_KILOMETERS(m) (m / 1000.0f) +#define METERS_TO_MILES(m) (m / 1609.344f) +#define METERS_TO_NAUTICALMILES(m) (m / 1852.00f) -#define MWH_TO_WH(mWh) (mWh / 1000.0f) +#define MWH_TO_WH(mWh) (mWh / 1000.0f) -#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f) -#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f) -#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f) +#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f) +#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f) +#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f) -#define CMSEC_TO_MPH(cms) (CMSEC_TO_CENTIMPH(cms) / 100.0f) -#define CMSEC_TO_KPH(cms) (CMSEC_TO_CENTIKPH(cms) / 100.0f) -#define CMSEC_TO_KNOTS(cms) (CMSEC_TO_CENTIKNOTS(cms) / 100.0f) +#define CMSEC_TO_MPH(cms) (CMSEC_TO_CENTIMPH(cms) / 100.0f) +#define CMSEC_TO_KPH(cms) (CMSEC_TO_CENTIKPH(cms) / 100.0f) +#define CMSEC_TO_KNOTS(cms) (CMSEC_TO_CENTIKNOTS(cms) / 100.0f) -#define C_TO_KELVIN(temp) (temp + 273.15f) +#define KMH_TO_MS(kmh) (kmh / 3.6f) + +#define C_TO_KELVIN(temp) (temp + 273.15f) // Standard Sea Level values // Ref:https://en.wikipedia.org/wiki/Standard_sea_level diff --git a/src/main/io/osd.c b/src/main/io/osd.c index d44ea0a8988..f049dd83006 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -391,34 +391,109 @@ static int32_t osdConvertVelocityToUnit(int32_t vel) * @param _3D is a 3D velocity * @param _max is a maximum velocity */ -void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max) +void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max) { switch ((osd_unit_e)osdConfig()->units) { - case OSD_UNIT_UK: - FALLTHROUGH; - case OSD_UNIT_METRIC_MPH: - FALLTHROUGH; - case OSD_UNIT_IMPERIAL: - if (_max) { - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_MPH : SYM_MPH)); - } else { - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_MPH : SYM_MPH)); - } - break; - case OSD_UNIT_METRIC: - if (_max) { - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_KMH : SYM_KMH)); - } else { - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_KMH : SYM_KMH)); - } - break; - case OSD_UNIT_GA: - if (_max) { - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_KT : SYM_KT)); - } else { - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), (_3D ? SYM_3D_KT : SYM_KT)); - } - break; + case OSD_UNIT_UK: + FALLTHROUGH; + case OSD_UNIT_METRIC_MPH: + FALLTHROUGH; + case OSD_UNIT_IMPERIAL: + if (_max) { + switch (speedType) { + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + break; + } + } else { + switch (speedType){ + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_MPH); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + break; + } + } + break; + case OSD_UNIT_METRIC: + if (_max) { + switch (speedType) { + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + break; + } + } else { + switch (speedType) { + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KMH); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + break; + } + } + break; + case OSD_UNIT_GA: + if (_max) { + switch (speedType) { + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KT); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + break; + } + } else { + switch (speedType) { + case OSD_SPEED_TYPE_GROUND: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KT); + break; + case OSD_SPEED_TYPE_AIR: + tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); + break; + case OSD_SPEED_TYPE_3D: + tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); + break; + case OSD_SPEED_TYPE_MIN_GROUND: + tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KT); + break; + } + } + break; } } @@ -427,7 +502,7 @@ void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max) */ static void osdGenerateAverageVelocityStr(char* buff) { uint32_t cmPerSec = getTotalTravelDistance() / getFlightTime(); - osdFormatVelocityStr(buff, cmPerSec, false, false); + osdFormatVelocityStr(buff, cmPerSec, OSD_SPEED_TYPE_GROUND, false); } /** @@ -1883,19 +1958,23 @@ static bool osdDrawSingleElement(uint8_t item) break; case OSD_GPS_SPEED: - osdFormatVelocityStr(buff, gpsSol.groundSpeed, false, false); + osdFormatVelocityStr(buff, gpsSol.groundSpeed, OSD_SPEED_TYPE_GROUND, false); + break; + + case OSD_NAV_MIN_GROUND_SPEED: + osdFormatVelocityStr(buff, getMinGroundSpeed(navConfig()->general.min_ground_speed) * 100, OSD_SPEED_TYPE_MIN_GROUND, false); break; case OSD_GPS_MAX_SPEED: - osdFormatVelocityStr(buff, stats.max_speed, false, true); + osdFormatVelocityStr(buff, stats.max_speed, OSD_SPEED_TYPE_GROUND, true); break; case OSD_3D_SPEED: - osdFormatVelocityStr(buff, osdGet3DSpeed(), true, false); + osdFormatVelocityStr(buff, osdGet3DSpeed(), OSD_SPEED_TYPE_3D, false); break; case OSD_3D_MAX_SPEED: - osdFormatVelocityStr(buff, stats.max_3D_speed, true, true); + osdFormatVelocityStr(buff, stats.max_3D_speed, OSD_SPEED_TYPE_3D, true); break; case OSD_GLIDESLOPE: @@ -3245,12 +3324,10 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_AIR_SPEED: { #ifdef USE_PITOT - buff[0] = SYM_AIR; - if (pitotIsHealthy()) { const float airspeed_estimate = getAirspeedEstimate(); - osdFormatVelocityStr(buff + 1, airspeed_estimate, false, false); + osdFormatVelocityStr(buff, airspeed_estimate, OSD_SPEED_TYPE_AIR, false); if ((osdConfig()->airspeed_alarm_min != 0 && airspeed_estimate < osdConfig()->airspeed_alarm_min) || (osdConfig()->airspeed_alarm_max != 0 && airspeed_estimate > osdConfig()->airspeed_alarm_max)) { TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); @@ -3258,6 +3335,7 @@ static bool osdDrawSingleElement(uint8_t item) } else { + buff[0] = SYM_AIR; strcpy(buff + 1, " X!"); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); } @@ -3270,9 +3348,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_AIR_MAX_SPEED: { #ifdef USE_PITOT - buff[0] = SYM_MAX; - buff[1] = SYM_AIR; - osdFormatVelocityStr(buff + 2, stats.max_air_speed, false, false); + osdFormatVelocityStr(buff, stats.max_air_speed, OSD_SPEED_TYPE_AIR, true); #else return false; #endif @@ -4837,7 +4913,7 @@ uint8_t drawStat_Speed(uint8_t col, uint8_t row, uint8_t statValX) displayWrite(osdDisplayPort, col, row, "MAX/AVG SPEED"); - osdFormatVelocityStr(buff2, stats.max_3D_speed, true, false); + osdFormatVelocityStr(buff2, stats.max_3D_speed, OSD_SPEED_TYPE_3D, false); tfp_sprintf(buff, ": %s/", osdFormatTrimWhiteSpace(buff2)); multiValueXOffset = strlen(buff); displayWrite(osdDisplayPort, statValX, row, buff); @@ -6138,7 +6214,7 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { if (posControl.cruise.multicopterSpeed >= 50.0f) { char buf[6]; - osdFormatVelocityStr(buf, posControl.cruise.multicopterSpeed, false, false); + osdFormatVelocityStr(buf, posControl.cruise.multicopterSpeed, OSD_SPEED_TYPE_GROUND, false); tfp_sprintf(messageBuf, "(SPD %s)", buf); } else { strcpy(messageBuf, "(HOLD)"); diff --git a/src/main/io/osd.h b/src/main/io/osd.h index b2e94b52729..6e61299dcfe 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -313,6 +313,7 @@ typedef enum { OSD_H_DIST_TO_FENCE, OSD_V_DIST_TO_FENCE, OSD_NAV_FW_ALT_CONTROL_RESPONSE, + OSD_NAV_MIN_GROUND_SPEED, OSD_ITEM_COUNT // MUST BE LAST } osd_items_e; @@ -366,6 +367,13 @@ typedef enum { OSD_CRSF_LQ_TYPE3 } osd_crsf_lq_format_e; +typedef enum { + OSD_SPEED_TYPE_GROUND, + OSD_SPEED_TYPE_AIR, + OSD_SPEED_TYPE_3D, + OSD_SPEED_TYPE_MIN_GROUND, +} osd_SpeedTypes_e; + typedef struct osdLayoutsConfig_s { // Layouts uint16_t item_pos[OSD_LAYOUT_COUNT][OSD_ITEM_COUNT]; @@ -537,7 +545,7 @@ void osdShowEEPROMSavedNotification(void); void osdCrosshairPosition(uint8_t *x, uint8_t *y); bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros); void osdFormatAltitudeSymbol(char *buff, int32_t alt); -void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max); +void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max); // Returns a heading angle in degrees normalized to [0, 360). int osdGetHeadingAngle(int angle); diff --git a/src/main/navigation/navigation_fixedwing.c b/src/main/navigation/navigation_fixedwing.c index 49c693fa0c2..17c673760b9 100755 --- a/src/main/navigation/navigation_fixedwing.c +++ b/src/main/navigation/navigation_fixedwing.c @@ -558,10 +558,10 @@ int16_t applyFixedWingMinSpeedController(timeUs_t currentTimeUs) previousTimePositionUpdate = currentTimeUs; if (deltaMicrosPositionUpdate < MAX_POSITION_UPDATE_INTERVAL_US) { - float velThrottleBoost = ((navConfig()->general.min_ground_speed * 100.0f) - posControl.actualState.velXY) * NAV_FW_THROTTLE_SPEED_BOOST_GAIN * US2S(deltaMicrosPositionUpdate); + float velThrottleBoost = ((getMinGroundSpeed(navConfig()->general.min_ground_speed) * 100.0f) - posControl.actualState.velXY) * NAV_FW_THROTTLE_SPEED_BOOST_GAIN * US2S(deltaMicrosPositionUpdate); // If we are in the deadband of 50cm/s - don't update speed boost - if (fabsf(posControl.actualState.velXY - (navConfig()->general.min_ground_speed * 100.0f)) > 50) { + if (fabsf(posControl.actualState.velXY - (getMinGroundSpeed(navConfig()->general.min_ground_speed) * 100.0f)) > 50) { throttleSpeedAdjustment += velThrottleBoost; } diff --git a/src/main/programming/logic_condition.c b/src/main/programming/logic_condition.c index 4143664616f..d9583dfa496 100644 --- a/src/main/programming/logic_condition.c +++ b/src/main/programming/logic_condition.c @@ -453,6 +453,12 @@ static int logicConditionCompute( return true; break; + case LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED: + logicConditionValuesByType[LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED] = constrain(operandA, 25, 150); + LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_MIN_GROUND_SPEED); + return true; + break; + case LOGIC_CONDITION_FLIGHT_AXIS_ANGLE_OVERRIDE: if (operandA >= 0 && operandA <= 2) { @@ -711,6 +717,10 @@ static int logicConditionGetFlightOperandValue(int operand) { return gpsSol.groundSpeed; break; + case LOGIC_CONDITION_OPERAND_FLIGHT_MIN_GROUND_SPEED: // m/s + return getMinGroundSpeed(navConfig()->general.min_ground_speed); + break; + //FIXME align with osdGet3DSpeed case LOGIC_CONDITION_OPERAND_FLIGHT_3D_SPEED: // cm/s return osdGet3DSpeed(); @@ -1107,6 +1117,18 @@ uint32_t getLoiterRadius(uint32_t loiterRadius) { #endif } +uint32_t getMinGroundSpeed(uint32_t minGroundSpeed) { +#ifdef USE_PROGRAMMING_FRAMEWORK + if (LOGIC_CONDITION_GLOBAL_FLAG(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_MIN_GROUND_SPEED)) { + return constrain(logicConditionValuesByType[LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED], minGroundSpeed, 150); + } else { + return minGroundSpeed; + } +#else + return minGroundSpeed; +#endif +} + float getFlightAxisAngleOverride(uint8_t axis, float angle) { if (flightAxisOverride[axis].angleTargetActive) { return flightAxisOverride[axis].angleTarget; diff --git a/src/main/programming/logic_condition.h b/src/main/programming/logic_condition.h index f5653bb68cc..aafc16b797b 100644 --- a/src/main/programming/logic_condition.h +++ b/src/main/programming/logic_condition.h @@ -84,7 +84,8 @@ typedef enum { LOGIC_CONDITION_LED_PIN_PWM = 52, LOGIC_CONDITION_DISABLE_GPS_FIX = 53, LOGIC_CONDITION_RESET_MAG_CALIBRATION = 54, - LOGIC_CONDITION_LAST = 55, + LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED = 55, + LOGIC_CONDITION_LAST } logicOperation_e; typedef enum logicOperandType_s { @@ -146,6 +147,7 @@ typedef enum { LOGIC_CONDITION_OPERAND_FLIGHT_FLOWN_LOITER_RADIUS, // 43 LOGIC_CONDITION_OPERAND_FLIGHT_LQ_DOWNLINK, // 44 LOGIC_CONDITION_OPERAND_FLIGHT_UPLINK_RSSI_DBM, // 45 + LOGIC_CONDITION_OPERAND_FLIGHT_MIN_GROUND_SPEED, // m/s // 46 } logicFlightOperands_e; typedef enum { @@ -200,6 +202,7 @@ typedef enum { #ifdef USE_GPS_FIX_ESTIMATION LOGIC_CONDITION_GLOBAL_FLAG_DISABLE_GPS_FIX = (1 << 11), #endif + LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_MIN_GROUND_SPEED = (1 << 12), } logicConditionsGlobalFlags_t; typedef enum { @@ -261,6 +264,7 @@ float getThrottleScale(float globalThrottleScale); int16_t getRcCommandOverride(int16_t command[], uint8_t axis); int16_t getRcChannelOverride(uint8_t channel, int16_t originalValue); uint32_t getLoiterRadius(uint32_t loiterRadius); +uint32_t getMinGroundSpeed(uint32_t minGroundSpeed); float getFlightAxisAngleOverride(uint8_t axis, float angle); float getFlightAxisRateOverride(uint8_t axis, float rate); bool isFlightAxisAngleOverrideActive(uint8_t axis); From 5b9d5a762545cb81ea8da54f078304d5de0150c7 Mon Sep 17 00:00:00 2001 From: Mr D - RC Date: Mon, 24 Feb 2025 20:57:08 +0000 Subject: [PATCH 2/7] Update - Added horizontal wind speed to the programming framework. - Added min ground speed and horizontal wind speed to programming framework docs. Along with a couple of missing entries - Added min ground speed to the OSD doc, plus another that was missing. --- docs/OSD.md | 2 ++ docs/Programming Framework.md | 5 +++++ src/main/programming/logic_condition.c | 15 +++++++++++++++ src/main/programming/logic_condition.h | 1 + 4 files changed, 23 insertions(+) diff --git a/docs/OSD.md b/docs/OSD.md index 58f459ccc3f..81f670fecf6 100644 --- a/docs/OSD.md +++ b/docs/OSD.md @@ -196,6 +196,8 @@ Here are the OSD Elements provided by INAV. | 163 | OSD_COURSE_TO_FENCE | 8.0.0 | | | 164 | OSD_H_DIST_TO_FENCE | 8.0.0 | | | 165 | OSD_V_DIST_TO_FENCE | 8.0.0 | | +| 166 | OSD_NAV_FW_ALT_CONTROL_RESPONSE | 8.0.0 | | +| 167 | OSD_NAV_MIN_GROUND_SPEED | 9.0.0 | | # Pilot Logos diff --git a/docs/Programming Framework.md b/docs/Programming Framework.md index db8aa787cb1..c102099d270 100644 --- a/docs/Programming Framework.md +++ b/docs/Programming Framework.md @@ -101,6 +101,7 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 52 | LED Pin PWM | Value `Operand A` from [`0` : `100`] starts PWM generation on LED Pin. See [LED pin PWM](LED%20pin%20PWM.md). Any other value stops PWM generation (stop to allow ws2812 LEDs updates in shared modes). | | 53 | Disable GPS Sensor Fix | Disables the GNSS sensor fix. For testing GNSS failure. | | 54 | Mag calibration | Trigger a magnetometer calibration. | +| 55 | Override Minimum Ground Speed | When active, sets the minimum ground speed to the value specified in `Operand A` [m/s]. Minimum allowed value is set in `nav_min_ground_speed`. Maximum value is `150` | ### Operands @@ -163,6 +164,10 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 41 | FW Land Sate | Integer `1` - `5`, indicates the status of the FW landing, 0 Idle, 1 Downwind, 2 Base Leg, 3 Final Approach, 4 Glide, 5 Flare | | 42 | Current battery profile | The active battery profile. Integer `[1..MAX_PROFILE_COUNT]` | | 43 | Flown Loiter Radius [m] | The actual loiter radius flown by a fixed wing during hold modes, in `meters` | +| 44 | Downlink Link Quality | | +| 45 | Uplink RSSI [dBm] | | +| 46 | Minimum Ground Speed [m/s] | The current minimum ground speed allowed in navigation flight modes | +| 47 | Horizontal Wind Speed [cm/s] | Estimated wind speed. If the wind estimator is unavailble or the wind speed is invalid, -1 is returned | #### FLIGHT_MODE diff --git a/src/main/programming/logic_condition.c b/src/main/programming/logic_condition.c index d9583dfa496..b0af6138e10 100644 --- a/src/main/programming/logic_condition.c +++ b/src/main/programming/logic_condition.c @@ -47,6 +47,7 @@ #include "flight/imu.h" #include "flight/pid.h" #include "flight/mixer_profile.h" +#include "flight/wind_estimator.h" #include "drivers/io_port_expander.h" #include "io/osd_common.h" #include "sensors/diagnostics.h" @@ -734,6 +735,20 @@ static int logicConditionGetFlightOperandValue(int operand) { #endif break; + case LOGIC_CONDITION_OPERAND_FLIGHT_HORIZONTAL_WIND_SPEED: // cm/s +#ifdef USE_WIND_ESTIMATOR + { + if (isEstimatedWindSpeedValid()) { + uint16_t angle; + return getEstimatedHorizontalWindSpeed(&angle); + } else + return -1; + } +#else + return -1; +#endif + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_ALTITUDE: // cm return constrain(getEstimatedActualPosition(Z), INT32_MIN, INT32_MAX); break; diff --git a/src/main/programming/logic_condition.h b/src/main/programming/logic_condition.h index aafc16b797b..9dce05720ac 100644 --- a/src/main/programming/logic_condition.h +++ b/src/main/programming/logic_condition.h @@ -148,6 +148,7 @@ typedef enum { LOGIC_CONDITION_OPERAND_FLIGHT_LQ_DOWNLINK, // 44 LOGIC_CONDITION_OPERAND_FLIGHT_UPLINK_RSSI_DBM, // 45 LOGIC_CONDITION_OPERAND_FLIGHT_MIN_GROUND_SPEED, // m/s // 46 + LOGIC_CONDITION_OPERAND_FLIGHT_HORIZONTAL_WIND_SPEED, // cm/s // 47 } logicFlightOperands_e; typedef enum { From 2731ed5ab7a81507d8e8030200c198aa8a50766f Mon Sep 17 00:00:00 2001 From: Mr D - RC Date: Mon, 24 Feb 2025 21:29:04 +0000 Subject: [PATCH 3/7] Add wind direction to PF --- docs/Programming Framework.md | 3 ++- src/main/programming/logic_condition.c | 22 ++++++++++++++++++++++ src/main/programming/logic_condition.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/Programming Framework.md b/docs/Programming Framework.md index c102099d270..34b9e46987a 100644 --- a/docs/Programming Framework.md +++ b/docs/Programming Framework.md @@ -167,7 +167,8 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn | 44 | Downlink Link Quality | | | 45 | Uplink RSSI [dBm] | | | 46 | Minimum Ground Speed [m/s] | The current minimum ground speed allowed in navigation flight modes | -| 47 | Horizontal Wind Speed [cm/s] | Estimated wind speed. If the wind estimator is unavailble or the wind speed is invalid, -1 is returned | +| 47 | Horizontal Wind Speed [cm/s] | Estimated wind speed. If the wind estimator is unavailble or the wind estimation is invalid, -1 is returned | +| 48 | Wind Direction [deg] | Estimated wind direction. If the wind estimator is unavailble or the wind estimation is invalid, -1 is returned | #### FLIGHT_MODE diff --git a/src/main/programming/logic_condition.c b/src/main/programming/logic_condition.c index b0af6138e10..cf3390515b6 100644 --- a/src/main/programming/logic_condition.c +++ b/src/main/programming/logic_condition.c @@ -749,6 +749,28 @@ static int logicConditionGetFlightOperandValue(int operand) { #endif break; + case LOGIC_CONDITION_OPERAND_FLIGHT_WIND_DIRECTION: // deg +#ifdef USE_WIND_ESTIMATOR + { + if (isEstimatedWindSpeedValid()) { + uint16_t angle; + getEstimatedHorizontalWindSpeed(&angle); + int32_t windAngle = (CENTIDEGREES_TO_DEGREES((int)angle) - DECIDEGREES_TO_DEGREES(attitude.values.yaw) + 22); + while (windAngle < 0) { + windAngle += 360; + } + while (windAngle >= 360) { + windAngle -= 360; + } + return windAngle; + } else + return -1; + } +#else + return -1; +#endif + break; + case LOGIC_CONDITION_OPERAND_FLIGHT_ALTITUDE: // cm return constrain(getEstimatedActualPosition(Z), INT32_MIN, INT32_MAX); break; diff --git a/src/main/programming/logic_condition.h b/src/main/programming/logic_condition.h index 9dce05720ac..bbcf3b329a4 100644 --- a/src/main/programming/logic_condition.h +++ b/src/main/programming/logic_condition.h @@ -149,6 +149,7 @@ typedef enum { LOGIC_CONDITION_OPERAND_FLIGHT_UPLINK_RSSI_DBM, // 45 LOGIC_CONDITION_OPERAND_FLIGHT_MIN_GROUND_SPEED, // m/s // 46 LOGIC_CONDITION_OPERAND_FLIGHT_HORIZONTAL_WIND_SPEED, // cm/s // 47 + LOGIC_CONDITION_OPERAND_FLIGHT_WIND_DIRECTION, // deg // 48 } logicFlightOperands_e; typedef enum { From 52961a910661ca22e70c01b7f898260c8ad74234 Mon Sep 17 00:00:00 2001 From: Mr D - RC Date: Mon, 24 Feb 2025 21:50:20 +0000 Subject: [PATCH 4/7] Bug fix Corrected min constraint value for min ground speed programming framework operand A. --- src/main/programming/logic_condition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/programming/logic_condition.c b/src/main/programming/logic_condition.c index cf3390515b6..25db930135d 100644 --- a/src/main/programming/logic_condition.c +++ b/src/main/programming/logic_condition.c @@ -455,7 +455,7 @@ static int logicConditionCompute( break; case LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED: - logicConditionValuesByType[LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED] = constrain(operandA, 25, 150); + logicConditionValuesByType[LOGIC_CONDITION_OVERRIDE_MIN_GROUND_SPEED] = constrain(operandA, navConfig()->general.min_ground_speed, 150); LOGIC_CONDITION_GLOBAL_FLAG_ENABLE(LOGIC_CONDITION_GLOBAL_FLAG_OVERRIDE_MIN_GROUND_SPEED); return true; break; From 6f9d8fca44cc9f649bc9362c3fb5c0d692580aad Mon Sep 17 00:00:00 2001 From: Darren Lines Date: Sun, 12 Oct 2025 17:31:22 +0100 Subject: [PATCH 5/7] Added back returning the string length, as there is something that uses it now --- src/main/io/osd.c | 49 +++++++++++++++++++++++++---------------------- src/main/io/osd.h | 2 +- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 1838bdeb37b..87be2433e9f 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -390,9 +390,12 @@ static int32_t osdConvertVelocityToUnit(int32_t vel) * @param vel Raw velocity (i.e. as taken from gpsSol.groundSpeed in centimeters/seconds) * @param _3D is a 3D velocity * @param _max is a maximum velocity + * @return length of the formatted string */ -void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max) +int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max) { + int strLen = 0; + switch ((osd_unit_e)osdConfig()->units) { case OSD_UNIT_UK: FALLTHROUGH; @@ -402,13 +405,13 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b if (_max) { switch (speedType) { case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); break; case OSD_SPEED_TYPE_MIN_GROUND: break; @@ -416,16 +419,16 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b } else { switch (speedType){ case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); break; case OSD_SPEED_TYPE_MIN_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; } } @@ -434,13 +437,13 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b if (_max) { switch (speedType) { case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); break; case OSD_SPEED_TYPE_MIN_GROUND: break; @@ -448,16 +451,16 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b } else { switch (speedType) { case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); break; case OSD_SPEED_TYPE_MIN_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; } } @@ -466,13 +469,13 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b if (_max) { switch (speedType) { case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_KT); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%c%c%3d%c", SYM_MAX, SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MAX, (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); break; case OSD_SPEED_TYPE_MIN_GROUND: break; @@ -480,23 +483,23 @@ void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, b } else { switch (speedType) { case OSD_SPEED_TYPE_GROUND: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_KT); break; case OSD_SPEED_TYPE_AIR: - tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_AIR, (int)osdConvertVelocityToUnit(vel), SYM_KT); break; case OSD_SPEED_TYPE_3D: - tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); + strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); break; case OSD_SPEED_TYPE_MIN_GROUND: - tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KT); break; } } break; } - return 0; + return strLen; } /** diff --git a/src/main/io/osd.h b/src/main/io/osd.h index 7430d094763..7c60016d46c 100644 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -576,7 +576,7 @@ void osdShowEEPROMSavedNotification(void); void osdCrosshairPosition(uint8_t *x, uint8_t *y); bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros); void osdFormatAltitudeSymbol(char *buff, int32_t alt); -void osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max); +int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bool _max); // Returns a heading angle in degrees normalized to [0, 360). int osdGetHeadingAngle(int angle); From 78594648f7c1eb774df2a303f23117a8e2f15de5 Mon Sep 17 00:00:00 2001 From: Darren Lines Date: Sun, 12 Oct 2025 17:36:38 +0100 Subject: [PATCH 6/7] Updated `OSD_ADSB_WARNING` to use updated `osdFormatVelocityStr` call --- src/main/io/osd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 87be2433e9f..31980757b66 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -2320,7 +2320,7 @@ static bool osdDrawSingleElement(uint8_t item) tfp_sprintf(buff, "%s", getAdsbEmitterTypeString(vehicle->vehicleValues.emitterType)); // Vehicle speed - adsbLengthForClearSecondLine = osdFormatVelocityStr(buff + 7, vehicle->vehicleValues.horVelocity, false, false); + adsbLengthForClearSecondLine = osdFormatVelocityStr(buff + 7, vehicle->vehicleValues.horVelocity, OSD_SPEED_TYPE_GROUND, false); // draw values buff[6] = SYM_BLANK; // space for direction arrow From 5960acadab36779d630e17b9b3c2365f4189f26d Mon Sep 17 00:00:00 2001 From: Darren Lines Date: Sun, 12 Oct 2025 20:49:59 +0100 Subject: [PATCH 7/7] Moved the min ground speed symbol to work with sprintf --- src/main/drivers/osd_symbols.h | 5 ++--- src/main/io/osd.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/drivers/osd_symbols.h b/src/main/drivers/osd_symbols.h index 35b9c61a424..88b7f92ee54 100644 --- a/src/main/drivers/osd_symbols.h +++ b/src/main/drivers/osd_symbols.h @@ -176,14 +176,13 @@ #define SYM_FLIGHT_HOURS_REMAINING 0xDB // 219 Flight time (hours) remaining #define SYM_GROUND_COURSE 0xDC // 220 Ground course #define SYM_ALERT 0xDD // 221 General alert symbol +#define SYM_MIN_GROUND_SPEED 0xDE // 222 Minimum Ground Speed #define SYM_TERRAIN_FOLLOWING 0xFB // 251 Terrain following (also Alt adjust) #define SYM_CROSS_TRACK_ERROR 0xFC // 252 Cross track error -#define SYM_ADSB 0xFD // 253 ADBS +#define SYM_ADSB 0xFD // 253 ADSB #define SYM_BLACKBOX 0xFE // 254 Blackbox -#define SYM_ADSB 0xFD // 253 ADSB - #define SYM_LOGO_START 0x101 // 257 to 297, INAV logo #define SYM_LOGO_WIDTH 10 #define SYM_LOGO_HEIGHT 4 diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 31980757b66..86c2e787f43 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -428,7 +428,7 @@ int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bo strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_MPH); break; case OSD_SPEED_TYPE_MIN_GROUND: - strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_MPH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MIN_GROUND_SPEED, (int)osdConvertVelocityToUnit(vel), SYM_MPH); break; } } @@ -460,7 +460,7 @@ int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bo strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KMH); break; case OSD_SPEED_TYPE_MIN_GROUND: - strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KMH); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MIN_GROUND_SPEED, (int)osdConvertVelocityToUnit(vel), SYM_KMH); break; } } @@ -492,7 +492,7 @@ int osdFormatVelocityStr(char* buff, int32_t vel, osd_SpeedTypes_e speedType, bo strLen = tfp_sprintf(buff, "%3d%c", (int)osdConvertVelocityToUnit(vel), SYM_3D_KT); break; case OSD_SPEED_TYPE_MIN_GROUND: - strLen = tfp_sprintf(buff, "%c%3d%c", SYM_GROUND_COURSE, (int)osdConvertVelocityToUnit(vel), SYM_KT); + strLen = tfp_sprintf(buff, "%c%3d%c", SYM_MIN_GROUND_SPEED, (int)osdConvertVelocityToUnit(vel), SYM_KT); break; } }