From a8ef274d4c6f936224921180cf27097237718bb0 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Sun, 15 Jun 2025 01:48:22 +0300 Subject: [PATCH] ... --- cxx/mcc_mount.h | 84 ++++++++++------------------ cxx/mcc_mount_coord.h | 46 ++++++++++++++- cxx/mcc_mount_pz.h | 126 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 182 insertions(+), 74 deletions(-) diff --git a/cxx/mcc_mount.h b/cxx/mcc_mount.h index b90e501..6ee1522 100644 --- a/cxx/mcc_mount.h +++ b/cxx/mcc_mount.h @@ -12,12 +12,12 @@ #include #include "spdlog/sinks/null_sink.h" -#include "mcc_coord.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 "mount_pz.h" +// #include "mount_astrom.h" +#include "mcc_mount_pz.h" namespace mcc @@ -26,47 +26,6 @@ namespace mcc /* BASIC DATA DEFINITIONS */ -// coordinate system related constants -enum class MccCoordKind : uint8_t { - COORDS_KIND_RA_IRCS, // IRCS right ascension - COORDS_KIND_RA_APP, // apparent right ascension - COORDS_KIND_HA, // hour angle - COORDS_KIND_AZ, // azimuth - COORDS_KIND_X, // co-longitude coordinate - COORDS_KIND_DEC_IRCS, // IRCS declination - COORDS_KIND_DEC_APP, // apparent declination - COORDS_KIND_ALT, // altitude - COORDS_KIND_ZD, // zenithal distance - COORDS_KIND_Y // co-latitude coordinate -}; - - -enum class MccCoordPairKind : uint16_t { - // catalog's - COORDS_KIND_RADEC_IRCS = (int)MccCoordKind::COORDS_KIND_RA_IRCS + ((int)MccCoordKind::COORDS_KIND_DEC_IRCS << 8), - // apparent RA and DEC - COORDS_KIND_RADEC_APP = (int)MccCoordKind::COORDS_KIND_RA_APP + ((int)MccCoordKind::COORDS_KIND_DEC_APP << 8), - // apparent HA (hour angle) and DEC - COORDS_KIND_HADEC_APP = (int)MccCoordKind::COORDS_KIND_HA + ((int)MccCoordKind::COORDS_KIND_DEC_APP << 8), - // Azimuth and Altitude - COORDS_KIND_AZALT = (int)MccCoordKind::COORDS_KIND_AZ + ((int)MccCoordKind::COORDS_KIND_ALT << 8), - // Azimuth and Zenithal distance - COORDS_KIND_AZZD = (int)MccCoordKind::COORDS_KIND_AZ + ((int)MccCoordKind::COORDS_KIND_ZD << 8), - // co-longitude and co-latitude (e.g. mount hardware drive/axis encoders) - COORDS_KIND_XY = (int)MccCoordKind::COORDS_KIND_X + ((int)MccCoordKind::COORDS_KIND_Y << 8), -}; - -template -static constexpr std::string_view MccCoordPairKindStr = - KIND == MccCoordPairKind::COORDS_KIND_RADEC_IRCS ? "RADEC-IRCS" - : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? "RADEC-APP" - : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? "HADEC-APP" - : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? "Azimuth-Altitude" - : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? "AzimuthZendist" - : KIND == MccCoordPairKind::COORDS_KIND_XY ? "XY" - : "UNKNOWN"; - - // meteo parameters (e.g. to compute refraction) struct MccMountMeteo { @@ -151,8 +110,8 @@ struct MccMountConfig { virtual ~MccMountConfig() = default; - astrom::MccLeapSeconds leapSeconds; - astrom::MccIersBulletinA iersBulletinA; + // astrom::MccLeapSeconds leapSeconds; + // astrom::MccIersBulletinA iersBulletinA; MccMountSiteInfo siteInfo{.latitude = 0.0, .longitude = 0.0, .elevation = 0.0, .name{"ALL-ZERO"}}; @@ -239,12 +198,29 @@ public: /* prohibited zone related public methods */ - template + template ZT, std::derived_from... ZTs> size_t pzAddZone(ZT zone, ZTs... zones) { - _pzInZoneFunc.emplace_back([zone = std::move(zone)](const MccAngle& x, const MccAngle& y, void* ctx) mutable { - auto context = *static_cast(ctx); - return zone.inZone(x, y, context); + static constexpr auto pi2 = std::numbers::pi / 2.0; + + _pzRequestFunc.emplace_back([zone = std::move(zone), this]() { + mount_telemetry_t data = _mountTelemetry.load(); + + if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_AZALT) { + return zone.request(MccAngleAZ(data.tagAZ), MccAngleALT(pi2 - data.tagZD)); + } else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_AZZD) { + return zone.request(MccAngleAZ(data.tagAZ), MccAngleZD(data.tagZD)); + } else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + return zone.request(MccAngleRA_APP(data.tagRA), MccAngleDEC_APP(data.tagDEC)); + } else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + return zone.request(MccAngleHA_APP(data.tagHA), MccAngleDEC_APP(data.tagDEC)); + } else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + return zone.request(MccAngleRA_APP(data.tagRA), MccAngleDEC_APP(data.tagDEC)); + } else if constexpr (ZT::preferedCoordKind == MccCoordPairKind::COORDS_KIND_XY) { + return zone.request(MccAngleX(data.mntPosX), MccAngleY(data.mntPosY)); + } else { + static_assert(false, "UNKNOWN COORDINATE SYSTEM!!!"); + } }); @@ -252,12 +228,12 @@ public: psAddZone(std::move(zones)...); } - return _pzInZoneFunc.size(); + return _pzRequestFunc.size(); } void pzClearZone() { - _pzInZoneFunc.clear(); + _pzRequestFunc.clear(); } @@ -267,9 +243,7 @@ protected: typedef std::chrono::duration pz_duration_t; - std::vector> _pzInZoneFunc; - std::vector> _pzTimeToZoneFunc; - std::vector> _pzTimeFromZoneFunc; + std::vector> _pzRequestFunc{}; }; // end of MccMount class diff --git a/cxx/mcc_mount_coord.h b/cxx/mcc_mount_coord.h index e4acb76..8fb353a 100644 --- a/cxx/mcc_mount_coord.h +++ b/cxx/mcc_mount_coord.h @@ -324,17 +324,32 @@ class MccAngleAZ : public MccAngle using MccAngle::MccAngle; }; +class MccAngleALT; + class MccAngleZD : public MccAngle { using MccAngle::MccAngle; + + MccAngleZD(const MccAngleALT&); }; class MccAngleALT : public MccAngle { using MccAngle::MccAngle; + + MccAngleALT(const MccAngleZD& zd) + { + _angleInRads = std::numbers::pi / 2.0 - (double)zd; + } }; +MccAngleZD::MccAngleZD(const MccAngleALT& alt) +{ + _angleInRads = std::numbers::pi / 2.0 - (double)alt; +} + + class MccAngleX : public MccAngle // some co-longitude coordinate { using MccAngle::MccAngle; @@ -358,15 +373,44 @@ class MccAngleLON : public MccAngle }; +enum class MccCoordKind : size_t { + COORDS_KIND_GENERIC = traits::mcc_type_hash, + COORDS_KIND_RA_ICRS = traits::mcc_type_hash, + COORDS_KIND_DEC_ICRS = traits::mcc_type_hash, + COORDS_KIND_RA_APP = traits::mcc_type_hash, + COORDS_KIND_DEC_APP = traits::mcc_type_hash, + COORDS_KIND_HA = traits::mcc_type_hash, + COORDS_KIND_AZ = traits::mcc_type_hash, + COORDS_KIND_ZD = traits::mcc_type_hash, + COORDS_KIND_ALT = traits::mcc_type_hash, + COORDS_KIND_X = traits::mcc_type_hash, + COORDS_KIND_Y = traits::mcc_type_hash, + COORDS_KIND_LAT = traits::mcc_type_hash, + COORDS_KIND_LON = traits::mcc_type_hash +}; + enum class MccCoordPairKind : size_t { COORDS_KIND_GENERIC = traits::mcc_type_pair_hash(), COORDS_KIND_RADEC_ICRS = traits::mcc_type_pair_hash(), COORDS_KIND_RADEC_APP = traits::mcc_type_pair_hash(), - COORDS_KIND_HADEC = traits::mcc_type_pair_hash(), + COORDS_KIND_HADEC_APP = traits::mcc_type_pair_hash(), COORDS_KIND_AZZD = traits::mcc_type_pair_hash(), COORDS_KIND_AZALT = traits::mcc_type_pair_hash(), COORDS_KIND_XY = traits::mcc_type_pair_hash(), COORDS_KIND_LATLON = traits::mcc_type_pair_hash() }; + +template +static constexpr std::string_view MccCoordPairKindStr = + KIND == MccCoordPairKind::COORDS_KIND_RADEC_ICRS ? "RADEC-IRCS" + : KIND == MccCoordPairKind::COORDS_KIND_RADEC_APP ? "RADEC-APP" + : KIND == MccCoordPairKind::COORDS_KIND_HADEC_APP ? "HADEC-APP" + : KIND == MccCoordPairKind::COORDS_KIND_AZALT ? "Azimuth-Altitude" + : KIND == MccCoordPairKind::COORDS_KIND_AZZD ? "Azimuth-Zendist" + : KIND == MccCoordPairKind::COORDS_KIND_XY ? "X-Y" + : KIND == MccCoordPairKind::COORDS_KIND_LATLON ? "Latitude-Longitude" + : "UNKNOWN"; + + } // namespace mcc diff --git a/cxx/mcc_mount_pz.h b/cxx/mcc_mount_pz.h index 3893624..267a1b0 100644 --- a/cxx/mcc_mount_pz.h +++ b/cxx/mcc_mount_pz.h @@ -16,19 +16,21 @@ namespace mcc class MccProhibitedZone { public: + static constexpr MccCoordPairKind preferedCoordKind = MccCoordPairKind::COORDS_KIND_AZALT; + + // floating-point time duration (seconds) typedef std::chrono::duration pz_duration_t; + struct pz_request_t { bool in_zone{false}; // true if given coordinates are within the zone pz_duration_t time_to{0.0}; // a time duration to reach the zone pz_duration_t time_from{0.0}; // a time duration to exit the zone }; - struct pz_context_t { - }; - MccProhibitedZone(std::string_view name) : _name(name) {} + virtual ~MccProhibitedZone() = default; std::string_view name() const { @@ -37,62 +39,150 @@ public: // check if given position (x,y) in the zone template XT, std::derived_from YT> - bool inZone(const XT& x, + bool inZone(this auto&& self, + const XT& x, const YT& y, - const pz_context_t& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { - static constexpr size_t coord_kind = traits::mcc_type_pair_hash(); - - return false; + return std::forward(self).inZoneImpl(x, y, utc); } // returns a time duration to reach the zone // 0 - if already within // Inf - if it never reaches the zone template XT, std::derived_from YT> - pz_duration_t timeTo(const XT& x, + pz_duration_t timeTo(this auto&& self, + const XT& x, const YT& y, - const pz_context_t& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { - static constexpr size_t coord_kind = traits::mcc_type_pair_hash(); + return std::forward(self).timeToImpl(x, y, utc); } // returns a time duration to exit from the zone // 0 - if given position (x,y) is out of the zone // Inf - if (x,y) is always within the zone template XT, std::derived_from YT> - pz_duration_t timeFrom(const XT& x, + pz_duration_t timeFrom(this auto&& self, + const XT& x, const YT& y, - const pz_context_t& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { - static constexpr size_t coord_kind = traits::mcc_type_pair_hash(); + return std::forward(self).timeFromImpl(x, y, utc); } + // all-in-one request (call three methods above) template XT, std::derived_from YT> pz_request_t request(const XT& x, const YT& y, - const pz_context_t& context, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) { pz_request_t res{.in_zone = false, .time_to = pz_duration_t{0.0}, .time_from{0.0}}; - res.in_zone = inZone(x, y, context, utc); + res.in_zone = inZone(x, y, utc); if (res.in_zone) { - res.time_from = timeFrom(x, y, context, utc); + res.time_from = timeFrom(x, y, utc); } else { - res.time_to = timeFrom(x, y, context, utc); + res.time_to = timeFrom(x, y, utc); } return res; } protected: + MccProhibitedZone(std::string_view name) : _name(name) {} + std::string_view _name; + + + template XT, std::derived_from YT> + bool inZoneImpl(const XT&, const YT&, traits::mcc_systime_c auto const&) + { + return false; + } + + + template XT, std::derived_from YT> + pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&) + { + return pz_duration_t{std::numeric_limits::infinity()}; + } + + + template XT, std::derived_from YT> + pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&) + { + return pz_duration_t{0.0}; + } +}; + + +/* SOME PROHIBITED ZONE IMPLEMENTATIONS */ + + +// minimal or maximal altitude prohibited zones + +enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT }; + +template +class MccAltLimitPZ : public MccProhibitedZone +{ +public: + static constexpr MccAltLimitKind altLimitKind = KIND; + + MccAltLimitPZ(const MccAngle& alt_limit) + : MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE" + : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE" + : "ALTLIMIT-UNKNOWN"), + _altLimit(alt_limit) + { + _altLimit.normalize(); + } + +private: + MccAngle _altLimit; + + template XT, std::derived_from YT> + bool inZoneImpl(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc) + { + static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash(); + + if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) { // trivial case + if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) { + return y <= _altLimit; + } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { + return y >= _altLimit; + } + } else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZZD) { // trivial case + return inZoneImpl(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc); + } else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + // implementation ... + return false; + } else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + // implementation ... + return false; + } else { + throw std::system_error(std::make_error_code(std::errc::operation_not_supported)); + } + + return false; + } + + + template XT, std::derived_from YT> + pz_duration_t timeToImpl(const XT&, const YT&, traits::mcc_systime_c auto const&) + { + return pz_duration_t{std::numeric_limits::infinity()}; + } + + + template XT, std::derived_from YT> + pz_duration_t timeFromImpl(const XT&, const YT&, traits::mcc_systime_c auto const&) + { + return pz_duration_t{0.0}; + } }; } // namespace mcc