...
This commit is contained in:
@@ -29,6 +29,7 @@ template <MccAltLimitKind KIND = MccAltLimitKind::MIN_ALT_LIMIT>
|
||||
class MccAltLimitPZ
|
||||
// class MccAltLimitPZ : public MccProhibitedZone
|
||||
{
|
||||
protected:
|
||||
static constexpr auto pi2 = std::numbers::pi * 2.0;
|
||||
|
||||
public:
|
||||
@@ -36,16 +37,16 @@ public:
|
||||
|
||||
static constexpr MccAltLimitKind altLimitKind = KIND;
|
||||
|
||||
typedef MccAngle coord_t;
|
||||
// floating-point time duration (seconds)
|
||||
typedef std::chrono::duration<double> duration_t;
|
||||
|
||||
typedef MccAngle coord_t;
|
||||
typedef std::chrono::system_clock::time_point time_point_t;
|
||||
|
||||
static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
||||
static constexpr duration_t zeroDuration{0.0};
|
||||
|
||||
MccAltLimitPZ(const MccAngle& alt_limit, const MccAngle& lat)
|
||||
MccAltLimitPZ(const coord_t& alt_limit, const coord_t& lat, traits::mcc_astrom_engine_c auto* astrom_engine)
|
||||
// : MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
||||
// : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||
// : "ALTLIMIT-UNKNOWN"),
|
||||
@@ -53,6 +54,21 @@ public:
|
||||
{
|
||||
_lat_lim = pi2 - _abs_lat;
|
||||
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
|
||||
|
||||
using astrom_engine_t = decltype(*astrom_engine);
|
||||
using astrom_coord_t = typename astrom_engine_t::coord_t;
|
||||
|
||||
static_assert(std::convertible_to<coord_t, astrom_coord_t>,
|
||||
"ASTROMETRY ENGINE AND THE ZONE COORDINATE TYPE ARE NOT COMPATIBLE!");
|
||||
static_assert(std::convertible_to<astrom_coord_t, coord_t>,
|
||||
"ASTROMETRY ENGINE AND THE ZONE COORDINATE TYPE ARE NOT COMPATIBLE!");
|
||||
|
||||
_coord2coord = [astrom_engine, this](MccCoordPairKind kind_from, coord_t x_from, coord_t y_from,
|
||||
time_point_t tpoint, MccCoordPairKind kind_to, coord_t& x_to,
|
||||
coord_t& y_to) {
|
||||
auto err = astrom_engine->coord2coord(kind_from, std::move(x_from), std::move(y_from), tpoint, kind_to,
|
||||
x_to, y_to, tpoint);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -118,59 +134,84 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
// bool inZone(const XT& x, const YT& y, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
bool inZone(const XT& x, const YT& y)
|
||||
bool inZone(traits::mcc_celestial_point_c auto const& target)
|
||||
{
|
||||
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
||||
coord_t alt, az;
|
||||
|
||||
if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) { // trivial case
|
||||
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
|
||||
return y <= _altLimit;
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
|
||||
return y >= _altLimit;
|
||||
}
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZZD) { // trivial case
|
||||
// return inZone(x, MccAngleALT(std::numbers::pi / 2 - (double)y), utc);
|
||||
return inZone(x, MccAngleALT(std::numbers::pi / 2 - (double)y));
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
// implementation ...
|
||||
return false;
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
|
||||
// implementation ...
|
||||
return false;
|
||||
} else {
|
||||
throw std::system_error(std::make_error_code(std::errc::operation_not_supported));
|
||||
_coord2coord(target.coordPairKind, target.x, target.y, target.time_point, MccCoordPairKind::COORDS_KIND_AZALT,
|
||||
az, alt);
|
||||
|
||||
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
|
||||
return alt <= _altLimit;
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
|
||||
return alt >= _altLimit;
|
||||
}
|
||||
}
|
||||
|
||||
duration_t timeTo(traits::mcc_celestial_point_c auto const& target)
|
||||
{
|
||||
coord_t ha, dec;
|
||||
|
||||
if (inZone(target)) {
|
||||
return zeroDuration;
|
||||
}
|
||||
|
||||
return false;
|
||||
_coord2coord(target.coordPairKind, target.x, target.y, target.time_point,
|
||||
MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec);
|
||||
|
||||
if (!doesObjectReachZone(ha)) {
|
||||
return infiniteDuration;
|
||||
}
|
||||
|
||||
if constexpr (KIND ==
|
||||
MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one after upper culmination
|
||||
return compute(ha, dec, false);
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one before upper
|
||||
// culmination
|
||||
return compute(ha, dec, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
duration_t timeTo(const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
duration_t timeFrom(traits::mcc_celestial_point_c auto const& target)
|
||||
{
|
||||
return duration_t{std::numeric_limits<double>::infinity()};
|
||||
coord_t ha, dec;
|
||||
|
||||
if (!inZone(target)) {
|
||||
return zeroDuration;
|
||||
}
|
||||
|
||||
_coord2coord(target.coordPairKind, target.x, target.y, target.time_point,
|
||||
MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec);
|
||||
|
||||
if (!doesObjectExitFromZone(ha)) {
|
||||
return infiniteDuration;
|
||||
}
|
||||
|
||||
if (!doesObjectReachZone(ha)) {
|
||||
return zeroDuration;
|
||||
}
|
||||
|
||||
if constexpr (KIND ==
|
||||
MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one before upper culmination
|
||||
return compute(ha, dec, true);
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one after upper
|
||||
// culmination
|
||||
return compute(ha, dec, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
duration_t timeFrom(const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
return duration_t{0.0};
|
||||
}
|
||||
|
||||
private:
|
||||
MccAngle _altLimit, _latitude, _abs_lat, _lat_lim;
|
||||
coord_t _altLimit, _latitude, _abs_lat, _lat_lim;
|
||||
|
||||
bool doesObjectReachZone(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
// wrapper function
|
||||
std::function<coord_t(MccCoordPairKind, coord_t, coord_t, time_point_t, MccCoordPairKind, coord_t&, coord_t&)>
|
||||
_coord2coord{};
|
||||
|
||||
bool doesObjectReachZone(const coord_t& dec_app)
|
||||
{
|
||||
// check for limit conditions
|
||||
auto dd = std::abs(telemetry_data.mntDEC);
|
||||
auto dd = std::abs(dec_app);
|
||||
|
||||
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
|
||||
dd += _altLimit;
|
||||
@@ -189,11 +230,16 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool doesObjectReachZone(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
return doesObjectReachZone(telemetry_data.mntDEC);
|
||||
}
|
||||
|
||||
bool doesObjectExitFromZone(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
|
||||
bool doesObjectExitFromZone(const coord_t& dec_app)
|
||||
{
|
||||
// check for limit conditions
|
||||
auto dd = std::abs(telemetry_data.mntDEC);
|
||||
auto dd = std::abs(dec_app);
|
||||
|
||||
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
|
||||
dd -= _altLimit;
|
||||
@@ -212,10 +258,16 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
double cos_ha = (std::sin(_altLimit) - std::sin(telemetry_data.mntDEC) * std::sin(_latitude)) /
|
||||
std::cos(telemetry_data.mntDEC) / std::cos(_latitude);
|
||||
return doesObjectExitFromZone(telemetry_data.mntDEC);
|
||||
}
|
||||
|
||||
|
||||
duration_t compute(const coord_t& ha_app, const coord_t& dec_app, bool before_upper_culm)
|
||||
{
|
||||
double cos_ha =
|
||||
(std::sin(_altLimit) - std::sin(dec_app) * std::sin(_latitude)) / std::cos(dec_app) / std::cos(_latitude);
|
||||
|
||||
if (cos_ha > 1.0) { // should not be!
|
||||
return infiniteDuration;
|
||||
@@ -228,7 +280,7 @@ private:
|
||||
ha = std::acos(cos_ha); // HA after upper culmination!!
|
||||
}
|
||||
|
||||
MccAngle time_ang = ha - telemetry_data.mntHA; // in sideral time scale
|
||||
MccAngle time_ang = ha - ha_app; // in sideral time scale
|
||||
|
||||
if (time_ang < 0.0) { // next day
|
||||
time_ang += pi2;
|
||||
@@ -238,6 +290,11 @@ private:
|
||||
|
||||
return duration_t{time_ang.seconds()};
|
||||
}
|
||||
|
||||
duration_t compute(traits::mcc_mount_telemetry_data_c auto const& telemetry_data, bool before_upper_culm)
|
||||
{
|
||||
return compute(telemetry_data.mntHA, telemetry_data.mntDEC, before_upper_culm);
|
||||
}
|
||||
};
|
||||
|
||||
typedef MccAltLimitPZ<MccAltLimitKind::MIN_ALT_LIMIT> MccMinAltPZ;
|
||||
|
||||
Reference in New Issue
Block a user