1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-13 11:29:56 +03:00

Merge branch 'master' of https://github.com/RomanLut/inav into osd-joystick

This commit is contained in:
Roman Lut 2023-10-09 15:12:10 +02:00
commit 8ed76152a8
29 changed files with 253 additions and 170 deletions

View file

@ -56,6 +56,7 @@ Krzysztof Rosinski
Kyle Manna Kyle Manna
Larry Davis Larry Davis
Marc Egli Marc Egli
Marcelo Bezerra
Mark Williams Mark Williams
Martin Budden Martin Budden
Matthew Evans Matthew Evans

View file

@ -44,9 +44,9 @@ The stick positions are combined to activate different functions:
| Bypass Nav Arm disable | LOW | HIGH | CENTER | CENTER | | Bypass Nav Arm disable | LOW | HIGH | CENTER | CENTER |
| Save setting | LOW | LOW | LOW | HIGH | | Save setting | LOW | LOW | LOW | HIGH |
| Enter OSD Menu (CMS) | CENTER | LOW | HIGH | CENTER | | Enter OSD Menu (CMS) | CENTER | LOW | HIGH | CENTER |
| Enter Camera OSD(RuncamDevice)| RIGHT | CENTER | CENTER | CENTER | | Enter Camera OSD(RuncamDevice)| CENTER | HIGH | CENTER | CENTER |
| Exit Camera OSD (RuncamDevice)| LEFT | CENTER | CENTER | CENTER | | Exit Camera OSD (RuncamDevice)| CENTER | LOW | CENTER | CENTER |
| Confirm - Camera OSD | RIGHT | CENTER | CENTER | CENTER | | Confirm - Camera OSD | CENTER | HIGH | CENTER | CENTER |
| Navigation - Camera OSD | CENTER | CENTER | * | * | | Navigation - Camera OSD | CENTER | CENTER | * | * |
For graphical stick position in all transmitter modes, check out [this page](https://www.mrd-rc.com/tutorials-tools-and-testing/inav-flight/inav-stick-commands-for-all-transmitter-modes/). For graphical stick position in all transmitter modes, check out [this page](https://www.mrd-rc.com/tutorials-tools-and-testing/inav-flight/inav-stick-commands-for-all-transmitter-modes/).

View file

@ -153,6 +153,9 @@ IPF can be edited using INAV Configurator user interface, or via CLI. To use COn
| 35 | AGL_STATUS | boolean `1` when AGL can be trusted, `0` when AGL estimate can not be trusted | | 35 | AGL_STATUS | boolean `1` when AGL can be trusted, `0` when AGL estimate can not be trusted |
| 36 | AGL | integer Above The Groud Altitude in `cm` | | 36 | AGL | integer Above The Groud Altitude in `cm` |
| 37 | RANGEFINDER_RAW | integer raw distance provided by the rangefinder in `cm` | | 37 | RANGEFINDER_RAW | integer raw distance provided by the rangefinder in `cm` |
| 38 | ACTIVE_MIXER_PROFILE | Which mixers are currently active (for vtol etc) |
| 39 | MIXER_TRANSITION_ACTIVE | Currently switching between mixers (quad to plane etc) |
| 40 | ATTITUDE_YAW | current heading (yaw) in `degrees` |
#### FLIGHT_MODE #### FLIGHT_MODE

View file

@ -89,23 +89,6 @@ To change for example the configuration of the fourth sensor to label `BATT`, mi
`temp_sensor 3 2 7d01186838f2ff28 5 450 0 BATT` `temp_sensor 3 2 7d01186838f2ff28 5 450 0 BATT`
## Building a custom firmware with temperature sensor support (F3 only)
This needs to be added in the `target.h` file:
```
#define USE_TEMPERATURE_SENSOR
#define TEMPERATURE_I2C_BUS BUS_I2Cx // replace x with the index of the I²C bus the temperature sensors will be connected to
// for LM75 sensors support
#define USE_TEMPERATURE_LM75
// for DS18B20 sensors
#define USE_1WIRE
#define USE_1WIRE_DS2482
#define USE_TEMPERATURE_DS18B20
```
## Configuring the way OSD temperature labels are displayed ## Configuring the way OSD temperature labels are displayed
You can use the `osd_temp_label_align` setting to chose how the labels for the temperature sensor's values are displayed. Possible alignment values are `LEFT` and `RIGHT`. You can use the `osd_temp_label_align` setting to chose how the labels for the temperature sensor's values are displayed. Possible alignment values are `LEFT` and `RIGHT`.

View file

@ -16,7 +16,7 @@ Building the pull request manually or using custom/unofficial targets is not the
- Make sure the pull request has passed all checks, otherwise you may not have pre-compiled firmware images. - Make sure the pull request has passed all checks, otherwise you may not have pre-compiled firmware images.
- Make a diff all backup of your existing INAV configuration. - Make a diff all backup of your existing INAV configuration.
- Take notes of what INAV target you are using. - Take notes of what INAV target you are using.
- You will need a recent version of INAV Configurator from master, or even a specific branch. If you don't need a specific branch, [inav-configurator-next](http://seyrsnys.myzen.co.uk/inav-configurator-next/) usually has recent unofficial pre-built versions of INAV Configurator. If your pull requests refers to an inav-configruator pull request, you are likely to need a specific branch of the configurator. In that case you can try to build it from source by following the build [``Instructions``](https://github.com/iNavFlight/inav-configurator#building-and-running-inav-configurator-locally-for-development) or follow instructions on how to do any needed configuration changes using the CLI. - You will need a recent version of INAV Configurator from master, or even a specific branch. If you don't need a specific branch, [inav-configurator-next](https://seyrsnys-inav-cfg-next.surge.sh/) usually has recent unofficial pre-built versions of INAV Configurator. If your pull requests refers to an inav-configruator pull request, you are likely to need a specific branch of the configurator. In that case you can try to build it from source by following the build [``Instructions``](https://github.com/iNavFlight/inav-configurator#building-and-running-inav-configurator-locally-for-development) or follow instructions on how to do any needed configuration changes using the CLI.
# Finding the pull request # Finding the pull request
This is easy, but you will need to be logged in to your GitHub account. This is easy, but you will need to be logged in to your GitHub account.
@ -31,18 +31,11 @@ Once you find the one you are looking for, go ahead an open it!
Click on the ``Checks`` tab Click on the ``Checks`` tab
Click on ``Build firmware``, it should take you to the ``Actions`` tab. Click on the down arrow next to the number of artifacts
![Search results](assets/pr_testing/build_firmware.png) ![Artifact list](assets/pr_testing/artifacts_download.png)
You should see a summary with a column saying ``Artifacts`` and a number. Click on the number to be taken to the list of artifacts. You should see a list of files. The one without SITL in the name, the biggest one, will be a zip file with all official target .hex files. Click on it to download it to your computer.
Extract all files and select the firmware for your target using the configurator by clicking on ``Load Firmware [Local]`` button. Don't forget to use the ``Full chip erase`` option, as there are no guarantees the firmware will be compatible with your existing settings.
![Search results](assets/pr_testing/actions_summary.png)
On the ``Artifacts`` list, there should be an artifact without SITL in its name.
![Search results](assets/pr_testing/artifact_listing.png)
Click on it to download the zip file containing pre-compiled firmware images for all INAV official targets. Extract all files and select the firmware for your target using the configurator by clicking on ``Load Firmware [Local]`` button. Don't forget to use the ``Full chip erase`` option, as there are no guarantees the firmware will be compatible with your existing settings.
# I have flashed the new firmware, what should I do next? # I have flashed the new firmware, what should I do next?

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View file

@ -25,15 +25,15 @@
#endif #endif
// Undefine this for use libc sinf/cosf. Keep this defined to use fast sin/cos approximations // Undefine this for use libc sinf/cosf. Keep this defined to use fast sin/cos approximations
#define FAST_MATH // order 9 approximation #define FAST_MATH // order 9 approximation
//#define VERY_FAST_MATH // order 7 approximation //#define VERY_FAST_MATH // order 7 approximation
// Use floating point M_PI instead explicitly. // Use floating point M_PI instead explicitly.
#define M_PIf 3.14159265358979323846f #define M_PIf 3.14159265358979323846f
#define M_LN2f 0.69314718055994530942f #define M_LN2f 0.69314718055994530942f
#define M_Ef 2.71828182845904523536f #define M_Ef 2.71828182845904523536f
#define RAD (M_PIf / 180.0f) #define RAD (M_PIf / 180.0f)
#define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100) #define DEGREES_TO_CENTIDEGREES(angle) ((angle) * 100)
#define CENTIDEGREES_TO_DEGREES(angle) ((angle) / 100.0f) #define CENTIDEGREES_TO_DEGREES(angle) ((angle) / 100.0f)
@ -56,46 +56,46 @@
#define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD) #define RADIANS_TO_CENTIDEGREES(angle) (((angle) * 100.0f) / RAD)
#define CENTIDEGREES_TO_RADIANS(angle) (((angle) / 100.0f) * RAD) #define CENTIDEGREES_TO_RADIANS(angle) (((angle) / 100.0f) * RAD)
#define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f) #define CENTIMETERS_TO_CENTIFEET(cm) (cm / 0.3048f)
#define CENTIMETERS_TO_FEET(cm) (cm / 30.48f) #define CENTIMETERS_TO_FEET(cm) (cm / 30.48f)
#define CENTIMETERS_TO_METERS(cm) (cm / 100.0f) #define CENTIMETERS_TO_METERS(cm) (cm / 100.0f)
#define METERS_TO_CENTIMETERS(m) (m * 100) #define METERS_TO_CENTIMETERS(m) (m * 100)
#define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f) #define CMSEC_TO_CENTIMPH(cms) (cms * 2.2369363f)
#define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f) #define CMSEC_TO_CENTIKPH(cms) (cms * 3.6f)
#define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f) #define CMSEC_TO_CENTIKNOTS(cms) (cms * 1.943845f)
#define C_TO_KELVIN(temp) (temp + 273.15f) #define C_TO_KELVIN(temp) (temp + 273.15f)
// Standard Sea Level values // Standard Sea Level values
// Ref:https://en.wikipedia.org/wiki/Standard_sea_level // Ref:https://en.wikipedia.org/wiki/Standard_sea_level
#define SSL_AIR_DENSITY 1.225f // kg/m^3 #define SSL_AIR_DENSITY 1.225f // kg/m^3
#define SSL_AIR_PRESSURE 101325.01576f // Pascal #define SSL_AIR_PRESSURE 101325.01576f // Pascal
#define SSL_AIR_TEMPERATURE 288.15f // K #define SSL_AIR_TEMPERATURE 288.15f // K
// copied from https://code.google.com/p/cxutil/source/browse/include/cxutil/utility.h#70 // copied from https://code.google.com/p/cxutil/source/browse/include/cxutil/utility.h#70
#define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \ #define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
( __extension__ ({ \ ( __extension__ ({ \
__typeof__(lexpr) lvar = (lexpr); \ __typeof__(lexpr) lvar = (lexpr); \
__typeof__(rexpr) rvar = (rexpr); \ __typeof__(rexpr) rvar = (rexpr); \
lvar binoper rvar ? lvar : rvar; \ lvar binoper rvar ? lvar : rvar; \
})) }))
#define _CHOOSE_VAR2(prefix, unique) prefix##unique #define _CHOOSE_VAR2(prefix, unique) prefix##unique
#define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique) #define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#define _CHOOSE(binoper, lexpr, rexpr) \ #define _CHOOSE(binoper, lexpr, rexpr) \
_CHOOSE2( \ _CHOOSE2( \
binoper, \ binoper, \
lexpr, _CHOOSE_VAR(_left, __COUNTER__), \ lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
rexpr, _CHOOSE_VAR(_right, __COUNTER__) \ rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
) )
#define MIN(a, b) _CHOOSE(<, a, b) #define MIN(a, b) _CHOOSE(<, a, b)
#define MAX(a, b) _CHOOSE(>, a, b) #define MAX(a, b) _CHOOSE(>, a, b)
#define _ABS_II(x, var) \ #define _ABS_II(x, var) \
( __extension__ ({ \ ( __extension__ ({ \
__typeof__(x) var = (x); \ __typeof__(x) var = (x); \
var < 0 ? -var : var; \ var < 0 ? -var : var; \
})) }))
#define _ABS_I(x, var) _ABS_II(x, var) #define _ABS_I(x, var) _ABS_II(x, var)
#define ABS(x) _ABS_I(x, _CHOOSE_VAR(_abs, __COUNTER__)) #define ABS(x) _ABS_I(x, _CHOOSE_VAR(_abs, __COUNTER__))
@ -114,8 +114,7 @@ typedef union {
fp_angles_def angles; fp_angles_def angles;
} fp_angles_t; } fp_angles_t;
typedef struct stdev_s typedef struct stdev_s {
{
float m_oldM, m_newM, m_oldS, m_newS; float m_oldM, m_newM, m_oldS, m_newS;
int m_n; int m_n;
} stdev_t; } stdev_t;

View file

@ -228,6 +228,7 @@
#define SYM_HOME_DIST 0x165 // 357 DIST #define SYM_HOME_DIST 0x165 // 357 DIST
#define SYM_AH_CH_CENTER 0x166 // 358 Crossair center #define SYM_AH_CH_CENTER 0x166 // 358 Crossair center
#define SYM_FLIGHT_DIST_REMAINING 0x167 // 359 Flight distance reminaing #define SYM_FLIGHT_DIST_REMAINING 0x167 // 359 Flight distance reminaing
#define SYM_ODOMETER 0x168 // 360 Odometer
#define SYM_AH_CH_TYPE3 0x190 // 400 to 402, crosshair 3 #define SYM_AH_CH_TYPE3 0x190 // 400 to 402, crosshair 3
#define SYM_AH_CH_TYPE4 0x193 // 403 to 405, crosshair 4 #define SYM_AH_CH_TYPE4 0x193 // 403 to 405, crosshair 4

View file

@ -305,6 +305,7 @@ static void activateConfig(void)
{ {
activateControlRateConfig(); activateControlRateConfig();
activateBatteryProfile(); activateBatteryProfile();
activateMixerConfig();
resetAdjustmentStates(); resetAdjustmentStates();
@ -486,7 +487,6 @@ bool setConfigMixerProfile(uint8_t profileIndex)
profileIndex = 0; profileIndex = 0;
} }
systemConfigMutable()->current_mixer_profile_index = profileIndex; systemConfigMutable()->current_mixer_profile_index = profileIndex;
// setMixerProfile(profileIndex);
return ret; return ret;
} }

