@@ -390,46 +390,124 @@ static int32_t osdConvertVelocityToUnit(int32_t vel)
390390 * @param vel Raw velocity (i.e. as taken from gpsSol.groundSpeed in centimeters/seconds)
391391 * @param _3D is a 3D velocity
392392 * @param _max is a maximum velocity
393+ * @return length of the formatted string
393394 */
394- int osdFormatVelocityStr (char * buff , int32_t vel , bool _3D , bool _max )
395+ int osdFormatVelocityStr (char * buff , int32_t vel , osd_SpeedTypes_e speedType , bool _max )
395396{
397+ int strLen = 0 ;
398+
396399 switch ((osd_unit_e )osdConfig ()-> units ) {
397- case OSD_UNIT_UK :
398- FALLTHROUGH ;
399- case OSD_UNIT_METRIC_MPH :
400- FALLTHROUGH ;
401- case OSD_UNIT_IMPERIAL :
402- if (_max ) {
403- return tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_MPH : SYM_MPH ));
404- } else {
405- return tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_MPH : SYM_MPH ));
406- }
407- break ;
408- case OSD_UNIT_METRIC :
409- if (_max ) {
410- return tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_KMH : SYM_KMH ));
411- } else {
412- return tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_KMH : SYM_KMH ));
413- }
414- break ;
415- case OSD_UNIT_GA :
416- if (_max ) {
417- return tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_KT : SYM_KT ));
418- } else {
419- return tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), (_3D ? SYM_3D_KT : SYM_KT ));
420- }
421- break ;
400+ case OSD_UNIT_UK :
401+ FALLTHROUGH ;
402+ case OSD_UNIT_METRIC_MPH :
403+ FALLTHROUGH ;
404+ case OSD_UNIT_IMPERIAL :
405+ if (_max ) {
406+ switch (speedType ) {
407+ case OSD_SPEED_TYPE_GROUND :
408+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_MPH );
409+ break ;
410+ case OSD_SPEED_TYPE_AIR :
411+ strLen = tfp_sprintf (buff , "%c%c%3d%c" , SYM_MAX , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_MPH );
412+ break ;
413+ case OSD_SPEED_TYPE_3D :
414+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_3D_MPH );
415+ break ;
416+ case OSD_SPEED_TYPE_MIN_GROUND :
417+ break ;
418+ }
419+ } else {
420+ switch (speedType ){
421+ case OSD_SPEED_TYPE_GROUND :
422+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_MPH );
423+ break ;
424+ case OSD_SPEED_TYPE_AIR :
425+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_MPH );
426+ break ;
427+ case OSD_SPEED_TYPE_3D :
428+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_3D_MPH );
429+ break ;
430+ case OSD_SPEED_TYPE_MIN_GROUND :
431+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MIN_GROUND_SPEED , (int )osdConvertVelocityToUnit (vel ), SYM_MPH );
432+ break ;
433+ }
434+ }
435+ break ;
436+ case OSD_UNIT_METRIC :
437+ if (_max ) {
438+ switch (speedType ) {
439+ case OSD_SPEED_TYPE_GROUND :
440+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_KMH );
441+ break ;
442+ case OSD_SPEED_TYPE_AIR :
443+ strLen = tfp_sprintf (buff , "%c%c%3d%c" , SYM_MAX , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_KMH );
444+ break ;
445+ case OSD_SPEED_TYPE_3D :
446+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_3D_KMH );
447+ break ;
448+ case OSD_SPEED_TYPE_MIN_GROUND :
449+ break ;
450+ }
451+ } else {
452+ switch (speedType ) {
453+ case OSD_SPEED_TYPE_GROUND :
454+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_KMH );
455+ break ;
456+ case OSD_SPEED_TYPE_AIR :
457+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_KMH );
458+ break ;
459+ case OSD_SPEED_TYPE_3D :
460+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_3D_KMH );
461+ break ;
462+ case OSD_SPEED_TYPE_MIN_GROUND :
463+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MIN_GROUND_SPEED , (int )osdConvertVelocityToUnit (vel ), SYM_KMH );
464+ break ;
465+ }
466+ }
467+ break ;
468+ case OSD_UNIT_GA :
469+ if (_max ) {
470+ switch (speedType ) {
471+ case OSD_SPEED_TYPE_GROUND :
472+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_KT );
473+ break ;
474+ case OSD_SPEED_TYPE_AIR :
475+ strLen = tfp_sprintf (buff , "%c%c%3d%c" , SYM_MAX , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_KT );
476+ break ;
477+ case OSD_SPEED_TYPE_3D :
478+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MAX , (int )osdConvertVelocityToUnit (vel ), SYM_3D_KT );
479+ break ;
480+ case OSD_SPEED_TYPE_MIN_GROUND :
481+ break ;
482+ }
483+ } else {
484+ switch (speedType ) {
485+ case OSD_SPEED_TYPE_GROUND :
486+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_KT );
487+ break ;
488+ case OSD_SPEED_TYPE_AIR :
489+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_AIR , (int )osdConvertVelocityToUnit (vel ), SYM_KT );
490+ break ;
491+ case OSD_SPEED_TYPE_3D :
492+ strLen = tfp_sprintf (buff , "%3d%c" , (int )osdConvertVelocityToUnit (vel ), SYM_3D_KT );
493+ break ;
494+ case OSD_SPEED_TYPE_MIN_GROUND :
495+ strLen = tfp_sprintf (buff , "%c%3d%c" , SYM_MIN_GROUND_SPEED , (int )osdConvertVelocityToUnit (vel ), SYM_KT );
496+ break ;
497+ }
498+ }
499+ break ;
422500 }
423501
424- return 0 ;
502+ return strLen ;
425503}
426504
427505/**
428506 * Returns the average velocity. This always uses stats, so can be called as an OSD element later if wanted, to show a real time average
429507 */
430508static void osdGenerateAverageVelocityStr (char * buff ) {
431509 uint32_t cmPerSec = getTotalTravelDistance () / getFlightTime ();
432- osdFormatVelocityStr (buff , cmPerSec , false , false);
510+ osdFormatVelocityStr (buff , cmPerSec , OSD_SPEED_TYPE_GROUND , false);
433511}
434512
435513/**
@@ -1919,19 +1997,23 @@ static bool osdDrawSingleElement(uint8_t item)
19191997 break ;
19201998
19211999 case OSD_GPS_SPEED :
1922- osdFormatVelocityStr (buff , gpsSol .groundSpeed , false, false);
2000+ osdFormatVelocityStr (buff , gpsSol .groundSpeed , OSD_SPEED_TYPE_GROUND , false);
2001+ break ;
2002+
2003+ case OSD_NAV_MIN_GROUND_SPEED :
2004+ osdFormatVelocityStr (buff , getMinGroundSpeed (navConfig ()-> general .min_ground_speed ) * 100 , OSD_SPEED_TYPE_MIN_GROUND , false);
19232005 break ;
19242006
19252007 case OSD_GPS_MAX_SPEED :
1926- osdFormatVelocityStr (buff , stats .max_speed , false , true);
2008+ osdFormatVelocityStr (buff , stats .max_speed , OSD_SPEED_TYPE_GROUND , true);
19272009 break ;
19282010
19292011 case OSD_3D_SPEED :
1930- osdFormatVelocityStr (buff , osdGet3DSpeed (), true , false);
2012+ osdFormatVelocityStr (buff , osdGet3DSpeed (), OSD_SPEED_TYPE_3D , false);
19312013 break ;
19322014
19332015 case OSD_3D_MAX_SPEED :
1934- osdFormatVelocityStr (buff , stats .max_3D_speed , true , true);
2016+ osdFormatVelocityStr (buff , stats .max_3D_speed , OSD_SPEED_TYPE_3D , true);
19352017 break ;
19362018
19372019 case OSD_GLIDESLOPE :
@@ -2238,7 +2320,7 @@ static bool osdDrawSingleElement(uint8_t item)
22382320 tfp_sprintf (buff , "%s" , getAdsbEmitterTypeString (vehicle -> vehicleValues .emitterType ));
22392321
22402322 // Vehicle speed
2241- adsbLengthForClearSecondLine = osdFormatVelocityStr (buff + 7 , vehicle -> vehicleValues .horVelocity , false , false);
2323+ adsbLengthForClearSecondLine = osdFormatVelocityStr (buff + 7 , vehicle -> vehicleValues .horVelocity , OSD_SPEED_TYPE_GROUND , false);
22422324
22432325 // draw values
22442326 buff [6 ] = SYM_BLANK ; // space for direction arrow
@@ -3326,19 +3408,18 @@ static bool osdDrawSingleElement(uint8_t item)
33263408 case OSD_AIR_SPEED :
33273409 {
33283410 #ifdef USE_PITOT
3329- buff [0 ] = SYM_AIR ;
3330-
33313411 if (pitotIsHealthy ())
33323412 {
33333413 const float airspeed_estimate = getAirspeedEstimate ();
3334- osdFormatVelocityStr (buff + 1 , airspeed_estimate , false , false);
3414+ osdFormatVelocityStr (buff , airspeed_estimate , OSD_SPEED_TYPE_AIR , false);
33353415 if ((osdConfig ()-> airspeed_alarm_min != 0 && airspeed_estimate < osdConfig ()-> airspeed_alarm_min ) ||
33363416 (osdConfig ()-> airspeed_alarm_max != 0 && airspeed_estimate > osdConfig ()-> airspeed_alarm_max )) {
33373417 TEXT_ATTRIBUTES_ADD_BLINK (elemAttr );
33383418 }
33393419 }
33403420 else
33413421 {
3422+ buff [0 ] = SYM_AIR ;
33423423 strcpy (buff + 1 , " X!" );
33433424 TEXT_ATTRIBUTES_ADD_BLINK (elemAttr );
33443425 }
@@ -3351,9 +3432,7 @@ static bool osdDrawSingleElement(uint8_t item)
33513432 case OSD_AIR_MAX_SPEED :
33523433 {
33533434 #ifdef USE_PITOT
3354- buff [0 ] = SYM_MAX ;
3355- buff [1 ] = SYM_AIR ;
3356- osdFormatVelocityStr (buff + 2 , stats .max_air_speed , false, false);
3435+ osdFormatVelocityStr (buff , stats .max_air_speed , OSD_SPEED_TYPE_AIR , true);
33573436 #else
33583437 return false;
33593438 #endif
@@ -4919,7 +4998,7 @@ uint8_t drawStat_Speed(uint8_t col, uint8_t row, uint8_t statValX)
49194998
49204999 displayWrite (osdDisplayPort , col , row , "MAX/AVG SPEED" );
49215000
4922- osdFormatVelocityStr (buff2 , stats .max_3D_speed , true , false);
5001+ osdFormatVelocityStr (buff2 , stats .max_3D_speed , OSD_SPEED_TYPE_3D , false);
49235002 tfp_sprintf (buff , ": %s/" , osdFormatTrimWhiteSpace (buff2 ));
49245003 multiValueXOffset = strlen (buff );
49255004 displayWrite (osdDisplayPort , statValX , row , buff );
@@ -6220,7 +6299,7 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
62206299 if (FLIGHT_MODE (NAV_COURSE_HOLD_MODE )) {
62216300 if (posControl .cruise .multicopterSpeed >= 50.0f ) {
62226301 char buf [6 ];
6223- osdFormatVelocityStr (buf , posControl .cruise .multicopterSpeed , false , false);
6302+ osdFormatVelocityStr (buf , posControl .cruise .multicopterSpeed , OSD_SPEED_TYPE_GROUND , false);
62246303 tfp_sprintf (messageBuf , "(SPD %s)" , buf );
62256304 } else {
62266305 strcpy (messageBuf , "(HOLD)" );
0 commit comments