diff --git a/mcc/mcc_angle.h b/mcc/mcc_angle.h index 211d4b0..b16fbef 100644 --- a/mcc/mcc_angle.h +++ b/mcc/mcc_angle.h @@ -566,6 +566,15 @@ enum class MccCoordPairKind : size_t { COORDS_KIND_UNKNOWN = traits::mcc_type_pair_hash() }; +template +static constexpr bool mccIsObsCoordPairKind = + (PK == MccCoordPairKind::COORDS_KIND_RADEC_OBS || PK == MccCoordPairKind::COORDS_KIND_HADEC_OBS || + PK == MccCoordPairKind::COORDS_KIND_AZZD || PK == MccCoordPairKind::COORDS_KIND_AZALT); + +template +static constexpr bool mccIsAppCoordPairKind = + (PK == MccCoordPairKind::COORDS_KIND_RADEC_APP || PK == MccCoordPairKind::COORDS_KIND_HADEC_APP); + static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_ICRS_STR = "RADEC-IRCS"; static constexpr std::string_view MCC_COORDPAIR_KIND_RADEC_APP_STR = "RADEC-APP"; diff --git a/mcc/mcc_ccte_erfa.h b/mcc/mcc_ccte_erfa.h index 8da070f..3ef1ad0 100644 --- a/mcc/mcc_ccte_erfa.h +++ b/mcc/mcc_ccte_erfa.h @@ -505,9 +505,8 @@ public: // first, compute HA from CIO-based RA!!! lst_eo(); if (!ret) { - // ha = MccAngle(lst - from_pt.X + eo).normalize(); - ha = MccAngle(lst - from_pt.X - eo).normalize(); - // ha = MccAngle(lst - from_pt.X - eo).normalize(); + ha = MccAngle(lst - from_pt.X + eo).normalize(); + // ha = MccAngle(lst - from_pt.X - eo).normalize(); } else { return ret; } @@ -534,8 +533,8 @@ public: } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { lst_eo(); if (!ret) { - // to_pt->X = MccAngle(lst - from_pt.X + eo).normalize(); - to_pt->X = MccAngle(lst - from_pt.X - eo).normalize(); + to_pt->X = MccAngle(lst - from_pt.X + eo).normalize(); + // to_pt->X = MccAngle(lst - from_pt.X - eo).normalize(); to_pt->Y = from_pt.Y; } else { return ret; @@ -559,8 +558,8 @@ public: azalt2hadec(from_pt, to_pt); lst_eo(); if (!ret) { - // to_pt->X = MccAngle(lst - to_pt->X + eo).normalize(); - to_pt->X = MccAngle(lst - to_pt->X - eo).normalize(); + to_pt->X = MccAngle(lst - to_pt->X + eo).normalize(); + // to_pt->X = MccAngle(lst - to_pt->X - eo).normalize(); } } else { ret = MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; diff --git a/mcc/mcc_coord.h b/mcc/mcc_coord.h index d6d5a2a..06aaf3b 100644 --- a/mcc/mcc_coord.h +++ b/mcc/mcc_coord.h @@ -331,7 +331,58 @@ protected: template auto toHelper(PT& cpair) { - double ra_icrs, dec_icrs, ra_obs, dec_obs, ha_obs, az_obs, zd_obs, lst, eo; + static constexpr double half_pi = std::numbers::pi / 2.0; + + // HA, DEC to AZ, ALT (AZ from the South through the West) + auto hadec2azalt = [](double ha, double dec, double phi, double& az, double& alt) { + const auto cos_phi = std::cos(phi), sin_phi = std::sin(phi); + const auto cos_dec = std::cos(dec), sin_dec = std::sin(dec); + const auto cos_ha = std::cos(ha), sin_ha = std::sin(ha); + + auto x = sin_phi * cos_dec * cos_ha - cos_phi * sin_dec; + auto y = -cos_dec * sin_ha; + auto z = cos_phi * cos_dec * cos_ha + sin_phi * sin_dec; + + auto xx = x * x, yy = y * y; + decltype(x) r; + if (xx < yy) { + r = yy * sqrt(1.0 + xx / yy); + } else { + r = xx * sqrt(1.0 + yy / xx); + } + + az = utils::isEqual(r, 0.0) ? 0.0 : std::atan2(y, x); + if (az < 0.0) { + az += std::numbers::pi * 2.0; // to range of [0, 2*PI] + } + + alt = std::atan2(z, r); + }; + + // AZ, ALT to HA, DEC (AZ from the South through the West) + auto azalt2hadec = [](double az, double alt, double phi, double& ha, double& dec) { + const auto cos_phi = std::cos(phi), sin_phi = std::sin(phi); + const auto cos_az = std::cos(az), sin_az = std::sin(az); + const auto cos_alt = std::cos(alt), sin_alt = std::sin(alt); + + auto x = sin_phi * cos_alt * cos_az + cos_phi * sin_alt; + auto y = cos_alt * sin_az; + auto z = -cos_phi * cos_alt * cos_az + sin_phi * sin_alt; + + auto xx = x * x, yy = y * y; + decltype(x) r; + if (xx < yy) { + r = yy * sqrt(1.0 + xx / yy); + } else { + r = xx * sqrt(1.0 + yy / xx); + } + + ha = utils::isEqual(r, 0.0) ? 0.0 : std::atan2(y, x); + dec = std::atan2(z, r); + }; + + double phi; + double ra_icrs, dec_icrs, ra, dec, ha, az, zd, alt, lst, eo; static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_GENERIC, "UNSUPPORTED SKY POINT TRANSFORMATION!"); static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_UNKNOWN, "UNSUPPORTED SKY POINT TRANSFORMATION!"); @@ -373,7 +424,7 @@ protected: } } - // here, APP or OBS to ICRS + // here, from APP or OBS to ICRS if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS && PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { cpair = PT(PT::x_t(ra_icrs), PT::y_t(dec_icrs), MccCelestialCoordEpoch{}); @@ -381,32 +432,105 @@ protected: } if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + if constexpr (mccIsObsCoordPairKind) { + // cct_engine.icrsToObs(...) + } else if constexpr (mccIsAppCoordPairKind) { + // cct_engine.icrsToApp(...) + } else { + static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + } + + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { // cct_engine.icrsToApp(...) + cpair.setX(ra); + cpair.setY(dec); } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { // cct_engine.icrsToObs(...) } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { // cct_engine.icrsToApp(...) + cpair.setX(ha); + cpair.setY(dec); } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { // cct_engine.icrsToObs(...) } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { // cct_engine.icrsToObs(...) + cpair.setX(az); + cpair.setY(zd); } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { // cct_engine.icrsToObs(...) + cpair.setX(az); + cpair.setY(half_pi - zd); } else { static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); } } else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + // compute EO, LST, refract model + ha = lst + eo - cpair.x(); // from CIO based RA + + if constexpr (PT::pairKind != MccCoordPairKind::COORDS_KIND_HADEC_APP) { + hadec2azalt(ha, _y, phi, az, alt); // to app az, alt + // to observed zenithal distance: alt += z_corr + } + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + azalt2hadec(az, alt, phi, ha, dec); // to obs ha, dec + + ra = lst + eo - ha; // CIO based RA + cpair.setX(ra); + cpair.setY(dec); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { - // ha = lst + eo - ra? + cpair.setX(ha); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + azalt2hadec(az, alt, phi, ha, dec); // to obs ha, dec + cpair.setX(ha); + cpair.setY(dec); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { + cpair.setX(az); // ????????????!!!!!!!!! + cpair.setY(half_pi - alt); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { + cpair.setX(az); // ????????????!!!!!!!!! + cpair.setY(alt); } else { static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); } } else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + ha = lst + eo - cpair.x(); // from CIO based RA + + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + hadec2azalt(ha, _y, phi, az, alt); + // to apparent zenithal distance: alt -= z_corr; + azalt2hadec(az, alt, phi, ha, dec); // to app ha,dec + + ra = lst + eo - ha; // CIO based RA + cpair.setX(ra); + cpair.setY(dec); + + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + hadec2azalt(ha, _y, phi, az, alt); + // to apparent zenithal distance: alt -= z_corr; + azalt2hadec(az, alt, phi, ha, dec); // to app ha,dec + + cpair.setX(ha); + cpair.setY(dec); + + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + cpair.setX(ha); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { + hadec2azalt(ha, _y, phi, az, alt); + cpair.setX(az); + cpair.setY(half_pi - alt); + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { + hadec2azalt(ha, _y, phi, az, alt); + cpair.setX(az); + cpair.setY(alt); + } else { + static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + } } else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { } else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { } else if (pkind == MccCoordPairKind::COORDS_KIND_AZZD) { diff --git a/mcc/mcc_defaults.h b/mcc/mcc_defaults.h index b3da5a3..cd8f757 100644 --- a/mcc/mcc_defaults.h +++ b/mcc/mcc_defaults.h @@ -477,6 +477,8 @@ struct MccGenericTelemetryData : MccGenericEqtHrzCoords { MccJulianDay JD; coord_t LST; // local apparent sideral time + MccGenericCelestialPoint entered_target{}; + MccGenericPointingTarget target{}; coord_t speedX, speedY; diff --git a/mcc/mcc_generics.h b/mcc/mcc_generics.h index 898219b..fb8e06c 100644 --- a/mcc/mcc_generics.h +++ b/mcc/mcc_generics.h @@ -626,6 +626,9 @@ static constexpr void mcc_copy_pointing_target_coord(mcc_pointing_target_coord_c template concept mcc_telemetry_data_c = mcc_eqt_hrz_coord_c && std::default_initializable && requires(T t) { + // user entered target coordinates + requires mcc_celestial_point_c; + // target target coordinates requires mcc_pointing_target_coord_c; diff --git a/mcc/mcc_telemetry.h b/mcc/mcc_telemetry.h index b86da31..49434b2 100644 --- a/mcc/mcc_telemetry.h +++ b/mcc/mcc_telemetry.h @@ -132,6 +132,8 @@ public: using pcm_t = std::remove_cvref_t; using hardware_t = std::remove_cvref_t; + _data.entered_target.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS; + if constexpr (mccIsEquatorialMount(pcm_t::mountType)) { _data.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP; _data.target.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP; @@ -146,16 +148,11 @@ public: MccPCMResult pcm_res; mcc_tp2tp(_data.time_point, _data.target.time_point); + mcc_tp2tp(_data.time_point, _data.entered_target.time_point); - bool hw_coords = _data.target.pair_kind == MccCoordPairKind::COORDS_KIND_XY; - MccCelestialPoint hw_cp{.pair_kind = MccCoordPairKind::COORDS_KIND_XY}; - mcc_tp2tp(_data.time_point, hw_cp.time_point); - - if (hw_coords) { // compute corresponded observed coordinates - hw_cp.X = _data.target.X; - hw_cp.Y = _data.target.Y; - - auto pcm_err = controls->computePCM(_data.target, &pcm_res, &_data.target); + if (_data.entered_target.pair_kind == + MccCoordPairKind::COORDS_KIND_XY) { // compute corresponded observed coordinates + auto pcm_err = controls->computePCM(_data.entered_target, &pcm_res, &_data.target); if (pcm_err) { return mcc_deduce_error_code(pcm_err, MccTelemetryErrorCode::ERROR_PCM_COMP); } @@ -171,34 +168,23 @@ public: } else { static_assert(false, "UNKNOWN MOUNT TYPE!!!"); } - } - if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { - _data.target.X = _data.target.RA_ICRS; - _data.target.Y = _data.target.DEC_ICRS; - } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) { - _data.target.X = _data.target.AZ; - _data.target.Y = _data.target.ZD; - } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) { - _data.target.X = _data.target.AZ; - _data.target.Y = _data.target.ALT; - } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { - _data.target.X = _data.target.HA; - _data.target.Y = _data.target.DEC_APP; - } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { - _data.target.X = _data.target.RA_APP; - _data.target.Y = _data.target.DEC_APP; + auto ccte_err = controls->transformCoordinates(_data.target, &_data.target); + if (ccte_err) { + return mcc_deduce_error_code(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM); + } } else { - return MccTelemetryErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; - } + _data.target.pair_kind = _data.entered_target.pair_kind; - auto ccte_err = controls->transformCoordinates(_data.target, &_data.target); - if (ccte_err) { - if (hw_coords) { // restore coordinates pair kind - _data.target.pair_kind = MccCoordPairKind::COORDS_KIND_XY; + auto ccte_err = controls->transformCoordinates(_data.entered_target, &_data.target); + if (ccte_err) { + return mcc_deduce_error_code(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM); } - return mcc_deduce_error_code(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM); + if (_data.entered_target.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + _data.target.RA_ICRS = _data.entered_target.X; + _data.target.DEC_ICRS = _data.entered_target.Y; + } } if (stop_token.stop_requested()) { @@ -206,36 +192,9 @@ public: } if (_data.target.pair_kind != MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { - // fixed apparent coordinates (AZZD or HADEC) - // needs to compute ICRS - // (.X and .Y are already assigned above!) - - - // if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) { - // _data.target.X = _data.target.AZ; - // _data.target.Y = _data.target.ZD; - // } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) { - // _data.target.X = _data.target.AZ; - // _data.target.Y = _data.target.ALT; - // } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { - // _data.target.X = _data.target.HA; - // _data.target.Y = _data.target.DEC_APP; - // } else if (_data.target.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { - // _data.target.X = _data.target.RA_APP; - // _data.target.Y = _data.target.DEC_APP; - // } else { - // return MccTelemetryErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; - // } - MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; - ccte_err = controls->transformCoordinates(_data.target, &pt); + auto ccte_err = controls->transformCoordinates(_data.target, &pt); if (ccte_err) { - if (hw_coords) { // restore coordinates pair kind - _data.target.pair_kind = MccCoordPairKind::COORDS_KIND_XY; - _data.target.X = hw_cp.X; - _data.target.Y = hw_cp.Y; - } - return mcc_deduce_error_code(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM); } _data.target.RA_ICRS = pt.X; @@ -247,15 +206,11 @@ public: } // hardware coordinates - if (!hw_coords) { + if (_data.entered_target.pair_kind != MccCoordPairKind::COORDS_KIND_XY) { auto pcm_err = controls->computeInversePCM(_data.target, &pcm_res, &_data.target); if (pcm_err) { return mcc_deduce_error_code(pcm_err, MccTelemetryErrorCode::ERROR_PCM_COMP); } - } else { // restore coordinates pair kind - _data.target.pair_kind = MccCoordPairKind::COORDS_KIND_XY; - _data.target.X = hw_cp.X; - _data.target.Y = hw_cp.Y; } return MccTelemetryErrorCode::ERROR_OK; @@ -646,6 +601,10 @@ public: std::lock_guard lock{*_updateMutex}; + mcc_copy_celestial_point(pt, &_data.entered_target); + + + /* mcc_copy_celestial_point(pt, &_userTarget); @@ -672,6 +631,8 @@ public: return MccTelemetryErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; } + */ + return _updateTargetFunc({}); // return _setTargetFunc(pt);