204 lines
6.0 KiB
C++
204 lines
6.0 KiB
C++
#pragma once
|
|
|
|
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
|
|
|
/* AN GENERIC MOUNT CLASS IMPLEMENTATION */
|
|
|
|
// #include <atomic>
|
|
#include <chrono>
|
|
// #include <concepts>
|
|
// #include <cstdint>
|
|
#include <functional>
|
|
#include <string_view>
|
|
#include "spdlog/sinks/null_sink.h"
|
|
|
|
#include "mcc_finite_state_machine.h"
|
|
#include "mcc_mount_coord.h"
|
|
#include "mcc_spdlog.h"
|
|
#include "mcc_traits.h"
|
|
// #include "mount_astrom.h"
|
|
// #include "mcc_mount_pz.h"
|
|
#include "mcc_mount_concepts.h"
|
|
|
|
namespace mcc
|
|
{
|
|
|
|
|
|
template <traits::mcc_mount_config_c MOUNT_CONFIG>
|
|
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger
|
|
{
|
|
public:
|
|
typedef MOUNT_CONFIG mount_config_t;
|
|
typedef decltype(mount_config_t::telemetry) mount_telemetry_t;
|
|
typedef typename mount_telemetry_t::mount_telemetry_data_t mount_telemetry_data_t;
|
|
|
|
typedef decltype(mount_config_t::astrometryEngine) astrom_engine_t;
|
|
typedef decltype(mount_config_t::PEC) pec_t;
|
|
typedef decltype(mount_config_t::hardware) hardware_t;
|
|
typedef decltype(mount_config_t::slewModel) slew_model_t;
|
|
typedef decltype(mount_config_t::guidingModel) guiding_model_t;
|
|
|
|
typedef typename slew_model_t::slew_params_t slew_params_t;
|
|
|
|
|
|
/* constructors and destructor */
|
|
|
|
template <fsm::traits::fsm_state_c InitStateT, traits::mcc_input_char_range LogMarkT = std::string_view>
|
|
MccMount(mount_config_t mount_config,
|
|
InitStateT,
|
|
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"),
|
|
const LogMarkT& logger_mark = "[MOUNT]")
|
|
: fsm::MccFiniteStateMachine(InitStateT{}),
|
|
utils::MccSpdlogLogger(logger),
|
|
_mountConfig(std::move(mount_config)),
|
|
_mountTelemetry(_mountConfig.telemetry),
|
|
_slewModel(_mountConfig.slewModel),
|
|
_guidingModel(_mountConfig.guidingModel)
|
|
{
|
|
addMarkToPatternIdx(logger_mark);
|
|
|
|
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()));
|
|
}
|
|
|
|
|
|
virtual ~MccMount()
|
|
{
|
|
logDebug("Delete MccMount class instance: thread = {}", getThreadId());
|
|
}
|
|
|
|
|
|
/* public methods */
|
|
|
|
void initMount()
|
|
{
|
|
this->logInfo("STATE: {}", this->currentStateID());
|
|
}
|
|
|
|
void stopMount() {}
|
|
|
|
void shutdownMount() {}
|
|
|
|
void slewMount(slew_params_t params) {}
|
|
|
|
void startGuiding() {}
|
|
|
|
|
|
// mount_config_t mountConfig() const
|
|
// {
|
|
// return _mountConfig;
|
|
// }
|
|
|
|
// returns "mount_config_t&" or "mount_config_t const&"
|
|
decltype(auto) mountConfig(this auto&& self)
|
|
{
|
|
auto& config_ref = std::forward<decltype(self)>(self)._mountConfig;
|
|
|
|
return config_ref;
|
|
}
|
|
|
|
mount_telemetry_data_t mountTelemetryData() const
|
|
{
|
|
mount_telemetry_data_t mnt_data;
|
|
|
|
auto err = _mountTelemetry.data(mnt_data);
|
|
if (err) {
|
|
// log ....
|
|
}
|
|
|
|
return mnt_data;
|
|
}
|
|
|
|
|
|
/* prohibited zone related public methods */
|
|
|
|
// add zones to mount control system
|
|
template <traits::mcc_prohibited_zone_c<mount_telemetry_data_t> ZT,
|
|
traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
|
size_t pzAddZone(ZT zone, ZTs... zones)
|
|
{
|
|
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
|
|
|
_pzFuncs.emplace_back(
|
|
{.coordPairKind = ZT::zoneCoordPairKind,
|
|
.name = std::format("{}", zone_ptr->name()),
|
|
.inZoneFunc = [zone_ptr,
|
|
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
|
.timeToFunc = [zone_ptr,
|
|
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeTo(tmry_data); },
|
|
.timeFromFunc =
|
|
[zone_ptr, this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeFrom(tmry_data); }});
|
|
|
|
|
|
if constexpr (sizeof...(ZTs)) {
|
|
pzAddZone(std::move(zones)...);
|
|
}
|
|
|
|
return _pzFuncs.size();
|
|
}
|
|
|
|
// delete all zones from mount control system
|
|
void pzClearZone()
|
|
{
|
|
// stop mount here?!!
|
|
_pzFuncs.clear();
|
|
}
|
|
|
|
|
|
protected:
|
|
mount_config_t _mountConfig;
|
|
mount_telemetry_t& _mountTelemetry;
|
|
slew_model_t& _slewModel;
|
|
guiding_model_t& _guidingModel;
|
|
|
|
// a type to which the result of calling prohibited zone class methods 'timeTo' and 'timeFrom' will be converted
|
|
typedef std::chrono::duration<double> pz_duration_t; // seconds as floating-point number
|
|
|
|
typedef std::function<bool(const mount_telemetry_data_t&)> pz_inzone_func_t;
|
|
typedef std::function<pz_duration_t(const mount_telemetry_data_t&)> pz_timeto_func_t;
|
|
typedef std::function<pz_duration_t(const mount_telemetry_data_t&)> pz_timefrom_func_t;
|
|
struct pz_funcs_t {
|
|
MccCoordPairKind coordPairKind;
|
|
std::string name;
|
|
pz_inzone_func_t inZoneFunc;
|
|
pz_timeto_func_t timeToFunc;
|
|
pz_timefrom_func_t timeFromFunc;
|
|
};
|
|
|
|
std::vector<pz_funcs_t> _pzFuncs{};
|
|
|
|
|
|
template <typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
|
auto forEachPZone(FuncT&& func, std::tuple<ZTs...>& zones)
|
|
{
|
|
std::array<traits::mcc_retval_t<FuncT>, sizeof...(ZTs)> result;
|
|
|
|
forEachPZoneHelper(std::forward<FuncT>(func), zones, result);
|
|
}
|
|
|
|
template <size_t I = 0, typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
|
auto forEachPZoneHelper(FuncT&& func, std::tuple<ZTs...>& zones, auto& result)
|
|
requires(I < sizeof...(ZTs))
|
|
{
|
|
std::get<I>(result) = std::forward<FuncT>(func)(std::get<I>(zones), mountTelemetryData());
|
|
|
|
forEachPZoneHelper<I + 1>(std::forward<FuncT>(func), zones, result);
|
|
}
|
|
|
|
}; // end of MccMount class
|
|
|
|
|
|
namespace traits
|
|
{
|
|
|
|
// given mount class must be a descendant of MccMount
|
|
template <typename T>
|
|
concept mcc_mount_c = requires(T t) { []<typename... Ts>(MccMount<Ts...>*) {}(&t); };
|
|
|
|
} // namespace traits
|
|
|
|
} // namespace mcc
|