diff --git a/cxx/mcc_mount_astro_erfa.h b/cxx/mcc_mount_astro_erfa.h index d84c23f..3b5993a 100644 --- a/cxx/mcc_mount_astro_erfa.h +++ b/cxx/mcc_mount_astro_erfa.h @@ -10,10 +10,39 @@ #include "mcc_astrom_iers.h" +#include "mcc_mount_concepts.h" #include "mcc_mount_coord.h" -// #include "mcc_mount_astrom.h" -#include "mcc_mount_concepts.h" + +namespace mcc::astrom::erfa +{ +enum class MccMountAstromEngineERFAErrorCode : int { + ERROR_OK = 0, + ERROR_INVALID_INPUT_ARG, + ERROR_JULDATE_INVALID_YEAR, + ERROR_JULDATE_INVALID_MONTH, + ERROR_BULLETINA_OUT_OF_RANGE, + ERROR_LEAPSECONDS_OUT_OF_RANGE, + ERROR_DUBIOUS_YEAR, + ERROR_UNACCEPTABLE_DATE, + ERROR_UPDATE_LEAPSECONDS, + ERROR_UPDATE_BULLETINA, +}; + +} + + +namespace std +{ + +template <> +class is_error_code_enum : public true_type +{ +}; + +} // namespace std + + namespace mcc::astrom::erfa { @@ -22,6 +51,62 @@ namespace mcc::astrom::erfa #include +/* error category definition */ + +// error category +struct MccMountAstromEngineERFACategory : public std::error_category { + MccMountAstromEngineERFACategory() : std::error_category() {} + + const char* name() const noexcept + { + return "ADC_GENERIC_DEVICE"; + } + + std::string message(int ec) const + { + MccMountAstromEngineERFAErrorCode err = static_cast(ec); + + switch (err) { + case MccMountAstromEngineERFAErrorCode::ERROR_OK: + return "OK"; + case MccMountAstromEngineERFAErrorCode::ERROR_INVALID_INPUT_ARG: + return "invalid argument"; + case MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_YEAR: + return "invalid year number"; + case MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_MONTH: + return "invalid month number"; + case MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE: + return "time point is out of range"; + case MccMountAstromEngineERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE: + return "time point is out of range"; + case MccMountAstromEngineERFAErrorCode::ERROR_DUBIOUS_YEAR: + return "dubious year"; + case MccMountAstromEngineERFAErrorCode::ERROR_UNACCEPTABLE_DATE: + return "unacceptable date"; + case MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS: + return "leap seconds update error"; + case MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA: + return "bulletin A update error"; + default: + return "UNKNOWN"; + } + } + + static const MccMountAstromEngineERFACategory& get() + { + static const MccMountAstromEngineERFACategory constInst; + return constInst; + } +}; + + +inline std::error_code make_error_code(MccMountAstromEngineERFAErrorCode ec) +{ + return std::error_code(static_cast(ec), MccMountAstromEngineERFACategory::get()); +} + + + /* A concept for ERFA-library compatible type to represent anglular quantities */ template concept mcc_erfa_angle_t = std::constructible_from && std::convertible_to; @@ -29,32 +114,10 @@ concept mcc_erfa_angle_t = std::constructible_from && std::convertibl template class MccMountAstromEngineERFA { -protected: - static constexpr std::array engineErrorString = {"OK", - "invalid argument", - "invalid year", - "invalid month", - "time point is out of range", - "time point is out of range", - "dubious year", - "unacceptable year", - "leap seconds update error", - "bulletin A update error"}; - public: static constexpr double DEFAULT_WAVELENGTH = 0.55; // default observed wavelength in mkm - enum error_t : size_t { - ERROR_OK = 0, - ERROR_INVALID_INPUT_ARG, - ERROR_JULDATE_INVALID_YEAR, - ERROR_JULDATE_INVALID_MONTH, - ERROR_BULLETINA_OUT_OF_RANGE, - ERROR_LEAPSECONDS_OUT_OF_RANGE, - ERROR_DUBIOUS_YEAR, - ERROR_UNACCEPTABLE_DATE, - ERROR_UPDATE_LEAPSECONDS, - ERROR_UPDATE_BULLETINA, - }; + + typedef std::error_code error_t; // meteo parameters (to compute refraction) @@ -140,10 +203,10 @@ public: std::lock_guard lock{_stateMutex}; if (!_currentState._leapSeconds.load(stream, comment_sym)) { - return ERROR_UPDATE_LEAPSECONDS; + return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -152,10 +215,10 @@ public: std::lock_guard lock{_stateMutex}; if (!_currentState._leapSeconds.load(filename, comment_sym)) { - return ERROR_UPDATE_LEAPSECONDS; + return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -164,10 +227,10 @@ public: std::lock_guard lock{_stateMutex}; if (!_currentState._bulletinA.load(stream, comment_sym)) { - return ERROR_UPDATE_BULLETINA; + return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -176,19 +239,13 @@ public: std::lock_guard lock{_stateMutex}; if (!_currentState._bulletinA.load(filename, comment_sym)) { - return ERROR_UPDATE_BULLETINA; + return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } - - std::string errorString(error_t err) const - { - return engineErrorString[err]; - } - /* time-related methods */ // templated generic version @@ -203,10 +260,10 @@ public: static constexpr std::chrono::year MIN_YEAR = -4799y; if (ymd.year() < MIN_YEAR) { - return ERROR_JULDATE_INVALID_YEAR; + return MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_YEAR; } if (!ymd.month().ok()) { - return ERROR_JULDATE_INVALID_MONTH; + return MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_MONTH; } int64_t im = (unsigned)ymd.month(); @@ -223,7 +280,7 @@ public: using fd_t = std::chrono::duration>; // fraction of day juldate.mjd = static_cast(mjd_int) + std::chrono::duration_cast(time_point - dd).count(); - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } error_t greg2jul(time_point_t time_point, juldate_t& juldate) @@ -242,14 +299,14 @@ public: if (tai_utc.has_value()) { tt.mjd += std::chrono::duration_cast(tai_utc.value()).count(); } else { - return ERROR_LEAPSECONDS_OUT_OF_RANGE; + return MccMountAstromEngineERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE; } auto tt_tai = _currentState._bulletinA.TT_TAI(); tt.mjd = juldate.mjd + std::chrono::duration_cast(tt_tai).count(); - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -270,7 +327,7 @@ public: if (dut1.has_value()) { ut1 += std::chrono::duration_cast(dut1.value()).count(); } else { // out of range - return ERROR_BULLETINA_OUT_OF_RANGE; + return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; } } @@ -288,7 +345,7 @@ public: juldate_t tt; auto err = terrestrialTime(juldate, tt); - if (err != ERROR_OK) { + if (err != MccMountAstromEngineERFAErrorCode::ERROR_OK) { return err; } @@ -297,7 +354,7 @@ public: gst += _currentState.lon; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -306,13 +363,13 @@ public: juldate_t tt; auto err = terrestrialTime(juldate, tt); - if (err != ERROR_OK) { + if (err != MccMountAstromEngineERFAErrorCode::ERROR_OK) { return err; } eo = eraEo06a(tt.MJD0, tt.mjd); - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } /* atmospheric refraction-related methods */ @@ -324,7 +381,7 @@ public: eraRefco(_currentState.meteo.pressure, _currentState.meteo.temperature, _currentState.meteo.humidity, _currentState.wavelength, &refr.refa, &refr.refb); - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -337,7 +394,7 @@ public: corr = ref_params.refa / tanALT + ref_params.refb / tanALT / tanALT / tanALT; } - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } /* coordinates conversional methods */ @@ -357,12 +414,12 @@ public: auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd); if (!dut1.has_value()) { - return ERROR_BULLETINA_OUT_OF_RANGE; + return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; } auto pol_pos = _currentState._bulletinA.polarCoords(juldate.mjd); if (!pol_pos.has_value()) { - return ERROR_BULLETINA_OUT_OF_RANGE; + return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; } const auto arcsec2rad = std::numbers::pi / 180 / 3600; pol_pos->x *= arcsec2rad; @@ -376,9 +433,9 @@ public: &oaz, &ozd, &oha, &odec, &ora, &eo_); if (ret == 1) { - return ERROR_DUBIOUS_YEAR; + return MccMountAstromEngineERFAErrorCode::ERROR_DUBIOUS_YEAR; } else if (ret == -1) { - return ERROR_UNACCEPTABLE_DATE; + return MccMountAstromEngineERFAErrorCode::ERROR_UNACCEPTABLE_DATE; } ra_app = ora; @@ -388,7 +445,7 @@ public: ha = oha; eo = eo_; - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -402,7 +459,7 @@ public: az = r_az; alt = r_alt; - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } error_t azalt2hadec(coord_t az, coord_t alt, coord_t& ha, coord_t& dec) @@ -416,7 +473,7 @@ public: ha = r_ha; dec = r_dec; - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } @@ -426,7 +483,7 @@ public: pa = eraHd2pa(ha, dec, _currentState.lat); - return ERROR_OK; + return MccMountAstromEngineERFAErrorCode::ERROR_OK; } diff --git a/cxx/mcc_mount_concepts.h b/cxx/mcc_mount_concepts.h index 57b42e4..b471748 100644 --- a/cxx/mcc_mount_concepts.h +++ b/cxx/mcc_mount_concepts.h @@ -97,12 +97,6 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) { 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, eo) @@ -249,7 +243,7 @@ concept mcc_mount_telemetry_data_c = requires(T telemetry) { template concept mcc_mount_telemetry_c = requires(T t, const T t_const) { - typename T::error_t; + requires mcc_error_c; // // a class that at least contains celestial (equatorial and horizontal) coordinates // requires requires(typename T::mount_telemetry_data_t telemetry) { diff --git a/cxx/mcc_mount_pec.h b/cxx/mcc_mount_pec.h index c5d579b..e92edad 100644 --- a/cxx/mcc_mount_pec.h +++ b/cxx/mcc_mount_pec.h @@ -12,6 +12,65 @@ #include "mcc_mount_concepts.h" #include "mcc_mount_coord.h" +namespace mcc +{ + +enum class MccMountDefaultPECErrorCode : int { ERROR_OK, ERROR_INVALID_INPUTS_BISPLEV, ERROR_EXCEED_MAX_ITERS }; + +/* error category definition */ + +// error category +struct MccMountDefaultPECCategory : public std::error_category { + MccMountDefaultPECCategory() : std::error_category() {} + + const char* name() const noexcept + { + return "ADC_GENERIC_DEVICE"; + } + + std::string message(int ec) const + { + MccMountDefaultPECErrorCode err = static_cast(ec); + + switch (err) { + case MccMountDefaultPECErrorCode::ERROR_OK: + return "OK"; + case MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV: + return "invalid input arguments for bispev"; + case MccMountDefaultPECErrorCode::ERROR_EXCEED_MAX_ITERS: + return "exceed maximum of iterations number"; + default: + return "UNKNOWN"; + } + } + + static const MccMountDefaultPECCategory& get() + { + static const MccMountDefaultPECCategory constInst; + return constInst; + } +}; + + +inline std::error_code make_error_code(MccMountDefaultPECErrorCode ec) +{ + return std::error_code(static_cast(ec), MccMountDefaultPECCategory::get()); +} +} // namespace mcc + + +namespace std +{ + +template <> +class is_error_code_enum : public true_type +{ +}; + +} // namespace std + + + namespace mcc { @@ -165,7 +224,7 @@ public: if (ret) { res.dx = std::numeric_limits::quiet_NaN(); res.dy = std::numeric_limits::quiet_NaN(); - return std::error_code(); // !!!!!!!!!!!!!! + return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV; } @@ -175,7 +234,7 @@ public: if (ret) { res.dx = std::numeric_limits::quiet_NaN(); res.dy = std::numeric_limits::quiet_NaN(); - return std::error_code(); // !!!!!!!!!!!!!! + return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV; } @@ -187,7 +246,7 @@ public: static_assert(false, "UNSUPPORTED"); } - return std::error_code(); + return MccMountDefaultPECErrorCode::ERROR_OK; } // from celestial to encoder (use of iterative scheme) @@ -196,35 +255,59 @@ public: coord_t e2 = eps * eps; coord_t xi = x, yi = y; - coord_t xp, yp; + coord_t xe, ye; size_t iter = 1; // the first iteration auto err = compute(x, y, res); if (!err) { - xp = x - res.dx; - yp = y - res.dy; + // 'encoder' cocordinates + xe = x - res.dx; + ye = y - res.dy; - bool ok = ((xp - x) * (xp - x) + (yp - y) * (yp - y)) <= e2; + err = compute(xe, ye, res); // to celestial + if (err) { + return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV; + } + + xi = xe + res.dx; // celestial + yi = ye + res.dy; + + auto rx = (x - xi); + auto ry = (y - yi); + auto d = rx * rx + ry * ry; + + bool ok = d <= e2; if (ok) { - return std::error_code(); + return MccMountDefaultPECErrorCode::ERROR_OK; } while (iter < max_iter) { - xi = xp; - yi = xp; - err = compute(xi, yi, res); - xp -= res.dx; - yp -= res.dy; - - ok = ((xp - xi) * (xp - xi) + (yp - yi) * (yp - yi)) <= e2; - if (ok) { - return std::error_code(); + err = compute(xi, yi, res); // to encoder + if (err) { + return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV; } + xe = x - res.dx; + ye = y - res.dy; + + err = compute(xe, ye, res); // to celestial + if (err) { + return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV; + } + + xi = xe + res.dx; // celestial + yi = ye + res.dy; + + ok = ((x - xi) * (x - xi) + (y - yi) * (y - yi)) <= e2; + if (ok) { + return MccMountDefaultPECErrorCode::ERROR_OK; + } + + ++iter; } - // err = "exceed max iterations";!!! + err = MccMountDefaultPECErrorCode::ERROR_EXCEED_MAX_ITERS; } return err; diff --git a/cxx/mcc_mount_telemetry.h b/cxx/mcc_mount_telemetry.h index 633ba19..985d62d 100644 --- a/cxx/mcc_mount_telemetry.h +++ b/cxx/mcc_mount_telemetry.h @@ -139,42 +139,6 @@ public: typedef DATA_T mount_telemetry_data_t; - // mount current telemetry data: time, position and related quantities - // struct mount_telemetry_data_t { - // typedef typename astrom_engine_t::coord_t coord_t; - - // // time-related - // typename astrom_engine_t::time_point_t utc; // time point of measurements, UTC - // typename astrom_engine_t::juldate_t jd; // Julian date - // typename astrom_engine_t::sideral_time_t siderTime; // local apperant sideral time - // // typename astrom_engine_t::time_point_t ut1; // Universal time - // // typename astrom_engine_t::time_point_t tt; // Terrestial time - - // // apparent target (user-input) current coordinates (in radians) - // coord_t tagRA, tagDEC; - // coord_t tagHA; - // coord_t tagAZ, tagALT; - // coord_t tagPA; // paralactic angle - - // // encoder-measured current mount coordinates (in radians) - // coord_t mntRA, mntDEC; - // coord_t mntHA; - // coord_t mntAZ, mntALT; - // typename astrom_engine_t::pa_t mntPA; - - // // encoder-measured (non-corrected for PCS) current mount position and moving speed (in radians, radians/s) - // // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one - // coord_t mntPosX, mntPosY; - - // // current refraction coefficients - // typename pec_t::pec_result_t currRefrCoeffs; - // // current refraction correction (for mntALT) - // coord_t currRefr; - - // // PEC (pointing error correction): - // // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one - // coord_t pecX, pecY; - // }; MccMountTelemetry(astrom_engine_t& astrom_engine, pec_t& pec, hardware_t& hardware) : _astromEngine(astrom_engine), _pec(pec), _hardware(hardware) diff --git a/cxx/mcc_slew_model.h b/cxx/mcc_slew_model.h index f955bbe..4e12ced 100644 --- a/cxx/mcc_slew_model.h +++ b/cxx/mcc_slew_model.h @@ -19,7 +19,6 @@ namespace mcc * [azimuth, zenithal distance] (see sources code below) */ -template class MccSimpleSlewModel { public: @@ -37,26 +36,47 @@ public: }; - template - MccSimpleSlewModel(HARDWARE_T& hardware, ASTROM_T& astrom_engine, PEC_T& pec) + template + MccSimpleSlewModel(MOUNT_CONTROLS_T& mount_controls) { - const auto p_hardware = &hardware; - const auto p_astrom_engine = &astrom_engine; - const auto p_pec = &pec; + // deduce controls types + using astrom_engine_t = decltype(mount_controls.astrometryEngine); + using hardware_t = decltype(mount_controls.hardware); + using pec_t = decltype(mount_controls.PEC); + using telemetry_t = decltype(mount_controls.telemetry); + using tpl_pz_t = decltype(mount_controls.prohibitedZones); + + static constexpr size_t Nzones = std::tuple_size_v; + + const auto p_mount_controls = &mount_controls; + + // prohibited zones related lambdas + auto check_zones = [p_mount_controls](std::array& result, + std::index_sequence) { + ((result[Is] = std::get(p_mount_controls->prohibitedZones).inZone(p_mount_controls->telemetry.data())), + ...); + + bool flag = false; + ((flag |= result[Is]), ...); + + return flag; + }; + _slewFunc = [p_mount_controls](this auto&& self, const slew_params_t& slew_pars) { + auto& astrom_engine = p_mount_controls->astrometryEngine; + auto& hardware = p_mount_controls->hardware; + auto& pec = p_mount_controls->PEC; + auto& telemetry = p_mount_controls->telemetry; - _slewFunc = [p_hardware, p_astrom_engine, p_pec](this auto&& self, const slew_params_t& slew_pars, - TELEMETRY_T& telemetry) { - using coord_t = typename ASTROM_T::coord_t; - using jd_t = typename ASTROM_T::juldate_t; + using coord_t = typename astrom_engine_t::coord_t; + using jd_t = typename astrom_engine_t::juldate_t; - typename HARDWARE_T::axes_pos_t ax_pos; + typename hardware_t::axes_pos_t ax_pos; error_t res_err; - typename ASTROM_T::error_t ast_err; + typename astrom_engine_t::error_t ast_err; + typename pec_t::error_t pec_err; if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_XY) { // trivial case (the pair is interpretated as raw encoder coordinates) @@ -66,26 +86,24 @@ public: mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // catalog coordinates jd_t jd; coord_t ra_app, dec_app, ha, az, alt; - typename ASTROM_T::eo_t eo; + typename astrom_engine_t::eo_t eo; - ast_err = p_astrom_engine->greg2jul(std::chrono::system_clock::now(), jd); + ast_err = astrom_engine->greg2jul(std::chrono::system_clock::now(), jd); if (!ast_err) { - ast_err = p_astrom_engine->icrs2obs(slew_pars.x, slew_pars.y, jd, ra_app, dec_app, ha, az, alt, eo); + ast_err = astrom_engine->icrs2obs(slew_pars.x, slew_pars.y, jd, ra_app, dec_app, ha, az, alt, eo); if (!ast_err) { - if constexpr (mccIsEquatorialMount(PEC_T::mountType)) { + if constexpr (mccIsEquatorialMount(pec_t::mountType)) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP, .x = ha, .y = dec_app, - .stop = slew_pars.stop}, - telemetry); - } else if constexpr (mccIsAltAzMount(PEC_T::mountType)) { + .stop = slew_pars.stop}); + } else if constexpr (mccIsAltAzMount(pec_t::mountType)) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT, .x = az, .y = alt, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } else { static_assert(false, "UNKNOWN MOUNT TYPE!"); } @@ -94,78 +112,73 @@ public: } else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP) { // apparent jd_t jd; - typename ASTROM_T::eo_t eo; + typename astrom_engine_t::eo_t eo; - ast_err = p_astrom_engine->greg2jul(std::chrono::system_clock::now(), jd); + ast_err = astrom_engine->greg2jul(std::chrono::system_clock::now(), jd); if (!ast_err) { - typename ASTROM_T::sideral_time_t lst; - ast_err = p_astrom_engine->apparentSiderTime(jd, lst, true); + typename astrom_engine_t::sideral_time_t lst; + ast_err = astrom_engine->apparentSiderTime(jd, lst, true); if (!ast_err) { - ast_err = p_astrom_engine->eqOrigins(jd, eo); + ast_err = astrom_engine->eqOrigins(jd, eo); if (!ast_err) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP, .x = lst - slew_pars.x + eo, // HA = LST - RA_APP + EO .y = slew_pars.y, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } } } } else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP) { // apparent - if constexpr (mccIsEquatorialMount(PEC_T::mountType)) { // compute encoder coordinates + if constexpr (mccIsEquatorialMount(pec_t::mountType)) { // compute encoder coordinates coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0; - typename PEC_T::pec_result_t pec_res; + typename pec_t::pec_result_t pec_res; - auto err = p_pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10); - if (!err) { + pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10); + if (!pec_err) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY, .x = slew_pars.x - pec_res.dx, .y = slew_pars.y - pec_res.dy, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } - } else if constexpr (mccIsAltAzMount(PEC_T::mountType)) { + } else if constexpr (mccIsAltAzMount(pec_t::mountType)) { coord_t az, alt; - ast_err = p_astrom_engine->hadec2azalt(slew_pars.x, slew_pars.y, az, alt); + ast_err = astrom_engine->hadec2azalt(slew_pars.x, slew_pars.y, az, alt); if (!ast_err) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT, .x = az, .y = alt, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } } else { static_assert(false, "UNKNOWN MOUNT TYPE!"); } } else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_AZALT) { - if constexpr (mccIsEquatorialMount(PEC_T::mountType)) { + if constexpr (mccIsEquatorialMount(pec_t::mountType)) { coord_t ha, dec; - ast_err = p_astrom_engine->azalt2hadec(slew_pars.x, slew_pars.y, ha, dec); + ast_err = astrom_engine->azalt2hadec(slew_pars.x, slew_pars.y, ha, dec); if (!ast_err) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP, .x = ha, .y = dec, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } - } else if constexpr (mccIsAltAzMount(PEC_T::mountType)) { // compute encoder coordinates + } else if constexpr (mccIsAltAzMount(pec_t::mountType)) { // compute encoder coordinates coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0; - typename PEC_T::pec_result_t pec_res; + typename pec_t::pec_result_t pec_res; - auto err = p_pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10); - if (!err) { + pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10); + if (!pec_err) { res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY, .x = slew_pars.x - pec_res.dx, .y = slew_pars.y - pec_res.dy, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } } else { @@ -178,32 +191,57 @@ public: res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT, .x = slew_pars.x, .y = std::numbers::pi / 2.0 - slew_pars.y, - .stop = slew_pars.stop}, - telemetry); + .stop = slew_pars.stop}); } if (res_err) { return res_err; } - if (!ast_err) { - auto err = p_hardware->setPos(std::move(ax_pos)); + if (pec_err) { + // ??????????? + return std::error_code(); // !!!!!!!!!!!!!!! + } - while (true) { + if (!ast_err) { + typename telemetry_t::error_t t_err; + typename telemetry_t::mount_telemetry_data_t t_data; + + // move mount (it is assumed this is asynchronous operation!!!) + typename hardware_t::error_t err = hardware->setPos(std::move(ax_pos)); + + std::array pz_result; + + if (!err) { + // + // what is the condition for mount reaches given position?!! + // + while (true) { + t_err = telemetry.data(t_data); + if (t_err) { + // ?????????!!!!!!!!!! + } + + // check prohibited zones + if (check_zones(pz_result, std::make_index_sequence{})) { + // stop mount ?!!!!!!!!!!!!!!!!!!!!! + // return in-zone-error-code + } + } } } }; } - error_t slew(const slew_params_t& pars, TELEMETRY_T& telemetry) + error_t slew(const slew_params_t& pars) { - error_t res_err = _slewFunc(pars, telemetry); + error_t res_err = _slewFunc(pars); return res_err; } protected: - std::function _slewFunc{}; + std::function _slewFunc{}; }; diff --git a/cxx/tests/astrom_test.cpp b/cxx/tests/astrom_test.cpp index 0a93c88..6c41896 100644 --- a/cxx/tests/astrom_test.cpp +++ b/cxx/tests/astrom_test.cpp @@ -10,6 +10,7 @@ struct tel_data_t { typedef mcc::MccAngle coord_t; + typedef std::chrono::system_clock::time_point time_point_t; coord_t mntRA, mntDEC, mntHA; coord_t mntAZ, mntALT; @@ -187,7 +188,7 @@ int main(int argc, char* argv[]) auto res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor); std::cout << "eq of origins (from icrs2obs) = " << eor.sexagesimal(true) << "\n"; - std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\n"; + std::cout << "ret code (icrs2obs) = " << res.message() << "\n"; std::cout << "alt = " << alt1.sexagesimal() << "\n"; std::cout << "az = " << az1.sexagesimal() << "\n"; @@ -232,7 +233,7 @@ int main(int argc, char* argv[]) ra1 = "17:00:00"_hms; dec1 = "40:25:10.43"_dms; res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor); - std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\n"; + std::cout << "ret code (icrs2obs) = " << res.message() << "\n"; std::cout << "alt = " << alt1.sexagesimal() << "\n"; std::cout << "az = " << az1.sexagesimal() << "\n"; @@ -265,5 +266,10 @@ int main(int argc, char* argv[]) std::cout << "(MAXALT) time from zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n"; } + ra_o = 1.0; + dec_o = 2.0; + ha1 = ra_o * dec_o; + std::cout << "mult: " << ha1.degrees() << "\n"; + return ecode; }