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
{
public:
static constexpr auto mountType = MOUNT_CONFIG::mountType;
typedef MOUNT_CONFIG mount_config_t;
// typedef MOUNT_TELEMETRY mount_telemetry_t;
typedef decltype(mount_config_t::telemetry) mount_telemetry_t;
@ -175,6 +173,23 @@ protected:
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

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) {
typename T::coord_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
// 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)
{ 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;
// 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 std::chrono::system_clock::time_point time_point_t;
static constexpr pz_duration_t infDuration{std::numeric_limits<double>::infinity()};
static constexpr pz_duration_t zeroDuration{0.0};
static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
static constexpr duration_t zeroDuration{0.0};
//
// 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
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)) {
return zeroDuration;
}
if (!doesObjectReachZone(telemetry_data)) {
return infDuration;
return infiniteDuration;
}
if constexpr (KIND ==
@ -96,12 +96,16 @@ public:
}
// 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)) {
return zeroDuration;
}
if (!doesObjectExitFromZone(telemetry_data)) {
return infiniteDuration;
}
if (!doesObjectReachZone(telemetry_data)) {
return zeroDuration;
}
@ -145,20 +149,20 @@ public:
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
pz_duration_t timeTo(const XT& x,
const YT& y,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
duration_t timeTo(const XT& x,
const YT& y,
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>
pz_duration_t timeFrom(const XT& x,
const YT& y,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
duration_t timeFrom(const XT& x,
const YT& y,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
return pz_duration_t{0.0};
return duration_t{0.0};
}
private:
@ -186,13 +190,36 @@ private:
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)) /
std::cos(telemetry_data.mntDEC) / std::cos(_latitude);
if (cos_ha > 1.0) { // should not be!
return infDuration;
return infiniteDuration;
}
double ha;
@ -202,17 +229,6 @@ private:
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
if (time_ang < 0.0) { // next day
@ -221,7 +237,7 @@ private:
time_ang /= mcc_sideral_to_UT1_ratio; // to UT1 time scale
return pz_duration_t{time_ang.seconds()};
return duration_t{time_ang.seconds()};
}
};