diff --git a/cxx/CMakeLists.txt b/cxx/CMakeLists.txt index 540c954..2a38c23 100644 --- a/cxx/CMakeLists.txt +++ b/cxx/CMakeLists.txt @@ -120,7 +120,7 @@ set(CNTR_PROTO_LIB comm_proto) add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC}) set(MOUNT_SERVER_APP_SRC mount.h mount_state.h mount_server.cpp comm_server.h comm_server_endpoint.h comm_server_configfile.h mount_astrom.h - mount_astrom_default.h mcc_coord.h) + mount_astrom_default.h mcc_coord.h mount_pz.h) set(MOUNT_SERVER_APP mount_server) add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}) # target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR}) @@ -137,7 +137,6 @@ if (WITH_TESTS) add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp) set(ASTROM_TEST_APP astrom_test) - add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp - mount_pz.h) + add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp) target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB) endif() diff --git a/cxx/mcc_coord.h b/cxx/mcc_coord.h index 14f55b2..6a496bc 100644 --- a/cxx/mcc_coord.h +++ b/cxx/mcc_coord.h @@ -63,22 +63,20 @@ protected: public: enum norm_kind_t { - NORM_KIND_0_360, // [0,360] - NORM_KIND_0_180, // [0,180] - NORM_KIND_90_90, // [-90,90] + NORM_KIND_0_360, // [0,360] + NORM_KIND_0_180, // [0,180] + NORM_KIND_180_180, // [-180,180] + NORM_KIND_90_90, // [-90,90] }; MccAngle() = default; // by default angle is in radians - MccAngle(std::convertible_to auto const& val, const MccRadianTag tag = MccRadianTag{}) - : _angleInRads(val) - { - } + MccAngle(std::convertible_to auto const& val, const MccRadianTag = MccRadianTag{}) : _angleInRads(val) {} // construct angle in degrees, e.g.: // auto ang = MccAngle{180.0, mcc_degrees}; - MccAngle(std::convertible_to auto const& val, const MccDegreeTag tag) + MccAngle(std::convertible_to auto const& val, const MccDegreeTag) { _angleInRads = val * utils::deg2radCoeff; } @@ -127,6 +125,12 @@ public: } else if (_angleInRads < 0.0) { _angleInRads = -_angleInRads; } + } else if constexpr (KIND == NORM_KIND_180_180) { + if (_angleInRads > std::numbers::pi) { + _angleInRads = 2.0 * std::numbers::pi - _angleInRads; + } else if (_angleInRads < -std::numbers::pi) { + _angleInRads += 2.0 * std::numbers::pi; + } } else if constexpr (KIND == NORM_KIND_90_90) { if (_angleInRads >= 1.5 * std::numbers::pi) { _angleInRads = _angleInRads - 2.0 * std::numbers::pi; @@ -175,8 +179,7 @@ public: return sexagesimal(hms, prec); } - friend MccAngle operator+(std::convertible_to auto&& left, - std::convertible_to auto&& right) + friend MccAngle operator+(std::convertible_to auto&& left, std::convertible_to auto&& right) { // return std::forward(left)._angleInRads + // std::forward(right)._angleInRads; @@ -189,8 +192,7 @@ public: // } - friend MccAngle operator-(std::convertible_to auto&& left, - std::convertible_to auto&& right) + friend MccAngle operator-(std::convertible_to auto&& left, std::convertible_to auto&& right) { // return std::forward(left)._angleInRads - // std::forward(right)._angleInRads; diff --git a/cxx/mount_pz.h b/cxx/mount_pz.h index b0a1a98..911ceb0 100644 --- a/cxx/mount_pz.h +++ b/cxx/mount_pz.h @@ -1,6 +1,7 @@ #pragma once #include "mcc_coord.h" +#include "mount_astrom.h" namespace mcc { @@ -10,7 +11,7 @@ namespace traits template concept mcc_prohibited_zone_c = requires(T t, const T const_t) { - typename T::pzcoords_kind_t; + typename T::pzcontext_t; { const_t.name() } -> std::same_as; { const_t.desc() } -> std::same_as; @@ -18,22 +19,21 @@ concept mcc_prohibited_zone_c = requires(T t, const T const_t) { // check if given coordinates are within the zone { t.inZone(std::declval(), std::declval(), - std::declval()) + std::declval()) } -> std::convertible_to; // a time duration to reach the zone (0 - if already in the zone, chrono::duration<>::max() if never // reach the zone) { t.timeTo(std::declval(), std::declval(), - std::declval(), - std::declval()) + std::declval(), std::declval()) } -> mcc_time_duration_c; // a time duration to exit the zone (0 - if already out of the zone, chrono::duration<>::max() if // never exit the zone) { t.timeFrom(std::declval(), std::declval(), - std::declval(), + std::declval(), std::declval()) } -> mcc_time_duration_c; }; @@ -44,18 +44,21 @@ concept mcc_prohibited_zone_c = requires(T t, const T const_t) { class MccProhibitedZone { public: + enum pzcoords_kind_t { COORDS_KIND_RADEC_IRCS, COORDS_KIND_RADEC_APP, COORDS_KIND_HADEC_APP, COORDS_KIND_AZALT }; + + struct pzcontext_t { + typedef std::chrono::duration real_secs_t; // seconds duration in double + + pzcoords_kind_t coords_kind; + + real_secs_t dut1; // UT1-UTC + real_secs_t tt_tai; // TT-TAI + real_secs_t tai_utc; // TAI-UTC (leap seconds) + + MccAngle lat, lon; // site geographic coordinates + }; + virtual ~MccProhibitedZone() = default; - - bool inZone(this auto&& self, const MccAngle& x, const MccAngle& y) - { - return std::forward(self).inZoneImpl(x, y); - } - -protected: - bool inZoneImpl(const MccAngle&, const MccAngle&) - { - return false; - } }; class MccMinAltPZ : public MccProhibitedZone @@ -98,6 +101,47 @@ private: }; +enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT }; + +template +class MccAltLimitPZ +{ +public: + static constexpr MccAltLimitKind altLimitType = LIMIT; + + MccAltLimitPZ(const MccAngle& alt_limit) : _altLimit(alt_limit) + { + _altLimit.normalize(); + } + + bool inZone(const MccAngle& x, const MccAngle& y, const MccProhibitedZone::pzcontext_t& context) + { + if (context.coords_kind == MccProhibitedZone::COORDS_KIND_AZALT) { // trivial case + if constexpr (LIMIT == MccAltLimitKind::MIN_ALT_LIMIT) { + return y <= _altLimit; + } else if constexpr (LIMIT == MccAltLimitKind::MAX_ALT_LIMIT) { + return y >= _altLimit; + } + } else if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) { + auto dd = + astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, std::chrono::system_clock::now(), + context.dut1, context.tt_tai, context.tai_utc); + } + } + + + auto timeTo(const MccAngle& x, + const MccAngle& y, + const MccProhibitedZone::pzcontext_t& context, + traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) + { + } + +private: + MccAngle _altLimit; +}; + + /* * a general planar ellipse equation: * A*(x-xc)^2 + B*(x-xc)(y-yc) + C*(y-yc)^2 = 1 @@ -168,10 +212,7 @@ public: } // circle - MccEllipsePZ(const MccAngle& xc, const MccAngle& yc, const MccAngle& a) - : mcc::MccEllipsePZ(xc, yc, a, a) - { - } + MccEllipsePZ(const MccAngle& xc, const MccAngle& yc, const MccAngle& a) : mcc::MccEllipsePZ(xc, yc, a, a) {} private: