...
This commit is contained in:
parent
172d38f5e2
commit
3c4045e620
@ -3,7 +3,8 @@
|
||||
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
||||
|
||||
/*
|
||||
* BASIC EVENTS AND MOUNT STATES DEFINITIONS
|
||||
* BASIC EVENTS AND MOUNT STATES DEFINITIONS (REFERENCE IMPLEMENTATION)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@ -12,18 +13,332 @@
|
||||
namespace mcc
|
||||
{
|
||||
|
||||
template <MccMountType MOUNT_TYPE,
|
||||
std::derived_from<MccMountConfig> CONFIG_TYPE,
|
||||
std::derived_from<MccMount<MOUNT_TYPE, CONFIG_TYPE>> MountT>
|
||||
struct MccMountInitEvent {
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
concept mcc_mount_c = requires {
|
||||
requires std::same_as<const MccMountType, decltype(T::mountType)>;
|
||||
|
||||
typename T::mount_config_t;
|
||||
|
||||
requires std::derived_from<T, MccMount<T::mountType, typename T::mount_config_t>>;
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
|
||||
|
||||
/* MOUNT STATE MACHINE STATES */
|
||||
|
||||
|
||||
// a base class for mount state machine events
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
class MccMountEventBase
|
||||
{
|
||||
protected:
|
||||
typedef MountT mount_t;
|
||||
|
||||
MccMountEventBase(mount_t& mount) : _mount(mount) {}
|
||||
|
||||
virtual ~MccMountEventBase() = default;
|
||||
|
||||
mount_t& mount() const
|
||||
{
|
||||
return _mount;
|
||||
}
|
||||
|
||||
mount_t& _mount;
|
||||
};
|
||||
|
||||
|
||||
// transit to IDLE state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventIDLE : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-IDLE-EVENT";
|
||||
|
||||
// CTAD does not work for clang++ (at least till v. 20 and -std=c++23)!
|
||||
// so, one must explicitly define constructor here
|
||||
MccMountEventIDLE(MountT& mount) : base_t(mount) {}
|
||||
};
|
||||
|
||||
|
||||
// transit to initialization state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventInit : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-INIT-EVENT";
|
||||
|
||||
MccMountInitEvent(MountT& mount) : _mount(mount) {}
|
||||
// CTAD does not work for clang++ (at least till v. 20 and -std=c++23)!
|
||||
// so, one must explicitly define constructor here
|
||||
MccMountEventInit(MountT& mount) : base_t(mount) {}
|
||||
};
|
||||
|
||||
MountT mount() const { return _mount; }
|
||||
|
||||
private:
|
||||
MountT& _mount;
|
||||
// transit to error state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventError : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-ERROR-EVENT";
|
||||
|
||||
using event_data_t = std::error_code;
|
||||
|
||||
event_data_t eventData() const
|
||||
{
|
||||
return _error;
|
||||
}
|
||||
|
||||
MccMountEventError(MountT& mount, const event_data_t& error) : base_t(mount), _error(error) {}
|
||||
|
||||
protected:
|
||||
event_data_t _error;
|
||||
};
|
||||
|
||||
|
||||
// transit to slew state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventSlew : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-SLEW-EVENT";
|
||||
|
||||
struct event_data_t {
|
||||
MccCoordPairKind kind{MccCoordPairKind::COORDS_KIND_RADEC_IRCS};
|
||||
MccAngle x{0.0}, y{0.0};
|
||||
|
||||
bool stop{false}; // stop after slewing: if false - start guiding
|
||||
};
|
||||
|
||||
event_data_t eventData() const
|
||||
{
|
||||
return _eventData;
|
||||
}
|
||||
|
||||
MccMountEventSlew(MountT& mount, const event_data_t& ev_data) : base_t(mount), _eventData(ev_data) {}
|
||||
|
||||
protected:
|
||||
event_data_t _eventData;
|
||||
};
|
||||
|
||||
|
||||
// transit to guiding state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventGuiding : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-GUIDING-EVENT";
|
||||
|
||||
// CTAD does not work for clang++ (at least till v. 20 and -std=c++23)!
|
||||
// so, one must explicitly define constructor here
|
||||
MccMountEventGuiding(MountT& mount) : base_t(mount) {}
|
||||
};
|
||||
|
||||
|
||||
// transit to stop state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventStop : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-STOP-EVENT";
|
||||
|
||||
enum event_data_t {
|
||||
EVENT_STOP_CLIENT, // software stop (mount client)
|
||||
EVENT_STOP_BUTTON // hardware button
|
||||
};
|
||||
|
||||
event_data_t eventData() const
|
||||
{
|
||||
return _reason;
|
||||
}
|
||||
|
||||
MccMountEventStop(MountT& mount, event_data_t reason) : base_t(mount), _reason(reason) {}
|
||||
|
||||
protected:
|
||||
event_data_t _reason;
|
||||
};
|
||||
|
||||
|
||||
// transit to shutdown state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountEventShutdown : public MccMountEventBase<MountT> {
|
||||
typedef MccMountEventBase<MountT> base_t;
|
||||
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-SHUTDOWN-EVENT";
|
||||
|
||||
// CTAD does not work for clang++ (at least till v. 20 and -std=c++23)!
|
||||
// so, one must explicitly define constructor here
|
||||
MccMountEventShutdown(MountT& mount) : base_t(mount) {}
|
||||
};
|
||||
|
||||
|
||||
/* MOUNT STATE MACHINE STATES */
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateBase {
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void exit(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
std::forward<decltype(self)>(self).exitImpl(event);
|
||||
|
||||
event.mount().logDebug("Exit from '{}' state due to '{}' event ...", self_t::ID, EvT::ID);
|
||||
}
|
||||
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void enter(this auto&& self, EvT& event)
|
||||
{
|
||||
using self_t = std::remove_cvref_t<decltype(self)>;
|
||||
|
||||
event.mount().logDebug("Enter to '{}' state due to '{}' event ...", self_t::ID, EvT::ID);
|
||||
|
||||
std::forward<decltype(self)>(self).enterImpl(event);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void exitImpl(EvT& event)
|
||||
{
|
||||
event.mount().logWarning("Call an empty MccMountStateBase::exitImpl method!!! Event type is '{}'", EvT::ID);
|
||||
}
|
||||
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void enterImpl(EvT& event)
|
||||
{
|
||||
event.mount().logWarning("Call an empty MccMountStateBase::enterImpl method!!! Event type is '{}'", EvT::ID);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// just forward declarations
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateIDLE;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateInit;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateError;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateSlew;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateStop;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateGuiding;
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateShutdown;
|
||||
|
||||
|
||||
// initialization state
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateInit : MccMountStateBase<MountT> {
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-INIT-STATE";
|
||||
|
||||
using transition_t = fsm::fsm_transition_table_t<std::pair<MccMountEventIDLE<MountT>, MccMountStateIDLE<MountT>>>;
|
||||
|
||||
protected:
|
||||
void exitImpl(MccMountEventIDLE<MountT>& event)
|
||||
{
|
||||
// normal exit from the state
|
||||
}
|
||||
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void enterImpl(EvT& event)
|
||||
{
|
||||
event.mount().initMount();
|
||||
|
||||
// switch to IDLE state
|
||||
event.mount().template dispatchEvent<MccMountEventIDLE<MountT>>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateError : MccMountStateBase<MountT> {
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-ERROR-STATE";
|
||||
|
||||
using transition_t = fsm::fsm_transition_table_t<
|
||||
std::pair<MccMountEventIDLE<MountT>, MccMountStateIDLE<MountT>>, // ???? after error correction?
|
||||
std::pair<MccMountEventInit<MountT>, MccMountStateInit<MountT>>,
|
||||
std::pair<MccMountEventError<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventSlew<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventGuiding<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventStop<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
||||
|
||||
protected:
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void exitImpl(EvT& event)
|
||||
{
|
||||
event.mount().logWarning(
|
||||
"The mount is in the error state!!! One must correct it before transit to any states! Event type is '{}'",
|
||||
EvT::ID);
|
||||
}
|
||||
|
||||
void exitImpl(MccMountEventIDLE<MountT>& event)
|
||||
{
|
||||
event.mount().logWarning("Suppose the error was corrected!");
|
||||
}
|
||||
|
||||
void exitImpl(MccMountEventInit<MountT>& event)
|
||||
{
|
||||
// normal exit from the state
|
||||
}
|
||||
|
||||
template <std::derived_from<MccMountEventBase<MountT>> EvT>
|
||||
void enterImpl(EvT& event)
|
||||
{
|
||||
auto err = event.eventData();
|
||||
|
||||
event.mount().logError("The mount is in the error state: code = {}, category = {}, message = '{}'", err.value(),
|
||||
err.category().name(), err.message());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateIDLE : MccMountStateBase<MountT> {
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-IDLE-STATE";
|
||||
|
||||
using transition_t =
|
||||
fsm::fsm_transition_table_t<std::pair<MccMountEventInit<MountT>, MccMountStateInit<MountT>>,
|
||||
std::pair<MccMountEventError<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventSlew<MountT>, MccMountStateSlew<MountT>>,
|
||||
std::pair<MccMountEventGuiding<MountT>, MccMountStateGuiding<MountT>>,
|
||||
std::pair<MccMountEventStop<MountT>, MccMountStateIDLE<MountT>>,
|
||||
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
||||
};
|
||||
|
||||
|
||||
template <traits::mcc_mount_c MountT>
|
||||
struct MccMountStateShutdown : MccMountStateBase<MountT> {
|
||||
static constexpr std::string_view ID = "MCC-MOUNT-SHUTDOWN-STATE";
|
||||
|
||||
using transition_t =
|
||||
fsm::fsm_transition_table_t<std::pair<MccMountEventInit<MountT>, MccMountStateInit<MountT>>,
|
||||
std::pair<MccMountEventError<MountT>, MccMountStateError<MountT>>,
|
||||
std::pair<MccMountEventSlew<MountT>, MccMountStateSlew<MountT>>,
|
||||
std::pair<MccMountEventGuiding<MountT>, MccMountStateGuiding<MountT>>,
|
||||
std::pair<MccMountEventStop<MountT>, MccMountStateIDLE<MountT>>,
|
||||
std::pair<MccMountEventShutdown<MountT>, MccMountStateShutdown<MountT>>>;
|
||||
};
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
31
cxx/mount.h
31
cxx/mount.h
@ -222,7 +222,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Constructors and destructor */
|
||||
|
||||
template <fsm::traits::fsm_state_c InitStateT>
|
||||
@ -244,17 +243,26 @@ public:
|
||||
updateIERSDatabase(IERS_DB_EARTH_ORIENT);
|
||||
}
|
||||
|
||||
virtual ~MccMount() { logDebug("Delete MccMount class instance: thread = {}", getThreadId()); }
|
||||
virtual ~MccMount()
|
||||
{
|
||||
logDebug("Delete MccMount class instance: thread = {}", getThreadId());
|
||||
}
|
||||
|
||||
|
||||
/* Public methods */
|
||||
|
||||
MccMountPosition getMountData() const noexcept { return _currentMountOrient.load(); }
|
||||
MccMountPosition getMountData() const noexcept
|
||||
{
|
||||
return _currentMountOrient.load();
|
||||
}
|
||||
|
||||
|
||||
// geo location setters/getters
|
||||
|
||||
void setGeoLocation(const MccMountSiteInfo& geoloc) { _geoLocation.store(geoloc); }
|
||||
void setGeoLocation(const MccMountSiteInfo& geoloc)
|
||||
{
|
||||
_geoLocation.store(geoloc);
|
||||
}
|
||||
|
||||
void setSiteLatitude(const MccAngle& lat)
|
||||
{
|
||||
@ -282,14 +290,23 @@ public:
|
||||
}
|
||||
|
||||
|
||||
MccMountSiteInfo getGeoLocation() const { return _geoLocation.load(); }
|
||||
MccMountSiteInfo getGeoLocation() const
|
||||
{
|
||||
return _geoLocation.load();
|
||||
}
|
||||
|
||||
|
||||
// current meteo setters/getters
|
||||
|
||||
void setMeteo(const MccMountMeteo& meteo) { _currentMeteo.store(meteo); }
|
||||
void setMeteo(const MccMountMeteo& meteo)
|
||||
{
|
||||
_currentMeteo.store(meteo);
|
||||
}
|
||||
|
||||
MccMountMeteo getMeteo() const { return _currentMeteo.load(); }
|
||||
MccMountMeteo getMeteo() const
|
||||
{
|
||||
return _currentMeteo.load();
|
||||
}
|
||||
|
||||
|
||||
/* prohibited zone related methods */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user