227 lines
7.4 KiB
C++
227 lines
7.4 KiB
C++
#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
|