mountcontrol/cxx/mcc_slew_guiding_model_common.h
2025-08-08 23:50:55 +03:00

139 lines
4.5 KiB
C++

#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;
typedef std::chrono::system_clock::time_point time_point_t;
MccCoordPairKind coordPairKind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
coord_t x{0.0}, y{0.0};
};
static_assert(traits::mcc_celestial_point_c<MccCelestialPoint>, "MccCelestialPoint INVALID DECLARATION!");
/* COMMON SLEW-AND-GUIDING POINT CLASS DEFINITION */
template <typename coord_t>
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<double> 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<double> 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<typename MccCelestialPoint::coord_t> {
typedef MccSimpleSlewAndGuidingModelParams<typename MccCelestialPoint::coord_t> slew_guiding_params_t;
};
/* CHECK FOR CURRENT MOUNT POSITION IN PROHIBITED ZONES */
template <traits::mcc_mount_telemetry_data_c TelemetryDataT, traits::mcc_prohibited_zone_c<TelemetryDataT>... ZTs>
auto mccCheckInZonePZTuple(const TelemetryDataT& telemetry_data,
const std::tuple<ZTs...>& tuple_zones,
std::array<bool, sizeof...(ZTs)>& 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]<size_t... Is>(std::index_sequence<Is...>) {
(((*p_in_zone)[Is] = std::get<Is>(*p_tuple_zones).inZone(*p_tdata)), ...);
}(std::make_index_sequence<sizeof...(ZTs)>{});
return [p_in_zone]<size_t... Is>(std::index_sequence<Is...>) {
return ((*p_in_zone)[Is] || ...);
}(std::make_index_sequence<sizeof...(ZTs)>{});
}
template <traits::mcc_mount_telemetry_data_c TelemetryDataT,
traits::mcc_irange_of_pzones_c<TelemetryDataT> RT,
std::ranges::output_range<bool> 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