#pragma once /* MOUNT CONTROL COMPONENTS LIBRARY */ #include #include "mcc_traits.h" /* SOME LIBRARY-WIDE DECLARATIONS */ namespace mcc { // mount construction type (only the most common ones) enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTAZ_TYPE }; template static constexpr std::string_view MccMountTypeStr = TYPE == MccMountType::GERMAN_TYPE ? "GERMAN" : TYPE == MccMountType::FORK_TYPE ? "FORK" : TYPE == MccMountType::CROSSAXIS_TYPE ? "CROSSAXIS" : TYPE == MccMountType::ALTAZ_TYPE ? "ALTAZ" : "UNKNOWN"; } // namespace mcc namespace mcc::traits { /* ASTROMETRY-RELATED COMPUTATION ENGINE */ template concept mcc_astrom_engine_c = requires(T t, const T t_const) { typename T::engine_err_t; typename T::engine_state_t; requires std::movable; typename T::coord_t; // type for coordinates representation typename T::time_point_t; // type to represent UTC time point typename T::juldate_t; // type to represent Julian date typename T::sideral_time_t; // type to represent sideral time typename T::pa_t; // type to represent parallactic angle typename T::refract_result_t; { t.setState(std::declval()) }; { t_const.getState() } -> std::same_as; { t_const.errorString(std::declval()) } -> mcc_formattable; /* coordinates conversional methods */ // ICRS RA and DEC to observed place: icrs2obs(ra, dec, jd, ra_app, dec_app, ha, az, alt) { t.icrs2obs(std::declval(), std::declval(), std::declval(), std::declval(), std::declval(), std::declval(), std::declval(), std::declval()) } -> std::same_as; // compute hour angle and declination from azimuth and altitude: hadec2azalt(ha, dec, az, alt) { t.hadec2azalt(std::declval(), std::declval(), std::declval(), std::declval()) } -> std::same_as; // compute azimuth and altitude from hour angle and declination: azalt2hadec(az, alt, ha, dec) { t.azalt2hadec(std::declval(), std::declval(), std::declval(), std::declval()) } -> std::same_as; // compute parallactic angle: hadec2pa(ha, dec, pa) { t.hadec2pa(std::declval(), std::declval(), std::declval()) } -> std::same_as; /* time-related methods */ // Gregorian Calendar time point to Julian Date: greg2jul(time_point, jd) { t.greg2jul(std::declval(), std::declval()) } -> std::same_as; // apparent sideral time: apparentSiderTime(jd, gst, islocal) // if islocal == false then the method must return the Greenwich apparent sideral time, otherwise - local one { t.apparentSiderTime(std::declval(), std::declval(), std::declval()) } -> std::same_as; /* atmospheric refraction-related methods */ { t.refraction(std::declval()) } -> std::same_as; }; /* MOUNT AXES AND MOTORS HARDWARE GENERIC ABSTRACTION */ // encoder basic concept (e.g. mount axis encoder or motor shaft one) template concept mcc_hw_encoder_c = requires(T t, const T t_const) { typename T::error_t; typename T::time_point_t; typename T::coord_t; typename T::speed_t; typename T::accel_t; requires requires(typename T::state_t st) { requires std::same_as; requires std::same_as; requires std::same_as; requires std::same_as; }; { t_const.errorString(std::declval()) } -> mcc_formattable; { t_const.id() } -> mcc_formattable; { t.getState(std::declval()) } -> std::same_as; }; template concept mcc_hw_motor_c = requires(T t, const T t_const) { typename T::error_t; typename T::coord_t; typename T::speed_t; typename T::accel_t; requires requires(typename T::pos_t st) { requires std::same_as; requires std::same_as; // means maximal allowed speed requires std::same_as; // means a maximal allowed acceleration (jerk) }; { t_const.errorString(std::declval()) } -> mcc_formattable; { t_const.id() } -> mcc_formattable; { t.toPos(std::declval()) } -> std::same_as; { t.stop() } -> std::same_as; }; namespace details { template concept mcc_tuple_enc_ref_c = mcc_tuple_c && requires(T t) { []