...
This commit is contained in:
parent
5f802ff57e
commit
c7dd816481
@ -50,7 +50,7 @@ public:
|
||||
|
||||
Asibfm700Mount(Asibfm700MountConfig const& config,
|
||||
std::shared_ptr<spdlog::logger> logger,
|
||||
const auto& pattern_range = LOGGER_DEFAULT_FORMAT);
|
||||
const auto& pattern_range = mcc::utils::MccSpdlogLogger::LOGGER_DEFAULT_FORMAT);
|
||||
|
||||
~Asibfm700Mount();
|
||||
};
|
||||
|
||||
@ -52,7 +52,7 @@ struct MccFiniteStateMachineCategory : public std::error_category {
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
return "ADC_GENERIC_DEVICE";
|
||||
return "MCC-FSM-ERROR-CATEGORY";
|
||||
}
|
||||
|
||||
std::string message(int ec) const
|
||||
|
||||
@ -14,6 +14,8 @@ namespace mcc
|
||||
|
||||
enum class MccGenericMountErrorCode : int { ERROR_OK, ERROR_HW_INIT, ERROR_HW_STOP, ERROR_HW_GETSTATE };
|
||||
|
||||
enum class MccGenericFsmMountErrorCode : int { ERROR_OK, ERROR_INVALID_OPERATION, ERROR_UNKNOWN_EVENT };
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
|
||||
@ -25,6 +27,11 @@ class is_error_code_enum<mcc::MccGenericMountErrorCode> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
class is_error_code_enum<mcc::MccGenericFsmMountErrorCode> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
@ -75,6 +82,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
MccGenericMount(MccGenericMount&&) = default;
|
||||
MccGenericMount(const MccGenericMount&) = delete;
|
||||
|
||||
MccGenericMount& operator=(MccGenericMount&&) = default;
|
||||
MccGenericMount& operator=(const MccGenericMount&) = delete;
|
||||
|
||||
virtual ~MccGenericMount() = default;
|
||||
|
||||
error_t stopMount()
|
||||
@ -114,20 +127,29 @@ public:
|
||||
/* GENERIC FINITE-STATE-MACHINE MOUNT REFERENCE IMPLEMENTATION */
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_generic_fsm_mount_event_c =
|
||||
fsm::traits::fsm_event_c<T> && std::constructible_from<typename T::mount_t*> && requires(T t) {
|
||||
{ t.mount() } -> std::same_as<typename T::mount_t*>;
|
||||
};
|
||||
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountBaseEvent {
|
||||
typedef MOUNT_T mount_t;
|
||||
|
||||
// static constexpr std::string_view ID{""};
|
||||
virtual ~MccGenericFsmMountBaseEvent() = default;
|
||||
|
||||
MOUNT_T& mount() const
|
||||
MOUNT_T* mount() const
|
||||
{
|
||||
return _mount;
|
||||
}
|
||||
|
||||
protected:
|
||||
MOUNT_T& _mount;
|
||||
MOUNT_T* _mount;
|
||||
|
||||
MccGenericFsmMountBaseEvent(MOUNT_T& mount) : _mount(mount) {}
|
||||
MccGenericFsmMountBaseEvent(MOUNT_T* mount) : _mount(mount) {}
|
||||
};
|
||||
|
||||
|
||||
@ -141,7 +163,24 @@ template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountStopEvent;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountErrorEvent;
|
||||
struct MccGenericFsmMountErrorEvent : MccGenericFsmMountBaseEvent<MOUNT_T> {
|
||||
static constexpr std::string_view ID{"GENERIC-MOUNT-ERROR-EVENT"};
|
||||
|
||||
typedef typename MOUNT_T::error_t mount_error_t;
|
||||
|
||||
MccGenericFsmMountErrorEvent(MOUNT_T* mount, const mount_error_t& err)
|
||||
: MccGenericFsmMountBaseEvent<MOUNT_T>(mount), _err(err)
|
||||
{
|
||||
}
|
||||
|
||||
mount_error_t eventData() const noexcept
|
||||
{
|
||||
return _err;
|
||||
}
|
||||
|
||||
protected:
|
||||
mount_error_t _err;
|
||||
};
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountSlewEvent;
|
||||
@ -149,138 +188,306 @@ struct MccGenericFsmMountSlewEvent;
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountTrackEvent;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountBaseState {
|
||||
// static constexpr std::string_view ID{""};
|
||||
virtual ~MccGenericFsmMountBaseState() = default;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountBaseState {
|
||||
// typedef MOUNT_T mount_t;
|
||||
|
||||
protected:
|
||||
MccGenericFsmMountBaseState() = default;
|
||||
// virtual ~MccGenericFsmMountBaseState() = default;
|
||||
|
||||
template <fsm::traits::fsm_event_c EvT>
|
||||
void exitLog(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
// protected:
|
||||
// MccGenericFsmMountBaseState() = default;
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
event.mount().logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
}
|
||||
}
|
||||
// template <fsm::traits::fsm_event_c EvT>
|
||||
// void exitLog(this auto&& self, EvT& event)
|
||||
// {
|
||||
// using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
template <fsm::traits::fsm_event_c EvT>
|
||||
void enterLog(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
// if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
// std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
// event.mount()->logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
// }
|
||||
// }
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
event.mount().logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
}
|
||||
}
|
||||
};
|
||||
// template <fsm::traits::fsm_event_c EvT>
|
||||
// void enterLog(this auto&& self, EvT& event)
|
||||
// {
|
||||
// using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountStartState;
|
||||
// if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
// std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
// event.mount()->logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountIdleState;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountStartState;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountStopState;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountIdleState;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountErrorState;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountStopState;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountSlewState;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountErrorState;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountTrackState;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountSlewState;
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T>
|
||||
struct MccGenericFsmMountInitState {
|
||||
static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"};
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountTrackState;
|
||||
|
||||
using transition_t = fsm::fsm_transition_table_t<
|
||||
std::pair<MccGenericFsmMountIdleEvent<MOUNT_T>, MccGenericFsmMountIdleState<MOUNT_T>>,
|
||||
std::pair<MccGenericFsmMountErrorEvent<MOUNT_T>, MccGenericFsmMountErrorState<MOUNT_T>>,
|
||||
std::pair<MccGenericFsmMountInitEvent<MOUNT_T>, MccGenericFsmMountInitState<MOUNT_T>>>;
|
||||
// template <mcc_generic_mount_c MOUNT_T>
|
||||
// struct MccGenericFsmMountInitState : MccGenericFsmMountBaseState<MOUNT_T> {
|
||||
// static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"};
|
||||
|
||||
// using transition_t = fsm::fsm_transition_table_t<
|
||||
// std::pair<MccGenericFsmMountIdleEvent<MOUNT_T>, MccGenericFsmMountIdleState<MOUNT_T>>,
|
||||
// std::pair<MccGenericFsmMountErrorEvent<MOUNT_T>, MccGenericFsmMountErrorState<MOUNT_T>>,
|
||||
// std::pair<MccGenericFsmMountInitEvent<MOUNT_T>, MccGenericFsmMountInitState<MOUNT_T>>>;
|
||||
|
||||
|
||||
void exit(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
event.mount().logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!");
|
||||
}
|
||||
}
|
||||
// void exit(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
// {
|
||||
// if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
// event.mount()->logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!");
|
||||
// }
|
||||
// }
|
||||
|
||||
void enter(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
event.mount().logWarn(
|
||||
"It seems a re-entering to the initializing state was asked! Ignore the event and wait for the mount "
|
||||
"to initialize!");
|
||||
}
|
||||
}
|
||||
// void enter(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
// {
|
||||
// if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
// event.mount()->logWarn(
|
||||
// "It seems a re-entering to the initializing state was asked! Ignore the event and wait for the mount
|
||||
// " "to initialize!");
|
||||
// }
|
||||
// }
|
||||
|
||||
void exit(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
exitLog(event);
|
||||
}
|
||||
// void exit(fsm::traits::fsm_event_c auto& event)
|
||||
// {
|
||||
// exitLog(event);
|
||||
// }
|
||||
|
||||
void enter(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
enterLog(event);
|
||||
}
|
||||
};
|
||||
// void enter(fsm::traits::fsm_event_c auto& event)
|
||||
// {
|
||||
// enterLog(event);
|
||||
// auto err = event.mount()->initMount();
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
template <mcc_generic_mount_c MOUNT_T,
|
||||
fsm::traits::fsm_state_c START_STATE_T = MccGenericFsmMountStartState<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c INIT_EVENT_T = MccGenericFsmMountInitEvent<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c IDLE_EVENT_T = MccGenericFsmMountIdleEvent<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c STOP_EVENT_T = MccGenericFsmMountStopEvent<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c ERROR_EVENT_T = MccGenericFsmMountErrorEvent<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c SLEW_EVENT_T = MccGenericFsmMountSlewEvent<MOUNT_T>,
|
||||
fsm::traits::fsm_event_c TRACK_EVENT_T = MccGenericFsmMountTrackEvent<MOUNT_T>>
|
||||
mcc_generic_fsm_mount_event_c INIT_EVENT_T = MccGenericFsmMountInitEvent<MOUNT_T>,
|
||||
mcc_generic_fsm_mount_event_c STOP_EVENT_T = MccGenericFsmMountStopEvent<MOUNT_T>,
|
||||
mcc_generic_fsm_mount_event_c SLEW_EVENT_T = MccGenericFsmMountSlewEvent<MOUNT_T>,
|
||||
mcc_generic_fsm_mount_event_c TRACK_EVENT_T = MccGenericFsmMountTrackEvent<MOUNT_T>>
|
||||
class MccGenericFsmMount : public MOUNT_T, protected fsm::MccFiniteStateMachine
|
||||
{
|
||||
// to prevent infinite recursion!
|
||||
static_assert(!std::derived_from<MOUNT_T, MccGenericFsmMount>, "!!!!!!!!!");
|
||||
|
||||
public:
|
||||
using typename MOUNT_T::error_t;
|
||||
typedef std::error_code error_t;
|
||||
|
||||
protected:
|
||||
/* default states implementation */
|
||||
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountBaseState {
|
||||
virtual ~MccGenericFsmMountBaseState() = default;
|
||||
|
||||
protected:
|
||||
MccGenericFsmMountBaseState() = default;
|
||||
|
||||
template <fsm::traits::fsm_event_c EvT>
|
||||
void exitLog(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
event.mount()->logDebug(std::format("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
}
|
||||
}
|
||||
|
||||
template <fsm::traits::fsm_event_c EvT>
|
||||
void enterLog(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T> &&
|
||||
std::derived_from<EvT, MccGenericFsmMountBaseEvent<MOUNT_T>>) {
|
||||
event.mount()->logDebug(std::format("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct MccGenericFsmMountErrorState;
|
||||
|
||||
struct MccGenericFsmMountStartState;
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountIdleState;
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountStopState;
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountSlewState;
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountTrackState;
|
||||
|
||||
template <fsm::traits::fsm_state_c ERROR_STATE_T>
|
||||
struct MccGenericFsmMountInitState : MccGenericFsmMountBaseState<ERROR_STATE_T> {
|
||||
static constexpr std::string_view ID{"GENERIC-MOUNT-INIT-STATE"};
|
||||
|
||||
using transition_t = fsm::fsm_transition_table_t<
|
||||
std::pair<MccGenericFsmMountIdleEvent<MOUNT_T>, MccGenericFsmMountIdleState<MccGenericFsmMountErrorState>>,
|
||||
std::pair<MccGenericFsmMountErrorEvent<MOUNT_T>, MccGenericFsmMountErrorState>,
|
||||
std::pair<MccGenericFsmMountInitEvent<MOUNT_T>, MccGenericFsmMountInitState>>;
|
||||
|
||||
|
||||
void exit(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
event.mount()->logWarn("It seems a re-entering to the initializing state was asked! Ignore the event!");
|
||||
}
|
||||
}
|
||||
|
||||
void enter(MccGenericFsmMountInitEvent<MOUNT_T>& event)
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
event.mount()->logWarn(
|
||||
"It seems a re-entering to the initializing state was asked! Ignore the event and wait for the "
|
||||
"mount "
|
||||
"to initialize!");
|
||||
}
|
||||
}
|
||||
|
||||
void exit(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
exitLog(event);
|
||||
}
|
||||
|
||||
void enter(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
enterLog(event);
|
||||
auto err = event.mount()->initMount();
|
||||
}
|
||||
};
|
||||
|
||||
struct MccGenericFsmMountErrorState // default implementation (just log error)
|
||||
{
|
||||
static constexpr std::string_view ID{"GENERIC-MOUNT-ERROR-STATE"};
|
||||
|
||||
using transition_t = fsm::fsm_transition_table_t<
|
||||
std::pair<MccGenericFsmMountErrorEvent<MOUNT_T>, MccGenericFsmMountErrorState>,
|
||||
std::pair<MccGenericFsmMountIdleEvent<MOUNT_T>, MccGenericFsmMountIdleState<MccGenericFsmMountErrorState>>,
|
||||
std::pair<MccGenericFsmMountInitEvent<MOUNT_T>, MccGenericFsmMountInitState<MccGenericFsmMountErrorState>>>;
|
||||
|
||||
void exit(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
exitLog(event);
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
event.mount()->logWarn(
|
||||
std::format("The mount is in the error state!!! One must correct it before transit to any states! "
|
||||
"Event type is '{}'",
|
||||
decltype(event)::ID));
|
||||
}
|
||||
}
|
||||
|
||||
void enter(fsm::traits::fsm_event_c auto& event)
|
||||
{
|
||||
enterLog(event);
|
||||
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
auto err = event.eventData();
|
||||
event.mount()->logError(
|
||||
std::format("The mount is in the error state: code = {}, category = {}, message = '{}'",
|
||||
err.value(), err.category().name(), err.message()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
MccGenericFsmMount(MOUNT_T mount, fsm::traits::fsm_state_c auto start_state)
|
||||
: MOUNT_T(std::move(mount)), fsm::MccFiniteStateMachine(std::move(start_state))
|
||||
{
|
||||
}
|
||||
|
||||
// reimplementation of base-class methods to adapt it to FSM-behavior
|
||||
|
||||
auto initMount()
|
||||
{
|
||||
this->dispatchEvent(INIT_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(INIT_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
auto stopMount()
|
||||
{
|
||||
this->dispatchEvent(STOP_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(STOP_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
auto slewToTarget()
|
||||
{
|
||||
this->dispatchEvent(SLEW_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(SLEW_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
auto stopSlewing()
|
||||
{
|
||||
this->dispatchEvent(STOP_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(STOP_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
auto trackTarget()
|
||||
{
|
||||
this->dispatchEvent(TRACK_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(TRACK_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
auto stopTracking()
|
||||
{
|
||||
this->dispatchEvent(STOP_EVENT_T{*this});
|
||||
try {
|
||||
this->dispatchEvent(STOP_EVENT_T{this});
|
||||
} catch (std::system_error const& exc) {
|
||||
return exc.code();
|
||||
}
|
||||
|
||||
return MccGenericFsmMountErrorCode::ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user