This commit is contained in:
Timur A. Fatkhullin 2025-04-21 23:57:05 +03:00
parent 9315018bda
commit f8aaccb06d
3 changed files with 77 additions and 35 deletions

View File

@ -120,7 +120,7 @@ set(CNTR_PROTO_LIB comm_proto)
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC}) add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
set(MOUNT_SERVER_APP_SRC mount.h mount_state.h mount_server.cpp comm_server.h comm_server_endpoint.h comm_server_configfile.h mount_astrom.h set(MOUNT_SERVER_APP_SRC mount.h mount_state.h mount_server.cpp comm_server.h comm_server_endpoint.h comm_server_configfile.h mount_astrom.h
mount_astrom_default.h mcc_coord.h) mount_astrom_default.h mcc_coord.h mount_pz.h)
set(MOUNT_SERVER_APP mount_server) set(MOUNT_SERVER_APP mount_server)
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}) add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC})
# target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR}) # target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR})
@ -137,7 +137,6 @@ if (WITH_TESTS)
add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp) add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp)
set(ASTROM_TEST_APP astrom_test) set(ASTROM_TEST_APP astrom_test)
add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp)
mount_pz.h)
target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB) target_link_libraries(${ASTROM_TEST_APP} ERFA_LIB)
endif() endif()

View File

