Line data Source code
1 : /*
2 : * This file is free software: you can redistribute it and/or modify it
3 : * under the terms of the GNU General Public License as published by the
4 : * Free Software Foundation, either version 3 of the License, or
5 : * (at your option) any later version.
6 : *
7 : * This file is distributed in the hope that it will be useful, but
8 : * WITHOUT ANY WARRANTY; without even the implied warranty of
9 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 : * See the GNU General Public License for more details.
11 : *
12 : * You should have received a copy of the GNU General Public License along
13 : * with this program. If not, see <http://www.gnu.org/licenses/>.
14 : *
15 : */
16 :
17 : #pragma once
18 :
19 : #include "AP_OSD_config.h"
20 :
21 : #include <AP_HAL/AP_HAL_Boards.h>
22 : #include <AP_HAL/Semaphores.h>
23 : #include <AP_Param/AP_Param.h>
24 : #include <AP_Math/AP_Math.h>
25 : #include <AP_ESC_Telem/AP_ESC_Telem.h>
26 : #include <RC_Channel/RC_Channel.h>
27 : #include <GCS_MAVLink/GCS_config.h>
28 : #include <AP_OLC/AP_OLC.h>
29 : #include <AP_MSP/msp.h>
30 : #include <AP_Baro/AP_Baro.h>
31 : #include <AP_RPM/AP_RPM_config.h>
32 : #if HAL_GCS_ENABLED
33 : #include <GCS_MAVLink/GCS_MAVLink.h>
34 : #endif
35 : #include <AC_Fence/AC_Fence_config.h>
36 : #include <AP_RangeFinder/AP_RangeFinder_config.h>
37 :
38 : class AP_OSD_Backend;
39 : class AP_MSP;
40 :
41 : #define AP_OSD_NUM_DISPLAY_SCREENS 4
42 : #if OSD_PARAM_ENABLED
43 : #define AP_OSD_NUM_PARAM_SCREENS 2
44 : #else
45 : #define AP_OSD_NUM_PARAM_SCREENS 0
46 : #endif
47 : #define AP_OSD_NUM_SCREENS (AP_OSD_NUM_DISPLAY_SCREENS + AP_OSD_NUM_PARAM_SCREENS)
48 :
49 : #define PARAM_INDEX(key, idx, group) (uint32_t(uint32_t(key) << 23 | uint32_t(idx) << 18 | uint32_t(group)))
50 : #define PARAM_TOKEN_INDEX(token) PARAM_INDEX(AP_Param::get_persistent_key(token.key), token.idx, token.group_element)
51 :
52 : #define AP_OSD_NUM_SYMBOLS 107
53 : #define OSD_MAX_INSTANCES 2
54 :
55 : #if AP_OSD_LINK_STATS_EXTENSIONS_ENABLED
56 : // For the moment, these extra panels only work with CRSF protocol based RC systems
57 : #define AP_OSD_EXTENDED_LNK_STATS 1
58 : #define AP_OSD_WARN_RSSI_DEFAULT -100 // Default value for OSD RSSI panel warning, in dbm
59 : #else
60 : #define AP_OSD_EXTENDED_LNK_STATS 0
61 : #define AP_OSD_WARN_RSSI_DEFAULT 30 // Default value for OSD RSSI panel warning, in %
62 : #endif
63 :
64 : /*
65 : class to hold one setting
66 : */
67 : class AP_OSD_Setting
68 : {
69 : public:
70 : AP_Int8 enabled;
71 : AP_Int8 xpos;
72 : AP_Int8 ypos;
73 :
74 : AP_OSD_Setting(bool enabled = 0, uint8_t x = 0, uint8_t y = 0);
75 :
76 : // User settable parameters
77 : static const struct AP_Param::GroupInfo var_info[];
78 :
79 : private:
80 : const float default_enabled;
81 : const float default_xpos;
82 : const float default_ypos;
83 : };
84 :
85 : class AP_OSD;
86 :
87 : class AP_OSD_AbstractScreen
88 : {
89 : friend class AP_OSD;
90 : public:
91 : // constructor
92 12366 : AP_OSD_AbstractScreen() {}
93 0 : virtual void draw(void) {}
94 :
95 : void set_backend(AP_OSD_Backend *_backend);
96 :
97 : AP_Int8 enabled;
98 : AP_Int16 channel_min;
99 : AP_Int16 channel_max;
100 :
101 : protected:
102 : bool check_option(uint32_t option);
103 : #if HAL_WITH_MSP_DISPLAYPORT
104 0 : virtual uint8_t get_txt_resolution() const {
105 0 : return 0;
106 : }
107 0 : virtual uint8_t get_font_index() const {
108 0 : return 0;
109 : }
110 : #endif
111 : enum unit_type {
112 : ALTITUDE=0,
113 : SPEED=1,
114 : VSPEED=2,
115 : DISTANCE=3,
116 : DISTANCE_LONG=4,
117 : TEMPERATURE=5,
118 : UNIT_TYPE_LAST=6,
119 : };
120 :
121 : char u_icon(enum unit_type unit);
122 : float u_scale(enum unit_type unit, float value);
123 :
124 : AP_OSD_Backend *backend;
125 : AP_OSD *osd;
126 :
127 : static uint8_t symbols_lookup_table[AP_OSD_NUM_SYMBOLS];
128 : };
129 :
130 : #if OSD_ENABLED
131 : /*
132 : class to hold one screen of settings
133 : */
134 : class AP_OSD_Screen : public AP_OSD_AbstractScreen
135 : {
136 : public:
137 : // constructor
138 : AP_OSD_Screen();
139 :
140 : // skip the drawing if we are not using a font based backend. This saves a lot of flash space when
141 : // using the MSP OSD system on boards that don't have a MAX7456
142 : #if HAL_WITH_OSD_BITMAP || HAL_WITH_MSP_DISPLAYPORT
143 : void draw(void) override;
144 : #endif
145 :
146 : // User settable parameters
147 : static const struct AP_Param::GroupInfo var_info[];
148 : static const struct AP_Param::GroupInfo var_info2[];
149 :
150 : #if HAL_WITH_MSP_DISPLAYPORT
151 548 : uint8_t get_txt_resolution() const override {
152 548 : return txt_resolution;
153 : }
154 548 : uint8_t get_font_index() const override {
155 548 : return font_index;
156 : }
157 : #endif
158 : private:
159 : friend class AP_MSP;
160 : friend class AP_MSP_Telem_Backend;
161 : friend class AP_MSP_Telem_DJI;
162 :
163 : static const uint8_t message_visible_width = 26;
164 : static const uint8_t message_scroll_time_ms = 200;
165 : static const uint8_t message_scroll_delay = 5;
166 :
167 : static constexpr float ah_max_pitch = DEG_TO_RAD * 20;
168 : //typical fpv camera has 80deg vertical field of view, 16 row of chars
169 : static constexpr float ah_pitch_rad_to_char = 16.0f/(DEG_TO_RAD * 80);
170 :
171 : enum class VoltageType {
172 : VOLTAGE,
173 : RESTING_VOLTAGE,
174 : AVG_CELL,
175 : RESTING_CELL,
176 : };
177 :
178 : AP_OSD_Setting altitude{true, 23, 8};
179 : AP_OSD_Setting bat_volt{true, 24, 1};
180 : AP_OSD_Setting rssi{true, 1, 1};
181 : AP_OSD_Setting link_quality{false,1,1};
182 : AP_OSD_Setting restvolt{false, 24, 2};
183 : AP_OSD_Setting avgcellvolt{false, 24, 3};
184 : AP_OSD_Setting avgcellrestvolt{false, 24, 4};
185 : AP_OSD_Setting current{true, 25, 2};
186 : AP_OSD_Setting batused{true, 23, 3};
187 : AP_OSD_Setting sats{true, 1, 3};
188 : AP_OSD_Setting fltmode{true, 2, 8};
189 : AP_OSD_Setting message{true, 2, 6};
190 : AP_OSD_Setting gspeed{true, 2, 14};
191 : AP_OSD_Setting horizon{true, 14, 8};
192 : AP_OSD_Setting home{true, 14, 1};
193 : AP_OSD_Setting throttle{true, 24, 11};
194 : AP_OSD_Setting heading{true, 13, 2};
195 : AP_OSD_Setting compass{true, 15, 3};
196 : AP_OSD_Setting wind{false, 2, 12};
197 : AP_OSD_Setting aspeed{false, 2, 13};
198 : AP_OSD_Setting aspd1;
199 : AP_OSD_Setting aspd2;
200 : AP_OSD_Setting vspeed{true, 24, 9};
201 : #if AP_RPM_ENABLED
202 : AP_OSD_Setting rrpm{false, 2, 2};
203 : #endif
204 : #if HAL_WITH_ESC_TELEM
205 : AP_OSD_Setting esc_temp {false, 24, 13};
206 : AP_OSD_Setting esc_rpm{false, 22, 12};
207 : AP_OSD_Setting esc_amps{false, 24, 14};
208 : #endif
209 : AP_OSD_Setting gps_latitude{true, 9, 13};
210 : AP_OSD_Setting gps_longitude{true, 9, 14};
211 : AP_OSD_Setting roll_angle;
212 : AP_OSD_Setting pitch_angle;
213 : AP_OSD_Setting temp;
214 : #if BARO_MAX_INSTANCES > 1
215 : AP_OSD_Setting btemp;
216 : #endif
217 : AP_OSD_Setting hdop;
218 : AP_OSD_Setting waypoint;
219 : AP_OSD_Setting xtrack_error;
220 : AP_OSD_Setting dist{false,22,11};
221 : AP_OSD_Setting stat{false,0,0};
222 : AP_OSD_Setting flightime{false, 23, 10};
223 : AP_OSD_Setting climbeff{false,0,0};
224 : AP_OSD_Setting eff{false, 22, 10};
225 : AP_OSD_Setting atemp;
226 : AP_OSD_Setting bat2_vlt;
227 : AP_OSD_Setting bat2used;
228 : AP_OSD_Setting current2;
229 : AP_OSD_Setting clk;
230 : AP_OSD_Setting callsign;
231 : AP_OSD_Setting vtx_power;
232 : AP_OSD_Setting hgt_abvterr{false, 23, 7};
233 : AP_OSD_Setting fence{false, 14, 9};
234 : AP_OSD_Setting rngf;
235 : #if HAL_PLUSCODE_ENABLE
236 : AP_OSD_Setting pluscode;
237 : #endif
238 : AP_OSD_Setting sidebars{false, 4, 5};
239 :
240 : #if AP_OSD_EXTENDED_LNK_STATS
241 : // Extended link stats data panels
242 : AP_OSD_Setting rc_tx_power{false, 25, 12};
243 : AP_OSD_Setting rc_rssi_dbm{false, 6, 2};
244 : AP_OSD_Setting rc_snr{false, 23, 13};
245 : AP_OSD_Setting rc_active_antenna{false, 27, 13};
246 : AP_OSD_Setting rc_lq{false, 18, 2};
247 : #endif
248 :
249 : // MSP OSD only
250 : AP_OSD_Setting crosshair;
251 : AP_OSD_Setting home_dist{true, 1, 1};
252 : AP_OSD_Setting home_dir{true, 1, 1};
253 : AP_OSD_Setting power{true, 1, 1};
254 : AP_OSD_Setting cell_volt{true, 1, 1};
255 : AP_OSD_Setting batt_bar{true, 1, 1};
256 : AP_OSD_Setting arming{true, 1, 1};
257 :
258 : #if HAL_WITH_MSP_DISPLAYPORT
259 : // Per screen HD resolution options (currently supported only by DisplayPort)
260 : AP_Int8 txt_resolution;
261 : AP_Int8 font_index;
262 : #endif
263 : #if HAL_WITH_ESC_TELEM
264 : AP_Int8 esc_index;
265 : #endif
266 :
267 : void draw_altitude(uint8_t x, uint8_t y);
268 : void draw_bat_volt(uint8_t instance,VoltageType type,uint8_t x, uint8_t y);
269 : void draw_bat_volt(uint8_t x, uint8_t y);
270 : void draw_avgcellvolt(uint8_t x, uint8_t y);
271 : void draw_avgcellrestvolt(uint8_t x, uint8_t y);
272 : void draw_restvolt(uint8_t x, uint8_t y);
273 : void draw_rssi(uint8_t x, uint8_t y);
274 : void draw_link_quality(uint8_t x, uint8_t y);
275 : void draw_current(uint8_t x, uint8_t y);
276 : void draw_current(uint8_t instance, uint8_t x, uint8_t y);
277 : void draw_batused(uint8_t x, uint8_t y);
278 : void draw_batused(uint8_t instance, uint8_t x, uint8_t y);
279 : void draw_sats(uint8_t x, uint8_t y);
280 : void draw_fltmode(uint8_t x, uint8_t y);
281 : void draw_message(uint8_t x, uint8_t y);
282 : void draw_gspeed(uint8_t x, uint8_t y);
283 : void draw_horizon(uint8_t x, uint8_t y);
284 : void draw_home(uint8_t x, uint8_t y);
285 : void draw_throttle(uint8_t x, uint8_t y);
286 : void draw_heading(uint8_t x, uint8_t y);
287 : #if AP_RPM_ENABLED
288 : void draw_rrpm(uint8_t x, uint8_t y);
289 : #endif
290 : #ifdef HAL_OSD_SIDEBAR_ENABLE
291 : void draw_sidebars(uint8_t x, uint8_t y);
292 : #endif
293 : void draw_compass(uint8_t x, uint8_t y);
294 : void draw_wind(uint8_t x, uint8_t y);
295 : void draw_aspeed(uint8_t x, uint8_t y);
296 : void draw_aspd1(uint8_t x, uint8_t y);
297 : void draw_aspd2(uint8_t x, uint8_t y);
298 : void draw_vspeed(uint8_t x, uint8_t y);
299 : #if HAL_PLUSCODE_ENABLE
300 : void draw_pluscode(uint8_t x, uint8_t y);
301 : #endif
302 : //helper functions
303 : void draw_speed(uint8_t x, uint8_t y, float angle_rad, float magnitude);
304 : void draw_distance(uint8_t x, uint8_t y, float distance);
305 : char get_arrow_font_index (int32_t angle_cd);
306 : #if HAL_WITH_ESC_TELEM
307 : void draw_esc_temp(uint8_t x, uint8_t y);
308 : void draw_esc_rpm(uint8_t x, uint8_t y);
309 : void draw_esc_amps(uint8_t x, uint8_t y);
310 : #endif
311 : void draw_gps_latitude(uint8_t x, uint8_t y);
312 : void draw_gps_longitude(uint8_t x, uint8_t y);
313 : void draw_roll_angle(uint8_t x, uint8_t y);
314 : void draw_pitch_angle(uint8_t x, uint8_t y);
315 : void draw_temp(uint8_t x, uint8_t y);
316 : #if BARO_MAX_INSTANCES > 1
317 : void draw_btemp(uint8_t x, uint8_t y);
318 : #endif
319 : void draw_hdop(uint8_t x, uint8_t y);
320 : void draw_waypoint(uint8_t x, uint8_t y);
321 : void draw_xtrack_error(uint8_t x, uint8_t y);
322 : void draw_dist(uint8_t x, uint8_t y);
323 : void draw_stat(uint8_t x, uint8_t y);
324 : void draw_flightime(uint8_t x, uint8_t y);
325 : void draw_climbeff(uint8_t x, uint8_t y);
326 : void draw_eff(uint8_t x, uint8_t y);
327 : void draw_atemp(uint8_t x, uint8_t y);
328 : void draw_bat2_vlt(uint8_t x, uint8_t y);
329 : void draw_bat2used(uint8_t x, uint8_t y);
330 : void draw_clk(uint8_t x, uint8_t y);
331 : void draw_callsign(uint8_t x, uint8_t y);
332 : void draw_current2(uint8_t x, uint8_t y);
333 : void draw_vtx_power(uint8_t x, uint8_t y);
334 : void draw_hgt_abvterr(uint8_t x, uint8_t y);
335 : #if AP_FENCE_ENABLED
336 : void draw_fence(uint8_t x, uint8_t y);
337 : #endif
338 : #if AP_RANGEFINDER_ENABLED
339 : void draw_rngf(uint8_t x, uint8_t y);
340 : #endif
341 :
342 : #if AP_OSD_EXTENDED_LNK_STATS
343 : // Extended link stats data panels
344 : bool is_btfl_fonts();
345 : void draw_rc_tx_power(uint8_t x, uint8_t y);
346 : void draw_rc_rssi_dbm(uint8_t x, uint8_t y);
347 : void draw_rc_snr(uint8_t x, uint8_t y);
348 : void draw_rc_active_antenna(uint8_t x, uint8_t y);
349 : void draw_rc_lq(uint8_t x, uint8_t y);
350 : #endif
351 :
352 : struct {
353 : bool load_attempted;
354 : const char *str;
355 : } callsign_data;
356 : };
357 : #endif // OSD_ENABLED
358 :
359 : #if OSD_PARAM_ENABLED
360 : /*
361 : class to hold one setting
362 : */
363 : class AP_OSD_ParamSetting
364 : {
365 : public:
366 :
367 : enum class Type : uint8_t {
368 : NONE = 0,
369 : SERIAL_PROTOCOL = 1,
370 : SERVO_FUNCTION = 2,
371 : AUX_FUNCTION = 3,
372 : FLIGHT_MODE = 4,
373 : FAILSAFE_ACTION = 5,
374 : FAILSAFE_ACTION_1 = 6,
375 : FAILSAFE_ACTION_2 = 7,
376 : NUM_TYPES = 8,
377 : };
378 :
379 : AP_Int8 enabled;
380 : AP_Int8 xpos;
381 : AP_Int8 ypos;
382 :
383 : // configured index.
384 : AP_Int32 _param_group;
385 : AP_Int16 _param_key;
386 : AP_Int8 _param_idx;
387 : // metadata
388 : AP_Float _param_min;
389 : AP_Float _param_max;
390 : AP_Float _param_incr;
391 : AP_Enum<Type> _type;
392 :
393 : // parameter number
394 : uint8_t _param_number;
395 : AP_Param* _param;
396 : ap_var_type _param_type;
397 : AP_Param::ParamToken _current_token;
398 :
399 : // structure to contain setting constraints for important settings
400 : struct ParamMetadata {
401 : float min_value;
402 : float max_value;
403 : float increment;
404 : uint8_t values_max;
405 : const char** values;
406 : };
407 :
408 : // compact structure used to hold default values for static initialization
409 : struct Initializer {
410 : uint8_t index;
411 : AP_Param::ParamToken token;
412 : Type type;
413 : };
414 :
415 : static const ParamMetadata _param_metadata[];
416 :
417 37098 : AP_OSD_ParamSetting() {};
418 : AP_OSD_ParamSetting(uint8_t param_number);
419 : AP_OSD_ParamSetting(const Initializer& initializer);
420 :
421 : // initialize the setting from the configured information
422 : void update();
423 : // grab the parameter name
424 0 : void copy_name(char* name, size_t len) const {
425 0 : _param->copy_name_token(_current_token, name, len);
426 0 : if (len > 16) name[16] = 0;
427 0 : }
428 : // copy the name converting FOO_BAR_BAZ to FooBarBaz
429 : void copy_name_camel_case(char* name, size_t len) const;
430 : // set the ranges from static metadata
431 : bool set_from_metadata();
432 : bool set_by_name(const char* name, uint8_t config_type, float pmin=0, float pmax=0, float pincr=0);
433 : void guess_ranges(bool force = false);
434 : void save_as_new();
435 :
436 0 : const ParamMetadata* get_custom_metadata() const {
437 0 : return (_type > 0 ? &_param_metadata[_type - 1] : nullptr);
438 : }
439 :
440 : // User settable parameters
441 : static const struct AP_Param::GroupInfo var_info[];
442 :
443 : private:
444 : float default_enabled;
445 : float default_ypos;
446 : float default_param_group;
447 : float default_param_idx;
448 : float default_param_key;
449 : float default_type;
450 :
451 : };
452 :
453 : /*
454 : class to hold one screen of settings
455 : */
456 : class AP_OSD_ParamScreen : public AP_OSD_AbstractScreen
457 : {
458 : public:
459 : AP_OSD_ParamScreen(uint8_t index);
460 :
461 : enum class Event {
462 : NONE,
463 : MENU_ENTER,
464 : MENU_UP,
465 : MENU_DOWN,
466 : MENU_EXIT
467 : };
468 :
469 : enum class MenuState {
470 : PARAM_SELECT,
471 : PARAM_VALUE_MODIFY,
472 : PARAM_PARAM_MODIFY
473 : };
474 :
475 : static const uint8_t NUM_PARAMS = 9;
476 : static const uint8_t SAVE_PARAM = NUM_PARAMS + 1;
477 :
478 : #if OSD_ENABLED && (HAL_WITH_OSD_BITMAP || HAL_WITH_MSP_DISPLAYPORT)
479 : void draw(void) override;
480 : #endif
481 : #if HAL_GCS_ENABLED
482 : void handle_write_msg(const mavlink_osd_param_config_t& packet, const class GCS_MAVLINK& link);
483 : void handle_read_msg(const mavlink_osd_param_show_config_t& packet, const class GCS_MAVLINK& link);
484 : #endif
485 : // get a setting and associated metadata
486 : AP_OSD_ParamSetting* get_setting(uint8_t param_idx);
487 : // Save button co-ordinates
488 : AP_Int8 save_x;
489 : AP_Int8 save_y;
490 :
491 : // User settable parameters
492 : static const struct AP_Param::GroupInfo var_info[];
493 :
494 : private:
495 : AP_OSD_ParamSetting params[NUM_PARAMS];
496 :
497 : void save_parameters();
498 : #if OSD_ENABLED
499 : void update_state_machine();
500 : void draw_parameter(uint8_t param_number, uint8_t x, uint8_t y);
501 : void modify_parameter(uint8_t number, Event ev);
502 : void modify_configured_parameter(uint8_t number, Event ev);
503 :
504 : #if AP_RC_CHANNEL_ENABLED
505 : Event map_rc_input_to_event() const;
506 : #endif
507 :
508 : uint8_t _selected_param = 1;
509 : MenuState _menu_state = MenuState::PARAM_SELECT;
510 : Event _last_rc_event = Event::NONE;
511 :
512 : // start time of the current button press
513 : uint32_t _transition_start_ms;
514 : // timeout of the current button press
515 : uint32_t _transition_timeout_ms;
516 : // number of consecutive times the current transition has happened
517 : uint32_t _transition_count;
518 : #endif
519 : uint16_t _requires_save;
520 : };
521 :
522 : #endif // OSD_PARAM_ENABLED
523 :
524 : class AP_OSD
525 : {
526 : public:
527 : friend class AP_OSD_Screen;
528 : friend class AP_MSP;
529 : friend class AP_MSP_Telem_Backend;
530 : friend class AP_OSD_ParamScreen;
531 : //constructor
532 : AP_OSD();
533 :
534 : /* Do not allow copies */
535 : CLASS_NO_COPY(AP_OSD);
536 :
537 : // get singleton instance
538 310843 : static AP_OSD *get_singleton()
539 : {
540 310843 : return _singleton;
541 : }
542 :
543 : // init - perform required initialisation
544 : void init();
545 :
546 : // User settable parameters
547 : static const struct AP_Param::GroupInfo var_info[];
548 :
549 : enum osd_types {
550 : OSD_NONE=0,
551 : OSD_MAX7456=1,
552 : OSD_SITL=2,
553 : OSD_MSP=3,
554 : OSD_TXONLY=4,
555 : OSD_MSP_DISPLAYPORT=5
556 : };
557 :
558 : bool init_backend(const osd_types type, const uint8_t instance);
559 :
560 : enum switch_method {
561 : TOGGLE=0,
562 : PWM_RANGE=1,
563 : AUTO_SWITCH=2,
564 : };
565 :
566 : AP_Int8 osd_type;
567 : AP_Int8 osd_type2; // additional backend active in parallel
568 : AP_Int8 font_num;
569 : AP_Int32 options;
570 :
571 : #if OSD_ENABLED
572 : AP_Int8 rc_channel;
573 : AP_Int8 sw_method;
574 :
575 : AP_Int8 v_offset;
576 : AP_Int8 h_offset;
577 :
578 : AP_Int8 warn_rssi;
579 : AP_Int8 warn_nsat;
580 : AP_Int32 warn_terr;
581 : AP_Float warn_avgcellvolt;
582 : AP_Float max_battery_voltage;
583 : AP_Int8 cell_count;
584 : AP_Float warn_restvolt;
585 : AP_Float warn_avgcellrestvolt;
586 : AP_Float warn_batvolt;
587 : AP_Float warn_bat2volt;
588 : AP_Int8 msgtime_s;
589 : AP_Int8 arm_scr;
590 : AP_Int8 disarm_scr;
591 : AP_Int8 failsafe_scr;
592 : AP_Int32 button_delay_ms;
593 :
594 : #if AP_OSD_EXTENDED_LNK_STATS
595 : AP_Int8 warn_lq;
596 : AP_Int8 warn_snr;
597 : #endif
598 :
599 : #if HAL_OSD_SIDEBAR_ENABLE
600 : AP_Int8 sidebar_h_offset;
601 : AP_Int8 sidebar_v_ext;
602 : #endif
603 :
604 : enum {
605 : OPTION_DECIMAL_PACK = 1U<<0,
606 : OPTION_INVERTED_WIND = 1U<<1,
607 : OPTION_INVERTED_AH_ROLL = 1U<<2,
608 : OPTION_IMPERIAL_MILES = 1U<<3,
609 : OPTION_DISABLE_CROSSHAIR = 1U<<4,
610 : OPTION_BF_ARROWS = 1U<<5,
611 : OPTION_AVIATION_AH = 1U<<6,
612 : #if AP_OSD_EXTENDED_LNK_STATS
613 : OPTION_RF_MODE_ALONG_WITH_LQ = 1U<<7,
614 : #endif
615 : };
616 :
617 : enum {
618 : UNITS_METRIC=0,
619 : UNITS_IMPERIAL=1,
620 : UNITS_SI=2,
621 : UNITS_AVIATION=3,
622 : UNITS_LAST=4,
623 : };
624 :
625 : AP_Int8 units;
626 :
627 : AP_OSD_Screen screen[AP_OSD_NUM_DISPLAY_SCREENS];
628 :
629 : struct NavInfo {
630 : float wp_distance;
631 : int32_t wp_bearing;
632 : float wp_xtrack_error;
633 : uint16_t wp_number;
634 : };
635 :
636 : struct StatsInfo {
637 : uint32_t last_update_ms;
638 : float last_distance_m;
639 : float max_dist_m;
640 : float max_alt_m;
641 : float max_speed_mps;
642 : float max_airspeed_mps;
643 : float max_current_a;
644 : float avg_current_a;
645 : float min_voltage_v = FLT_MAX;
646 : float min_rssi = FLT_MAX; // 0-1
647 : int16_t max_esc_temp;
648 : };
649 :
650 : void set_nav_info(NavInfo &nav_info);
651 0 : const volatile StatsInfo& get_stats_info() const {return _stats;};
652 : // disable the display
653 0 : void disable() {
654 0 : _disable = true;
655 0 : }
656 : // enable the display
657 0 : void enable() {
658 0 : _disable = false;
659 0 : }
660 : #if AP_SCRIPTING_ENABLED
661 0 : AP_OSD_Backend *scripting_get_backend() {
662 : // set the override under the semaphore so the OSD thread sees a
663 : // consistent value; the scripting binding takes it again for the call
664 0 : WITH_SEMAPHORE(_sem);
665 0 : scripting_override = true;
666 0 : override_count = 0;
667 0 : return _backends[0];
668 0 : }
669 0 : void draw_screen() {
670 0 : if (scripting_override) {
671 0 : update_osd();
672 : }
673 0 : }
674 0 : bool display_disabled() const { return _disable; }
675 0 : uint8_t get_screen() const { return current_screen; }
676 : #endif // AP_SCRIPTING_ENABLED
677 :
678 1096 : AP_OSD_AbstractScreen& get_screen(uint8_t idx) {
679 : #if OSD_PARAM_ENABLED
680 1096 : if (idx >= AP_OSD_NUM_DISPLAY_SCREENS) {
681 0 : return param_screen[idx - AP_OSD_NUM_DISPLAY_SCREENS];
682 : }
683 : #endif
684 1096 : return screen[idx];
685 : }
686 :
687 : // Check whether arming is allowed
688 : bool pre_arm_check(char *failure_msg, const uint8_t failure_msg_len) const;
689 139988 : bool is_readonly_screen() const { return current_screen < AP_OSD_NUM_DISPLAY_SCREENS; }
690 : // get the current screen
691 10254 : uint8_t get_current_screen() const { return current_screen; };
692 : #endif // OSD_ENABLED
693 : #if OSD_PARAM_ENABLED
694 : AP_OSD_ParamScreen param_screen[AP_OSD_NUM_PARAM_SCREENS] { 0, 1 };
695 : // return a setting for use by TX based OSD
696 0 : AP_OSD_ParamSetting* get_setting(uint8_t screen_idx, uint8_t param_idx) {
697 0 : if (screen_idx >= AP_OSD_NUM_PARAM_SCREENS) {
698 0 : return nullptr;
699 : }
700 0 : return param_screen[screen_idx].get_setting(param_idx);
701 : }
702 : #endif
703 : // handle OSD parameter configuration
704 : #if HAL_GCS_ENABLED
705 : void handle_msg(const mavlink_message_t &msg, const class GCS_MAVLINK& link);
706 : #endif
707 :
708 : // allow threads to lock against OSD update
709 0 : HAL_Semaphore &get_semaphore(void) {
710 0 : return _sem;
711 : }
712 :
713 : private:
714 : void osd_thread();
715 : #if OSD_ENABLED
716 : void update_osd();
717 : void update_stats();
718 : void update_current_screen();
719 : void next_screen();
720 :
721 : //variables for screen switching
722 : uint8_t current_screen;
723 : uint16_t previous_channel_value;
724 : bool switch_debouncer;
725 : uint32_t last_switch_ms;
726 : struct NavInfo nav_info;
727 : int8_t previous_pwm_screen;
728 : int8_t pre_fs_screen;
729 : bool was_armed;
730 : bool was_failsafe;
731 : bool _disable;
732 :
733 : StatsInfo _stats;
734 : #endif
735 : AP_OSD_Backend *_backends[OSD_MAX_INSTANCES];
736 : uint8_t _backend_count;
737 :
738 : #if AP_SCRIPTING_ENABLED
739 : // bool for scripting override and counter to timeout override
740 : bool scripting_override;
741 : uint8_t override_count;
742 : #endif // AP_SCRIPTING_ENABLED
743 : static AP_OSD *_singleton;
744 : // multi-thread access support
745 : HAL_Semaphore _sem;
746 : };
747 :
748 : namespace AP
749 : {
750 : AP_OSD *osd();
751 : };
|