232 lines
7.2 KiB
C++
232 lines
7.2 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
|
|
{
|
|
|
|
|
|
|
|
// mount configuration
|
|
template <MccMountType MOUNT_TYPE>
|
|
struct MccMountConfig {
|
|
static constexpr MccMountType mountType = MOUNT_TYPE;
|
|
|
|
virtual ~MccMountConfig() = default;
|
|
};
|
|
|
|
|
|
namespace traits
|
|
{
|
|
|
|
// given mount configuration class must be a descendant of MccMountConfig
|
|
template <typename T>
|
|
concept mcc_mountconfig_c = requires(T t) { []<MccMountType MOUNT_TYPE>(MccMountConfig<MOUNT_TYPE>*) {}(&t); };
|
|
|
|
} // namespace traits
|
|
|
|
|
|
template <traits::mcc_mountconfig_c MOUNT_CONFIG, traits::mcc_mount_telemetry_c MOUNT_TELEMETRY>
|
|
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger
|
|
{
|
|
public:
|
|
static constexpr auto mountType = MOUNT_CONFIG::mountType;
|
|
|
|
typedef MOUNT_CONFIG mount_config_t;
|
|
typedef MOUNT_TELEMETRY mount_telemetry_t;
|
|
typedef typename mount_telemetry_t::mount_telemetry_data_t mount_telemetry_data_t;
|
|
|
|
struct slew_param_t {
|
|
MccCoordPairKind kind; // input coordinates type
|
|
|
|
MccAngle x; // co-longitude (e.g. RA or Az)
|
|
MccAngle y; // co-latitude (e.g. DEC or ZD)
|
|
|
|
bool stop; // stop after slewing
|
|
};
|
|
|
|
/* constructors and destructor */
|
|
|
|
template <fsm::traits::fsm_state_c InitStateT, traits::mcc_input_char_range LogMarkT = std::string_view>
|
|
MccMount(InitStateT,
|
|
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"),
|
|
const LogMarkT& logger_mark = "[MOUNT]")
|
|
: fsm::MccFiniteStateMachine(InitStateT{}), utils::MccSpdlogLogger(logger)
|
|
{
|
|
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_param_t params) {}
|
|
|
|
void startGuiding() {}
|
|
|
|
|
|
mount_config_t mountConfig() const
|
|
{
|
|
return _mountConfig;
|
|
}
|
|
|
|
|
|
mount_telemetry_data_t mountTelemetry() const
|
|
{
|
|
return _mountTelemetry.data();
|
|
}
|
|
|
|
|
|
/* prohibited zone related public methods */
|
|
|
|
// add zones to mount control system
|
|
template <traits::mcc_prohibited_zone_c ZT, traits::mcc_prohibited_zone_c... ZTs>
|
|
size_t pzAddZone(ZT zone, ZTs... zones)
|
|
{
|
|
static constexpr auto pi2 = std::numbers::pi / 2.0;
|
|
|
|
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
|
|
|
// typename ZT::coord_t x, y;
|
|
|
|
if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_AZALT) { // azimuth and altitude
|
|
_pzFuncs.emplace_back({.coordPairKind = ZT::preferedCoordKind,
|
|
.inZoneFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->inZone(tmry_data.mntAZ, tmry_data.mntALT, tmry_data.utc);
|
|
},
|
|
.timeToFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->timeTo(tmry_data.mntAZ, tmry_data.mntALT, tmry_data.utc);
|
|
},
|
|
.timeFromFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->timeFrom(tmry_data.mntAZ, tmry_data.mntALT, tmry_data.utc);
|
|
}});
|
|
|
|
} else if constexpr (ZT::preferedCoordKind ==
|
|
MccCoordPairKind::COORDS_KIND_AZZD) { // azimuth and zenithal distance
|
|
_pzFuncs.emplace_back(
|
|
{.coordPairKind = ZT::preferedCoordKind,
|
|
.inZoneFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->inZone(tmry_data.mntAZ, pi2 - tmry_data.mntALT, tmry_data.utc);
|
|
},
|
|
.timeToFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->timeTo(tmry_data.mntAZ, pi2 - tmry_data.mntALT, tmry_data.utc);
|
|
},
|
|
.timeFromFunc =
|
|
[zone_ptr, this]() {
|
|
auto tmry_data = _mountTelemetry.data();
|
|
|
|
return zone_ptr->timeFrom(tmry_data.mntAZ, pi2 - tmry_data.mntALT, tmry_data.utc);
|
|
}});
|
|
|
|
} else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
|
} else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
|
} else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
|
|
} else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_XY) {
|
|
} else {
|
|
static_assert(false, "UNKNOWN COORDINATE SYSTEM!!!");
|
|
}
|
|
|
|
if constexpr (sizeof...(ZTs)) {
|
|
pzAddZone(std::move(zones)...);
|
|
}
|
|
|
|
return _pzFuncs.size();
|
|
}
|
|
|
|
// delete all zones from mount control system
|
|
void pzClearZone()
|
|
{
|
|
_pzFuncs.clear();
|
|
}
|
|
|
|
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
|
auto pzInZone(const XT& x, const YT& y, traits::mcc_time_duration_c auto const& utc)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
mount_config_t _mountConfig;
|
|
mount_telemetry_t _mountTelemetry;
|
|
|
|
// 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()> pz_inzone_func_t;
|
|
typedef std::function<pz_duration_t()> pz_timeto_func_t;
|
|
typedef std::function<pz_duration_t()> pz_timefrom_func_t;
|
|
struct pz_funcs_t {
|
|
MccCoordPairKind coordPairKind;
|
|
pz_inzone_func_t inZoneFunc;
|
|
pz_timeto_func_t timeToFunc;
|
|
pz_timefrom_func_t timeFromFunc;
|
|
};
|
|
|
|
std::vector<pz_funcs_t> _pzFuncs{};
|
|
|
|
}; // 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
|