diff --git a/include/mcc/mcc_angle.h b/include/mcc/mcc_angle.h index f86a4b9..0fb2cf8 100644 --- a/include/mcc/mcc_angle.h +++ b/include/mcc/mcc_angle.h @@ -435,23 +435,36 @@ static T1 operator/(const T1& v1, const T2& v2) std::string MccAngleFancyString(std::convertible_to auto const& ang, std::format_string val_fmt = "{:.2f}") { + using ang_t = std::decay_t; std::string s; double abs_ang; - if constexpr (std::is_arithmetic_v>) { + if constexpr (std::is_arithmetic_v) { abs_ang = std::abs(ang); } else { abs_ang = std::abs(MccAngle{ang}); } if (abs_ang < 1.0_arcmins) { - std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.arcsecs()); + if constexpr (std::derived_from) { + std::format_to(std::back_inserter(s), val_fmt, ang.arcsecs()); + } else { + std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.arcsecs()); + } s += " arcsecs"; } else if (abs_ang < 1.0_degs) { - std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.arcmins()); + if constexpr (std::derived_from) { + std::format_to(std::back_inserter(s), val_fmt, ang.arcmins()); + } else { + std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.arcmins()); + } s += " arcmins"; } else { - std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.degrees()); + if constexpr (std::derived_from) { + std::format_to(std::back_inserter(s), val_fmt, ang.degrees()); + } else { + std::format_to(std::back_inserter(s), val_fmt, MccAngle{ang}.degrees()); + } s += " degs"; } diff --git a/include/mcc/mcc_coordinate.h b/include/mcc/mcc_coordinate.h index 6eb6e3f..646d0ee 100644 --- a/include/mcc/mcc_coordinate.h +++ b/include/mcc/mcc_coordinate.h @@ -537,6 +537,78 @@ public: return error_t{}; } + // 'inner' transformation + error_t to(MccCoordPairKind pair_kind) + { + return to(pair_kind, _epoch); + } + + error_t to(MccCoordPairKind pair_kind, mcc_coord_epoch_c auto const& epoch) + { + // do not use here "mcc_coord_epoch_c::operator==" to avoid + // unnecessary computations (astrometrical algorithms mainly use Julian date as input) + if (pair_kind == _pairKind && utils::isEqual(epoch.MJD(), _epoch.MJD())) { + _epoch = epoch; + + return error_t{}; + } + + auto tr_func = [&, this](T& cp) { + if constexpr (T::pairKind != MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + cp.setEpoch(epoch); + } + + auto err = to(cp); + + if (!err) { + from(cp); + } + + return err; + }; + + switch (pair_kind) { + case MccCoordPairKind::COORDS_KIND_RADEC_ICRS: { + MccSkyRADEC_ICRS cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_RADEC_OBS: { + MccSkyRADEC_OBS cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_RADEC_APP: { + MccSkyRADEC_APP cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_HADEC_OBS: { + MccSkyHADEC_OBS cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_HADEC_APP: { + MccSkyHADEC_APP cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_AZZD: { + MccSkyAZZD cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_AZALT: { + MccSkyAZALT cp; + return tr_func(cp); + } break; + case MccCoordPairKind::COORDS_KIND_GENERIC: + case MccCoordPairKind::COORDS_KIND_UNKNOWN: + case MccCoordPairKind::COORDS_KIND_LONLAT: + case MccCoordPairKind::COORDS_KIND_XY: { + MccGenXY cp; + return tr_func(cp); + } break; + default: + return error_t{}; + } + + return error_t{}; + } error_t refractCorrection(mcc_angle_c auto* dZ) const { @@ -751,6 +823,8 @@ protected: double phi = cctEngine.getStateERFA().lat; double ra_icrs, dec_icrs, ra, dec, ha, az, zd, alt, lst, eo; + static_assert(PT::pairKind != MccCoordPairKind::COORDS_KIND_LONLAT, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + // static_assert(PT::pairKind != MccCoordPairKind::COORDS_KIND_XY, "UNSUPPORTED SKY POINT TRANSFORMATION!"); static_assert(PT::pairKind != MccCoordPairKind::COORDS_KIND_GENERIC, "UNSUPPORTED SKY POINT TRANSFORMATION!"); static_assert(PT::pairKind != MccCoordPairKind::COORDS_KIND_UNKNOWN, "UNSUPPORTED SKY POINT TRANSFORMATION!"); @@ -786,7 +860,8 @@ protected: // 1) convert stored coordinates to ICRS ones // 2) convert from the computed ICRS coordinates to required ones MccCoordPairKind pkind = _pairKind; - if (!utils::isEqual(_epoch.MJD(), cpair.MJD())) { // convert stored pair to ICRS one (ra_icrs, dec_icrs) + if (!utils::isEqual(_epoch.MJD(), + cpair.MJD())) { // convert stored pair to ICRS one (ra_icrs, dec_icrs) if (_pairKind != MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { pkind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS; @@ -955,7 +1030,8 @@ protected: cpair.setY(dec); } else { obj->hadec2azalt(ha, dec, phi, az, alt); - if constexpr (mccIsObsCoordPairKind) { // RADEC_OBS, HADEC_OBS, AZALT, AZZD + if constexpr (mccIsObsCoordPairKind) { // RADEC_OBS, HADEC_OBS, + // AZALT, AZZD // correct for refraction: alt += dz_refr double dZ; ccte_err = cctEngine.refractionInverseCorrection(MCC_HALF_PI - alt, &dZ); @@ -1008,7 +1084,8 @@ protected: }; -/* MCC-LIBRARY DEFAULT SKY POINT CLASS IMPLEMENTATION BASED ON THE ERFA LIBRARY */ +/* MCC-LIBRARY DEFAULT SKY POINT CLASS IMPLEMENTATION BASED ON THE ERFA LIBRARY + */ typedef MccGenericSkyPoint MccSkyPoint; diff --git a/include/mcc/mcc_movement_controls.h b/include/mcc/mcc_movement_controls.h index 5b2dc34..ac13e1d 100644 --- a/include/mcc/mcc_movement_controls.h +++ b/include/mcc/mcc_movement_controls.h @@ -807,9 +807,6 @@ public: log_pos(tdata, dist); - logger->logInfo( - std::format(" final target-to-mount distance {}", MccAngleFancyString(std::get<2>(dist)))); - if (!slew_and_stop) { // start tracking _trackingFunc(); } else { @@ -858,6 +855,8 @@ public: logger->logInfo(std::format(" braking acceleration Y: {} degs/s^2 (in config: {} rads/s^2)", MccAngle(braking_accelY).degrees(), _currentParams.brakingAccelY)); logger->logInfo(std::format(" min time to prohibited zone: {} seconds", min_time_to_pzone_in_secs)); + logger->logInfo( + std::format(" max target-to-mount distance: {} arcseconds", _currentParams.trackingMaxCoordDiff)); _pathFile << "# \n"; @@ -870,6 +869,8 @@ public: typename TELEMETRY_T::telemetry_data_t tdata; typename HARDWARE_T::hardware_state_t hw_state; + std::tuple dist; + auto t_err = telemetry->telemetryData(&tdata); if (t_err) { @@ -881,6 +882,31 @@ public: return; } + log_pos(tdata, dist); + + { + std::lock_guard lock{*_currentParamsMutex}; + if (_currentParams.trackingMaxCoordDiff < std::get<2>(dist)) { + logger->logInfo( + std::format("The target-to-mount distance {} is greater than allowed one ({})! Track current " + "mount position!", + MccAngleFancyString(std::get<2>(dist)), + MccAngleFancyString(_currentParams.trackingMaxCoordDiff))); + + telemetry->setPointingTarget(tdata.mountPos); + } + } + + t_err = telemetry->telemetryData(&tdata); + if (t_err) { + *_lastError = mcc_deduced_err(t_err, MccSimpleMovementControlsErrorCode::ERROR_GET_TELEMETRY); + (*cb_sptr)(STATUS_T::MOUNT_STATUS_ERROR); + + _pathFile.save(); + + return; + } + *_lastError = check_pzones(tdata, min_time_to_pzone_in_secs, braking_accelX, braking_accelY); if (_lastError->load()) { @@ -895,8 +921,6 @@ public: mcc_deduced_coord_pair_t tag_cp, mnt_cp; - std::tuple dist; - *_stopMoving = false; while (!_stopMoving->load()) { @@ -928,20 +952,6 @@ public: last_hw_time = tdata.hwState.XY.epoch().UTC(); - // auto ccte_err = tdata.targetPos.to(tag_cp); - // if (ccte_err) { - // *_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP); - // } - // ccte_err = tdata.mountPos.to(mnt_cp); - // if (ccte_err) { - // *_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP); - // } - - // auto dist = utils::distanceOnSphere(tag_cp.x(), tag_cp.y(), mnt_cp.x(), mnt_cp.y()); - - // logger->logTrace(std::format( - // " target-to-mount distance: {} (dx = {}, dy = {})", MccAngleFancyString(std::get<2>(dist)), - // MccAngleFancyString(std::get<0>(dist)), MccAngleFancyString(std::get<1>(dist)))); // resend new position since target coordinates are changed in time hw_state.movementState = HARDWARE_T::hardware_movement_state_t::HW_MOVE_TRACKING;