#pragma once /* MOUNT CONTROL COMPONENTS LIBRARY */ /* COMMON DECLARATION FOR SLEW AND GUIDING MODELS GENERIC IMPLEMENTATIONS */ #include "mcc_mount_concepts.h" namespace mcc { /* DEFAULT CLASS TO REPRESENT CELESTIAL POINT */ struct MccCelestialPoint { typedef double coord_t; MccCoordPairKind coordPairKind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; coord_t x{0.0}, y{0.0}; }; static_assert(traits::mcc_celestial_point_c, "MccCelestialPoint INVALID DECLARATION!"); /* COMMON SLEW-AND-GUIDING POINT CLASS DEFINITION */ template struct MccSimpleSlewAndGuidingModelParams { // ******* default constants ******* static constexpr size_t defaultWithinToleranceCycleNumber = 10; static constexpr size_t defaultMaxAdjustingCycleNumber = 100; // common parameters // timeout to wait telemetry update (in seconds, as floating-point) std::chrono::duration telemetryUpdateTimeout{1.0}; // ******* slewing-related parameters ******* // target-mount coordinate difference to start adjusting of slewing (in radians) coord_t adjustCoordDiff{(double)MccAngle{10.0_degs}}; // coordinates difference to stop slewing (in radians) coord_t slewToleranceRadius{(double)MccAngle{5.0_arcsecs}}; // slew process timeout std::chrono::seconds slewTimeout{3600}; std::chrono::duration telemetryPollingInterval{0.1}; // if true - stop mount after the slewing bool stopAfterSlew{false}; coord_t slewXRate{0.0}; // maximal slewing rate (0 means move with maximal allowed rate) coord_t slewYRate{0.0}; // maximal slewing rate (0 means move with maximal allowed rate) coord_t adjustXRate{(double)MccAngle{5.0_arcmins}}; // maximal adjusting rate (a rate at the final slewing stage) coord_t adjustYRate{(double)MccAngle{5.0_arcmins}}; // maximal adjusting rate (a rate at the final slewing stage) // number of consecutive measurements within slewToleranceRadius radius to stop adjusting of slewing size_t withinToleranceCycleNumber{defaultWithinToleranceCycleNumber}; // maximal allowed number of adjusting cycles size_t maxAdjustingCycleNumber{defaultMaxAdjustingCycleNumber}; // ******* guiding-related parameters ******* coord_t correctionRange[2]{(double)MccAngle(0.3_arcsecs), (double)MccAngle(5.0_arcsecs)}; bool dualAxisGuiding{true}; // mount must be of an equatorial type: false means guiding along only HA-axis }; struct MccSlewAndGuidingPoint : MccCelestialPoint, MccSimpleSlewAndGuidingModelParams { typedef MccSimpleSlewAndGuidingModelParams slew_guiding_params_t; }; /* CHECK FOR CURRENT MOUNT POSITION IN PROHIBITED ZONES */ template ... ZTs> auto mccCheckInZonePZTuple(const TelemetryDataT& telemetry_data, const std::tuple& tuple_zones, std::array& in_zone) { const auto p_tdata = &telemetry_data; const auto p_tuple_zones = &tuple_zones; const auto p_in_zone = &in_zone; [p_tdata, p_tuple_zones, p_in_zone](std::index_sequence) { (((*p_in_zone)[Is] = std::get(*p_tuple_zones).inZone(*p_tdata)), ...); }(std::make_index_sequence{}); return [p_in_zone](std::index_sequence) { return ((*p_in_zone)[Is] || ...); }(std::make_index_sequence{}); } template RT, std::ranges::output_range ResT> auto mccCheckInZonePZRange(const TelemetryDataT& telemetry_data, const RT& pzones, ResT& result) { bool in_zone = false; auto Npz = std::ranges::distance(pzones); if (!Npz) { return in_zone; } auto res_sz = std::ranges::distance(result); bool ok; size_t i = 1; auto res_iter = result.begin(); for (auto& el : pzones) { ok = el.inZone(telemetry_data); in_zone |= ok; if (i > res_sz) { std::back_inserter(result) = ok; } else { std::ranges::advance(res_iter, 1); *res_iter = ok; } ++i; } return in_zone; } } // namespace mcc