View file

@ -1582,6 +1582,21 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
break; break;
#endif #endif
#ifdef USE_RATE_DYNAMICS
case MSP2_INAV_RATE_DYNAMICS:
{
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.sensitivityCenter);
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.sensitivityEnd);
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.correctionCenter);
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.correctionEnd);
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.weightCenter);
sbufWriteU8(dst, currentControlRateProfile->rateDynamics.weightEnd);
}
break;
#endif
default: default:
return false; return false;
} }
@ -3040,6 +3055,27 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break; break;
#endif #endif
#ifdef USE_RATE_DYNAMICS
case MSP2_INAV_SET_RATE_DYNAMICS:
if (dataSize == 6) {
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.sensitivityCenter = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.sensitivityEnd = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.correctionCenter = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.correctionEnd = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.weightCenter = sbufReadU8(src);
((controlRateConfig_t*)currentControlRateProfile)->rateDynamics.weightEnd = sbufReadU8(src);
} else {
return MSP_RESULT_ERROR;
}
break;
#endif
default: default:
return MSP_RESULT_ERROR; return MSP_RESULT_ERROR;
} }

View file

@ -3,8 +3,8 @@
#ifdef USE_STATS #ifdef USE_STATS
typedef struct statsConfig_s { typedef struct statsConfig_s {
uint32_t stats_total_time; // [s] uint32_t stats_total_time; // [Seconds]
uint32_t stats_total_dist; // [m] uint32_t stats_total_dist; // [Metres]
#ifdef USE_ADC #ifdef USE_ADC
uint32_t stats_total_energy; // deciWatt hour (x0.1Wh) uint32_t stats_total_energy; // deciWatt hour (x0.1Wh)
#endif #endif

View file

@ -77,11 +77,15 @@ void pgResetFn_mixerProfiles(mixerProfile_t *instance)
} }
} }
void mixerConfigInit(void) void activateMixerConfig(){
{
currentMixerProfileIndex = getConfigMixerProfile(); currentMixerProfileIndex = getConfigMixerProfile();
currentMixerConfig = *mixerConfig(); currentMixerConfig = *mixerConfig();
nextProfileIndex = (currentMixerProfileIndex + 1) % MAX_MIXER_PROFILE_COUNT; nextProfileIndex = (currentMixerProfileIndex + 1) % MAX_MIXER_PROFILE_COUNT;
}
void mixerConfigInit(void)
{
activateMixerConfig();
servosInit(); servosInit();
mixerUpdateStateFlags(); mixerUpdateStateFlags();
mixerInit(); mixerInit();

View file

@ -73,5 +73,6 @@ static inline const mixerProfile_t* mixerProfiles_CopyArray_by_index(int _index)
bool outputProfileHotSwitch(int profile_index); bool outputProfileHotSwitch(int profile_index);
bool checkMixerProfileHotSwitchAvalibility(void); bool checkMixerProfileHotSwitchAvalibility(void);
void activateMixerConfig(void);
void mixerConfigInit(void); void mixerConfigInit(void);
void outputProfileUpdateTask(timeUs_t currentTimeUs); void outputProfileUpdateTask(timeUs_t currentTimeUs);

View file

@ -209,8 +209,8 @@ float calculateRemainingFlightTimeBeforeRTH(bool takeWindIntoAccount) {
// returns meters // returns meters
float calculateRemainingDistanceBeforeRTH(bool takeWindIntoAccount) { float calculateRemainingDistanceBeforeRTH(bool takeWindIntoAccount) {
// Fixed wing only for now // Fixed wing only for now, and must be armed
if (!(STATE(FIXED_WING_LEGACY) || ARMING_FLAG(ARMED))) { if (!STATE(AIRPLANE) || !ARMING_FLAG(ARMED)) {
return -1; return -1;
} }

View file

@ -316,7 +316,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals)
case OSD_UNIT_UK: case OSD_UNIT_UK:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), FEET_PER_MILE, decimals, 3, digits)) { if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), FEET_PER_MILE, decimals, 3, digits, false)) {
buff[sym_index] = symbol_mi; buff[sym_index] = symbol_mi;
} else { } else {
buff[sym_index] = symbol_ft; buff[sym_index] = symbol_ft;
@ -326,7 +326,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals)
case OSD_UNIT_METRIC_MPH: case OSD_UNIT_METRIC_MPH:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
if (osdFormatCentiNumber(buff, dist, METERS_PER_KILOMETER, decimals, 3, digits)) { if (osdFormatCentiNumber(buff, dist, METERS_PER_KILOMETER, decimals, 3, digits, false)) {
buff[sym_index] = symbol_km; buff[sym_index] = symbol_km;
} else { } else {
buff[sym_index] = symbol_m; buff[sym_index] = symbol_m;
@ -334,7 +334,7 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals)
buff[sym_index + 1] = '\0'; buff[sym_index + 1] = '\0';
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), (uint32_t)FEET_PER_NAUTICALMILE, decimals, 3, digits)) { if (osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(dist), (uint32_t)FEET_PER_NAUTICALMILE, decimals, 3, digits, false)) {
buff[sym_index] = symbol_nm; buff[sym_index] = symbol_nm;
} else { } else {
buff[sym_index] = symbol_ft; buff[sym_index] = symbol_ft;
@ -489,7 +489,7 @@ static void osdFormatWindSpeedStr(char *buff, int32_t ws, bool isValid)
break; break;
} }
osdFormatCentiNumber(buff, centivalue, 0, 2, 0, 3); osdFormatCentiNumber(buff, centivalue, 0, 2, 0, 3, false);
if (!isValid && ((millis() / 1000) % 4 < 2)) if (!isValid && ((millis() / 1000) % 4 < 2))
suffix = '*'; suffix = '*';
@ -562,7 +562,7 @@ void osdFormatAltitudeSymbol(char *buff, int32_t alt)
case OSD_UNIT_GA: case OSD_UNIT_GA:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
if (osdFormatCentiNumber(buff + totalDigits - digits, CENTIMETERS_TO_CENTIFEET(alt), 1000, 0, 2, digits)) { if (osdFormatCentiNumber(buff + totalDigits - digits, CENTIMETERS_TO_CENTIFEET(alt), 1000, 0, 2, digits, false)) {
// Scaled to kft // Scaled to kft
buff[symbolIndex++] = symbolKFt; buff[symbolIndex++] = symbolKFt;
} else { } else {
@ -575,7 +575,7 @@ void osdFormatAltitudeSymbol(char *buff, int32_t alt)
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
// alt is alredy in cm // alt is alredy in cm
if (osdFormatCentiNumber(buff + totalDigits - digits, alt, 1000, 0, 2, digits)) { if (osdFormatCentiNumber(buff + totalDigits - digits, alt, 1000, 0, 2, digits, false)) {
// Scaled to km // Scaled to km
buff[symbolIndex++] = SYM_ALT_KM; buff[symbolIndex++] = SYM_ALT_KM;
} else { } else {
@ -1151,7 +1151,7 @@ static void osdFormatGVar(char *buff, uint8_t index)
buff[1] = '0'+index; buff[1] = '0'+index;
buff[2] = ':'; buff[2] = ':';
#ifdef USE_PROGRAMMING_FRAMEWORK #ifdef USE_PROGRAMMING_FRAMEWORK
osdFormatCentiNumber(buff + 3, (int32_t)gvGet(index)*(int32_t)100, 1, 0, 0, 5); osdFormatCentiNumber(buff + 3, (int32_t)gvGet(index)*(int32_t)100, 1, 0, 0, 5, false);
#endif #endif
} }
@ -1162,7 +1162,7 @@ static void osdFormatRpm(char *buff, uint32_t rpm)
if (rpm) { if (rpm) {
if ( digitCount(rpm) > osdConfig()->esc_rpm_precision) { if ( digitCount(rpm) > osdConfig()->esc_rpm_precision) {
uint8_t rpmMaxDecimals = (osdConfig()->esc_rpm_precision - 3); uint8_t rpmMaxDecimals = (osdConfig()->esc_rpm_precision - 3);
osdFormatCentiNumber(buff + 1, rpm / 10, 0, rpmMaxDecimals, rpmMaxDecimals, osdConfig()->esc_rpm_precision-1); osdFormatCentiNumber(buff + 1, rpm / 10, 0, rpmMaxDecimals, rpmMaxDecimals, osdConfig()->esc_rpm_precision-1, false);
buff[osdConfig()->esc_rpm_precision] = 'K'; buff[osdConfig()->esc_rpm_precision] = 'K';
buff[osdConfig()->esc_rpm_precision+1] = '\0'; buff[osdConfig()->esc_rpm_precision+1] = '\0';
} }
@ -1486,13 +1486,13 @@ static void osdFormatPidControllerOutput(char *buff, const char *label, const pi
strcpy(buff, label); strcpy(buff, label);
for (uint8_t i = strlen(label); i < 5; ++i) buff[i] = ' '; for (uint8_t i = strlen(label); i < 5; ++i) buff[i] = ' ';
uint8_t decimals = showDecimal ? 1 : 0; uint8_t decimals = showDecimal ? 1 : 0;
osdFormatCentiNumber(buff + 5, pidController->proportional * scale, 0, decimals, 0, 4); osdFormatCentiNumber(buff + 5, pidController->proportional * scale, 0, decimals, 0, 4, false);
buff[9] = ' '; buff[9] = ' ';
osdFormatCentiNumber(buff + 10, pidController->integrator * scale, 0, decimals, 0, 4); osdFormatCentiNumber(buff + 10, pidController->integrator * scale, 0, decimals, 0, 4, false);
buff[14] = ' '; buff[14] = ' ';
osdFormatCentiNumber(buff + 15, pidController->derivative * scale, 0, decimals, 0, 4); osdFormatCentiNumber(buff + 15, pidController->derivative * scale, 0, decimals, 0, 4, false);
buff[19] = ' '; buff[19] = ' ';
osdFormatCentiNumber(buff + 20, pidController->output_constrained * scale, 0, decimals, 0, 4); osdFormatCentiNumber(buff + 20, pidController->output_constrained * scale, 0, decimals, 0, 4, false);
buff[24] = '\0'; buff[24] = '\0';
} }
@ -1508,7 +1508,7 @@ static void osdDisplayBatteryVoltage(uint8_t elemPosX, uint8_t elemPosY, uint16_
elemAttr = TEXT_ATTRIBUTES_NONE; elemAttr = TEXT_ATTRIBUTES_NONE;
digits = MIN(digits, 5); digits = MIN(digits, 5);
osdFormatCentiNumber(buff, voltage, 0, decimals, 0, digits); osdFormatCentiNumber(buff, voltage, 0, decimals, 0, digits, false);
buff[digits] = SYM_VOLT; buff[digits] = SYM_VOLT;
buff[digits+1] = '\0'; buff[digits+1] = '\0';
const batteryState_e batteryVoltageState = checkBatteryVoltageState(); const batteryState_e batteryVoltageState = checkBatteryVoltageState();
@ -1602,7 +1602,7 @@ static void osdDisplayAdjustableDecimalValue(uint8_t elemPosX, uint8_t elemPosY,
displayWrite(osdDisplayPort, elemPosX, elemPosY, str); displayWrite(osdDisplayPort, elemPosX, elemPosY, str);
elemAttr = TEXT_ATTRIBUTES_NONE; elemAttr = TEXT_ATTRIBUTES_NONE;
osdFormatCentiNumber(buff, value * 100, 0, maxDecimals, 0, MIN(valueLength, 8)); osdFormatCentiNumber(buff, value * 100, 0, maxDecimals, 0, MIN(valueLength, 8), false);
if (isAdjustmentFunctionSelected(adjFunc)) if (isAdjustmentFunctionSelected(adjFunc))
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
displayWriteWithAttr(osdDisplayPort, elemPosX + strlen(str) + 1 + valueOffset, elemPosY, buff, elemAttr); displayWriteWithAttr(osdDisplayPort, elemPosX + strlen(str) + 1 + valueOffset, elemPosY, buff, elemAttr);
@ -1707,7 +1707,7 @@ static bool osdDrawSingleElement(uint8_t item)
} }
case OSD_CURRENT_DRAW: { case OSD_CURRENT_DRAW: {
osdFormatCentiNumber(buff, getAmperage(), 0, 2, 0, 3); osdFormatCentiNumber(buff, getAmperage(), 0, 2, 0, 3, false);
buff[3] = SYM_AMP; buff[3] = SYM_AMP;
buff[4] = '\0'; buff[4] = '\0';
@ -1734,7 +1734,7 @@ static bool osdDrawSingleElement(uint8_t item)
buff[5] = SYM_MAH; buff[5] = SYM_MAH;
buff[6] = '\0'; buff[6] = '\0';
} else { } else {
if (osdFormatCentiNumber(buff, getMAhDrawn() * 100, 1000, 0, (mah_digits - 2), mah_digits)) { if (osdFormatCentiNumber(buff, getMAhDrawn() * 100, 1000, 0, (mah_digits - 2), mah_digits, false)) {
// Shown in Ah // Shown in Ah
buff[mah_digits] = SYM_AH; buff[mah_digits] = SYM_AH;
} else { } else {
@ -1749,7 +1749,7 @@ static bool osdDrawSingleElement(uint8_t item)
} }
case OSD_WH_DRAWN: case OSD_WH_DRAWN:
osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3, false);
osdUpdateBatteryCapacityOrVoltageTextAttributes(&elemAttr); osdUpdateBatteryCapacityOrVoltageTextAttributes(&elemAttr);
buff[3] = SYM_WH; buff[3] = SYM_WH;
buff[4] = '\0'; buff[4] = '\0';
@ -1764,7 +1764,7 @@ static bool osdDrawSingleElement(uint8_t item)
else if (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH) else if (currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH)
tfp_sprintf(buff, "%4lu", (unsigned long)getBatteryRemainingCapacity()); tfp_sprintf(buff, "%4lu", (unsigned long)getBatteryRemainingCapacity());
else // currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH else // currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MWH
osdFormatCentiNumber(buff + 1, getBatteryRemainingCapacity() / 10, 0, 2, 0, 3); osdFormatCentiNumber(buff + 1, getBatteryRemainingCapacity() / 10, 0, 2, 0, 3, false);
buff[4] = currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH; buff[4] = currentBatteryProfile->capacity.unit == BAT_CAPACITY_UNIT_MAH ? SYM_MAH : SYM_WH;
buff[5] = '\0'; buff[5] = '\0';
@ -1834,7 +1834,7 @@ static bool osdDrawSingleElement(uint8_t item)
buff[0] = SYM_GLIDESLOPE; buff[0] = SYM_GLIDESLOPE;
if (glideSlope > 0.0f && glideSlope < 100.0f) { if (glideSlope > 0.0f && glideSlope < 100.0f) {
osdFormatCentiNumber(buff + 1, glideSlope * 100.0f, 0, 2, 0, 3); osdFormatCentiNumber(buff + 1, glideSlope * 100.0f, 0, 2, 0, 3, false);
} else { } else {
buff[1] = buff[2] = buff[3] = '-'; buff[1] = buff[2] = buff[3] = '-';
} }
@ -1912,6 +1912,39 @@ static bool osdDrawSingleElement(uint8_t item)
osdFormatDistanceSymbol(buff + 1, getTotalTravelDistance(), 0); osdFormatDistanceSymbol(buff + 1, getTotalTravelDistance(), 0);
break; break;
case OSD_ODOMETER:
{
displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_ODOMETER);
uint32_t odometerDist = (uint32_t)(getTotalTravelDistance() / 100);
#ifdef USE_STATS
odometerDist+= statsConfig()->stats_total_dist;
#endif
odometerDist = odometerDist / 10;
switch (osdConfig()->units) {
case OSD_UNIT_UK:
FALLTHROUGH;
case OSD_UNIT_IMPERIAL:
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(odometerDist), FEET_PER_MILE, 1, 0, 6, true);
buff[6] = SYM_MI;
break;
default:
case OSD_UNIT_GA:
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(odometerDist), (uint32_t)FEET_PER_NAUTICALMILE, 1, 0, 6, true);
buff[6] = SYM_NM;
break;
case OSD_UNIT_METRIC_MPH:
FALLTHROUGH;
case OSD_UNIT_METRIC:
osdFormatCentiNumber(buff, odometerDist, METERS_PER_KILOMETER, 1, 0, 6, true);
buff[6] = SYM_KM;
break;
}
buff[7] = '\0';
elemPosX++;
}
break;
case OSD_GROUND_COURSE: case OSD_GROUND_COURSE:
{ {
buff[0] = SYM_GROUND_COURSE; buff[0] = SYM_GROUND_COURSE;
@ -1994,7 +2027,7 @@ static bool osdDrawSingleElement(uint8_t item)
digits = 3U; digits = 3U;
} }
#endif #endif
osdFormatCentiNumber(&buff[2], centiHDOP, 0, 1, 0, digits); osdFormatCentiNumber(&buff[2], centiHDOP, 0, 1, 0, digits, false);
break; break;
} }
@ -2147,37 +2180,38 @@ static bool osdDrawSingleElement(uint8_t item)
updatedTimestamp = currentTimeUs; updatedTimestamp = currentTimeUs;
} }
#endif #endif
//buff[0] = SYM_TRIP_DIST;
displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_FLIGHT_DIST_REMAINING); displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_FLIGHT_DIST_REMAINING);
if ((!ARMING_FLAG(ARMED)) || (distanceMeters == -1)) { if ((!ARMING_FLAG(ARMED)) || (distanceMeters == -1)) {
buff[4] = SYM_BLANK; buff[3] = SYM_BLANK;
buff[5] = '\0'; buff[4] = '\0';
strcpy(buff + 1, "---"); strcpy(buff, "---");
} else if (distanceMeters == -2) { } else if (distanceMeters == -2) {
// Wind is too strong to come back with cruise throttle // Wind is too strong to come back with cruise throttle
buff[1] = buff[2] = buff[3] = SYM_WIND_HORIZONTAL; buff[0] = buff[1] = buff[2] = SYM_WIND_HORIZONTAL;
switch ((osd_unit_e)osdConfig()->units){ switch ((osd_unit_e)osdConfig()->units){
case OSD_UNIT_UK: case OSD_UNIT_UK:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
buff[4] = SYM_DIST_MI; buff[3] = SYM_DIST_MI;
break; break;
case OSD_UNIT_METRIC_MPH: case OSD_UNIT_METRIC_MPH:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
buff[4] = SYM_DIST_KM; buff[3] = SYM_DIST_KM;
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
buff[4] = SYM_DIST_NM; buff[3] = SYM_DIST_NM;
break; break;
} }
buff[5] = '\0'; buff[4] = '\0';
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
} else { } else {
osdFormatDistanceSymbol(buff + 1, distanceMeters * 100, 0); osdFormatDistanceSymbol(buff, distanceMeters * 100, 0);
if (distanceMeters == 0) if (distanceMeters == 0)
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
} }
elemPosX++;
break; break;
case OSD_FLYMODE: case OSD_FLYMODE:
@ -2423,7 +2457,7 @@ static bool osdDrawSingleElement(uint8_t item)
buff[0] = SYM_ROLL_LEVEL; buff[0] = SYM_ROLL_LEVEL;
if (ABS(attitude.values.roll) >= 1) if (ABS(attitude.values.roll) >= 1)
buff[0] += (attitude.values.roll < 0 ? -1 : 1); buff[0] += (attitude.values.roll < 0 ? -1 : 1);
osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.roll)), 0, 1, 0, 3); osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.roll)), 0, 1, 0, 3, false);
break; break;
case OSD_ATTITUDE_PITCH: case OSD_ATTITUDE_PITCH:
@ -2433,7 +2467,7 @@ static bool osdDrawSingleElement(uint8_t item)
buff[0] = SYM_PITCH_DOWN; buff[0] = SYM_PITCH_DOWN;
else if (attitude.values.pitch < 0) else if (attitude.values.pitch < 0)
buff[0] = SYM_PITCH_UP; buff[0] = SYM_PITCH_UP;
osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.pitch)), 0, 1, 0, 3); osdFormatCentiNumber(buff + 1, DECIDEGREES_TO_CENTIDEGREES(ABS(attitude.values.pitch)), 0, 1, 0, 3, false);
break; break;
case OSD_ARTIFICIAL_HORIZON: case OSD_ARTIFICIAL_HORIZON:
@ -2494,7 +2528,7 @@ static bool osdDrawSingleElement(uint8_t item)
break; break;
} }
osdFormatCentiNumber(buff, value, 0, 1, 0, 3); osdFormatCentiNumber(buff, value, 0, 1, 0, 3, false);
buff[3] = sym; buff[3] = sym;
buff[4] = '\0'; buff[4] = '\0';
break; break;
@ -2527,7 +2561,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
// mAh/foot // mAh/foot
if (efficiencyValid) { if (efficiencyValid) {
osdFormatCentiNumber(buff, (value * METERS_PER_FOOT), 1, 2, 2, 3); osdFormatCentiNumber(buff, (value * METERS_PER_FOOT), 1, 2, 2, 3, false);
tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_FT_0, SYM_AH_V_FT_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_FT_0, SYM_AH_V_FT_1);
} else { } else {
buff[0] = buff[1] = buff[2] = '-'; buff[0] = buff[1] = buff[2] = '-';
@ -2541,7 +2575,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
// mAh/metre // mAh/metre
if (efficiencyValid) { if (efficiencyValid) {
osdFormatCentiNumber(buff, value, 1, 2, 2, 3); osdFormatCentiNumber(buff, value, 1, 2, 2, 3, false);
tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_M_0, SYM_AH_V_M_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_AH_V_M_0, SYM_AH_V_M_1);
} else { } else {
buff[0] = buff[1] = buff[2] = '-'; buff[0] = buff[1] = buff[2] = '-';
@ -2836,7 +2870,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_POWER: case OSD_POWER:
{ {
bool kiloWatt = osdFormatCentiNumber(buff, getPower(), 1000, 2, 2, 3); bool kiloWatt = osdFormatCentiNumber(buff, getPower(), 1000, 2, 2, 3, false);
buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT;
buff[4] = '\0'; buff[4] = '\0';
@ -2999,7 +3033,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_UNIT_UK: case OSD_UNIT_UK:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10, 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10, 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1);
} else { } else {
@ -3013,7 +3047,7 @@ static bool osdDrawSingleElement(uint8_t item)
} }
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10, 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10, 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1);
} else { } else {
@ -3029,7 +3063,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_UNIT_METRIC_MPH: case OSD_UNIT_METRIC_MPH:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
moreThanAh = osdFormatCentiNumber(buff, value * 100, 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, value * 100, 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1);
} else { } else {
@ -3070,17 +3104,17 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_UNIT_UK: case OSD_UNIT_UK:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10000, 0, 2, 0, 3); osdFormatCentiNumber(buff, value * METERS_PER_MILE / 10000, 0, 2, 0, 3, false);
buff[3] = SYM_WH_MI; buff[3] = SYM_WH_MI;
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10000, 0, 2, 0, 3); osdFormatCentiNumber(buff, value * METERS_PER_NAUTICALMILE / 10000, 0, 2, 0, 3, false);
buff[3] = SYM_WH_NM; buff[3] = SYM_WH_NM;
break; break;
case OSD_UNIT_METRIC_MPH: case OSD_UNIT_METRIC_MPH:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
osdFormatCentiNumber(buff, value / 10, 0, 2, 0, 3); osdFormatCentiNumber(buff, value / 10, 0, 2, 0, 3, false);
buff[3] = SYM_WH_KM; buff[3] = SYM_WH_KM;
break; break;
} }
@ -3094,7 +3128,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_GFORCE: case OSD_GFORCE:
{ {
buff[0] = SYM_GFORCE; buff[0] = SYM_GFORCE;
osdFormatCentiNumber(buff + 1, GForce, 0, 2, 0, 3); osdFormatCentiNumber(buff + 1, GForce, 0, 2, 0, 3, false);
if (GForce > osdConfig()->gforce_alarm * 100) { if (GForce > osdConfig()->gforce_alarm * 100) {
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
} }
@ -3107,7 +3141,7 @@ static bool osdDrawSingleElement(uint8_t item)
{ {
float GForceValue = GForceAxis[item - OSD_GFORCE_X]; float GForceValue = GForceAxis[item - OSD_GFORCE_X];
buff[0] = SYM_GFORCE_X + item - OSD_GFORCE_X; buff[0] = SYM_GFORCE_X + item - OSD_GFORCE_X;
osdFormatCentiNumber(buff + 1, GForceValue, 0, 2, 0, 4); osdFormatCentiNumber(buff + 1, GForceValue, 0, 2, 0, 4, false);
if ((GForceValue < osdConfig()->gforce_axis_alarm_min * 100) || (GForceValue > osdConfig()->gforce_axis_alarm_max * 100)) { if ((GForceValue < osdConfig()->gforce_axis_alarm_min * 100) || (GForceValue > osdConfig()->gforce_axis_alarm_max * 100)) {
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
} }
@ -3283,7 +3317,7 @@ static bool osdDrawSingleElement(uint8_t item)
} }
buff[0] = SYM_SCALE; buff[0] = SYM_SCALE;
if (osdMapData.scale > 0) { if (osdMapData.scale > 0) {
bool scaled = osdFormatCentiNumber(&buff[1], osdMapData.scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3); bool scaled = osdFormatCentiNumber(&buff[1], osdMapData.scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3, false);
buff[4] = scaled ? symScaled : symUnscaled; buff[4] = scaled ? symScaled : symUnscaled;
// Make sure this is cleared if the map stops being drawn // Make sure this is cleared if the map stops being drawn
osdMapData.scale = 0; osdMapData.scale = 0;
@ -3452,14 +3486,14 @@ static bool osdDrawSingleElement(uint8_t item)
#ifdef USE_POWER_LIMITS #ifdef USE_POWER_LIMITS
case OSD_PLIMIT_REMAINING_BURST_TIME: case OSD_PLIMIT_REMAINING_BURST_TIME:
osdFormatCentiNumber(buff, powerLimiterGetRemainingBurstTime() * 100, 0, 1, 0, 3); osdFormatCentiNumber(buff, powerLimiterGetRemainingBurstTime() * 100, 0, 1, 0, 3, false);
buff[3] = 'S'; buff[3] = 'S';
buff[4] = '\0'; buff[4] = '\0';
break; break;
case OSD_PLIMIT_ACTIVE_CURRENT_LIMIT: case OSD_PLIMIT_ACTIVE_CURRENT_LIMIT:
if (currentBatteryProfile->powerLimits.continuousCurrent) { if (currentBatteryProfile->powerLimits.continuousCurrent) {
osdFormatCentiNumber(buff, powerLimiterGetActiveCurrentLimit(), 0, 2, 0, 3); osdFormatCentiNumber(buff, powerLimiterGetActiveCurrentLimit(), 0, 2, 0, 3, false);
buff[3] = SYM_AMP; buff[3] = SYM_AMP;
buff[4] = '\0'; buff[4] = '\0';
@ -3473,7 +3507,7 @@ static bool osdDrawSingleElement(uint8_t item)
case OSD_PLIMIT_ACTIVE_POWER_LIMIT: case OSD_PLIMIT_ACTIVE_POWER_LIMIT:
{ {
if (currentBatteryProfile->powerLimits.continuousPower) { if (currentBatteryProfile->powerLimits.continuousPower) {
bool kiloWatt = osdFormatCentiNumber(buff, powerLimiterGetActivePowerLimit(), 1000, 2, 2, 3); bool kiloWatt = osdFormatCentiNumber(buff, powerLimiterGetActivePowerLimit(), 1000, 2, 2, 3, false);
buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT;
buff[4] = '\0'; buff[4] = '\0';
@ -3750,6 +3784,7 @@ void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig)
//line 2 //line 2
osdLayoutsConfig->item_pos[0][OSD_HOME_DIST] = OSD_POS(1, 1); osdLayoutsConfig->item_pos[0][OSD_HOME_DIST] = OSD_POS(1, 1);
osdLayoutsConfig->item_pos[0][OSD_TRIP_DIST] = OSD_POS(1, 2); osdLayoutsConfig->item_pos[0][OSD_TRIP_DIST] = OSD_POS(1, 2);
osdLayoutsConfig->item_pos[0][OSD_ODOMETER] = OSD_POS(1, 3);
osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_CELL_VOLTAGE] = OSD_POS(12, 1); osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_CELL_VOLTAGE] = OSD_POS(12, 1);
osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE] = OSD_POS(12, 1); osdLayoutsConfig->item_pos[0][OSD_MAIN_BATT_SAG_COMPENSATED_CELL_VOLTAGE] = OSD_POS(12, 1);
osdLayoutsConfig->item_pos[0][OSD_GPS_SPEED] = OSD_POS(23, 1); osdLayoutsConfig->item_pos[0][OSD_GPS_SPEED] = OSD_POS(23, 1);
@ -4012,7 +4047,7 @@ static void osdCompleteAsyncInitialization(void)
#ifdef USE_ADC #ifdef USE_ADC
if (feature(FEATURE_VBAT) && feature(FEATURE_CURRENT_METER)) { if (feature(FEATURE_VBAT) && feature(FEATURE_CURRENT_METER)) {
displayWrite(osdDisplayPort, statNameX, ++y, "TOTAL ENERGY:"); displayWrite(osdDisplayPort, statNameX, ++y, "TOTAL ENERGY:");
osdFormatCentiNumber(string_buffer, statsConfig()->stats_total_energy / 10, 0, 2, 0, 4); osdFormatCentiNumber(string_buffer, statsConfig()->stats_total_energy / 10, 0, 2, 0, 4, false);
strcat(string_buffer, "\xAB"); // SYM_WH strcat(string_buffer, "\xAB"); // SYM_WH
displayWrite(osdDisplayPort, statValueX-4, y, string_buffer); displayWrite(osdDisplayPort, statValueX-4, y, string_buffer);
@ -4023,18 +4058,18 @@ static void osdCompleteAsyncInitialization(void)
case OSD_UNIT_UK: case OSD_UNIT_UK:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3); osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3, false);
string_buffer[3] = SYM_WH_MI; string_buffer[3] = SYM_WH_MI;
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3); osdFormatCentiNumber(string_buffer, avg_efficiency / 10, 0, 2, 0, 3, false);
string_buffer[3] = SYM_WH_NM; string_buffer[3] = SYM_WH_NM;
break; break;
default: default:
case OSD_UNIT_METRIC_MPH: case OSD_UNIT_METRIC_MPH:
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
osdFormatCentiNumber(string_buffer, avg_efficiency / 10000 * METERS_PER_MILE, 0, 2, 0, 3); osdFormatCentiNumber(string_buffer, avg_efficiency / 10000 * METERS_PER_MILE, 0, 2, 0, 3, false);
string_buffer[3] = SYM_WH_KM; string_buffer[3] = SYM_WH_KM;
break; break;
} }
@ -4249,22 +4284,22 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
if (isSinglePageStatsCompatible || page == 1) { if (isSinglePageStatsCompatible || page == 1) {
if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) { if (osdConfig()->stats_min_voltage_unit == OSD_STATS_MIN_VOLTAGE_UNIT_BATTERY) {
displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :"); displayWrite(osdDisplayPort, statNameX, top, "MIN BATTERY VOLT :");
osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2); osdFormatCentiNumber(buff, stats.min_voltage, 0, osdConfig()->main_voltage_decimals, 0, osdConfig()->main_voltage_decimals + 2, false);
} else { } else {
displayWrite(osdDisplayPort, statNameX, top, "MIN CELL VOLTAGE :"); displayWrite(osdDisplayPort, statNameX, top, "MIN CELL VOLTAGE :");
osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3); osdFormatCentiNumber(buff, stats.min_voltage/getBatteryCellCount(), 0, 2, 0, 3, false);
} }
tfp_sprintf(buff, "%s%c", buff, SYM_VOLT); tfp_sprintf(buff, "%s%c", buff, SYM_VOLT);
displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statValuesX, top++, buff);
if (feature(FEATURE_CURRENT_METER)) { if (feature(FEATURE_CURRENT_METER)) {
displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :"); displayWrite(osdDisplayPort, statNameX, top, "MAX CURRENT :");
osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3); osdFormatCentiNumber(buff, stats.max_current, 0, 2, 0, 3, false);
tfp_sprintf(buff, "%s%c", buff, SYM_AMP); tfp_sprintf(buff, "%s%c", buff, SYM_AMP);
displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statValuesX, top++, buff);
displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :"); displayWrite(osdDisplayPort, statNameX, top, "MAX POWER :");
bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3); bool kiloWatt = osdFormatCentiNumber(buff, stats.max_power, 1000, 2, 2, 3, false);
buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT; buff[3] = kiloWatt ? SYM_KILOWATT : SYM_WATT;
buff[4] = '\0'; buff[4] = '\0';
displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statValuesX, top++, buff);
@ -4273,7 +4308,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) {
tfp_sprintf(buff, "%d%c", (int)getMAhDrawn(), SYM_MAH); tfp_sprintf(buff, "%d%c", (int)getMAhDrawn(), SYM_MAH);
} else { } else {
osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3); osdFormatCentiNumber(buff, getMWhDrawn() / 10, 0, 2, 0, 3, false);
tfp_sprintf(buff, "%s%c", buff, SYM_WH); tfp_sprintf(buff, "%s%c", buff, SYM_WH);
} }
displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statValuesX, top++, buff);
@ -4295,7 +4330,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) {
moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_MILE / totalDistance), 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_MI_0, SYM_MAH_MI_1);
} else { } else {
@ -4308,7 +4343,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
buff[5] = '\0'; buff[5] = '\0';
} }
} else { } else {
osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, digits); osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_MILE / totalDistance), 0, 2, 0, digits, false);
tfp_sprintf(buff, "%s%c", buff, SYM_WH_MI); tfp_sprintf(buff, "%s%c", buff, SYM_WH_MI);
if (!efficiencyValid) { if (!efficiencyValid) {
buff[0] = buff[1] = buff[2] = '-'; buff[0] = buff[1] = buff[2] = '-';
@ -4317,7 +4352,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) {
moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000.0f * METERS_PER_NAUTICALMILE / totalDistance), 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_NM_0, SYM_MAH_NM_1);
} else { } else {
@ -4330,7 +4365,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
buff[5] = '\0'; buff[5] = '\0';
} }
} else { } else {
osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, digits); osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10.0f * METERS_PER_NAUTICALMILE / totalDistance), 0, 2, 0, digits, false);
tfp_sprintf(buff, "%s%c", buff, SYM_WH_NM); tfp_sprintf(buff, "%s%c", buff, SYM_WH_NM);
if (!efficiencyValid) { if (!efficiencyValid) {
buff[0] = buff[1] = buff[2] = '-'; buff[0] = buff[1] = buff[2] = '-';
@ -4341,7 +4376,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
FALLTHROUGH; FALLTHROUGH;
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) { if (osdConfig()->stats_energy_unit == OSD_STATS_ENERGY_UNIT_MAH) {
moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, digits); moreThanAh = osdFormatCentiNumber(buff, (int32_t)(getMAhDrawn() * 10000000.0f / totalDistance), 1000, 0, 2, digits, false);
if (!moreThanAh) { if (!moreThanAh) {
tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1); tfp_sprintf(buff, "%s%c%c", buff, SYM_MAH_KM_0, SYM_MAH_KM_1);
} else { } else {
@ -4354,7 +4389,7 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
buff[5] = '\0'; buff[5] = '\0';
} }
} else { } else {
osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, digits); osdFormatCentiNumber(buff, (int32_t)(getMWhDrawn() * 10000.0f / totalDistance), 0, 2, 0, digits, false);
tfp_sprintf(buff, "%s%c", buff, SYM_WH_KM); tfp_sprintf(buff, "%s%c", buff, SYM_WH_KM);
if (!efficiencyValid) { if (!efficiencyValid) {
buff[0] = buff[1] = buff[2] = '-'; buff[0] = buff[1] = buff[2] = '-';
@ -4369,19 +4404,19 @@ static void osdShowStats(bool isSinglePageStatsCompatible, uint8_t page)
const float max_gforce = accGetMeasuredMaxG(); const float max_gforce = accGetMeasuredMaxG();
displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :"); displayWrite(osdDisplayPort, statNameX, top, "MAX G-FORCE :");
osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3); osdFormatCentiNumber(buff, max_gforce * 100, 0, 2, 0, 3, false);
displayWrite(osdDisplayPort, statValuesX, top++, buff); displayWrite(osdDisplayPort, statValuesX, top++, buff);
const acc_extremes_t *acc_extremes = accGetMeasuredExtremes(); const acc_extremes_t *acc_extremes = accGetMeasuredExtremes();
const float acc_extremes_min = acc_extremes[Z].min; const float acc_extremes_min = acc_extremes[Z].min;
const float acc_extremes_max = acc_extremes[Z].max; const float acc_extremes_max = acc_extremes[Z].max;
displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:"); displayWrite(osdDisplayPort, statNameX, top, "MIN/MAX Z G-FORCE:");
osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4); osdFormatCentiNumber(buff, acc_extremes_min * 100, 0, 2, 0, 4, false);
osdLeftAlignString(buff); osdLeftAlignString(buff);
strcat(osdFormatTrimWhiteSpace(buff),"/"); strcat(osdFormatTrimWhiteSpace(buff),"/");
multiValueLengthOffset = strlen(buff); multiValueLengthOffset = strlen(buff);
displayWrite(osdDisplayPort, statValuesX, top, buff); displayWrite(osdDisplayPort, statValuesX, top, buff);
osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3); osdFormatCentiNumber(buff, acc_extremes_max * 100, 0, 2, 0, 3, false);
osdLeftAlignString(buff); osdLeftAlignString(buff);
displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff); displayWrite(osdDisplayPort, statValuesX + multiValueLengthOffset, top++, buff);
} }