@ -63,22 +63,20 @@ protected:
public: public:
enum norm_kind_t { enum norm_kind_t {
NORM_KIND_0_360, // [0,360] NORM_KIND_0_360, // [0,360]
NORM_KIND_0_180, // [0,180] NORM_KIND_0_180, // [0,180]
NORM_KIND_90_90, // [-90,90] NORM_KIND_180_180, // [-180,180]
NORM_KIND_90_90, // [-90,90]
}; };
MccAngle() = default; MccAngle() = default;
// by default angle is in radians // by default angle is in radians
MccAngle(std::convertible_to<double> auto const& val, const MccRadianTag tag = MccRadianTag{}) MccAngle(std::convertible_to<double> auto const& val, const MccRadianTag = MccRadianTag{}) : _angleInRads(val) {}
: _angleInRads(val)
{
}
// construct angle in degrees, e.g.: // construct angle in degrees, e.g.:
// auto ang = MccAngle{180.0, mcc_degrees}; // auto ang = MccAngle{180.0, mcc_degrees};
MccAngle(std::convertible_to<double> auto const& val, const MccDegreeTag tag) MccAngle(std::convertible_to<double> auto const& val, const MccDegreeTag)
{ {
_angleInRads = val * utils::deg2radCoeff; _angleInRads = val * utils::deg2radCoeff;
} }
@ -127,6 +125,12 @@ public:
} else if (_angleInRads < 0.0) { } else if (_angleInRads < 0.0) {
_angleInRads = -_angleInRads; _angleInRads = -_angleInRads;
} }
} else if constexpr (KIND == NORM_KIND_180_180) {
if (_angleInRads > std::numbers::pi) {
_angleInRads = 2.0 * std::numbers::pi - _angleInRads;
} else if (_angleInRads < -std::numbers::pi) {
_angleInRads += 2.0 * std::numbers::pi;
}
} else if constexpr (KIND == NORM_KIND_90_90) { } else if constexpr (KIND == NORM_KIND_90_90) {
if (_angleInRads >= 1.5 * std::numbers::pi) { if (_angleInRads >= 1.5 * std::numbers::pi) {
_angleInRads = _angleInRads - 2.0 * std::numbers::pi; _angleInRads = _angleInRads - 2.0 * std::numbers::pi;
@ -175,8 +179,7 @@ public:
return sexagesimal<std::string>(hms, prec); return sexagesimal<std::string>(hms, prec);
} }
friend MccAngle operator+(std::convertible_to<MccAngle> auto&& left, friend MccAngle operator+(std::convertible_to<MccAngle> auto&& left, std::convertible_to<MccAngle> auto&& right)
std::convertible_to<MccAngle> auto&& right)
{ {
// return std::forward<decltype(left)>(left)._angleInRads + // return std::forward<decltype(left)>(left)._angleInRads +
// std::forward<decltype(right)>(right)._angleInRads; // std::forward<decltype(right)>(right)._angleInRads;
@ -189,8 +192,7 @@ public:
// } // }
friend MccAngle operator-(std::convertible_to<MccAngle> auto&& left, friend MccAngle operator-(std::convertible_to<MccAngle> auto&& left, std::convertible_to<MccAngle> auto&& right)
std::convertible_to<MccAngle> auto&& right)
{ {
// return std::forward<decltype(left)>(left)._angleInRads - // return std::forward<decltype(left)>(left)._angleInRads -
// std::forward<decltype(right)>(right)._angleInRads; // std::forward<decltype(right)>(right)._angleInRads;

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "mcc_coord.h" #include "mcc_coord.h"
#include "mount_astrom.h"
namespace mcc namespace mcc
{ {
@ -10,7 +11,7 @@ namespace traits
template <typename T> template <typename T>
concept mcc_prohibited_zone_c = requires(T t, const T const_t) { concept mcc_prohibited_zone_c = requires(T t, const T const_t) {
typename T::pzcoords_kind_t; typename T::pzcontext_t;
{ const_t.name() } -> std::same_as<std::string_view>; { const_t.name() } -> std::same_as<std::string_view>;
{ const_t.desc() } -> std::same_as<std::string_view>; { const_t.desc() } -> std::same_as<std::string_view>;
@ -18,22 +19,21 @@ concept mcc_prohibited_zone_c = requires(T t, const T const_t) {
// check if given coordinates are within the zone // check if given coordinates are within the zone
{ {
t.inZone(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(), t.inZone(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(),
std::declval<typename T::pzcoords_kind_t>()) std::declval<typename T::pzcontext_t>())
} -> std::convertible_to<bool>; } -> std::convertible_to<bool>;
// a time duration to reach the zone (0 - if already in the zone, chrono::duration<>::max() if never // a time duration to reach the zone (0 - if already in the zone, chrono::duration<>::max() if never
// reach the zone) // reach the zone)
{ {
t.timeTo(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(), t.timeTo(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(),
std::declval<typename T::pzcoords_kind_t>(), std::declval<typename T::pzcontext_t>(), std::declval<const std::chrono::system_clock::time_point&>())
std::declval<const std::chrono::system_clock::time_point&>())
} -> mcc_time_duration_c; } -> mcc_time_duration_c;
// a time duration to exit the zone (0 - if already out of the zone, chrono::duration<>::max() if // a time duration to exit the zone (0 - if already out of the zone, chrono::duration<>::max() if
// never exit the zone) // never exit the zone)
{ {
t.timeFrom(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(), t.timeFrom(std::declval<const MccAngle&>(), std::declval<const MccAngle&>(),
std::declval<typename T::pzcoords_kind_t>(), std::declval<typename T::pzcontext_t>(),
std::declval<const std::chrono::system_clock::time_point&>()) std::declval<const std::chrono::system_clock::time_point&>())
} -> mcc_time_duration_c; } -> mcc_time_duration_c;
}; };
@ -44,18 +44,21 @@ concept mcc_prohibited_zone_c = requires(T t, const T const_t) {
class MccProhibitedZone class MccProhibitedZone
{ {
public: public:
enum pzcoords_kind_t { COORDS_KIND_RADEC_IRCS, COORDS_KIND_RADEC_APP, COORDS_KIND_HADEC_APP, COORDS_KIND_AZALT };
struct pzcontext_t {
typedef std::chrono::duration<double> real_secs_t; // seconds duration in double
pzcoords_kind_t coords_kind;
real_secs_t dut1; // UT1-UTC
real_secs_t tt_tai; // TT-TAI
real_secs_t tai_utc; // TAI-UTC (leap seconds)
MccAngle lat, lon; // site geographic coordinates
};
virtual ~MccProhibitedZone() = default; virtual ~MccProhibitedZone() = default;
bool inZone(this auto&& self, const MccAngle& x, const MccAngle& y)
{
return std::forward<decltype(self)>(self).inZoneImpl(x, y);
}
protected:
bool inZoneImpl(const MccAngle&, const MccAngle&)
{
return false;
}
}; };
class MccMinAltPZ : public MccProhibitedZone class MccMinAltPZ : public MccProhibitedZone
@ -98,6 +101,47 @@ private:
}; };
enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT };
template <MccAltLimitKind LIMIT = MccAltLimitKind::MIN_ALT_LIMIT>
class MccAltLimitPZ
{
public:
static constexpr MccAltLimitKind altLimitType = LIMIT;
MccAltLimitPZ(const MccAngle& alt_limit) : _altLimit(alt_limit)
{
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
}
bool inZone(const MccAngle& x, const MccAngle& y, const MccProhibitedZone::pzcontext_t& context)
{
if (context.coords_kind == MccProhibitedZone::COORDS_KIND_AZALT) { // trivial case
if constexpr (LIMIT == MccAltLimitKind::MIN_ALT_LIMIT) {
return y <= _altLimit;
} else if constexpr (LIMIT == MccAltLimitKind::MAX_ALT_LIMIT) {
return y >= _altLimit;
}
} else if (context.coords_kind == MccProhibitedZone::COORDS_KIND_RADEC_APP) {
auto dd =
astrom::mcc_time_to_alt(_altLimit, x, y, context.lat, context.lon, std::chrono::system_clock::now(),
context.dut1, context.tt_tai, context.tai_utc);
}
}
auto timeTo(const MccAngle& x,
const MccAngle& y,
const MccProhibitedZone::pzcontext_t& context,
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
{
}
private:
MccAngle _altLimit;
};
/* /*
* a general planar ellipse equation: * a general planar ellipse equation:
* A*(x-xc)^2 + B*(x-xc)(y-yc) + C*(y-yc)^2 = 1 * A*(x-xc)^2 + B*(x-xc)(y-yc) + C*(y-yc)^2 = 1
@ -168,10 +212,7 @@ public:
} }
// circle // circle
MccEllipsePZ(const MccAngle& xc, const MccAngle& yc, const MccAngle& a) MccEllipsePZ(const MccAngle& xc, const MccAngle& yc, const MccAngle& a) : mcc::MccEllipsePZ(xc, yc, a, a) {}
: mcc::MccEllipsePZ(xc, yc, a, a)
{
}
private: private: