This commit is contained in:
Timur A. Fatkhullin 2025-07-16 18:06:59 +03:00
parent 7e8d7eaa6b
commit 49db4aef08
3 changed files with 83 additions and 32 deletions

View File

@ -29,8 +29,6 @@ template <traits::mcc_mount_config_c MOUNT_CONFIG>
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger
{ {
public: public:
static constexpr auto mountType = MOUNT_CONFIG::mountType;
typedef MOUNT_CONFIG mount_config_t; typedef MOUNT_CONFIG mount_config_t;
// typedef MOUNT_TELEMETRY mount_telemetry_t; // typedef MOUNT_TELEMETRY mount_telemetry_t;
typedef decltype(mount_config_t::telemetry) mount_telemetry_t; typedef decltype(mount_config_t::telemetry) mount_telemetry_t;
@ -175,6 +173,23 @@ protected:
std::vector<pz_funcs_t> _pzFuncs{}; std::vector<pz_funcs_t> _pzFuncs{};
template <typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
auto forEachPZone(FuncT&& func, std::tuple<ZTs...>& zones)
{
std::array<traits::mcc_retval_t<FuncT>, sizeof...(ZTs)> result;
forEachPZoneHelper(std::forward<FuncT>(func), zones, result);
}
template <size_t I = 0, typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
auto forEachPZoneHelper(FuncT&& func, std::tuple<ZTs...>& zones, auto& result)
requires(I < sizeof...(ZTs))
{
std::get<I>(result) = std::forward<FuncT>(func)(std::get<I>(zones), mountTelemetryData());
forEachPZoneHelper<I + 1>(std::forward<FuncT>(func), zones, result);
}
}; // end of MccMount class }; // end of MccMount class

View File

@ -301,6 +301,17 @@ concept mcc_prohibited_zone_c =
mcc_mount_telemetry_data_c<TelemetryDataT> && std::movable<T> && requires(T t, const T t_const) { mcc_mount_telemetry_data_c<TelemetryDataT> && std::movable<T> && requires(T t, const T t_const) {
typename T::coord_t; typename T::coord_t;
typename T::time_point_t; typename T::time_point_t;
requires mcc_time_duration_c<typename T::duration_t>;
// static constexpr member to represent inifite duration
requires requires {
requires std::same_as<decltype(T::infiniteDuration), typename T::duration_t>;
[]() {
constexpr auto val = T::infiniteDuration;
return val;
};
};
// the type 'T' must define a static constexpr member of type MccCoordPairKind // the type 'T' must define a static constexpr member of type MccCoordPairKind
// to declarate type of coordinate pair used to describe the zone. // to declarate type of coordinate pair used to describe the zone.
@ -343,8 +354,17 @@ concept mcc_prohibited_zone_c =
// 'const mcc_mount_telemetry_data_c&' (const lvalue reference) // 'const mcc_mount_telemetry_data_c&' (const lvalue reference)
{ t.inZone(std::declval<const TelemetryDataT&>()) } -> std::convertible_to<bool>; { t.inZone(std::declval<const TelemetryDataT&>()) } -> std::convertible_to<bool>;
{ t.timeTo(std::declval<const TelemetryDataT&>()) } -> mcc_time_duration_c;
{ t.timeFrom(std::declval<const TelemetryDataT&>()) } -> mcc_time_duration_c; // a time duration to reach the zone.
// special values the method must return:
// 'infiniteDuration' if the given sky point never reaches the zone
// 0 (zero duration) if the given sky point is already in the zone or it never exits from the zone
{ t.timeTo(std::declval<const TelemetryDataT&>()) } -> std::same_as<typename T::duration_t>;
// a time duration to exit from the zone.
// special values the method must return:
// 0 (zero duration) if the given sky point already exited from the zone or it never reaches the zone
{ t.timeFrom(std::declval<const TelemetryDataT&>()) } -> std::same_as<typename T::duration_t>;
}; };

View File

@ -37,13 +37,13 @@ public:
static constexpr MccAltLimitKind altLimitKind = KIND; static constexpr MccAltLimitKind altLimitKind = KIND;
// floating-point time duration (seconds) // floating-point time duration (seconds)
typedef std::chrono::duration<double> pz_duration_t; typedef std::chrono::duration<double> duration_t;
typedef MccAngle coord_t; typedef MccAngle coord_t;
typedef std::chrono::system_clock::time_point time_point_t; typedef std::chrono::system_clock::time_point time_point_t;
static constexpr pz_duration_t infDuration{std::numeric_limits<double>::infinity()}; static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
static constexpr pz_duration_t zeroDuration{0.0}; static constexpr duration_t zeroDuration{0.0};
// //
// TODO: add context (e.g. TT-TAI, UT1-UTC, geo location and so on)!!! // TODO: add context (e.g. TT-TAI, UT1-UTC, geo location and so on)!!!
@ -76,14 +76,14 @@ public:
// returns a time to reach the zone // returns a time to reach the zone
pz_duration_t timeTo(traits::mcc_mount_telemetry_data_c auto const& telemetry_data) duration_t timeTo(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
{ {
if (inZone(telemetry_data)) { if (inZone(telemetry_data)) {
return zeroDuration; return zeroDuration;
} }
if (!doesObjectReachZone(telemetry_data)) { if (!doesObjectReachZone(telemetry_data)) {
return infDuration; return infiniteDuration;
} }
if constexpr (KIND == if constexpr (KIND ==
@ -96,12 +96,16 @@ public:
} }
// returns a time to exit from the zone // returns a time to exit from the zone
pz_duration_t timeFrom(traits::mcc_mount_telemetry_data_c auto const& telemetry_data) duration_t timeFrom(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
{ {
if (!inZone(telemetry_data)) { if (!inZone(telemetry_data)) {
return zeroDuration; return zeroDuration;
} }
if (!doesObjectExitFromZone(telemetry_data)) {
return infiniteDuration;
}
if (!doesObjectReachZone(telemetry_data)) { if (!doesObjectReachZone(telemetry_data)) {
return zeroDuration; return zeroDuration;
} }
@ -145,20 +149,20 @@ public:
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT> template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
pz_duration_t timeTo(const XT& x, duration_t timeTo(const XT& x,
const YT& y, const YT& y,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{ {
return pz_duration_t{std::numeric_limits<double>::infinity()}; return duration_t{std::numeric_limits<double>::infinity()};
} }
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT> template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
pz_duration_t timeFrom(const XT& x, duration_t timeFrom(const XT& x,
const YT& y, const YT& y,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now()) traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{ {
return pz_duration_t{0.0}; return duration_t{0.0};
} }
private: private:
@ -186,13 +190,36 @@ private:
return true; return true;
} }
pz_duration_t compute(traits::mcc_mount_telemetry_data_c auto const& telemetry_data, bool before_upper_culm)
bool doesObjectExitFromZone(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
{
// check for limit conditions
auto dd = std::abs(telemetry_data.mntDEC);
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
dd -= _altLimit;
if (-dd <= -_lat_lim) { // always below altitude limit
return false;
}
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
if ((dd >= (_abs_lat - _altLimit)) || (dd <= (_abs_lat + _altLimit))) { // always above altitude limit
return false;
}
} else {
static_assert(false, "UNKNOWN ALTITUDE LIMIT TYPE!");
}
return true;
}
duration_t compute(traits::mcc_mount_telemetry_data_c auto const& telemetry_data, bool before_upper_culm)
{ {
double cos_ha = (std::sin(_altLimit) - std::sin(telemetry_data.mntDEC) * std::sin(_latitude)) / double cos_ha = (std::sin(_altLimit) - std::sin(telemetry_data.mntDEC) * std::sin(_latitude)) /
std::cos(telemetry_data.mntDEC) / std::cos(_latitude); std::cos(telemetry_data.mntDEC) / std::cos(_latitude);
if (cos_ha > 1.0) { // should not be! if (cos_ha > 1.0) { // should not be!
return infDuration; return infiniteDuration;
} }
double ha; double ha;
@ -202,17 +229,6 @@ private:
ha = std::acos(cos_ha); // HA after upper culmination!! ha = std::acos(cos_ha); // HA after upper culmination!!
} }
// if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time moment after upper
// culmination!!!
// ha = std::acos(cos_ha); // HA after upper culmination!!
// } else if constexpr (KIND ==
// MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time moment before upper
// culmination!!!
// ha = -std::acos(cos_ha); // HA before upper culmination
// } else {
// static_assert(false, "UNKNOWN ALTITUDE LIMIT TYPE!");
// }
MccAngle time_ang = ha - telemetry_data.mntHA; // in sideral time scale MccAngle time_ang = ha - telemetry_data.mntHA; // in sideral time scale
if (time_ang < 0.0) { // next day if (time_ang < 0.0) { // next day
@ -221,7 +237,7 @@ private:
time_ang /= mcc_sideral_to_UT1_ratio; // to UT1 time scale time_ang /= mcc_sideral_to_UT1_ratio; // to UT1 time scale
return pz_duration_t{time_ang.seconds()}; return duration_t{time_ang.seconds()};
} }
}; };