...
This commit is contained in:
@@ -98,6 +98,43 @@ concept mcc_logger_c = requires(T t, const T t_const) {
|
||||
};
|
||||
|
||||
|
||||
/* A CONCEPT FOR COORDINATE REPRESENTATION */
|
||||
|
||||
// it is a fundametal floating-point type or
|
||||
// a class that can be constructed from or converted to the double fundametal type
|
||||
template <typename T>
|
||||
concept mcc_coord_t = std::floating_point<T> || (std::convertible_to<T, double> && std::constructible_from<T, double>);
|
||||
|
||||
|
||||
/* A CONCEPT FOR UTC TIME POINT REPRESENTATION */
|
||||
|
||||
// it is a std::chrono::sys_time<Duration> or
|
||||
// fundamental arithmetic type that represent number of seconds after the 00:00:00 of 1 January 1970 (UNIX time)
|
||||
template <typename T>
|
||||
concept mcc_utc_time_point_c = mcc_systime_c<T> || std::is_arithmetic_v<T>;
|
||||
|
||||
/* A CONCEPT FOR CLASS TO REPRESENT CELESTIAL POINT */
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_celestial_point_c = requires(T t) {
|
||||
// a type to represent UTC time point of coordinates
|
||||
// it's clear that this makes sense for apparent coordinates
|
||||
typename T::time_point_t;
|
||||
|
||||
// coordinates pair type (e.g. IRCS RA,DEC, Az,Alt and so on)
|
||||
requires std::same_as<decltype(t.coordPairKind), MccCoordPairKind>;
|
||||
|
||||
typename T::coord_t;
|
||||
|
||||
// co-longitude (e.g. RA or Az)
|
||||
requires std::same_as<decltype(t.x), typename T::coord_t>;
|
||||
|
||||
// co-latitude (e.g. DEC or ZD)
|
||||
requires std::same_as<decltype(t.y), typename T::coord_t>;
|
||||
};
|
||||
|
||||
|
||||
/* ASTROMETRY-RELATED COMPUTATION ENGINE */
|
||||
|
||||
template <typename T>
|
||||
@@ -128,10 +165,10 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) {
|
||||
} -> std::same_as<typename T::error_t>;
|
||||
|
||||
// observed place to ICRS RA and DEC: obs2icrs(type, x, y, jd, ra_icrs, dec_icrs)
|
||||
// (x,y) = (AZ, ZD) if type = MccCoordPairKind::COORDS_KIND_AZZD
|
||||
// (x,y) = (AZ, ALT) if type = MccCoordPairKind::COORDS_KIND_AZALT
|
||||
// (x,y) = (HA, DEC) if type = MccCoordPairKind::COORDS_KIND_HADEC_APP
|
||||
// (x,y) = (RA, DEC) if type = MccCoordPairKind::COORDS_KIND_RADEC_APP
|
||||
// (x, y) = (AZ, ZD) if type == MccCoordPairKind::COORDS_KIND_AZZD
|
||||
// (x, y) = (AZ, ALT) if type == MccCoordPairKind::COORDS_KIND_AZALT
|
||||
// (x, y) = (HA, DEC) if type == MccCoordPairKind::COORDS_KIND_HADEC_APP
|
||||
// (x, y) = (RA, DEC) if type == MccCoordPairKind::COORDS_KIND_RADEC_APP
|
||||
{
|
||||
t.obs2icrs(std::declval<MccCoordPairKind>(), std::declval<typename T::coord_t>(),
|
||||
std::declval<typename T::coord_t>(), std::declval<typename T::juldate_t>(),
|
||||
@@ -157,6 +194,26 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) {
|
||||
std::declval<typename T::pa_t&>())
|
||||
} -> std::same_as<typename T::error_t>;
|
||||
|
||||
|
||||
// transform coordinates according to its pair types and time points (a high-level wrapper):
|
||||
//
|
||||
// coord2coord(coord_pair_kind_from, x_from, y_from, time_point_from, coord_pair_kind_to, x_to, y_to, time_point_to)
|
||||
//
|
||||
// (x_*, y_*) = (AZ, ZD) if coord_pair_kind_* == MccCoordPairKind::COORDS_KIND_AZZD
|
||||
// (x_*, y_*) = (AZ, ALT) if coord_pair_kind_* == MccCoordPairKind::COORDS_KIND_AZALT
|
||||
// (x_*, y_*) = (HA, DEC) if coord_pair_kind_* == MccCoordPairKind::COORDS_KIND_HADEC_APP (apparent)
|
||||
// (x_*, y_*) = (RA, DEC) if coord_pair_kind_* == MccCoordPairKind::COORDS_KIND_RADEC_APP (apparent)
|
||||
// (x_*, y_*) = (RA, DEC) if coord_pair_kind_* == MccCoordPairKind::COORDS_KIND_RADEC_ICRS (ICRS)
|
||||
//
|
||||
// if coord_pair_kind_* and time_point_* are equal then x_to = x_from, y_to = y_from
|
||||
{
|
||||
t.coord2coord(std::declval<MccCoordPairKind>(), std::declval<typename T::coord_t>(),
|
||||
std::declval<typename T::coord_t>(), std::declval<typename T::time_point_t>(),
|
||||
std::declval<MccCoordPairKind>(), std::declval<typename T::coord_t&>(),
|
||||
std::declval<typename T::coord_t&>(), std::declval<typename T::time_point_t>())
|
||||
} -> std::same_as<typename T::error_t>;
|
||||
|
||||
|
||||
// compute equation of origins
|
||||
{
|
||||
t.eqOrigins(std::declval<typename T::juldate_t>(), std::declval<typename T::eo_t&>())
|
||||
@@ -355,23 +412,6 @@ concept mcc_mount_telemetry_c = requires(T t, const T t_const) {
|
||||
};
|
||||
|
||||
|
||||
/* A CONCEPT FOR CLASS TO REPRESENT CELESTIAL POINT */
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_celestial_point_c = requires(T t) {
|
||||
// input coordinates pair type (e.g. IRCS RA,DEC, Az,Alt and so on)
|
||||
requires std::same_as<decltype(t.coordPairKind), MccCoordPairKind>;
|
||||
|
||||
typename T::coord_t;
|
||||
|
||||
// co-longitude (e.g. RA or Az)
|
||||
requires std::same_as<decltype(t.x), typename T::coord_t>;
|
||||
|
||||
// co-latitude (e.g. DEC or ZD)
|
||||
requires std::same_as<decltype(t.y), typename T::coord_t>;
|
||||
};
|
||||
|
||||
|
||||
// /* SLEW PARAMETERS */
|
||||
|
||||
@@ -420,14 +460,85 @@ concept mcc_guiding_model_c = requires(T t) {
|
||||
|
||||
/* MOUNT PROHIBITED ZONE */
|
||||
|
||||
|
||||
struct MccPzoneAbstractInterface {
|
||||
bool inZone(this auto&& self, mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::inZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).inZone(telemetry_data);
|
||||
}
|
||||
}
|
||||
|
||||
bool inZone(this auto&& self, mcc_celestial_point_c auto const& sky_point)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::inZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).inZone(sky_point);
|
||||
}
|
||||
}
|
||||
|
||||
// returns a time to reach the zone
|
||||
auto timeTo(this auto&& self, mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::timeTo method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).timeTo(telemetry_data);
|
||||
}
|
||||
}
|
||||
|
||||
auto timeTo(this auto&& self, mcc_celestial_point_c auto const& sky_point)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::timeTo method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).timeTo(sky_point);
|
||||
}
|
||||
}
|
||||
|
||||
// returns a time to exit from the zone
|
||||
auto timeFrom(this auto&& self, mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::timeFrom method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).timeFrom(telemetry_data);
|
||||
}
|
||||
}
|
||||
|
||||
auto timeFrom(this auto&& self, mcc_celestial_point_c auto const& sky_point)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPzoneAbstractInterface>) {
|
||||
static_assert(false, "Call an empty MccPzoneAbstractInterface::timeFrom method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).timeFrom(sky_point);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename TelemetryDataT>
|
||||
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::coord_t;
|
||||
// typename T::time_point_t;
|
||||
requires mcc_time_duration_c<typename T::duration_t>;
|
||||
|
||||
// static constexpr member to represent inifite duration
|
||||
// static constexpr member to represent infinite duration
|
||||
requires requires {
|
||||
requires std::same_as<decltype(T::infiniteDuration), typename T::duration_t const>;
|
||||
[]() {
|
||||
@@ -446,46 +557,11 @@ concept mcc_prohibited_zone_c =
|
||||
};
|
||||
|
||||
|
||||
// the type 'T' must define a static constexpr member of type MccCoordPairKind
|
||||
// to declarate type of coordinate pair used to describe the zone.
|
||||
// This coordinate pair must be used as input in the 'inZone' class method.
|
||||
// requires requires {
|
||||
// requires std::same_as<decltype(T::zoneCoordPairKind), const MccCoordPairKind>;
|
||||
// []() {
|
||||
// constexpr MccCoordPairKind val = T::zoneCoordPairKind;
|
||||
// return val;
|
||||
// }(); // to ensure that 'zoneCoordPairKind' can be used at compile-time context
|
||||
// };
|
||||
|
||||
// return a name of the zone
|
||||
{ t_const.name() } -> mcc_formattable;
|
||||
|
||||
|
||||
// check if given coordinates are into the zone.
|
||||
// input coordinates interpretation is in according to 'zoneCoordPairKind' static constexpr member
|
||||
// {
|
||||
// t.inZone(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>())
|
||||
// } -> std::convertible_to<bool>;
|
||||
|
||||
|
||||
// // for given coordinates and time the method computes a time to reach the zone.
|
||||
// // implementation of the method must assume that input coordinates are apparent RA and DEC at given time
|
||||
// // point, while the time point is one from which computation should be performed (e.g. current time moment)
|
||||
// {
|
||||
// t.timeTo(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
|
||||
// std::declval<typename T::time_point_t>())
|
||||
// } -> mcc_time_duration_c;
|
||||
|
||||
|
||||
// // for given coordinates and time the method computes a time to exit from the zone
|
||||
// {
|
||||
// t.timeFrom(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
|
||||
// std::declval<typename T::time_point_t>())
|
||||
// } -> mcc_time_duration_c;
|
||||
|
||||
// requires for the methods above with the first argument of type
|
||||
// 'const mcc_mount_telemetry_data_c&' (const lvalue reference)
|
||||
|
||||
{ t.inZone(std::declval<const TelemetryDataT&>()) } -> std::convertible_to<bool>;
|
||||
|
||||
// a time duration to reach the zone.
|
||||
@@ -500,12 +576,129 @@ concept mcc_prohibited_zone_c =
|
||||
{ t.timeFrom(std::declval<const TelemetryDataT&>()) } -> std::same_as<typename T::duration_t>;
|
||||
};
|
||||
|
||||
// an input range of prohibited zones
|
||||
template <typename T, typename TelemetryDataT>
|
||||
concept mcc_irange_of_pzones_c = mcc_mount_telemetry_data_c<TelemetryDataT> && std::ranges::input_range<T> &&
|
||||
mcc_prohibited_zone_c<std::ranges::range_value_t<T>, TelemetryDataT>;
|
||||
// // an input range of prohibited zones
|
||||
// template <typename T, typename TelemetryDataT>
|
||||
// concept mcc_irange_of_pzones_c = mcc_mount_telemetry_data_c<TelemetryDataT> && std::ranges::input_range<T> &&
|
||||
// mcc_prohibited_zone_c<std::ranges::range_value_t<T>, TelemetryDataT>;
|
||||
|
||||
|
||||
// // a concept for a callable with the first argument of type satisfied to 'mcc_prohibited_zone_c'
|
||||
// template <typename T, typename TelemetryDataT>
|
||||
// concept mcc_pzone_foreach_func_c = mcc_is_callable<T> && mcc_mount_telemetry_data_c<TelemetryDataT> &&
|
||||
// mcc_prohibited_zone_c<mcc_func_arg1_t<T>, TelemetryDataT>;
|
||||
|
||||
|
||||
// There is no way to declare a concept of class with templated method so one needs to define
|
||||
// a generic interface of prohibited zones holder/container explicitly
|
||||
template <mcc_mount_telemetry_data_c TelemetryDataT>
|
||||
struct MccPZoneAbstractContainer {
|
||||
virtual ~MccPZoneAbstractContainer() = default;
|
||||
|
||||
// must return a size of the container after the addition of the given zone
|
||||
template <mcc_prohibited_zone_c<TelemetryDataT> ZT>
|
||||
size_t pzAddZone(this auto&& self, ZT zone)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzAddZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzAddZone(std::move(zone));
|
||||
}
|
||||
}
|
||||
|
||||
// clear the container
|
||||
auto pzClearZones(this auto&& self)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzClearZones method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzClearZones();
|
||||
}
|
||||
}
|
||||
|
||||
// must return the size of the container (number of zones)
|
||||
size_t pzSize(this auto&& self)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzSize method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// must return true if the given telemetry coordinates are in any of zones in the containe and
|
||||
// false otherwise
|
||||
template <typename RT>
|
||||
bool pzInZone(this auto&& self, const TelemetryDataT& tdata, RT& result)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzInZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzInZone(tdata, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RT>
|
||||
auto pzTimeTo(this auto&& self, const TelemetryDataT& tdata, RT& result)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzInZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzTimeTo(tdata, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RT>
|
||||
auto pzTimeFrom(this auto&& self, const TelemetryDataT& tdata, RT& result)
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
if constexpr (std::same_as<std::remove_cvref_t<self_t>, MccPZoneAbstractContainer>) {
|
||||
static_assert(false, "Call an empty MccPZoneAbstractContainer::pzInZone method");
|
||||
} else {
|
||||
return std::forward<self_t>(self).pzTimeFrom(tdata, result);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
MccPZoneAbstractContainer() = default;
|
||||
};
|
||||
|
||||
// a full concept for prohibited zones container
|
||||
template <typename T, typename TelemetryDataT>
|
||||
concept mcc_mount_pzones_container_c = std::derived_from<T, MccPZoneAbstractContainer<TelemetryDataT>> && requires {
|
||||
// common time duration type for zones 'timeTo' and 'timeFrom' methods
|
||||
requires mcc_time_duration_c<typename T::duration_t>;
|
||||
|
||||
// static constexpr member to represent infinite duration
|
||||
requires requires {
|
||||
requires std::same_as<decltype(T::infiniteDuration), typename T::duration_t const>;
|
||||
[]() {
|
||||
constexpr auto val = T::infiniteDuration;
|
||||
return val;
|
||||
};
|
||||
};
|
||||
|
||||
// static constexpr member to represent zero duration
|
||||
requires requires {
|
||||
requires std::same_as<decltype(T::zeroDuration), typename T::duration_t const>;
|
||||
[]() {
|
||||
constexpr auto val = T::zeroDuration;
|
||||
return val;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* MOUNT GENERIC CONTROLS */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user