rewrite MccGenericMovementControls class (single thread version)
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <atomic>
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
|
||||
#include "mcc_coordinate.h"
|
||||
@@ -236,6 +237,8 @@ template <std::movable PARAMS_T,
|
||||
MccGenericMovementControlsPolicy EXEC_POLICY = MccGenericMovementControlsPolicy::POLICY_ASYNC>
|
||||
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_T>(track_func)),
|
||||
_stopFunc(std::forward<STOP_FUNC_T>(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<std::chrono::nanoseconds>{defaultWaitTimeout}};
|
||||
|
||||
|
||||
|
||||
std::conditional_t<executePolicy == MccGenericMovementControlsPolicy::POLICY_ASYNC,
|
||||
std::future<void>,
|
||||
std::nullptr_t>
|
||||
_fstFuture{};
|
||||
|
||||
std::stop_source _fstStopSource{};
|
||||
|
||||
std::unique_ptr<std::atomic_flag> _wakeupRequest{new std::atomic_flag};
|
||||
std::unique_ptr<std::atomic_bool> _doSlew{new std::atomic_bool{false}};
|
||||
std::unique_ptr<std::atomic_bool> _doTrack{new std::atomic_bool{false}};
|
||||
std::unique_ptr<std::atomic_bool> _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
|
||||
|
||||
Reference in New Issue
Block a user