From b269581dcc06e5bd03bf1e6eb298b66e2d2118b2 Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Thu, 23 Jul 2026 09:19:52 +0100 Subject: [PATCH] AP_OSD: allow scripting override and add getters add semaphore protection for scripting bindings Add get_semaphore() to AP_OSD_Backend that delegates to the parent AP_OSD semaphore. Add semaphore keyword to scripting bindings so that all OSD method calls from Lua are thread-safe with respect to the OSD update thread. Co-Authored-By: Iampete1 --- libraries/AP_OSD/AP_OSD.cpp | 20 +++++++++++++++++++- libraries/AP_OSD/AP_OSD.h | 19 +++++++++++++++++++ libraries/AP_OSD/AP_OSD_Backend.h | 10 ++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/libraries/AP_OSD/AP_OSD.cpp b/libraries/AP_OSD/AP_OSD.cpp index a660f4bbc1c..89fd7d5dba6 100644 --- a/libraries/AP_OSD/AP_OSD.cpp +++ b/libraries/AP_OSD/AP_OSD.cpp @@ -320,6 +320,11 @@ void AP_OSD::init() bool AP_OSD::init_backend(const AP_OSD::osd_types type, const uint8_t instance) { + // don't re-initialize if backend already exists + if (_backends[instance] != nullptr) { + return false; + } + // check if we can run this backend instance in parallel with backend instance 0 if (instance > 0) { if (_backends[0] && !_backends[0]->is_compatible_with_backend_type(type)) { @@ -403,7 +408,20 @@ void AP_OSD::osd_thread() update_stats(); update_current_screen(); } - update_osd(); +#if AP_SCRIPTING_ENABLED + if (!scripting_override) { +#endif + update_osd(); +#if AP_SCRIPTING_ENABLED + } else { + override_count++; + if (override_count > 20) { + // timeout after 2 seconds and return to normal OSD + scripting_override = false; + override_count = 0; + } + } +#endif // AP_SCRIPTING_ENABLED } } diff --git a/libraries/AP_OSD/AP_OSD.h b/libraries/AP_OSD/AP_OSD.h index 3081574bfd3..904952752f8 100644 --- a/libraries/AP_OSD/AP_OSD.h +++ b/libraries/AP_OSD/AP_OSD.h @@ -657,6 +657,20 @@ public: void enable() { _disable = false; } +#if AP_SCRIPTING_ENABLED + AP_OSD_Backend *scripting_get_backend() { + scripting_override = true; + override_count = 0; + return _backends[0]; + } + void draw_screen() { + if (scripting_override) { + update_osd(); + } + } + bool display_disabled() const { return _disable; } + uint8_t get_screen() const { return current_screen; } +#endif // AP_SCRIPTING_ENABLED AP_OSD_AbstractScreen& get_screen(uint8_t idx) { #if OSD_PARAM_ENABLED @@ -718,6 +732,11 @@ private: AP_OSD_Backend *_backends[OSD_MAX_INSTANCES]; uint8_t _backend_count; +#if AP_SCRIPTING_ENABLED + // bool for scripting override and counter to timeout override + bool scripting_override; + uint8_t override_count; +#endif // AP_SCRIPTING_ENABLED static AP_OSD *_singleton; // multi-thread access support HAL_Semaphore _sem; diff --git a/libraries/AP_OSD/AP_OSD_Backend.h b/libraries/AP_OSD/AP_OSD_Backend.h index e81a3a08f07..cdb5ddd4241 100644 --- a/libraries/AP_OSD/AP_OSD_Backend.h +++ b/libraries/AP_OSD/AP_OSD_Backend.h @@ -61,6 +61,16 @@ public: // called by the OSD thread once virtual void osd_thread_run_once() { return; } +#if OSD_ENABLED && AP_SCRIPTING_ENABLED + // passthrough OSD functions for use by scripting + bool display_disabled() const { return _osd.display_disabled(); } + uint8_t get_screen() const { return _osd.get_screen(); } + void draw_screen() { _osd.draw_screen(); } + + // get semaphore for thread-safe access from scripting + HAL_Semaphore &get_semaphore() { return _osd.get_semaphore(); } +#endif + AP_OSD * get_osd() { return &_osd;