123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- #include "AP_OSD.h"
- #include "AP_OSD_MAX7456.h"
- #ifdef WITH_SITL_OSD
- #include "AP_OSD_SITL.h"
- #endif
- #include <AP_HAL/AP_HAL.h>
- #include <AP_HAL/Util.h>
- #include <RC_Channel/RC_Channel.h>
- #include <AP_AHRS/AP_AHRS.h>
- #include <AP_BattMonitor/AP_BattMonitor.h>
- #include <utility>
- #include <AP_Notify/AP_Notify.h>
- const AP_Param::GroupInfo AP_OSD::var_info[] = {
-
-
-
-
-
-
- AP_GROUPINFO_FLAGS("_TYPE", 1, AP_OSD, osd_type, 0, AP_PARAM_FLAG_ENABLE),
-
-
-
-
-
- AP_GROUPINFO("_CHAN", 2, AP_OSD, rc_channel, 0),
-
-
- AP_SUBGROUPINFO(screen[0], "1_", 3, AP_OSD, AP_OSD_Screen),
-
-
- AP_SUBGROUPINFO(screen[1], "2_", 4, AP_OSD, AP_OSD_Screen),
-
-
- AP_SUBGROUPINFO(screen[2], "3_", 5, AP_OSD, AP_OSD_Screen),
-
-
- AP_SUBGROUPINFO(screen[3], "4_", 6, AP_OSD, AP_OSD_Screen),
-
-
-
-
-
-
-
- AP_GROUPINFO("_SW_METHOD", 7, AP_OSD, sw_method, AP_OSD::TOGGLE),
-
-
-
-
-
- AP_GROUPINFO("_OPTIONS", 8, AP_OSD, options, OPTION_DECIMAL_PACK),
-
-
-
-
-
- AP_GROUPINFO("_FONT", 9, AP_OSD, font_num, 0),
-
-
-
-
-
-
- AP_GROUPINFO("_V_OFFSET", 10, AP_OSD, v_offset, 16),
-
-
-
-
-
-
- AP_GROUPINFO("_H_OFFSET", 11, AP_OSD, h_offset, 32),
-
-
-
-
-
- AP_GROUPINFO("_W_RSSI", 12, AP_OSD, warn_rssi, 30),
-
-
-
-
-
- AP_GROUPINFO("_W_NSAT", 13, AP_OSD, warn_nsat, 9),
-
-
-
-
-
- AP_GROUPINFO("_W_BATVOLT", 14, AP_OSD, warn_batvolt, 10.0f),
-
-
-
-
-
- AP_GROUPINFO("_UNITS", 15, AP_OSD, units, 0),
-
-
-
-
-
- AP_GROUPINFO("_MSG_TIME", 16, AP_OSD, msgtime_s, 10),
-
-
-
-
-
-
- AP_GROUPINFO("_ARM_SCR", 17, AP_OSD, arm_scr, 0),
-
-
-
-
-
-
- AP_GROUPINFO("_DSARM_SCR", 18, AP_OSD, disarm_scr, 0),
-
-
-
-
-
- AP_GROUPINFO("_FS_SCR", 19, AP_OSD, failsafe_scr, 0),
- AP_GROUPEND
- };
- extern const AP_HAL::HAL& hal;
- AP_OSD::AP_OSD()
- {
- AP_Param::setup_object_defaults(this, var_info);
-
- screen[0].enabled = 1;
- #ifdef WITH_SITL_OSD
- osd_type.set_default(2);
- #endif
-
- #ifdef HAL_OSD_TYPE_DEFAULT
- osd_type.set_default(HAL_OSD_TYPE_DEFAULT);
- #endif
- previous_pwm_screen = -1;
- }
- void AP_OSD::init()
- {
- switch ((enum osd_types)osd_type.get()) {
- case OSD_NONE:
- default:
- break;
- case OSD_MAX7456: {
- AP_HAL::OwnPtr<AP_HAL::Device> spi_dev = std::move(hal.spi->get_device("osd"));
- if (!spi_dev) {
- break;
- }
- backend = AP_OSD_MAX7456::probe(*this, std::move(spi_dev));
- if (backend == nullptr) {
- break;
- }
- hal.console->printf("Started MAX7456 OSD\n");
- break;
- }
- #ifdef WITH_SITL_OSD
- case OSD_SITL: {
- backend = AP_OSD_SITL::probe(*this);
- if (backend == nullptr) {
- break;
- }
- hal.console->printf("Started SITL OSD\n");
- break;
- }
- #endif
- }
- if (backend != nullptr) {
-
- hal.scheduler->thread_create(FUNCTOR_BIND_MEMBER(&AP_OSD::osd_thread, void), "OSD", 1024, AP_HAL::Scheduler::PRIORITY_IO, 1);
- }
- }
- void AP_OSD::osd_thread()
- {
- while (true) {
- hal.scheduler->delay(100);
- update_osd();
- }
- }
- void AP_OSD::update_osd()
- {
- backend->clear();
- stats();
- update_current_screen();
- screen[current_screen].set_backend(backend);
- screen[current_screen].draw();
- backend->flush();
- }
- void AP_OSD::stats()
- {
- uint32_t now = AP_HAL::millis();
- if (!AP_Notify::flags.armed) {
- last_update_ms = now;
- return;
- }
-
- uint32_t delta_ms = now - last_update_ms;
- last_update_ms = now;
-
- AP_AHRS &ahrs = AP::ahrs();
- Vector2f v = ahrs.groundspeed_vector();
- float speed = v.length();
- if (speed < 2.0) {
- speed = 0.0;
- }
- float dist_m = (speed * delta_ms)*0.001;
- last_distance_m += dist_m;
-
-
- max_speed_mps = fmaxf(max_speed_mps,speed);
-
-
- Location loc;
- if (ahrs.get_position(loc) && ahrs.home_is_set()) {
- const Location &home_loc = ahrs.get_home();
- float distance = home_loc.get_distance(loc);
- max_dist_m = fmaxf(max_dist_m, distance);
- }
-
-
- float alt;
- AP::ahrs().get_relative_position_D_home(alt);
- alt = -alt;
- max_alt_m = fmaxf(max_alt_m, alt);
-
- AP_BattMonitor &battery = AP::battery();
- float amps;
- if (battery.current_amps(amps)) {
- max_current_a = fmaxf(max_current_a, amps);
- }
- }
- void AP_OSD::update_current_screen()
- {
-
- if (AP_Notify::flags.armed){
- if (!was_armed && arm_scr > 0 && arm_scr <= AP_OSD_NUM_SCREENS && screen[arm_scr-1].enabled){
- current_screen = arm_scr-1;
- }
- was_armed = true;
- } else if (was_armed) {
- if (disarm_scr > 0 && disarm_scr <= AP_OSD_NUM_SCREENS && screen[disarm_scr-1].enabled){
- current_screen = disarm_scr-1;
- }
- was_armed = false;
- }
-
-
- if (AP_Notify::flags.failsafe_radio || AP_Notify::flags.failsafe_battery) {
- if (!was_failsafe && failsafe_scr > 0 && failsafe_scr <= AP_OSD_NUM_SCREENS && screen[failsafe_scr-1].enabled){
- pre_fs_screen = current_screen;
- current_screen = failsafe_scr-1;
- }
- was_failsafe = true;
- } else if (was_failsafe) {
- if (screen[pre_fs_screen].enabled){
- current_screen = pre_fs_screen;
- }
- was_failsafe = false;
- }
-
- if (rc_channel == 0) {
- return;
- }
- RC_Channel *channel = RC_Channels::rc_channel(rc_channel-1);
- if (channel == nullptr) {
- return;
- }
- int16_t channel_value = channel->get_radio_in();
- switch (sw_method) {
-
- default:
- case TOGGLE:
- if (previous_channel_value == 0) {
-
- previous_channel_value = channel_value;
- }
- if (abs(channel_value-previous_channel_value) > 200) {
- if (switch_debouncer) {
- next_screen();
- previous_channel_value = channel_value;
- } else {
- switch_debouncer = true;
- return;
- }
- }
- break;
-
- case PWM_RANGE:
- for (int i=0; i<AP_OSD_NUM_SCREENS; i++) {
- if (screen[i].enabled && screen[i].channel_min <= channel_value && screen[i].channel_max > channel_value && previous_pwm_screen != i) {
- current_screen = previous_pwm_screen = i;
- break;
- }
- }
- break;
-
- case AUTO_SWITCH:
- if (channel_value > channel->get_radio_trim()) {
- if (switch_debouncer) {
- uint32_t now = AP_HAL::millis();
- if (now - last_switch_ms > 1000) {
- next_screen();
- last_switch_ms = now;
- }
- } else {
- switch_debouncer = true;
- return;
- }
- } else {
- last_switch_ms = 0;
- }
- break;
- }
- switch_debouncer = false;
- }
- void AP_OSD::next_screen()
- {
- uint8_t t = current_screen;
- do {
- t = (t + 1)%AP_OSD_NUM_SCREENS;
- } while (t != current_screen && !screen[t].enabled);
- current_screen = t;
- }
- void AP_OSD::set_nav_info(NavInfo &navinfo)
- {
-
- nav_info = navinfo;
- }
|