...
This commit is contained in:
parent
64a3544bd8
commit
02afd65d6f
@ -317,7 +317,7 @@ protected:
|
|||||||
std::vector<std::string_view> _stateID{};
|
std::vector<std::string_view> _stateID{};
|
||||||
std::vector<std::string_view> _eventID{};
|
std::vector<std::string_view> _eventID{};
|
||||||
|
|
||||||
std::mutex _transitionMutex{};
|
std::recursive_mutex _transitionMutex{};
|
||||||
|
|
||||||
|
|
||||||
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
|
static MccFiniteStateMachine& copyInstance(const MccFiniteStateMachine* from, MccFiniteStateMachine* to)
|
||||||
@ -385,18 +385,23 @@ public:
|
|||||||
[states, currentState, this]<size_t... Is>(std::index_sequence<Is...>) {
|
[states, currentState, this]<size_t... Is>(std::index_sequence<Is...>) {
|
||||||
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
|
((_dispatchEventFunc<std::tuple_element_t<Is, all_events_t>>[this] =
|
||||||
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) {
|
[states, currentState, this]<traits::fsm_event_c EvT>(EvT& event) {
|
||||||
std::lock_guard lock(_transitionMutex);
|
// to avoid effects of possible compiler optimizations
|
||||||
|
// (here one needs to be sure that inside the lambda 'event' is used by reference)
|
||||||
|
const auto p_event = &event;
|
||||||
|
|
||||||
std::visit(
|
std::visit(
|
||||||
[&event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
|
[p_event, states, currentState, this]<traits::fsm_state_c curr_state_t>(curr_state_t*) {
|
||||||
using to_state_t = curr_state_t::transition_t::template find_state_by_event_t<EvT>;
|
using to_state_t = curr_state_t::transition_t::template find_state_by_event_t<EvT>;
|
||||||
|
|
||||||
if constexpr (!std::is_void_v<to_state_t>) {
|
if constexpr (!std::is_void_v<to_state_t>) {
|
||||||
|
std::lock_guard lock(_transitionMutex);
|
||||||
|
|
||||||
// exit from current
|
// exit from current
|
||||||
if constexpr (requires(curr_state_t inst) {
|
if constexpr (requires(curr_state_t inst) {
|
||||||
{ inst.exit(std::declval<EvT&>()) };
|
{ inst.exit(std::declval<EvT&>()) };
|
||||||
}) {
|
}) {
|
||||||
std::get<curr_state_t>(*states).exit(event);
|
// std::get<curr_state_t>(*states).exit(event);
|
||||||
|
std::get<curr_state_t>(*states).exit(*p_event);
|
||||||
} else if constexpr (requires(curr_state_t inst) {
|
} else if constexpr (requires(curr_state_t inst) {
|
||||||
{ inst.exit() };
|
{ inst.exit() };
|
||||||
}) {
|
}) {
|
||||||
@ -407,7 +412,8 @@ public:
|
|||||||
if constexpr (requires(EvT inst) {
|
if constexpr (requires(EvT inst) {
|
||||||
{ inst.onTransit() };
|
{ inst.onTransit() };
|
||||||
}) {
|
}) {
|
||||||
event.onTransit();
|
// event.onTransit();
|
||||||
|
p_event->onTransit();
|
||||||
}
|
}
|
||||||
|
|
||||||
*currentState = &std::get<to_state_t>(*states);
|
*currentState = &std::get<to_state_t>(*states);
|
||||||
@ -417,7 +423,8 @@ public:
|
|||||||
if constexpr (requires(to_state_t inst) {
|
if constexpr (requires(to_state_t inst) {
|
||||||
{ inst.enter(std::declval<EvT&>()) };
|
{ inst.enter(std::declval<EvT&>()) };
|
||||||
}) {
|
}) {
|
||||||
std::get<to_state_t>(*states).enter(event);
|
// std::get<to_state_t>(*states).enter(event);
|
||||||
|
std::get<to_state_t>(*states).enter(*p_event);
|
||||||
} else if constexpr (requires(to_state_t inst) {
|
} else if constexpr (requires(to_state_t inst) {
|
||||||
{ inst.enter() };
|
{ inst.enter() };
|
||||||
}) {
|
}) {
|
||||||
@ -450,6 +457,17 @@ public:
|
|||||||
|
|
||||||
(_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...);
|
(_eventID.emplace_back(std::tuple_element_t<Is, all_events_t>::ID), ...);
|
||||||
}(std::make_index_sequence<std::tuple_size_v<all_events_t>>());
|
}(std::make_index_sequence<std::tuple_size_v<all_events_t>>());
|
||||||
|
|
||||||
|
// call enter() method (if it exists) of the initial state
|
||||||
|
std::visit(
|
||||||
|
[]<traits::fsm_state_c curr_state_t>(curr_state_t* cstate) {
|
||||||
|
if constexpr (requires(curr_state_t inst) {
|
||||||
|
{ inst.enter() };
|
||||||
|
}) {
|
||||||
|
cstate->enter();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*currentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
MccFiniteStateMachine(const MccFiniteStateMachine& other)
|
MccFiniteStateMachine(const MccFiniteStateMachine& other)
|
||||||
|
|||||||
@ -155,13 +155,17 @@ public:
|
|||||||
|
|
||||||
template <fsm::traits::fsm_state_c InitStateT, traits::mcc_input_char_range LogMarkT = std::string_view>
|
template <fsm::traits::fsm_state_c InitStateT, traits::mcc_input_char_range LogMarkT = std::string_view>
|
||||||
MccMount(InitStateT,
|
MccMount(InitStateT,
|
||||||
const LogMarkT& logger_mark = "[MOUNT]",
|
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"),
|
||||||
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"))
|
const LogMarkT& logger_mark = "[MOUNT]")
|
||||||
: fsm::MccFiniteStateMachine(InitStateT{}), utils::MccSpdlogLogger(logger)
|
: fsm::MccFiniteStateMachine(InitStateT{}), utils::MccSpdlogLogger(logger)
|
||||||
{
|
{
|
||||||
addMarkToPatternIdx(logger_mark);
|
addMarkToPatternIdx(logger_mark);
|
||||||
|
|
||||||
logDebug("Create MccMount class instance: thread = {}", getThreadId());
|
logDebug("Create MccMount class instance: thread = {}", getThreadId());
|
||||||
|
|
||||||
|
auto ids = this->stateIDs();
|
||||||
|
auto r = ids | std::views::join_with(',');
|
||||||
|
logDebug("{}", std::string(r.begin(), r.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -173,7 +177,10 @@ public:
|
|||||||
|
|
||||||
/* public methods */
|
/* public methods */
|
||||||
|
|
||||||
void initMount() {}
|
void initMount()
|
||||||
|
{
|
||||||
|
this->logInfo("STATE: {}", this->currentStateID());
|
||||||
|
}
|
||||||
|
|
||||||
void stopMount() {}
|
void stopMount() {}
|
||||||
|
|
||||||
|
|||||||
@ -318,7 +318,7 @@ struct MccMountStateInit : MccMountStateBase<MountT> {
|
|||||||
{
|
{
|
||||||
this->enterLog(event);
|
this->enterLog(event);
|
||||||
|
|
||||||
auto mount = event.mount();
|
MountT& mount = event.mount();
|
||||||
mount.initMount();
|
mount.initMount();
|
||||||
|
|
||||||
// switch to IDLE state
|
// switch to IDLE state
|
||||||
@ -403,13 +403,13 @@ struct MccMountStateIDLE : MccMountStateBase<MountT> {
|
|||||||
std::pair<MccMountEventStop<MountT>, MccMountStateIDLE<MountT>>,
|
std::pair<MccMountEventStop<MountT>, MccMountStateIDLE<MountT>>,
|
||||||
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
||||||
|
|
||||||
template <std::derived_from<MccMountStateBase<MountT>> EvT>
|
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||||
void exit(EvT& event)
|
void exit(EvT& event)
|
||||||
{
|
{
|
||||||
this->exitLog(event);
|
this->exitLog(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::derived_from<MccMountStateBase<MountT>> EvT>
|
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||||
void enter(EvT& event)
|
void enter(EvT& event)
|
||||||
{
|
{
|
||||||
this->enterLog(event);
|
this->enterLog(event);
|
||||||
|
|||||||
@ -39,53 +39,47 @@ public:
|
|||||||
|
|
||||||
// check if given position (x,y) in the zone
|
// check if given position (x,y) in the zone
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
bool inZone(this auto&& self,
|
bool inZone(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||||
const XT& x,
|
|
||||||
const YT& y,
|
|
||||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
|
||||||
{
|
{
|
||||||
return std::forward<decltype(self)>(self).inZoneImpl(x, y, utc);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a time duration to reach the zone
|
// returns a time duration to reach the zone
|
||||||
// 0 - if already within
|
// 0 - if already within
|
||||||
// Inf - if it never reaches the zone
|
// Inf - if it never reaches the zone
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
pz_duration_t timeTo(this auto&& self,
|
pz_duration_t timeTo(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||||
const XT& x,
|
|
||||||
const YT& y,
|
|
||||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
|
||||||
{
|
{
|
||||||
return std::forward<decltype(self)>(self).timeToImpl(x, y, utc);
|
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a time duration to exit from the zone
|
// returns a time duration to exit from the zone
|
||||||
// 0 - if given position (x,y) is out of the zone
|
// 0 - if given position (x,y) is out of the zone
|
||||||
// Inf - if (x,y) is always within the zone
|
// Inf - if (x,y) is always within the zone
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
pz_duration_t timeFrom(this auto&& self,
|
pz_duration_t timeFrom(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||||
const XT& x,
|
|
||||||
const YT& y,
|
|
||||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
|
||||||
{
|
{
|
||||||
return std::forward<decltype(self)>(self).timeFromImpl(x, y, utc);
|
return pz_duration_t{0.0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// all-in-one request (call three methods above)
|
// all-in-one request (call three methods above)
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
pz_request_t request(const XT& x,
|
pz_request_t request(this auto&& self,
|
||||||
|
const XT& x,
|
||||||
const YT& y,
|
const YT& y,
|
||||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||||
{
|
{
|
||||||
|
using self_t = decltype(self);
|
||||||
|
|
||||||
pz_request_t res{.in_zone = false, .time_to = pz_duration_t{0.0}, .time_from{0.0}};
|
pz_request_t res{.in_zone = false, .time_to = pz_duration_t{0.0}, .time_from{0.0}};
|
||||||
|
|
||||||
res.in_zone = inZone(x, y, utc);
|
res.in_zone = std::forward<self_t>(self).inZone(x, y, utc);
|
||||||
|
|
||||||
if (res.in_zone) {
|
if (res.in_zone) {
|
||||||
res.time_from = timeFrom(x, y, utc);
|
res.time_from = std::forward<self_t>(self).timeFrom(x, y, utc);
|
||||||
} else {
|
} else {
|
||||||
res.time_to = timeFrom(x, y, utc);
|
res.time_to = std::forward<self_t>(self).timeTo(x, y, utc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -95,30 +89,10 @@ protected:
|
|||||||
MccProhibitedZone(std::string_view name) : _name(name) {}
|
MccProhibitedZone(std::string_view name) : _name(name) {}
|
||||||
|
|
||||||
std::string_view _name;
|
std::string_view _name;
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
|
||||||
bool inZoneImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
|
||||||
pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
|
||||||
{
|
|
||||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
|
||||||
pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
|
||||||
{
|
|
||||||
return pz_duration_t{0.0};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* SOME PROHIBITED ZONE IMPLEMENTATIONS */
|
/* SOME PROHIBITED ZONE IMPLEMENTATIONS */
|
||||||
|
|
||||||
|
|
||||||
@ -145,11 +119,8 @@ public:
|
|||||||
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
|
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
MccAngle _altLimit;
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
bool inZoneImpl(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc)
|
bool inZone(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||||
{
|
{
|
||||||
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
||||||
|
|
||||||
@ -160,7 +131,7 @@ private:
|
|||||||
return y >= _altLimit;
|
return y >= _altLimit;
|
||||||
}
|
}
|
||||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZZD) { // trivial case
|
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZZD) { // trivial case
|
||||||
return inZoneImpl(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc);
|
return inZone(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc);
|
||||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||||
// implementation ...
|
// implementation ...
|
||||||
return false;
|
return false;
|
||||||
@ -176,17 +147,25 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
pz_duration_t timeTo(const XT& x,
|
||||||
|
const YT& y,
|
||||||
|
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||||
{
|
{
|
||||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||||
pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
pz_duration_t timeFrom(const XT& x,
|
||||||
|
const YT& y,
|
||||||
|
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||||
{
|
{
|
||||||
return pz_duration_t{0.0};
|
return pz_duration_t{0.0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MccAngle _altLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
|
|
||||||
#include "../mcc_mount.h"
|
#include "../mcc_mount.h"
|
||||||
#include "../mcc_mount_events_states.h"
|
#include "../mcc_mount_events_states.h"
|
||||||
|
|
||||||
@ -7,9 +9,12 @@ int tests_mount(int, char**)
|
|||||||
|
|
||||||
using mount_t = MccMount<MccMountConfig<MccMountType::CROSSAXIS_TYPE>, MccMountTelemetry>;
|
using mount_t = MccMount<MccMountConfig<MccMountType::CROSSAXIS_TYPE>, MccMountTelemetry>;
|
||||||
|
|
||||||
mount_t mount(MccMountStateIDLE<mount_t>{});
|
auto logger = spdlog::stdout_color_mt("MOUNT");
|
||||||
|
logger->set_level(spdlog::level::debug);
|
||||||
|
|
||||||
|
mount_t mount(MccMountStateIDLE<mount_t>{}, logger);
|
||||||
|
|
||||||
|
mount.dispatchEvent(MccMountEventInit<mount_t>{mount});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user