From 36ffde80f5f3b5224247ea7d0208606bff5d173b Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Wed, 3 Sep 2025 00:32:05 +0300 Subject: [PATCH] ... --- mcc/mcc_guiding_model.h | 161 +++++++++++++++++++++------------- mcc/mcc_moving_model_common.h | 20 +---- mcc/mcc_pzone.h | 4 +- mcc/mcc_slewing_model.h | 6 +- 4 files changed, 108 insertions(+), 83 deletions(-) diff --git a/mcc/mcc_guiding_model.h b/mcc/mcc_guiding_model.h index 80283dd..f6b9ac6 100644 --- a/mcc/mcc_guiding_model.h +++ b/mcc/mcc_guiding_model.h @@ -14,6 +14,7 @@ namespace mcc enum class MccSimpleGuidingModelErrorCode : int { ERROR_OK, + ERROR_CCTE, ERROR_HW_GETSTATE, ERROR_HW_SETSTATE, ERROR_PCM_COMP, @@ -63,7 +64,17 @@ public: MccTelemetryData tdata; MccEqtHrzCoords intsc_coords; - double dist, dx, dy; + MccCelestialPoint target_in_future_pt; + + if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { + target_in_future_pt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP; + } else if constexpr (mccIsAltAzMount(CONTROLS_T::mountType)) { + target_in_future_pt.pair_kind = MccCoordPairKind::COORDS_KIND_AZZD; + } else { + static_assert(false, "UNKNOW MOUNT TYPE!"); + } + + // double dist, dx, dy; auto t_err = controls->telemetryData(&tdata); if (t_err) { @@ -89,8 +100,8 @@ public: intsc_coords.Y = intsc_coords.DEC_APP; } else { no_intersects = true; - intsc_coords.X = tdata.HA + 710.0_mins; // 12h - 10min - intsc_coords.Y = tdata.DEC_APP; + // intsc_coords.X = tdata.HA + 710.0_mins; // 12h - 10min + // intsc_coords.Y = tdata.DEC_APP; } } else if constexpr (mccIsAltAzMount(CONTROLS_T::mountType)) { if (std::isfinite(intsc_coords.AZ)) { @@ -103,33 +114,97 @@ public: static_assert(false, "UNKNOW MOUNT TYPE!"); } - MccPCMResult pcm_inv_res; + // MccPCMResult pcm_inv_res; - // endpoint of the mount moving - auto pcm_err = controls->computeInversePCM(intsc_coords, &pcm_inv_res, &hw_state); - if (pcm_err) { - return mcc_deduce_error(pcm_err, MccSimpleGuidingModelErrorCode::ERROR_PCM_COMP); - } + // // endpoint of the mount moving + // auto pcm_err = controls->computeInversePCM(intsc_coords, &pcm_inv_res, &hw_state); + // if (pcm_err) { + // return mcc_deduce_error(pcm_err, MccSimpleGuidingModelErrorCode::ERROR_PCM_COMP); + // } - if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { - hw_state.speedX = _currentParams.trackSpeedX; - hw_state.speedY = _currentParams.trackSpeedY; - } + // if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { + // hw_state.speedX = _currentParams.trackSpeedX; + // hw_state.speedY = _currentParams.trackSpeedY; + // } }; + + auto target_point = [&, this](MccCelestialPoint* point) { + auto dt = std::chrono::duration{tdata.HA} + + _currentParams.timeShiftToTargetPoint * mcc_sideral_to_UT1_ratio; // hour seconds + + auto tp_dt = std::chrono::duration_cast( + _currentParams.timeShiftToTargetPoint); + + // point in +time_dist future + MccCelestialPoint pt{ + .pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP, + .X = MccAngle(dt.count() * std::numbers::pi / 3600.0 / 15.0).normalize(), + .Y = tdata.DEC_APP}; + mcc_tp2tp(tdata.time_point + tp_dt, pt.time_point); + + point->time_point = pt.time_point; + + // check for prohibited zone + if (std::isfinite(intsc_coords.HA)) { + bool through_pzone = + (intsc_coords.HA - pt.X) <= 0; // must be <= 0 if point in future will be in the zone + through_pzone &= + (intsc_coords.HA - tdata.HA) > 0; // must be > 0 if point in future was out of the zone + + if (through_pzone) { + pt.X = intsc_coords.HA; + } + } + + auto ret = controls->transformCoordinates(std::move(pt), point); + if (ret) { + return mcc_deduce_error(ret, MccSimpleGuidingModelErrorCode::ERROR_CCTE); + } else { + MccPCMResult pcm_inv_res; + + // endpoint of the mount moving + auto pcm_err = controls->computeInversePCM(target_in_future_pt, &pcm_inv_res, &hw_state); + if (pcm_err) { + return mcc_deduce_error(pcm_err, MccSimpleGuidingModelErrorCode::ERROR_PCM_COMP); + } + + mcc_tp2tp(tdata.time_point, hw_state.time_point); + } + + return MccSimpleGuidingModelErrorCode::ERROR_OK; + }; + + auto pz_err = update_pzones_ipoint(); if (pz_err) { return mcc_deduce_error(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); } hw_state.moving_type = CONTROLS_T::hardware_moving_state_t::HW_MOVE_GUIDING; + + { + std::lock_guard lock{*_currentParamsMutex}; + + auto ccte_err = target_point(&target_in_future_pt); + if (ccte_err) { + return mcc_deduce_error(ccte_err, MccSimpleGuidingModelErrorCode::ERROR_CCTE); + } + + if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { + hw_state.speedX = _currentParams.trackSpeedX; + hw_state.speedY = _currentParams.trackSpeedY; + } + } + + // move mount auto hw_err = controls->hardwareSetState(hw_state); if (hw_err) { return mcc_deduce_error(hw_err, MccSimpleGuidingModelErrorCode::ERROR_HW_SETSTATE); } - std::chrono::steady_clock::time_point last_corr_tp; + std::chrono::steady_clock::time_point last_corr_tp, last_ipzone_update_tp; while (*_stopGuiding) { // wait for updated telemetry data @@ -160,62 +235,28 @@ public: break; } - t_err = controls->targetToMountDist(&dist); - if (t_err) { - return mcc_deduce_error(t_err, MccSimpleGuidingModelErrorCode::ERROR_DIST_TELEMETRY); - } - - if (*_stopGuiding) { - break; - } - { std::lock_guard lock{*_currentParamsMutex}; - - if (dist < _currentParams.guidingCorrectionRange[0] || - dist > _currentParams.guidingCorrectionRange[1]) { // moving with sideral speed - - hw_state.moving_type = CONTROLS_T::hardware_moving_state_t::HW_MOVE_TRACKING; - if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { - hw_state.speedX = _currentParams.trackSpeedX; - hw_state.speedY = _currentParams.trackSpeedY; - } else if constexpr (mccIsAltAzMount(CONTROLS_T::mountType)) { - static_assert(false, "NOT IMPLEMENTED!"); - } else { - static_assert(false, "UNKNOW MOUNT TYPE!"); - } - - hw_err = controls->hardwareSetState(hw_state); - if (hw_err) { - return mcc_deduce_error(hw_err, MccSimpleGuidingModelErrorCode::ERROR_HW_SETSTATE); - } - - continue; - } - auto now = std::chrono::steady_clock::now(); + if ((now - last_corr_tp) < _currentParams.guidingMinInterval) { continue; } - hw_state.X = tdata.target.X; - - if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { - if (_currentParams.dualAxisGuiding) { - hw_state.Y = tdata.target.Y; - } else { // only along HA-axis - hw_state.Y = tdata.Y; + // update prohibited zones intersection point + if ((now - last_ipzone_update_tp) < _currentParams.updatingPZoneInterval) { + pz_err = update_pzones_ipoint(); + if (pz_err) { + return mcc_deduce_error( + pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); } - } else if constexpr (mccIsAltAzMount(CONTROLS_T::mountType)) { - hw_state.Y = tdata.target.Y; - } else { - static_assert(false, "UNKNOW MOUNT TYPE!"); - } - if (t_err) { - return mcc_deduce_error(t_err, MccSimpleGuidingModelErrorCode::ERROR_DIFF_TELEMETRY); } - last_corr_tp = now; + // compute new target-in-future point + auto ccte_err = target_point(&target_in_future_pt); + if (ccte_err) { + return mcc_deduce_error(ccte_err, MccSimpleGuidingModelErrorCode::ERROR_CCTE); + } } // send corrections diff --git a/mcc/mcc_moving_model_common.h b/mcc/mcc_moving_model_common.h index f36f66f..df6f267 100644 --- a/mcc/mcc_moving_model_common.h +++ b/mcc/mcc_moving_model_common.h @@ -9,7 +9,6 @@ #include #include "mcc_angle.h" -#include "mcc_defaults.h" #include "mcc_generics.h" namespace mcc @@ -58,6 +57,8 @@ struct MccSimpleMovingModelParams { double trackSpeedX{}; double trackSpeedY{}; + // time shift into future to compute target position in future (UT1-scale time duration) + std::chrono::duration timeShiftToTargetPoint{10.0}; // ******* guiding mode ******* @@ -141,22 +142,5 @@ typename PZoneContT::error_t mcc_find_closest_pzone(PZoneContT* pz_cont, return err; } -auto mcc_compute_target_point(mcc_ccte_c auto const& ccte, - mcc_telemetry_c auto const& tdata, - traits::mcc_time_duration_c auto const& time_dist, - mcc_celestial_point_c auto* point) -{ - auto dt = std::chrono::duration{tdata.HA} + time_dist * mcc_sideral_to_UT1_ratio; // hour seconds - - // point in +time_dist future - MccCelestialPoint pt{.pair_kind = point->pair_kind, - .time_point = point->time_point + time_dist, - .X = dt.count() * std::numbers::pi / 3600.0 / 15.0, - .Y = tdata.DEC_APP}; - - point->time_point = pt.time_point; - - return ccte.transformCoordinates(std::move(pt), point); -} } // namespace mcc diff --git a/mcc/mcc_pzone.h b/mcc/mcc_pzone.h index 86d74d6..d44a64a 100644 --- a/mcc/mcc_pzone.h +++ b/mcc/mcc_pzone.h @@ -439,8 +439,8 @@ public: ret = _transformCoordinates(pt, &to_pt); if (!ret) { - point->X = MccAngle(to_pt.X).normalize(); - point->Y = MccAngle(to_pt.Y).normalize(); + point->X = to_pt.X; + point->Y = to_pt.Y; } } diff --git a/mcc/mcc_slewing_model.h b/mcc/mcc_slewing_model.h index 0c58623..3458800 100644 --- a/mcc/mcc_slewing_model.h +++ b/mcc/mcc_slewing_model.h @@ -87,15 +87,13 @@ public: : _stopSlewing(new std::atomic_bool()), _currentParamsMutex(new std::mutex) { _slewingFunc = [telemetry, hardware, pz_cont, this]() -> error_t { - *_stopSlewing = false; - // first, check target coordinates typename TelemetryT::error_t t_err; MccTelemetryData tdata; { std::lock_guard lock{*_currentParamsMutex}; - t_err = telemetry->waitForTelemetryData(&tdata, _currentParams.telemetryTimeout); + t_err = telemetry->telemetryData(&tdata); if (t_err) { return mcc_deduce_error(t_err, MccSimpleSlewingModelErrorCode::ERROR_GET_TELEMETRY); @@ -332,6 +330,8 @@ public: error_t slewToTarget() { + *_stopSlewing = false; + return _slewingFunc(); }