View file

@ -274,6 +274,7 @@ typedef enum {
OSD_PILOT_NAME, OSD_PILOT_NAME,
OSD_PAN_SERVO_CENTRED, OSD_PAN_SERVO_CENTRED,
OSD_MULTI_FUNCTION, OSD_MULTI_FUNCTION,
OSD_ODOMETER,
OSD_ITEM_COUNT // MUST BE LAST OSD_ITEM_COUNT // MUST BE LAST
} osd_items_e; } osd_items_e;
@ -483,7 +484,7 @@ void osdStartedSaveProcess(void);
void osdShowEEPROMSavedNotification(void); void osdShowEEPROMSavedNotification(void);
void osdCrosshairPosition(uint8_t *x, uint8_t *y); 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 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 osdFormatAltitudeSymbol(char *buff, int32_t alt);
void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max); void osdFormatVelocityStr(char* buff, int32_t vel, bool _3D, bool _max);
// Returns a heading angle in degrees normalized to [0, 360). // Returns a heading angle in degrees normalized to [0, 360).

View file

@ -256,18 +256,18 @@ void osdHudDrawPoi(uint32_t poiDistance, int16_t poiDirection, int32_t poiAltitu
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
{ {
if (poiType == 1) { if (poiType == 1) {
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 4, 4); osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 4, 4, false);
} else { } else {
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 3, 3); osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), FEET_PER_MILE, 0, 3, 3, false);
} }
} }
break; break;
case OSD_UNIT_GA: case OSD_UNIT_GA:
{ {
if (poiType == 1) { if (poiType == 1) {
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 4, 4); osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 4, 4, false);
} else { } else {
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 3, 3); osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(poiDistance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 3, 3, false);
} }
} }
break; break;
@ -278,9 +278,9 @@ void osdHudDrawPoi(uint32_t poiDistance, int16_t poiDirection, int32_t poiAltitu
case OSD_UNIT_METRIC: case OSD_UNIT_METRIC:
{ {
if (poiType == 1) { if (poiType == 1) {
osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 4, 4); osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 4, 4, false);
} else { } else {
osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 3, 3); osdFormatCentiNumber(buff, poiDistance * 100, METERS_PER_KILOMETER, 0, 3, 3, false);
} }
} }
break; break;

