From d42fa37a04076aa2a2a3f6abb5d8bb06bdf3dbb5 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 27 Feb 2026 18:02:02 +0300 Subject: [PATCH] rewrite MccGenericMovementControls class (single thread version) --- include/mcc/mcc_generic_movecontrols.h | 159 +++++++++++++++++++------ 1 file changed, 121 insertions(+), 38 deletions(-) diff --git a/include/mcc/mcc_generic_movecontrols.h b/include/mcc/mcc_generic_movecontrols.h index 8cbb5f9..b7b6924 100644 --- a/include/mcc/mcc_generic_movecontrols.h +++ b/include/mcc/mcc_generic_movecontrols.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "mcc_coordinate.h" @@ -236,6 +237,8 @@ template class MccGenericMovementControls { + enum { STATE_SLEW, STATE_TRACK, STATE_IDLE } _currentState; + public: static constexpr MccGenericMovementControlsPolicy executePolicy = EXEC_POLICY; @@ -251,6 +254,40 @@ public: _trackFunc(std::forward(track_func)), _stopFunc(std::forward(stop_func)) { + if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { + *_doSlew = false; + *_doTrack = false; + *_stopMovementRequest = false; + _currentState = STATE_IDLE; + + _fstFuture = std::async( + [&, this](std::stop_token stoken) { + while (!stoken.stop_requested()) { + if (_stopMovementRequest->load()) { + _currentState = STATE_IDLE; + _stopFunc(); + } + + if (_doSlew->load()) { + _currentState = STATE_SLEW; + _slewFunc(_slewAndStop->load()); + _currentState = STATE_IDLE; + } + + if (_doTrack->load()) { + _currentState = STATE_TRACK; + _trackFunc(); + _currentState = STATE_IDLE; + } + + // wait here ... + _wakeupRequest->wait(false, std::memory_order_relaxed); + + _wakeupRequest->clear(); + } + }, + _fstStopSource.get_token()); + } } MccGenericMovementControls(const MccGenericMovementControls&) = delete; @@ -261,27 +298,32 @@ public: virtual ~MccGenericMovementControls() { - // if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { - // // if future is valid then stop is already called - // if (!_stopFuncFuture.valid()) { - // // stopMount(); - // _stopFunc(); - // } - // } else { - // stopMount(); - // } - if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { - if (_slewFuncFuture.valid()) { - auto status = _slewFuncFuture.wait_for(_waitTimeout->load()); - } + // if (_slewFuncFuture.valid()) { + // auto status = _slewFuncFuture.wait_for(_waitTimeout->load()); + // } - if (_trackFuncFuture.valid()) { - auto status = _trackFuncFuture.wait_for(_waitTimeout->load()); - } + // if (_trackFuncFuture.valid()) { + // auto status = _trackFuncFuture.wait_for(_waitTimeout->load()); + // } - if (_stopFuncFuture.valid()) { - auto status = _stopFuncFuture.wait_for(_waitTimeout->load()); + // if (_stopFuncFuture.valid()) { + // auto status = _stopFuncFuture.wait_for(_waitTimeout->load()); + // } + + + *_doSlew = false; + *_doTrack = false; + // *_stopMovementRequest = false; + + _fstStopSource.request_stop(); + _wakeupRequest->test_and_set(); + _wakeupRequest->notify_one(); + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + if (_fstFuture.valid()) { + auto status = _fstFuture.wait_for(_waitTimeout->load()); } } } @@ -291,21 +333,33 @@ public: *_stopMovementRequest = false; if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { - if (_slewFuncFuture.valid()) { // already slewing - _slewFuncFuture = std::async( - std::launch::async, - [this](bool st) { - auto err = _stopFunc(); // first, stop mount - if (!err) { - return _slewFunc(st); - } else { - return err; - } - }, - slew_and_stop); - } else { - _slewFuncFuture = std::async(std::launch::async, _slewFunc, slew_and_stop); + // if (_slewFuncFuture.valid()) { // already slewing + // _slewFuncFuture = std::async( + // std::launch::async, + // [this](bool st) { + // auto err = _stopFunc(); // first, stop mount + // if (!err) { + // *_stopMovementRequest = false; + + // return _slewFunc(st); + // } else { + // return err; + // } + // }, + // slew_and_stop); + // } else { + // _slewFuncFuture = std::async(std::launch::async, _slewFunc, slew_and_stop); + // } + + + if (_currentState == STATE_SLEW || _currentState == STATE_TRACK) { // first, stop mount + *_stopMovementRequest = true; } + *_doTrack = false; + *_doSlew = true; + *_slewAndStop = slew_and_stop; + _wakeupRequest->test_and_set(); + _wakeupRequest->notify_one(); return MccGenericMovementControlsErrorCode::ERROR_OK; } else if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_BLOCKING) { @@ -320,9 +374,19 @@ public: *_stopMovementRequest = false; if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { - if (!_trackFuncFuture.valid()) { - _trackFuncFuture = std::async(std::launch::async, _trackFunc); - } // already tracking + // if (!_trackFuncFuture.valid()) { + // _trackFuncFuture = std::async(std::launch::async, _trackFunc); + // } // already tracking, just ignore + + if (_currentState != STATE_TRACK) { + if (_currentState == STATE_SLEW) { // first, stop mount + *_stopMovementRequest = true; + } + *_doSlew = false; + *_doTrack = true; + _wakeupRequest->test_and_set(); + _wakeupRequest->notify_one(); + } // already tracking, just ignore return MccGenericMovementControlsErrorCode::ERROR_OK; } else if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_BLOCKING) { @@ -338,9 +402,14 @@ public: if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC) { // if future is valid then stop is already called - if (!_stopFuncFuture.valid()) { - _stopFuncFuture = std::async(std::launch::async, _stopFunc); - } + // if (!_stopFuncFuture.valid()) { + // _stopFuncFuture = std::async(std::launch::async, _stopFunc); + // } + + *_doSlew = false; + *_doTrack = false; + _wakeupRequest->test_and_set(); + _wakeupRequest->notify_one(); return MccGenericMovementControlsErrorCode::ERROR_OK; } else if constexpr (executePolicy == MccGenericMovementControlsPolicy::POLICY_BLOCKING) { @@ -396,6 +465,20 @@ protected: new std::atomic{defaultWaitTimeout}}; + + std::conditional_t, + std::nullptr_t> + _fstFuture{}; + + std::stop_source _fstStopSource{}; + + std::unique_ptr _wakeupRequest{new std::atomic_flag}; + std::unique_ptr _doSlew{new std::atomic_bool{false}}; + std::unique_ptr _doTrack{new std::atomic_bool{false}}; + std::unique_ptr _slewAndStop{new std::atomic_bool{false}}; + + // utility methods // the method calculates the change in coordinates of a point over a given time given the current speed and braking