diff --git a/libraries/AP_OSD/AP_OSD.cpp b/libraries/AP_OSD/AP_OSD.cpp index 3293f0fdbc..7495374a44 100644 --- a/libraries/AP_OSD/AP_OSD.cpp +++ b/libraries/AP_OSD/AP_OSD.cpp @@ -121,6 +121,13 @@ const AP_Param::GroupInfo AP_OSD::var_info[] = { // @User: Standard AP_GROUPINFO("_W_BATVOLT", 14, AP_OSD, warn_batvolt, 10.0f), + // @Param: _UNITS + // @DisplayName: Display Units + // @Description: Sets the units to use in displaying items + // @Values: 0:Metric,1:Imperial + // @User: Standard + AP_GROUPINFO("_UNITS", 15, AP_OSD, units, 0), + AP_GROUPEND }; diff --git a/libraries/AP_OSD/AP_OSD.h b/libraries/AP_OSD/AP_OSD.h index f4d44e9063..73f67f85ff 100644 --- a/libraries/AP_OSD/AP_OSD.h +++ b/libraries/AP_OSD/AP_OSD.h @@ -103,8 +103,18 @@ private: bool check_option(uint32_t option); - char u_icon(uint16_t unit_type); - float u_scale(uint16_t unit_type, float value); + enum unit_type { + ALTITUDE=0, + SPEED=1, + VSPEED=2, + DISTANCE=3, + DISTANCE_LONG=4, + TEMPERATURE=5, + UNIT_TYPE_LAST=6, + }; + + char u_icon(enum unit_type unit); + float u_scale(enum unit_type unit, float value); void draw_altitude(uint8_t x, uint8_t y); void draw_bat_volt(uint8_t x, uint8_t y); @@ -136,17 +146,6 @@ private: void draw_gps_latitude(uint8_t x, uint8_t y); void draw_gps_longitude(uint8_t x, uint8_t y); - - enum { - ALTITUDE=0, - SPEED=1, - VSPEED=2, - DISTANCE=3, - DISTANCE_LONG=4, - TEMPERATURE=5, - UNIT_LAST=6, - }; - }; class AP_OSD { diff --git a/libraries/AP_OSD/AP_OSD_Screen.cpp b/libraries/AP_OSD/AP_OSD_Screen.cpp index 22fff9c191..9567cdd4b2 100644 --- a/libraries/AP_OSD/AP_OSD_Screen.cpp +++ b/libraries/AP_OSD/AP_OSD_Screen.cpp @@ -230,40 +230,73 @@ bool AP_OSD_Screen::check_option(uint32_t option) return (osd->options & option) != 0; } -char AP_OSD_Screen::u_icon(uint16_t unit) +/* + get the right units icon given a unit + */ +char AP_OSD_Screen::u_icon(enum unit_type unit) { - static const char icons[UNIT_LAST][AP_OSD::UNITS_LAST] = { - {(char)SYM_ALT_M, (char)SYM_ALT_FT}, //ALTITUDE - {(char)SYM_KMH, (char)SYM_MPH}, //SPEED - {(char)SYM_MS, (char)SYM_FS}, //VSPEED - {(char)SYM_M, (char)SYM_FT}, //DISTANCE - {(char)SYM_KM, (char)SYM_MI}, //DISTANCE_LONG - {(char)SYM_DEGREES_C, (char)SYM_DEGREES_F}//TEMPERATURE + static const char icons_metric[UNIT_TYPE_LAST] { + (char)SYM_ALT_M, //ALTITUDE + (char)SYM_KMH, //SPEED + (char)SYM_MS, //VSPEED + (char)SYM_M, //DISTANCE + (char)SYM_KM, //DISTANCE_LONG + (char)SYM_DEGREES_C //TEMPERATURE }; - return icons[unit][osd->units]; + static const char icons_imperial[UNIT_TYPE_LAST] { + (char)SYM_ALT_FT, //ALTITUDE + (char)SYM_MPH, //SPEED + (char)SYM_FS, //VSPEED + (char)SYM_FT, //DISTANCE + (char)SYM_MI, //DISTANCE_LONG + (char)SYM_DEGREES_F //TEMPERATURE + }; + static const char *icons[AP_OSD::UNITS_LAST] = { + icons_metric, + icons_imperial + }; + return icons[constrain_int16(osd->units, 0, AP_OSD::UNITS_LAST-1)][unit]; } -float AP_OSD_Screen::u_scale(uint16_t unit, float value) +/* + scale a value for the user selected units + */ +float AP_OSD_Screen::u_scale(enum unit_type unit, float value) { - static const float scale[UNIT_LAST][AP_OSD::UNITS_LAST] = { - {1.0f, 3.28084f}, //ALTITUDE - {3.6f, 2.23694f}, //SPEED - {1.0f, 3.28084f}, //VSPEED - {1.0f, 3.28084f}, //DISTANCE - {1.0f/1000.0f, 1.0f/1609.34f},//DISTANCE_LONG - {1.0f, 1.8f} //TEMPERATURE + static const float scale_metric[UNIT_TYPE_LAST] = { + 1.0, //ALTITUDE + 3.6, //SPEED + 1.0, //VSPEED + 1.0, //DISTANCE + 1.0/1000, //DISTANCE_LONG + 1.0, //TEMPERATURE }; - - static const float offset[UNIT_LAST][AP_OSD::UNITS_LAST] = { - {0.0f, 0.0f}, //ALTITUDE - {0.0f, 0.0f}, //SPEED - {0.0f, 0.0f}, //VSPEED - {0.0f, 0.0f}, //DISTANCE - {0.0f, 0.0f}, //DISTANCE_LONG - {0.0f, 32.0f}, //TEMPERATURE + static const float scale_imperial[UNIT_TYPE_LAST] = { + 3.28084, //ALTITUDE + 2.23694, //SPEED + 3.28084, //VSPEED + 3.28084, //DISTANCE + 1.0/1609.34, //DISTANCE_LONG + 1.8, //TEMPERATURE }; - - return value * scale[unit][osd->units] + offset[unit][osd->units]; + static const float offset_imperial[UNIT_TYPE_LAST] = { + 0.0, //ALTITUDE + 0.0, //SPEED + 0.0, //VSPEED + 0.0, //DISTANCE + 0.0, //DISTANCE_LONG + 32.0, //TEMPERATURE + }; + static const float *scale[AP_OSD::UNITS_LAST] = { + scale_metric, + scale_imperial + }; + static const float *offsets[AP_OSD::UNITS_LAST] = { + nullptr, + offset_imperial + }; + uint8_t units = constrain_int16(osd->units, 0, AP_OSD::UNITS_LAST-1); + return value * scale[units][unit] + (offsets[units]?offsets[units][unit]:0); } void AP_OSD_Screen::draw_altitude(uint8_t x, uint8_t y)