...
This commit is contained in:
@@ -217,6 +217,7 @@ set(MCC_SRC
|
||||
mcc_serialization_common.h
|
||||
mcc_deserializer.h
|
||||
mcc_serializer.h
|
||||
mcc_generic_mount.h
|
||||
)
|
||||
|
||||
if(USE_SPDLOG)
|
||||
|
||||
@@ -979,17 +979,17 @@ concept mcc_mount_status_c = requires {
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_generic_mount_c =
|
||||
mcc_logger_c<T> && mcc_pzone_container_c<T> && mcc_telemetry_c<T> && mcc_movement_controls_c<T> && requires(T t) {
|
||||
// error type
|
||||
requires mcc_error_c<typename T::error_t>;
|
||||
concept mcc_generic_mount_c = mcc_logger_c<T> && mcc_pzone_container_c<T> && mcc_telemetry_c<T> &&
|
||||
mcc_movement_controls_c<T> && requires(T t, const T t_const) {
|
||||
// error type
|
||||
requires mcc_error_c<typename T::error_t>;
|
||||
|
||||
requires mcc_mount_status_c<typename T::mount_status_t>;
|
||||
requires mcc_mount_status_c<typename T::mount_status_t>;
|
||||
|
||||
{ t.initMount() } -> std::same_as<typename T::error_t>;
|
||||
{ t.initMount() } -> std::same_as<typename T::error_t>;
|
||||
|
||||
{ t.mountStatus() } -> std::same_as<typename T::mount_status_t>;
|
||||
};
|
||||
{ t_const.mountStatus() } -> std::same_as<typename T::mount_status_t>;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
226
mcc_generic_mount.h
Normal file
226
mcc_generic_mount.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* MOUNT CONTROL COMPONENTS LIBRARY *
|
||||
* *
|
||||
* *
|
||||
* IMPLEMENTATION OF A GENERIC MOUNT CLASS *
|
||||
* (A SOME OF POSSIBLE GENERIC IMPLEMENTATIONS) *
|
||||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <thread>
|
||||
#include "mcc_error.h"
|
||||
|
||||
namespace mcc::impl
|
||||
{
|
||||
|
||||
enum class MccGenericMountErrorCode : int {
|
||||
ERROR_OK,
|
||||
ERROR_HW_INIT,
|
||||
ERROR_HW_STOP,
|
||||
ERROR_HW_GETSTATE,
|
||||
ERROR_SET_TARGET,
|
||||
ERROR_MOUNT_SLEW,
|
||||
ERROR_MOUNT_TRACK,
|
||||
ERROR_GET_TELEMETRY,
|
||||
ERROR_UNSUPPORTED_TARGET_COORDPAIR,
|
||||
ERROR_PZONE_COMP,
|
||||
ERROR_TARGET_IN_ZONE
|
||||
};
|
||||
|
||||
enum class MccGenericFsmMountErrorCode : int { ERROR_OK, ERROR_INVALID_OPERATION, ERROR_UNKNOWN_EVENT };
|
||||
|
||||
} // namespace mcc::impl
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
class is_error_code_enum<mcc::impl::MccGenericMountErrorCode> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
|
||||
namespace mcc::impl
|
||||
{
|
||||
|
||||
// error category
|
||||
struct MccGenericMountCategory : public std::error_category {
|
||||
MccGenericMountCategory() : std::error_category() {}
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
return "MCC-GENERIC-MOUNT";
|
||||
}
|
||||
|
||||
std::string message(int ec) const
|
||||
{
|
||||
MccGenericMountErrorCode err = static_cast<MccGenericMountErrorCode>(ec);
|
||||
|
||||
switch (err) {
|
||||
case MccGenericMountErrorCode::ERROR_OK:
|
||||
return "OK";
|
||||
case MccGenericMountErrorCode::ERROR_HW_INIT:
|
||||
return "an error occured while initializing mount";
|
||||
case MccGenericMountErrorCode::ERROR_HW_STOP:
|
||||
return "an error occured while stopping mount";
|
||||
case MccGenericMountErrorCode::ERROR_HW_GETSTATE:
|
||||
return "cannot get state of hardware";
|
||||
case MccGenericMountErrorCode::ERROR_SET_TARGET:
|
||||
return "cannot set target coordinates";
|
||||
case MccGenericMountErrorCode::ERROR_MOUNT_SLEW:
|
||||
return "slewing error";
|
||||
case MccGenericMountErrorCode::ERROR_MOUNT_TRACK:
|
||||
return "tracking error";
|
||||
case MccGenericMountErrorCode::ERROR_GET_TELEMETRY:
|
||||
return "cannot get telemetry data";
|
||||
case MccGenericMountErrorCode::ERROR_UNSUPPORTED_TARGET_COORDPAIR:
|
||||
return "unsupported coordinate pair of target";
|
||||
case MccGenericMountErrorCode::ERROR_PZONE_COMP:
|
||||
return "an error occured while computing prohibited zone";
|
||||
case MccGenericMountErrorCode::ERROR_TARGET_IN_ZONE:
|
||||
return "target coordinates are in prohibitted zone";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const MccGenericMountCategory& get()
|
||||
{
|
||||
static const MccGenericMountCategory constInst;
|
||||
return constInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline std::error_code make_error_code(MccGenericMountErrorCode ec)
|
||||
{
|
||||
return std::error_code(static_cast<int>(ec), MccGenericMountCategory::get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <mcc_hardware_c HARDWARE_T,
|
||||
mcc_telemetry_c TELEMETRY_T,
|
||||
mcc_pzone_container_c PZONE_CONT_T,
|
||||
mcc_movement_controls_c MOVE_CNTRL_T,
|
||||
mcc_logger_c LOGGER_T>
|
||||
class MccGenericMount : protected HARDWARE_T,
|
||||
public TELEMETRY_T,
|
||||
public PZONE_CONT_T,
|
||||
public MOVE_CNTRL_T,
|
||||
public LOGGER_T
|
||||
{
|
||||
public:
|
||||
using LOGGER_T::logDebug;
|
||||
using LOGGER_T::logError;
|
||||
using LOGGER_T::logInfo;
|
||||
using LOGGER_T::logTrace;
|
||||
using LOGGER_T::logWarn;
|
||||
|
||||
typedef MccError error_t;
|
||||
|
||||
using typename TELEMETRY_T::telemetry_data_t;
|
||||
|
||||
enum class mount_status_t : int {
|
||||
MOUNT_STATUS_ERROR,
|
||||
MOUNT_STATUS_IDLE,
|
||||
MOUNT_STATUS_UNINITIALIZED,
|
||||
MOUNT_STATUS_INITIALIZATION,
|
||||
MOUNT_STATUS_STOPPED,
|
||||
MOUNT_STATUS_STOPPING,
|
||||
MOUNT_STATUS_SLEWING,
|
||||
MOUNT_STATUS_ADJUSTING,
|
||||
MOUNT_STATUS_GUIDING,
|
||||
MOUNT_STATUS_TRACKING
|
||||
};
|
||||
|
||||
template <typename... HardwareCtorTs,
|
||||
typename... TelemetryCtorTs,
|
||||
typename... PzoneContCtorTs,
|
||||
typename... MoveCntrCtorTs,
|
||||
typename... LoggerCtorTs>
|
||||
MccGenericMount(std::tuple<HardwareCtorTs...> hw_ctor_args,
|
||||
std::tuple<TelemetryCtorTs...> telemetry_ctor_args,
|
||||
std::tuple<PzoneContCtorTs...> pzone_cont_ctor_ars,
|
||||
std::tuple<MoveCntrCtorTs...> move_cntrl_ctor_ars,
|
||||
std::tuple<LoggerCtorTs...> logger_ctor_args)
|
||||
: HARDWARE_T(std::make_from_tuple<HARDWARE_T>(std::move(hw_ctor_args))),
|
||||
TELEMETRY_T(std::make_from_tuple<TELEMETRY_T>(std::move(telemetry_ctor_args))),
|
||||
PZONE_CONT_T(std::make_from_tuple<PZONE_CONT_T>(pzone_cont_ctor_ars)),
|
||||
MOVE_CNTRL_T(std::make_from_tuple<MOVE_CNTRL_T>(move_cntrl_ctor_ars)),
|
||||
LOGGER_T(std::make_from_tuple<LOGGER_T>(logger_ctor_args))
|
||||
{
|
||||
logDebug(std::format("Create MccGenericMount class instance (thread: {})", std::this_thread::get_id()));
|
||||
}
|
||||
|
||||
MccGenericMount(const MccGenericMount&) = delete;
|
||||
MccGenericMount(MccGenericMount&&) = default;
|
||||
|
||||
MccGenericMount& operator=(const MccGenericMount&) = delete;
|
||||
MccGenericMount& operator=(MccGenericMount&&) = default;
|
||||
|
||||
virtual ~MccGenericMount()
|
||||
{
|
||||
logDebug(std::format("Delete MccGenericMount class instance (thread: {})", std::this_thread::get_id()));
|
||||
|
||||
auto err = MOVE_CNTRL_T::stopMount();
|
||||
if (err) {
|
||||
logError(formatError(err));
|
||||
}
|
||||
}
|
||||
|
||||
error_t initMount()
|
||||
{
|
||||
logInfo(std::format("Start MccGenericMount class initialization (thread: {}) ...", std::this_thread::get_id()));
|
||||
|
||||
*_lastMountError = MccGenericMountErrorCode::ERROR_OK;
|
||||
|
||||
*_mountStatus = mount_status_t::MOUNT_STATUS_INITIALIZATION;
|
||||
|
||||
auto hw_err = this->hardwareInit();
|
||||
if (hw_err) {
|
||||
*_mountStatus = mount_status_t::MOUNT_STATUS_ERROR;
|
||||
|
||||
*_lastMountError = mcc_deduce_err(hw_err, MccGenericMountErrorCode::ERROR_HW_INIT);
|
||||
} else {
|
||||
logInfo("Generic mount initialization was performed");
|
||||
|
||||
*_mountStatus = mount_status_t::IDLE;
|
||||
}
|
||||
|
||||
return *_lastMountError;
|
||||
}
|
||||
|
||||
mount_status_t mountStatus() const
|
||||
{
|
||||
return _mountStatus->load();
|
||||
}
|
||||
|
||||
error_t mountLastError() const
|
||||
{
|
||||
return _lastMountError->load();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<std::atomic<mount_status_t>> _mountStatus{
|
||||
new std::atomic<mount_status_t>{mount_status_t::MOUNT_STATUS_UNINITIALIZED}};
|
||||
|
||||
std::unique_ptr<std::atomic<error_t>> _lastMountError{new std::atomic<error_t>{MccGenericMountErrorCode::ERROR_OK}};
|
||||
|
||||
std::string formatError(error_t const& err, std::string_view prefix = "") const
|
||||
{
|
||||
return std::format("{}{} (category: {}, code: {})", prefix, err.message(), err.value(), err.category().name());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mcc::impl
|
||||
Reference in New Issue
Block a user