diff --git a/mcc/mcc_generics.h b/mcc/mcc_generics.h index 59c25f0..f875b85 100644 --- a/mcc/mcc_generics.h +++ b/mcc/mcc_generics.h @@ -157,9 +157,10 @@ concept mcc_julday_c = mcc_fp_type_like_c && requires(const T v) { /* ERROR CLASS CONCEPT */ template -concept mcc_error_c = std::convertible_to || requires(const T t) { - { t.operator bool() }; -}; +concept mcc_error_c = std::default_initializable && (std::convertible_to || requires(const T t) { + { t.operator bool() }; + (bool)T() == false; // default constucted value must be a "non-error"! + }); template @@ -716,13 +717,21 @@ struct mcc_pzone_interface_t { // NOTE: the method must return: // point = mcc_celestial_point_c{.pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC, .X = NaN, .Y = NaN} // if there is no intersection with the zone for given coordinates! - template SelfT, typename InputT> - RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point) - requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + template SelfT, typename InputT, typename ResultT> + RetT intersectPZone(this SelfT&& self, InputT coords, ResultT* point) + requires((mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + (mcc_eqt_hrz_coord_c || mcc_celestial_point_c)) && requires { self.intersectPZone(coords, point); } { return std::forward(self).intersectPZone(std::move(coords), point); } + // template SelfT, typename InputT> + // RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point) + // requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + // requires { self.intersectPZone(coords, point); } + // { + // return std::forward(self).intersectPZone(std::move(coords), point); + // } protected: mcc_pzone_interface_t() = default; @@ -788,9 +797,17 @@ struct mcc_pzone_container_interface_t { } - template SelfT, typename InputT, mcc_celestial_point_c CPT> - RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range auto* result) - requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) + // template SelfT, typename InputT, mcc_celestial_point_c CPT> + // RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range auto* result) + // requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) + // { + // return std::forward(self).intersectPZone(std::move(coords), result); + // } + + template SelfT, typename InputT, typename ResultT> + RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range auto* result) + requires((mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + (mcc_eqt_hrz_coord_c || mcc_celestial_point_c)) { return std::forward(self).intersectPZone(std::move(coords), result); } diff --git a/mcc/mcc_guiding_model.h b/mcc/mcc_guiding_model.h index 8dc3720..2bcfb45 100644 --- a/mcc/mcc_guiding_model.h +++ b/mcc/mcc_guiding_model.h @@ -54,37 +54,66 @@ public: typedef MccSimpleMovingModelParams guiding_params_t; - template - MccSimpleGuidingModel(TelemetryT* telemetry, HardwareT* hardware, PZoneContT* pz_cont) + template + MccSimpleGuidingModel(TelemetryT* telemetry, HardwareT* hardware, PcmT* pcm, PZoneContT* pz_cont) : _stopGuiding(new std::atomic_bool()), _currentParamsMutex(new std::mutex()) { - _guidingFunc = [telemetry, hardware, pz_cont, this]() -> error_t { - typename TelemetryT::error_t t_err; - - MccCelestialPoint cpt; + _guidingFunc = [telemetry, hardware, pcm, pz_cont, this]() -> error_t { typename HardwareT::hardware_state_t hw_state; + MccTelemetryData tdata; + MccEqtHrzCoords intsc_coords; + double dist; + + auto t_err = telemetry->waitForTelemetryData(&tdata, _currentParams.telemetryTimeout); + if (t_err) { + return mcc_deduce_error(t_err, MccSimpleGuidingModelErrorCode::ERROR_GET_TELEMETRY); + } + + + // compute intersection points with the prohibited zones + auto pz_err = mcc_find_closest_pzone(pz_cont, tdata, &intsc_coords); + if (pz_err) { + return mcc_deduce_error(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); + } + + bool no_intersects = false; + if constexpr (mccIsEquatorialMount(HardwareT::mountType)) { - cpt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP; + if (std::isfinite(intsc_coords.HA)) { + intsc_coords.X = intsc_coords.HA; + 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; + } } else if constexpr (mccIsAltAzMount(HardwareT::mountType)) { - cpt.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT; - static_assert(false, "NOT IMPLEMENTED!"); + if (std::isfinite(intsc_coords.AZ)) { + intsc_coords.X = intsc_coords.AZ; + intsc_coords.Y = intsc_coords.ZD; + } else { + no_intersects = true; + } } else { static_assert(false, "UNKNOW MOUNT TYPE!"); } + // compute position in future + auto hw_err = hardware->hardwareGetState(&hw_state); + if (hw_err) { + return mcc_deduce_error(hw_err, MccSimpleGuidingModelErrorCode::ERROR_HW_GETSTATE); + } + MccPCMResult pcm_inv_res; - MccTelemetryData tdata; - - std::vector> pz_timeto; // in seconds - std::chrono::duration min_time{0.0}; - std::vector intsc_pt(pz_cont->sizePZones(), cpt); - - // compute intersection points with the prohibited zones - auto pz_err = pz_cont->intersectPZone(tdata, &intsc_pt); - if (pz_err) { - return mcc_deduce_error(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); + // endpoint of the mount moving + auto pcm_err = pcm->computeInversePCM(intsc_coords, &pcm_inv_res, &hw_state); + if (pcm_err) { + return mcc_deduce_error(pcm_err, MccSimpleGuidingModelErrorCode::ERROR_PCM_COMP); } while (*_stopGuiding) { @@ -99,21 +128,22 @@ public: } } + if (*_stopGuiding) { + break; + } + // control prohibited zones - pz_err = pz_cont->timeToPZone(tdata, &pz_timeto); + if (mcc_is_near_pzones(pz_cont, tdata, _currentParams.minTimeToPZone, pz_err)) { + return MccSimpleGuidingModelErrorCode::ERROR_NEAR_PZONE; + } if (pz_err) { return mcc_deduce_error(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); } - min_time = std::chrono::duration{0}; - for (size_t i = 0; i < pz_cont->sizePZones(); ++i) { - if (pz_timeto[i] < _currentParams.minTimeToPZone) { - return MccSimpleGuidingModelErrorCode::ERROR_NEAR_PZONE; - } - if (pz_timeto[i] < min_time) { - min_time = pz_timeto[i]; - } + t_err = telemetry->targetToMountDist(&dist); + if (t_err) { + return mcc_deduce_error(t_err, MccSimpleGuidingModelErrorCode::ERROR_DIST_TELEMETRY); } } diff --git a/mcc/mcc_moving_model_common.h b/mcc/mcc_moving_model_common.h index eaceb20..1e2afce 100644 --- a/mcc/mcc_moving_model_common.h +++ b/mcc/mcc_moving_model_common.h @@ -9,6 +9,7 @@ #include #include "mcc_angle.h" +#include "mcc_generics.h" namespace mcc { @@ -60,4 +61,80 @@ struct MccSimpleMovingModelParams { bool dualAxisGuiding{true}; // mount must be of an equatorial type: false means guiding along only HA-axis }; + +template +bool mcc_is_near_pzones(PZoneContT* pz_cont, + mcc_telemetry_c auto const& tdata, + traits::mcc_time_duration_c auto const& min_timeto, + typename PZoneContT::error_t& err) +{ + using res_t = std::decay_t; + + std::vector pz_timeto; // in seconds + + err = pz_cont->timeToPZone(tdata, &pz_timeto); + if (err) { + return false; + } + + for (auto const& t : pz_timeto) { + if (t <= min_timeto) { + return true; + } + } + + return false; +} + + +template +typename PZoneContT::error_t mcc_find_closest_pzone(PZoneContT* pz_cont, + mcc_telemetry_c auto const& tdata, + mcc_eqt_hrz_coord_c auto* closest_coords) +{ + using res_t = std::decay_t; + + if (closest_coords == nullptr) { + return {}; + } + + res_t c; + + mcc_tp2tp(tdata.time_point, c.time_point); + + mcc_tp2tp(tdata.time_point, closest_coords->time_point); + closest_coords->X = std::numeric_limits::quiet_NaN(); + closest_coords->Y = std::numeric_limits::quiet_NaN(); + closest_coords->RA_APP = std::numeric_limits::quiet_NaN(); + closest_coords->DEC_APP = std::numeric_limits::quiet_NaN(); + closest_coords->HA = std::numeric_limits::quiet_NaN(); + closest_coords->AZ = std::numeric_limits::quiet_NaN(); + closest_coords->ZD = std::numeric_limits::quiet_NaN(); + closest_coords->ALT = std::numeric_limits::quiet_NaN(); + + std::vector pz_coords(c, pz_cont->sizePZones()); + + double dha, dha_min = std::numeric_limits::max(); + + auto err = pz_cont->intersectPZone(tdata, &pz_coords); + if (!err) { + for (auto const& rpt : pz_coords) { + if (std::isfinite(rpt.X) && std::isfinite(rpt.Y)) { + dha = rpt.HA - tdata.HA; + if (dha < 0.0) { + dha += std::numbers::pi * 2.0; + } + + if (dha < dha_min) { + dha_min = dha; + mcc_copy_eqt_hrz_coord(rpt, closest_coords); + } + } + } + } + + return err; +} + + } // namespace mcc diff --git a/mcc/mcc_pzone.h b/mcc/mcc_pzone.h index 91ed33c..15b9161 100644 --- a/mcc/mcc_pzone.h +++ b/mcc/mcc_pzone.h @@ -114,6 +114,24 @@ public: return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM; } }; + + _transformCoordinatesEqtHrzCoords = [ccte_engine](MccCelestialPoint from_pt, + MccEqtHrzCoords* to_pt) -> error_t { + if (to_pt == nullptr) { + return MccAltLimitPZErrorCode::ERROR_NULLPTR; + } + + auto err = ccte_engine->transformCoordinates(from_pt, to_pt); + if (!err) { + return MccAltLimitPZErrorCode::ERROR_OK; + } + + if (std::same_as) { + return err; + } else { + return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM; + } + }; } @@ -278,11 +296,79 @@ public: return ret; } - template - error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point) - requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) + // template + // error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point) + // requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) + // { + // // double ha, dec, az; + // double dec, az; + + // if (point == nullptr) { + // return MccAltLimitPZErrorCode::ERROR_NULLPTR; + // } + + // error_t ret = MccAltLimitPZErrorCode::ERROR_OK; + + // if constexpr (mcc_eqt_hrz_coord_c) { + // // ha = coords.HA; + // dec = coords.DEC_APP; + // } else { + // MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP}; + // mcc_tp2tp(coords.time_point, to_pt.time_point); + + // ret = getCoord(coords, &to_pt); + // if (ret) { + // return ret; + // } + + // // ha = to_pt.X; + // dec = to_pt.Y; + // } + + // double sinDec = sin(dec), cosDec = cos(dec); + + // auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat; + + // if (cos_ha > 1.0) { // no intersection + // // point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC; + // point->X = std::numeric_limits::quiet_NaN(); + // point->Y = std::numeric_limits::quiet_NaN(); + + // return ret; + // } + + // // WARNNIG: THE EXPRESSION ASSUMES THAT AZIMUTH IS COUNTED FROM THE SOUTH THROUGH THE WEST!!! + // double cosA = (-sinDec * _cosLat + cosDec * _sinLat * cos_ha) / _cosALim; + + // if constexpr (KIND == + // MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one after upper culmination + // az = std::acos(cosA); + // } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one before upper + // // culmination + // az = -std::acos(cosA); + // } + + // MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .X = az, .Y = _altLimit}; + // mcc_tp2tp(coords.time_point, pt.time_point); + + // MccCelestialPoint to_pt{.pair_kind = point->pair_kind}; + // mcc_tp2tp(point->time_point, to_pt.time_point); + + // ret = _transformCoordinates(pt, &to_pt); + // if (!ret) { + // point->X = MccAngle(to_pt.X).normalize(); + // point->Y = MccAngle(to_pt.Y).normalize(); + // } + + // return ret; + // } + + template + error_t intersectPZone(InputT coords, ResultT* point) + requires((mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + (mcc_eqt_hrz_coord_c || mcc_celestial_point_c)) { - double ha, dec, az; + double dec, az; if (point == nullptr) { return MccAltLimitPZErrorCode::ERROR_NULLPTR; @@ -291,7 +377,7 @@ public: error_t ret = MccAltLimitPZErrorCode::ERROR_OK; if constexpr (mcc_eqt_hrz_coord_c) { - ha = coords.HA; + // ha = coords.HA; dec = coords.DEC_APP; } else { MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP}; @@ -302,7 +388,7 @@ public: return ret; } - ha = to_pt.X; + // ha = to_pt.X; dec = to_pt.Y; } @@ -310,11 +396,20 @@ public: auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat; - if (cos_ha > 1.0) { // no intersection + if (cos_ha > 1.0) { // no intersection (outputs are all NaN) // point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC; point->X = std::numeric_limits::quiet_NaN(); point->Y = std::numeric_limits::quiet_NaN(); + if constexpr (mcc_eqt_hrz_coord_c) { + point->HA = std::numeric_limits::quiet_NaN(); + point->RA_APP = std::numeric_limits::quiet_NaN(); + point->DEC_APP = std::numeric_limits::quiet_NaN(); + point->AZ = std::numeric_limits::quiet_NaN(); + point->ZD = std::numeric_limits::quiet_NaN(); + point->ALT = std::numeric_limits::quiet_NaN(); + } + return ret; } @@ -332,13 +427,23 @@ public: MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .X = az, .Y = _altLimit}; mcc_tp2tp(coords.time_point, pt.time_point); - MccCelestialPoint to_pt{.pair_kind = point->pair_kind}; - mcc_tp2tp(point->time_point, to_pt.time_point); + if constexpr (mcc_eqt_hrz_coord_c) { + MccEqtHrzCoords to_pt; + mcc_tp2tp(point->time_point, to_pt.time_point); + ret = _transformCoordinates(pt, &to_pt); - ret = _transformCoordinates(pt, &to_pt); - if (!ret) { - point->X = MccAngle(to_pt.X).normalize(); - point->Y = MccAngle(to_pt.Y).normalize(); + if (!ret) { + mcc_copy_eqt_hrz_coord(to_pt, point); + } + } else { + MccCelestialPoint to_pt{.pair_kind = point->pair_kind}; + mcc_tp2tp(point->time_point, to_pt.time_point); + + ret = _transformCoordinates(pt, &to_pt); + if (!ret) { + point->X = MccAngle(to_pt.X).normalize(); + point->Y = MccAngle(to_pt.Y).normalize(); + } } return ret; @@ -349,6 +454,7 @@ protected: double _cosLat, _sinLat, _absLat, _latLim; std::function _transformCoordinates{}; + std::function _transformCoordinatesEqtHrzCoords{}; error_t getCoord(mcc_celestial_point_c auto const& from_pt, MccCelestialPoint* to_pt) { diff --git a/mcc/mcc_pzone_container.h b/mcc/mcc_pzone_container.h index d2ab2b9..aa443a3 100644 --- a/mcc/mcc_pzone_container.h +++ b/mcc/mcc_pzone_container.h @@ -152,18 +152,41 @@ public: return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC)); }); - _intersectZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) { + // _intersectZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) { + // auto ret = sptr->intersectPZone(pt, res_pt); + + // return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); + // }); + + // _intersectZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) { + // auto ret = sptr->intersectPZone(pt, res_pt); + + // return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); + // }); + + _intersectZoneFuncCPT2CPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) { auto ret = sptr->intersectPZone(pt, res_pt); return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); }); - _intersectZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) { + _intersectZoneFuncEHC2CPT.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) { auto ret = sptr->intersectPZone(pt, res_pt); return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); }); + _intersectZoneFuncCPT2EHC.emplace_back([sptr](const MccCelestialPoint& pt, MccEqtHrzCoords* res_pt) { + auto ret = sptr->intersectPZone(pt, res_pt); + + return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); + }); + + _intersectZoneFuncEHC2EHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccEqtHrzCoords* res_pt) { + auto ret = sptr->intersectPZone(pt, res_pt); + + return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC)); + }); return _inZoneFuncCPT.size(); } @@ -179,8 +202,12 @@ public: _timeFromZoneFuncCPT.clear(); _timeFromZoneFuncEHC.clear(); - _intersectZoneFuncCPT.clear(); - _intersectZoneFuncEHC.clear(); + // _intersectZoneFuncCPT.clear(); + // _intersectZoneFuncEHC.clear(); + _intersectZoneFuncCPT2CPT.clear(); + _intersectZoneFuncEHC2CPT.clear(); + _intersectZoneFuncCPT2EHC.clear(); + _intersectZoneFuncEHC2EHC.clear(); } @@ -298,14 +325,51 @@ public: return forEach(coords, apply_func, _timeFromZoneFuncCPT, _timeFromZoneFuncEHC); } - // template - // error_t intersectPZone(InputT coords, std::ranges::output_range auto* result) - // requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) - template - error_t intersectPZone(InputT coords, R* result) - requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && - std::ranges::output_range> && - mcc_celestial_point_c> + // template + // error_t intersectPZone(InputT coords, R* result) + // requires(mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + // std::ranges::output_range> && + // mcc_celestial_point_c> + // { + // if (result == nullptr) { + // return MccPZoneContainerErrorCode::ERROR_NULLPTR; + // } + + // if (traits::mcc_range_size(*result) < sizePZones()) { + // return MccPZoneContainerErrorCode::ERROR_INVALID_SIZE; + // } + + // // using CPT = std::ranges::range_value_t; + + // MccCelestialPoint pt; + + // auto apply_func = [&](auto& func, auto& pt_arg, size_t i) { + // auto ptr = result->begin(); + // std::ranges::advance(ptr, i); + + // pt.pair_kind = ptr->pair_kind; + // pt.time_point = ptr->time_point; + + // error_t ret = func(pt_arg, &pt); + // if (!ret) { + // // if (traits::mcc_range_size(*result) == i) { + // // std::back_inserter(*result) = CPT(); + // // } + + // mcc_copy_celestial_point(pt, &(*ptr)); + // } + + // return ret; + // }; + + // return forEach(coords, apply_func, _intersectZoneFuncCPT, _intersectZoneFuncEHC); + // } + template + error_t intersectPZone(InputT coords, ResultT* result) + requires((mcc_eqt_hrz_coord_c || mcc_celestial_point_c) && + std::ranges::output_range> && + (mcc_eqt_hrz_coord_c> || + mcc_celestial_point_c>)) { if (result == nullptr) { return MccPZoneContainerErrorCode::ERROR_NULLPTR; @@ -315,30 +379,40 @@ public: return MccPZoneContainerErrorCode::ERROR_INVALID_SIZE; } - // using CPT = std::ranges::range_value_t; - - MccCelestialPoint pt; - auto apply_func = [&](auto& func, auto& pt_arg, size_t i) { auto ptr = result->begin(); std::ranges::advance(ptr, i); - pt.pair_kind = ptr->pair_kind; - pt.time_point = ptr->time_point; + error_t ret; + if constexpr (mcc_eqt_hrz_coord_c) { + MccEqtHrzCoords pt; - error_t ret = func(pt_arg, &pt); - if (!ret) { - // if (traits::mcc_range_size(*result) == i) { - // std::back_inserter(*result) = CPT(); - // } + mcc_tp2tp(ptr->time_point, pt.time_point); - mcc_copy_celestial_point(pt, &(*ptr)); + ret = func(pt_arg, &pt); + if (!ret) { + mcc_copy_eqt_hrz_coord(pt, &(*ptr)); + } + } else { + MccCelestialPoint pt; + + pt.pair_kind = ptr->pair_kind; + mcc_tp2tp(ptr->time_point, pt.time_point); + + ret = func(pt_arg, &pt); + if (!ret) { + mcc_copy_celestial_point(pt, &(*ptr)); + } } return ret; }; - return forEach(coords, apply_func, _intersectZoneFuncCPT, _intersectZoneFuncEHC); + if constexpr (mcc_eqt_hrz_coord_c) { + return forEach(coords, apply_func, _intersectZoneFuncCPT2EHC, _intersectZoneFuncEHC2EHC); + } else { + return forEach(coords, apply_func, _intersectZoneFuncCPT2CPT, _intersectZoneFuncEHC2CPT); + } } @@ -352,8 +426,13 @@ protected: std::vector> _timeFromZoneFuncCPT; std::vector> _timeFromZoneFuncEHC; - std::vector> _intersectZoneFuncCPT; - std::vector> _intersectZoneFuncEHC; + // std::vector> _intersectZoneFuncCPT; + // std::vector> _intersectZoneFuncEHC; + + std::vector> _intersectZoneFuncCPT2CPT; + std::vector> _intersectZoneFuncEHC2CPT; + std::vector> _intersectZoneFuncCPT2EHC; + std::vector> _intersectZoneFuncEHC2EHC; error_t forEach(auto const& coords, auto& apply_func, auto& containerCPT, auto& containerEHC) { diff --git a/mcc/mcc_slewing_model.h b/mcc/mcc_slewing_model.h index fbbcc1a..2dd37db 100644 --- a/mcc/mcc_slewing_model.h +++ b/mcc/mcc_slewing_model.h @@ -255,7 +255,8 @@ public: if (adjust_mode && !_currentParams.slewAndStop) { // do not allow mount speed fall below sideral if constexpr (mccIsEquatorialMount(HardwareT::mountType)) { - if (tdata.speedX < slewing_params_t::sideralRate) { + // turn on sideral rate only if the current position point catches up with the target + if ((tdata.target.HA - tdata.HA) <= 0.0 && tdata.speedX < slewing_params_t::sideralRate) { hw_state.X = (double)tdata.target.X; hw_state.Y = (double)tdata.target.Y; diff --git a/mcc/mcc_tracking_model.h b/mcc/mcc_tracking_model.h index 3de9e9f..a81f72d 100644 --- a/mcc/mcc_tracking_model.h +++ b/mcc/mcc_tracking_model.h @@ -115,7 +115,7 @@ public: if constexpr (mccIsEquatorialMount(PcmT::mountType)) { - double dha_min = 0.0, dha; + double dha_min = std::numbers::pi * 2.0, dha; // find the closest pzone @@ -134,7 +134,7 @@ public: } } - if (utils::isEqual(dha_min, 0.0)) { // no intersections + if (utils::isEqual(dha_min, std::numbers::pi * 2.0)) { // no intersections no_intersects = true; cpt.X = tdata.HA + 710.0_mins; // 12h - 10min cpt.Y = tdata.DEC_APP;