#pragma once /* MOUNT CONTROL COMPONENTS LIBRARY */ #include #include "mcc_mount_coord.h" #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"; template static constexpr bool mcc_is_equatorial_mount = TYPE == MccMountType::GERMAN_TYPE ? true : TYPE == MccMountType::FORK_TYPE ? true : TYPE == MccMountType::CROSSAXIS_TYPE ? true : TYPE == MccMountType::ALTAZ_TYPE ? false : false; template static constexpr bool mcc_is_altaz_mount = TYPE == MccMountType::GERMAN_TYPE ? false : TYPE == MccMountType::FORK_TYPE ? false : TYPE == MccMountType::CROSSAXIS_TYPE ? false : TYPE == MccMountType::ALTAZ_TYPE ? true : false; static consteval bool mccIsEquatorialMount(const MccMountType type) { return type == MccMountType::GERMAN_TYPE ? true : type == MccMountType::FORK_TYPE ? true : type == MccMountType::CROSSAXIS_TYPE ? true : type == MccMountType::ALTAZ_TYPE ? false : false; }; static consteval bool mccIsAltAzMount(const MccMountType type) { return type == MccMountType::GERMAN_TYPE ? false : type == MccMountType::FORK_TYPE ? false : type == MccMountType::CROSSAXIS_TYPE ? false : type == MccMountType::ALTAZ_TYPE ? true : false; }; } // namespace mcc namespace mcc::traits { /* ASTROMETRY-RELATED COMPUTATION ENGINE */ template concept mcc_astrom_engine_c = requires(T t, const T t_const) { requires mcc_error_c; 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; // compute equation of origins { t.eqOrigins(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 */ // compute refraction-related quantities: refraction(refr_params) { t.refraction(std::declval()) } -> std::same_as; // compute refraction correction for given altitude: refractCorrection(alt, refr_params, refr_corr) { t.refractCorrection(std::declval(), std::declval(), std::declval()) } -> std::same_as; }; /* A VERY GENERIC MOUNT HARDWARE CONCEPT */ template concept mcc_mount_hardware_c = requires(T t, const T t_const) { requires mcc_error_c; typename T::config_t; typename T::time_point_t; typename T::coord_t; { t_const.id() } -> mcc_formattable; // hardware configuration { t.setConfig(std::declval()) } -> std::same_as; { t.getConfig(std::declval()) } -> std::same_as; // at least contains time of measurement and coordinates for x,y axes requires requires(typename T::axes_pos_t pos) { requires std::same_as; requires std::same_as; requires std::same_as; }; { t.setPos(std::declval()) } -> std::same_as; { t.getPos(std::declval()) } -> std::same_as; }; /* POINTING-ERROR CORRECTION */ template concept mcc_mount_pec_c = requires(T t, const T t_const) { requires mcc_error_c; typename T::coord_t; typename T::pec_data_t; // at least contains .dx and .dy fields requires requires(typename T::pec_result_t res) { requires std::same_as; requires std::same_as; }; { t.setData(std::declval()) } -> std::same_as; { t_const.getData(std::declval()) } -> std::same_as; { t.compute(std::declval(), std::declval(), std::declval()) } -> std::same_as; }; /* MOUNT STATE TELEMETRY */ template concept mcc_mount_telemetry_c = requires(T t, const T t_const) { typename T::error_t; typename T::mount_telemetry_data_t; { t_const.errorString(std::declval()) } -> mcc_formattable; { t.update() } -> std::same_as; { t_const.data() } -> std::same_as; }; /* MOUNT PROHIBITED ZONE */ template concept mcc_prohibited_zone_c = std::movable && requires(T t, const T t_const) { typename T::coord_t; typename T::time_point_t; // the type 'T' must define static constexpr member of type MccCoordPairKind // to declarate type of coordinate pair used to describe the zone. // This coordinate pair must be used as input in the class methods. requires requires { requires std::same_as; []() { constexpr MccCoordPairKind val = T::zoneCoordPairKind; }(); // to ensure that 'zoneCoordPairKind' can be used at compile-time context }; // return a name of the zone { t_const.name() } -> mcc_formattable; // check if given coordinates are in the zone at given time point { t.inZone(std::declval(), std::declval(), std::declval()) } -> std::convertible_to; // for given coordinates and time the method computes a time to reach the zone { t.timeTo(std::declval(), std::declval(), std::declval()) } -> mcc_time_duration_c; // for given coordinates and time the method computes a time to exit from the zone { t.timeFrom(std::declval(), std::declval(), std::declval()) } -> mcc_time_duration_c; }; /* MOUNT GENERIC CONFIGURATION */ template concept mcc_mount_config_c = requires(T t) { { t.astromEngine() } -> mcc_astrom_engine_c; { t.pec() } -> mcc_mount_pec_c; { t.hardware() } -> mcc_mount_hardware_c; }; } // namespace mcc::traits