View file

@ -38,7 +38,7 @@ int digitCount(int32_t value)
} }
bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length) bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros)
{ {
char *ptr = buff; char *ptr = buff;
char *dec; char *dec;
@ -86,7 +86,11 @@ bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int ma
// Done counting. Time to write the characters. // Done counting. Time to write the characters.
// Write spaces at the start // Write spaces at the start
while (remaining > 0) { while (remaining > 0) {
*ptr = SYM_BLANK; if (leadingZeros)
*ptr = '0';
else
*ptr = SYM_BLANK;
ptr++; ptr++;
remaining--; remaining--;
} }
@ -98,7 +102,11 @@ bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int ma
// Add any needed remaining leading spaces // Add any needed remaining leading spaces
while(rem_spaces > 0) while(rem_spaces > 0)
{ {
*ptr = SYM_BLANK; if (leadingZeros)
*ptr = '0';
else
*ptr = SYM_BLANK;
ptr++; ptr++;
remaining--; remaining--;
rem_spaces--; rem_spaces--;

View file

@ -33,6 +33,6 @@ int digitCount(int32_t value);
* of the same length. If the value doesn't fit into the provided length * of the same length. If the value doesn't fit into the provided length
* it will be divided by scale and true will be returned. * it will be divided by scale and true will be returned.
*/ */
bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length); bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros);
#endif #endif

View file

@ -92,3 +92,5 @@
#define MSP2_INAV_LED_STRIP_CONFIG_EX 0x2048 #define MSP2_INAV_LED_STRIP_CONFIG_EX 0x2048
#define MSP2_INAV_SET_LED_STRIP_CONFIG_EX 0x2049 #define MSP2_INAV_SET_LED_STRIP_CONFIG_EX 0x2049
#define MSP2_INAV_RATE_DYNAMICS 0x2060
#define MSP2_INAV_SET_RATE_DYNAMICS 0x2061

View file

@ -2879,6 +2879,9 @@ static void updateNavigationFlightStatistics(void)
} }
} }
/*
* Total travel distance in cm
*/
uint32_t getTotalTravelDistance(void) uint32_t getTotalTravelDistance(void)
{ {
return lrintf(posControl.totalTripDistance); return lrintf(posControl.totalTripDistance);

View file

@ -716,6 +716,10 @@ static int logicConditionGetFlightOperandValue(int operand) {
return constrain(attitude.values.pitch / 10, -180, 180); return constrain(attitude.values.pitch / 10, -180, 180);
break; break;
case LOGIC_CONDITION_OPERAND_FLIGHT_ATTITUDE_YAW: // deg
return constrain(attitude.values.yaw / 10, 0, 360);
break;
case LOGIC_CONDITION_OPERAND_FLIGHT_IS_ARMED: // 0/1 case LOGIC_CONDITION_OPERAND_FLIGHT_IS_ARMED: // 0/1
return ARMING_FLAG(ARMED) ? 1 : 0; return ARMING_FLAG(ARMED) ? 1 : 0;
break; break;

View file

@ -136,8 +136,9 @@ typedef enum {
LOGIC_CONDITION_OPERAND_FLIGHT_AGL_STATUS, //0,1,2 // 35 LOGIC_CONDITION_OPERAND_FLIGHT_AGL_STATUS, //0,1,2 // 35
LOGIC_CONDITION_OPERAND_FLIGHT_AGL, //0,1,2 // 36 LOGIC_CONDITION_OPERAND_FLIGHT_AGL, //0,1,2 // 36
LOGIC_CONDITION_OPERAND_FLIGHT_RANGEFINDER_RAW, //int // 37 LOGIC_CONDITION_OPERAND_FLIGHT_RANGEFINDER_RAW, //int // 37
LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_MIXER_PROFILE, //int // 39 LOGIC_CONDITION_OPERAND_FLIGHT_ACTIVE_MIXER_PROFILE, //int // 38
LOGIC_CONDITION_OPERAND_FLIGHT_MIXER_TRANSITION_ACTIVE, //0,1 // 40 LOGIC_CONDITION_OPERAND_FLIGHT_MIXER_TRANSITION_ACTIVE, //0,1 // 39
LOGIC_CONDITION_OPERAND_FLIGHT_ATTITUDE_YAW, // deg // 40
} logicFlightOperands_e; } logicFlightOperands_e;
typedef enum { typedef enum {

View file

@ -1 +1,2 @@
target_stm32h743xi(MATEKH743) target_stm32h743xi(MATEKH743)
target_stm32h743xi(MATEKH743HD)

View file

@ -19,7 +19,12 @@
#pragma once #pragma once
#define TARGET_BOARD_IDENTIFIER "H743" #define TARGET_BOARD_IDENTIFIER "H743"
#define USBD_PRODUCT_STRING "MATEKH743"
#if defined(MATEKH743HD)
#define USBD_PRODUCT_STRING "MATEKH743HD"
#else
#define USBD_PRODUCT_STRING "MATEKH743"
#endif
#define USE_TARGET_CONFIG #define USE_TARGET_CONFIG
@ -69,14 +74,16 @@
#define ICM42605_CS_PIN PC13 #define ICM42605_CS_PIN PC13
// *************** SPI2 OSD *********************** // *************** SPI2 OSD ***********************
#define USE_SPI_DEVICE_2 #define USE_SPI_DEVICE_2
#define SPI2_SCK_PIN PB13 #define SPI2_SCK_PIN PB13
#define SPI2_MISO_PIN PB14 #define SPI2_MISO_PIN PB14
#define SPI2_MOSI_PIN PB15 #define SPI2_MOSI_PIN PB15
#define USE_MAX7456 #if defined(MATEKH743)
#define MAX7456_SPI_BUS BUS_SPI2 #define USE_MAX7456
#define MAX7456_CS_PIN PB12 #define MAX7456_SPI_BUS BUS_SPI2
#define MAX7456_CS_PIN PB12
#endif
// *************** SPI3 SPARE for external RM3100 *********** // *************** SPI3 SPARE for external RM3100 ***********
#define USE_SPI_DEVICE_3 #define USE_SPI_DEVICE_3
@ -159,7 +166,7 @@
#define SERIAL_PORT_COUNT 9 #define SERIAL_PORT_COUNT 9
#define DEFAULT_RX_TYPE RX_TYPE_SERIAL #define DEFAULT_RX_TYPE RX_TYPE_SERIAL
#define SERIALRX_PROVIDER SERIALRX_SBUS #define SERIALRX_PROVIDER SERIALRX_CRSF
#define SERIALRX_UART SERIAL_PORT_USART6 #define SERIALRX_UART SERIAL_PORT_USART6
// *************** SDIO SD BLACKBOX******************* // *************** SDIO SD BLACKBOX*******************

View file

@ -14,55 +14,55 @@ TEST(OSDTest, TestCentiNumber)
//bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length); //bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length);
char buf[11] = "0123456789"; char buf[11] = "0123456789";
osdFormatCentiNumber(buf, 12345, 1, 2, 3, 7); osdFormatCentiNumber(buf, 12345, 1, 2, 3, 7, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, " 123.45")); EXPECT_FALSE(strcmp(buf, " 123.45"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, 12345, 1, 2, 2, 6); osdFormatCentiNumber(buf, 12345, 1, 2, 2, 6, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "123.45")); EXPECT_FALSE(strcmp(buf, "123.45"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, 12345, 1, 2, 2, 5); osdFormatCentiNumber(buf, 12345, 1, 2, 2, 5, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "123.4")); EXPECT_FALSE(strcmp(buf, "123.4"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, 12345, 1, 2, 2, 4); osdFormatCentiNumber(buf, 12345, 1, 2, 2, 4, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, " 123")); // this should be causing #8769 EXPECT_FALSE(strcmp(buf, " 123")); // this should be causing #8769
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, 12345, 1, 2, 2, 3); osdFormatCentiNumber(buf, 12345, 1, 2, 2, 3, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "123")); EXPECT_FALSE(strcmp(buf, "123"));
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, -12345, 1, 2, 2, 8); osdFormatCentiNumber(buf, -12345, 1, 2, 2, 8, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, " -123.45")); EXPECT_FALSE(strcmp(buf, " -123.45"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, -12345, 1, 2, 2, 7); osdFormatCentiNumber(buf, -12345, 1, 2, 2, 7, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "-123.45")); EXPECT_FALSE(strcmp(buf, "-123.45"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, -12345, 1, 2, 2, 6); osdFormatCentiNumber(buf, -12345, 1, 2, 2, 6, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "-123.4")); EXPECT_FALSE(strcmp(buf, "-123.4"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, -12345, 1, 2, 2, 5); osdFormatCentiNumber(buf, -12345, 1, 2, 2, 5, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, " -123")); EXPECT_FALSE(strcmp(buf, " -123"));
memset(buf, 0, 11); memset(buf, 0, 11);
osdFormatCentiNumber(buf, -12345, 1, 2, 2, 4); osdFormatCentiNumber(buf, -12345, 1, 2, 2, 4, false);
std::cout << "'" << buf << "'" << std::endl; std::cout << "'" << buf << "'" << std::endl;
EXPECT_FALSE(strcmp(buf, "-123")); EXPECT_FALSE(strcmp(buf, "-123"));