#pragma once /* MOUNT CONTROL COMPONENTS LIBRARY */ /* COMMON DEFINITIONS FOR SIMPLE SLEWING, TRACKING AND GUIDING MODEL IMPLEMENTATIONS */ #include #include "mcc_angle.h" #include "mcc_generics.h" namespace mcc { struct MccSimpleMovingModelParams { // ******* common for all modes ******* // mean celestial rate static constexpr double sideralRate = 15.0410686_arcsecs; // in radians per second // timeout to telemetry updating std::chrono::seconds telemetryTimeout{3}; // minimal time to prohibited zone (at current speed in slewing mode). if it is lesser then exit with error std::chrono::seconds minTimeToPZone{10}; // ******* slewing mode ******* bool slewAndStop{false}; // slew to target and stop mount // coordinates difference to stop slewing (in radians) double slewToleranceRadius{5.0_arcsecs}; // target-mount coordinate difference to start adjusting of slewing (in radians) double adjustCoordDiff{slewToleranceRadius * 10.0}; // slew process timeout std::chrono::seconds slewTimeout{3600}; double slewXRate{0.0}; // maximal slewing rate (0 means move with maximal allowed rate) double slewYRate{0.0}; // maximal slewing rate (0 means move with maximal allowed rate) std::chrono::milliseconds adjustCycleInterval{500}; // minimum time between two successive adjustments double adjustXRate{5.0_arcmins}; // maximal adjusting rate (a rate at the final slewing stage) double adjustYRate{5.0_arcmins}; // maximal adjusting rate (a rate at the final slewing stage) // ******* tracking mode ******* double trackSpeedX{}; double trackSpeedY{}; // ******* guiding mode ******* double correctionRange[2]{0.3_arcsecs, 3.0_arcsecs}; 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