...
This commit is contained in:
parent
62258a991b
commit
46e4b1e95f
@ -124,7 +124,7 @@ add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
||||
|
||||
|
||||
set(MCC_LIBRARY_SRC mcc_mount_concepts.h mcc_mount.h mcc_mount_coord.h mcc_mount_events_states.h mcc_finite_state_machine.h
|
||||
mcc_mount_pec.h mcc_mount_pz.h mcc_traits.h mcc_mount_telemetry.h mcc_mount_config.h mcc_mount_astro_erfa.h)
|
||||
mcc_mount_pec.h mcc_mount_pz.h mcc_traits.h mcc_mount_telemetry.h mcc_mount_config.h mcc_mount_astro_erfa.h mcc_astrom_iers.h mcc_astrom_iers_default.h)
|
||||
set(MCC_LIBRARY mcc)
|
||||
add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC})
|
||||
target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23)
|
||||
|
||||
@ -44,14 +44,6 @@ public:
|
||||
|
||||
typedef typename slew_model_t::slew_params_t slew_params_t;
|
||||
|
||||
// struct slew_params_t {
|
||||
// MccCoordPairKind kind; // input coordinates type
|
||||
|
||||
// typename mount_telemetry_data_t::coord_t x; // co-longitude (e.g. RA or Az)
|
||||
// typename mount_telemetry_data_t::coord_t y; // co-latitude (e.g. DEC or ZD)
|
||||
|
||||
// bool stop; // stop after slewing
|
||||
// };
|
||||
|
||||
/* constructors and destructor */
|
||||
|
||||
|
||||
@ -37,9 +37,12 @@ protected:
|
||||
"time point is out of range",
|
||||
"time point is out of range",
|
||||
"dubious year",
|
||||
"unacceptable year"};
|
||||
"unacceptable year",
|
||||
"leap seconds update error",
|
||||
"bulletin A update error"};
|
||||
|
||||
public:
|
||||
static constexpr double DEFAULT_WAVELENGTH = 0.55; // default observed wavelength in mkm
|
||||
enum error_t : size_t {
|
||||
ERROR_OK = 0,
|
||||
ERROR_INVALID_INPUT_ARG,
|
||||
@ -48,7 +51,9 @@ public:
|
||||
ERROR_BULLETINA_OUT_OF_RANGE,
|
||||
ERROR_LEAPSECONDS_OUT_OF_RANGE,
|
||||
ERROR_DUBIOUS_YEAR,
|
||||
ERROR_UNACCEPTABLE_DATE
|
||||
ERROR_UNACCEPTABLE_DATE,
|
||||
ERROR_UPDATE_LEAPSECONDS,
|
||||
ERROR_UPDATE_BULLETINA,
|
||||
};
|
||||
|
||||
|
||||
@ -66,7 +71,7 @@ public:
|
||||
struct engine_state_t {
|
||||
meteo_t meteo{.temperature = 0.0, .humidity = 0.5, .pressure = 1010.0};
|
||||
|
||||
double wavelength = 0.55; // observed wavelength in mkm
|
||||
double wavelength = DEFAULT_WAVELENGTH; // observed wavelength in mkm
|
||||
|
||||
AngleT lat = "00:00:00"_dms; // site latitude
|
||||
AngleT lon = "00:00:00"_dms; // site longitude
|
||||
@ -123,6 +128,61 @@ public:
|
||||
return _currentState;
|
||||
}
|
||||
|
||||
void updateMeteo(meteo_t meteo)
|
||||
{
|
||||
std::lock_guard lock{_stateMutex};
|
||||
|
||||
_currentState.meteo = std::move(meteo);
|
||||
}
|
||||
|
||||
error_t updateLeapSeconds(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '#')
|
||||
{
|
||||
std::lock_guard lock{_stateMutex};
|
||||
|
||||
if (!_currentState._leapSeconds.load(stream, comment_sym)) {
|
||||
return ERROR_UPDATE_LEAPSECONDS;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
error_t updateLeapSeconds(traits::mcc_input_char_range auto const& filename, char comment_sym = '#')
|
||||
{
|
||||
std::lock_guard lock{_stateMutex};
|
||||
|
||||
if (!_currentState._leapSeconds.load(filename, comment_sym)) {
|
||||
return ERROR_UPDATE_LEAPSECONDS;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
error_t updateBulletinA(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '*')
|
||||
{
|
||||
std::lock_guard lock{_stateMutex};
|
||||
|
||||
if (!_currentState._bulletinA.load(stream, comment_sym)) {
|
||||
return ERROR_UPDATE_BULLETINA;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
error_t updateBulletinA(traits::mcc_input_char_range auto const& filename, char comment_sym = '*')
|
||||
{
|
||||
std::lock_guard lock{_stateMutex};
|
||||
|
||||
if (!_currentState._bulletinA.load(filename, comment_sym)) {
|
||||
return ERROR_UPDATE_BULLETINA;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string errorString(error_t err) const
|
||||
{
|
||||
|
||||
@ -210,12 +210,12 @@ template <typename T>
|
||||
concept mcc_mount_telemetry_data_c = requires(T telemetry) {
|
||||
typename T::coord_t;
|
||||
|
||||
// target current coordinates
|
||||
requires std::same_as<decltype(telemetry.tagRA), typename T::coord_t>; // apparent RA
|
||||
requires std::same_as<decltype(telemetry.tagDEC), typename T::coord_t>; // apparent DEC
|
||||
requires std::same_as<decltype(telemetry.tagHA), typename T::coord_t>; // hour angle
|
||||
requires std::same_as<decltype(telemetry.tagAZ), typename T::coord_t>; // azimuth
|
||||
requires std::same_as<decltype(telemetry.tagALT), typename T::coord_t>; // altitude
|
||||
// // target current coordinates
|
||||
// requires std::same_as<decltype(telemetry.tagRA), typename T::coord_t>; // apparent RA
|
||||
// requires std::same_as<decltype(telemetry.tagDEC), typename T::coord_t>; // apparent DEC
|
||||
// requires std::same_as<decltype(telemetry.tagHA), typename T::coord_t>; // hour angle
|
||||
// requires std::same_as<decltype(telemetry.tagAZ), typename T::coord_t>; // azimuth
|
||||
// requires std::same_as<decltype(telemetry.tagALT), typename T::coord_t>; // altitude
|
||||
|
||||
// mount current coordinates
|
||||
requires std::same_as<decltype(telemetry.mntRA), typename T::coord_t>; // apparent RA
|
||||
|
||||
@ -230,7 +230,7 @@ public:
|
||||
template <typename T>
|
||||
T arcmins() const
|
||||
{
|
||||
return degrees<T>() * 60.0;
|
||||
return _angleInRads * 10800.0 / std::numbers::pi;
|
||||
}
|
||||
|
||||
double arcmins() const
|
||||
@ -242,7 +242,7 @@ public:
|
||||
template <typename T>
|
||||
T arcsecs() const
|
||||
{
|
||||
return degrees<T>() * 3600.0;
|
||||
return _angleInRads * 648000.0 / std::numbers::pi;
|
||||
}
|
||||
|
||||
double arcsecs() const
|
||||
@ -250,6 +250,39 @@ public:
|
||||
return arcsecs<double>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T hours() const
|
||||
{
|
||||
return _angleInRads * 12.0 / std::numbers::pi;
|
||||
}
|
||||
|
||||
double hours() const
|
||||
{
|
||||
return hours<double>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T minutes() const
|
||||
{
|
||||
return _angleInRads * 720.0 / std::numbers::pi;
|
||||
}
|
||||
|
||||
double minutes() const
|
||||
{
|
||||
return minutes<double>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T seconds() const
|
||||
{
|
||||
return _angleInRads * 43200.0 / std::numbers::pi;
|
||||
}
|
||||
|
||||
double seconds() const
|
||||
{
|
||||
return seconds<double>();
|
||||
}
|
||||
|
||||
|
||||
template <traits::mcc_output_char_range T>
|
||||
T sexagesimal(bool hms = false, int prec = 2) const
|
||||
|
||||
@ -16,22 +16,6 @@ namespace mcc
|
||||
{
|
||||
|
||||
|
||||
// namespace traits
|
||||
// {
|
||||
|
||||
// template <typename T, typename XT, typename YT>
|
||||
// concept mcc_mount_pec_c = requires(T t, const T t_const, XT x, YT y) {
|
||||
// typename T::pec_data_t;
|
||||
// typename T::pec_result_t;
|
||||
|
||||
// { t.setData(std::declval<typename T::pec_data_t>()) };
|
||||
// { t_const.getData() } -> std::same_as<typename T::pec_data_t>;
|
||||
|
||||
// { t.compute(std::declval<const XT&>(), std::declval<const YT&>()) } -> std::same_as<typename T::pec_result_t>;
|
||||
// };
|
||||
|
||||
// } // namespace traits
|
||||
|
||||
// type of PEC corrections (algorithm used):
|
||||
// PEC_TYPE_GEOMETRY - "classic" geometry-based correction coefficients
|
||||
// PEC_TYPE_GEOMETRY_BSPLINE - previous one and additional 2D B-spline corrections
|
||||
@ -39,7 +23,7 @@ namespace mcc
|
||||
enum class MccMountDefaultPECType { PEC_TYPE_GEOMETRY, PEC_TYPE_GEOMETRY_BSPLINE, PEC_TYPE_BSPLINE };
|
||||
|
||||
template <MccMountType MOUNT_TYPE>
|
||||
class MccMountDefaultPEC
|
||||
class MccMountDefaultPEC final
|
||||
{
|
||||
public:
|
||||
static constexpr MccMountType mountType = MOUNT_TYPE;
|
||||
@ -47,7 +31,7 @@ public:
|
||||
typedef MccAngle coord_t;
|
||||
|
||||
struct pec_result_t {
|
||||
MccAngle dx, dy;
|
||||
coord_t dx, dy;
|
||||
};
|
||||
|
||||
// "classic" geometric PEC coefficients
|
||||
@ -161,8 +145,11 @@ public:
|
||||
|
||||
res.dy = _geomCoeffs.zeroPointY + _geomCoeffs.misalignErr1 * sinX + _geomCoeffs.misalignErr2 * cosX +
|
||||
_geomCoeffs.tubeFlexure * (cosPhi * cosX * std::sin(y) - sinPhi * cosY);
|
||||
if (!utils::isEqual(cosX, 0.0)) {
|
||||
res.dy += _geomCoeffs.forkFlexure / cosX;
|
||||
|
||||
if constexpr (mountType == MccMountType::FORK_TYPE) {
|
||||
if (!utils::isEqual(cosX, 0.0)) {
|
||||
res.dy += _geomCoeffs.forkFlexure / cosX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,4 +199,8 @@ private:
|
||||
mutable std::mutex _pecDataMutex;
|
||||
};
|
||||
|
||||
|
||||
typedef MccMountDefaultPEC<MccMountType::ALTAZ_TYPE> MccMountDefaultAltAzPec;
|
||||
typedef MccMountDefaultPEC<MccMountType::FORK_TYPE> MccMountDefaultForkPec;
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
@ -7,93 +7,18 @@
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
|
||||
#include "mcc_mount_concepts.h"
|
||||
|
||||
#include "mcc_mount_coord.h"
|
||||
#include "mcc_traits.h"
|
||||
|
||||
|
||||
namespace mcc
|
||||
{
|
||||
|
||||
class MccProhibitedZone
|
||||
{
|
||||
public:
|
||||
static constexpr MccCoordPairKind preferedCoordKind = MccCoordPairKind::COORDS_KIND_AZALT;
|
||||
static constexpr double mcc_UT1_to_sideral_ratio = 1.002737909350795; // UT1/sideral
|
||||
|
||||
|
||||
// floating-point time duration (seconds)
|
||||
typedef std::chrono::duration<double> pz_duration_t;
|
||||
|
||||
|
||||
struct pz_request_t {
|
||||
bool in_zone{false}; // true if given coordinates are within the zone
|
||||
pz_duration_t time_to{0.0}; // a time duration to reach the zone
|
||||
pz_duration_t time_from{0.0}; // a time duration to exit the zone
|
||||
};
|
||||
|
||||
|
||||
virtual ~MccProhibitedZone() = default;
|
||||
|
||||
std::string_view name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
// check if given position (x,y) in the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
bool inZone(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns a time duration to reach the zone
|
||||
// 0 - if already within
|
||||
// Inf - if it never reaches the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeTo(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return pz_duration_t{std::numeric_limits<double>::infinity()};
|
||||
}
|
||||
|
||||
// returns a time duration to exit from the zone
|
||||
// 0 - if given position (x,y) is out of the zone
|
||||
// Inf - if (x,y) is always within the zone
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_duration_t timeFrom(const XT&, const YT&, traits::mcc_systime_c auto const&)
|
||||
{
|
||||
return pz_duration_t{0.0};
|
||||
}
|
||||
|
||||
|
||||
// all-in-one request (call three methods above)
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pz_request_t request(this auto&& self,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
{
|
||||
using self_t = decltype(self);
|
||||
|
||||
pz_request_t res{.in_zone = false, .time_to = pz_duration_t{0.0}, .time_from{0.0}};
|
||||
|
||||
res.in_zone = std::forward<self_t>(self).inZone(x, y, utc);
|
||||
|
||||
if (res.in_zone) {
|
||||
res.time_from = std::forward<self_t>(self).timeFrom(x, y, utc);
|
||||
} else {
|
||||
res.time_to = std::forward<self_t>(self).timeTo(x, y, utc);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
protected:
|
||||
MccProhibitedZone(std::string_view name) : _name(name) {}
|
||||
|
||||
std::string_view _name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* SOME PROHIBITED ZONE IMPLEMENTATIONS */
|
||||
/* SOME SIMPLE PROHIBITED ZONE IMPLEMENTATIONS */
|
||||
|
||||
|
||||
// minimal or maximal altitude prohibited zones
|
||||
@ -101,26 +26,86 @@ protected:
|
||||
enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT };
|
||||
|
||||
template <MccAltLimitKind KIND = MccAltLimitKind::MIN_ALT_LIMIT>
|
||||
class MccAltLimitPZ : public MccProhibitedZone
|
||||
class MccAltLimitPZ
|
||||
// class MccAltLimitPZ : public MccProhibitedZone
|
||||
{
|
||||
static constexpr auto pi2 = std::numbers::pi * 2.0;
|
||||
|
||||
public:
|
||||
static constexpr MccCoordPairKind preferedCoordKind = MccCoordPairKind::COORDS_KIND_AZALT;
|
||||
|
||||
static constexpr MccAltLimitKind altLimitKind = KIND;
|
||||
|
||||
// floating-point time duration (seconds)
|
||||
typedef std::chrono::duration<double> pz_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};
|
||||
|
||||
//
|
||||
// TODO: add context (e.g. TT-TAI, UT1-UTC, geo location and so on)!!!
|
||||
MccAltLimitPZ(const MccAngle& alt_limit)
|
||||
: MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
||||
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||
: "ALTLIMIT-UNKNOWN"),
|
||||
_altLimit(alt_limit)
|
||||
MccAltLimitPZ(const MccAngle& alt_limit, const MccAngle& lat)
|
||||
// : MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
||||
// : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||
// : "ALTLIMIT-UNKNOWN"),
|
||||
: _altLimit(alt_limit), _latitude(lat), _abs_lat(std::abs(_latitude)), _lat_lim(pi2 - _abs_lat)
|
||||
{
|
||||
_altLimit.normalize<MccAngle::NORM_KIND_90_90>();
|
||||
}
|
||||
|
||||
|
||||
consteval std::string_view name() const
|
||||
{
|
||||
return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
||||
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||
: "ALTLIMIT-UNKNOWN";
|
||||
}
|
||||
|
||||
// check if current mount coordinates are within the zone
|
||||
bool inZone(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
|
||||
return telemetry_data.mntALT <= _altLimit;
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
|
||||
return telemetry_data.mntALT >= _altLimit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// returns a time to reach the zone
|
||||
pz_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 compute(telemetry_data);
|
||||
}
|
||||
|
||||
// returns a time to exit from the zone
|
||||
pz_duration_t timeFrom(traits::mcc_mount_telemetry_data_c auto const& telemetry_data)
|
||||
{
|
||||
if (!inZone(telemetry_data)) {
|
||||
return zeroDuration;
|
||||
}
|
||||
|
||||
if (!doesObjectReachZone(telemetry_data)) {
|
||||
return zeroDuration;
|
||||
}
|
||||
|
||||
return compute(telemetry_data);
|
||||
}
|
||||
|
||||
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, traits::mcc_systime_c auto const& utc = std::chrono::system_clock::now())
|
||||
bool inZone(const XT& x, const YT& y)
|
||||
{
|
||||
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
||||
|
||||
@ -131,7 +116,8 @@ public:
|
||||
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), utc);
|
||||
return inZone(x, MccAngleALT(std::numbers::pi / 2 - (double)y));
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
// implementation ...
|
||||
return false;
|
||||
@ -164,8 +150,51 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
MccAngle _altLimit;
|
||||
MccAngle _altLimit, _latitude, _abs_lat, _lat_lim;
|
||||
|
||||
bool doesObjectReachZone(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) { // never fall below altitude limit
|
||||
return false;
|
||||
}
|
||||
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
|
||||
if ((dd < (_abs_lat - _altLimit)) || (dd > (_abs_lat + _altLimit))) { // never rise above altitude limit
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
static_assert(false, "UNKNOWN ALTITUDE LIMIT TYPE!");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pz_duration_t compute(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);
|
||||
|
||||
if (cos_ha > 1.0) { // should not be!
|
||||
return infDuration;
|
||||
}
|
||||
|
||||
MccAngle time_ang = std::acos(cos_ha) - telemetry_data.mntHA; // in sideral time scale
|
||||
if (time_ang < 0.0) { // next day
|
||||
time_ang += pi2;
|
||||
}
|
||||
|
||||
time_ang *= mcc_UT1_to_sideral_ratio;
|
||||
|
||||
return pz_duration_t{time_ang.seconds()};
|
||||
}
|
||||
};
|
||||
|
||||
typedef MccAltLimitPZ<MccAltLimitKind::MIN_ALT_LIMIT> MccMinAltPZ;
|
||||
typedef MccAltLimitPZ<MccAltLimitKind::MAX_ALT_LIMIT> MccMaxAltPZ;
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
@ -3,148 +3,157 @@
|
||||
|
||||
// #include "../mcc_coord.h"
|
||||
#include "../mcc_mount_astro_erfa.h"
|
||||
#include "../mcc_traits.h"
|
||||
#include "../mcc_mount_pz.h"
|
||||
#include "../mount_astrom.h"
|
||||
|
||||
|
||||
// BTA coords from maps.yandex.ru: 43.646711, 41.440732
|
||||
|
||||
struct tel_data_t {
|
||||
typedef mcc::MccAngle coord_t;
|
||||
|
||||
coord_t mntRA, mntDEC, mntHA;
|
||||
coord_t mntAZ, mntALT;
|
||||
coord_t mntPosX, mntPosY;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ecode = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " bulletinA-filename\n";
|
||||
exit(1);
|
||||
}
|
||||
// if (argc < 2) {
|
||||
// std::cerr << "Usage: " << argv[0] << " bulletinA-filename\n";
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
std::ifstream ist(argv[1]);
|
||||
if (!ist) {
|
||||
std::cerr << "Invalid filename!\n";
|
||||
exit(1);
|
||||
}
|
||||
// std::ifstream ist(argv[1]);
|
||||
// if (!ist) {
|
||||
// std::cerr << "Invalid filename!\n";
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
|
||||
mcc::astrom::MccIersBulletinA bullA;
|
||||
bullA.dump(std::cout);
|
||||
// mcc::astrom::MccIersBulletinA bullA;
|
||||
// bullA.dump(std::cout);
|
||||
|
||||
std::cout << "\n\n";
|
||||
// std::cout << "\n\n";
|
||||
|
||||
mcc::astrom::MccLeapSeconds lps;
|
||||
lps.dump(std::cout);
|
||||
// mcc::astrom::MccLeapSeconds lps;
|
||||
// lps.dump(std::cout);
|
||||
|
||||
std::cout << "\n\n";
|
||||
// std::cout << "\n\n";
|
||||
|
||||
bool ok = bullA.load(ist);
|
||||
bullA.dump(std::cerr);
|
||||
// bool ok = bullA.load(ist);
|
||||
// bullA.dump(std::cerr);
|
||||
|
||||
ist.close();
|
||||
// ist.close();
|
||||
|
||||
std::cout << "\n\n\n------------------\n";
|
||||
// std::cout << "\n\n\n------------------\n";
|
||||
|
||||
constexpr auto nnn = mcc::astrom::MccLeapSeconds::real_secs_t{std::numeric_limits<double>::quiet_NaN()};
|
||||
// constexpr auto nnn = mcc::astrom::MccLeapSeconds::real_secs_t{std::numeric_limits<double>::quiet_NaN()};
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
// std::cout << "LEAP SECS for now: " << lps[now].value_or(std::numeric_limits<double>::quiet_NaN()) << "\n";
|
||||
std::cout << "LEAP SECS for now: " << lps[now].value_or(nnn) << "\n";
|
||||
// // std::cout << "LEAP SECS for now: " << lps[now].value_or(std::numeric_limits<double>::quiet_NaN()) << "\n";
|
||||
// std::cout << "LEAP SECS for now: " << lps[now].value_or(nnn) << "\n";
|
||||
|
||||
// std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(std::numeric_limits<double>::quiet_NaN()) << " (" <<
|
||||
// now
|
||||
std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(nnn) << " (" << now << ")\n";
|
||||
// // std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(std::numeric_limits<double>::quiet_NaN()) << " (" <<
|
||||
// // now
|
||||
// std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(nnn) << " (" << now << ")\n";
|
||||
|
||||
double mjd = 61077.4;
|
||||
// double mjd = 61077.4;
|
||||
|
||||
// std::cout << "DUT1 for MJD = " << mjd << ": " <<
|
||||
// bullA.DUT1(mjd).value_or(std::numeric_limits<double>::quiet_NaN())
|
||||
std::cout << "DUT1 for MJD = " << mjd << ": " << bullA.DUT1(mjd).value_or(nnn) << "\n";
|
||||
// // std::cout << "DUT1 for MJD = " << mjd << ": " <<
|
||||
// // bullA.DUT1(mjd).value_or(std::numeric_limits<double>::quiet_NaN())
|
||||
// std::cout << "DUT1 for MJD = " << mjd << ": " << bullA.DUT1(mjd).value_or(nnn) << "\n";
|
||||
|
||||
|
||||
auto st = mcc::astrom::mcc_julday(now, mjd);
|
||||
std::cout << "MJD for now: " << std::setprecision(19) << mjd << " (" << now << ")\n";
|
||||
// auto st = mcc::astrom::mcc_julday(now, mjd);
|
||||
// std::cout << "MJD for now: " << std::setprecision(19) << mjd << " (" << now << ")\n";
|
||||
|
||||
// double pres = 786.6;
|
||||
// double temp = 0.0;
|
||||
// double hum = 0.8;
|
||||
// double A, B;
|
||||
// // double pres = 786.6;
|
||||
// // double temp = 0.0;
|
||||
// // double hum = 0.8;
|
||||
// // double A, B;
|
||||
|
||||
// erfa::eraRefco(pres, temp, hum, 0.5, &A, &B);
|
||||
// const double rr = 180.0 / std::numbers::pi * 60.0;
|
||||
// std::cout << "A(arcmin) = " << A * rr << "; B(arcmin) = " << B * rr << "\n";
|
||||
// // erfa::eraRefco(pres, temp, hum, 0.5, &A, &B);
|
||||
// // const double rr = 180.0 / std::numbers::pi * 60.0;
|
||||
// // std::cout << "A(arcmin) = " << A * rr << "; B(arcmin) = " << B * rr << "\n";
|
||||
|
||||
float alt_lim = 10.0;
|
||||
std::string_view ra_str = "06:30:00.0", dec_str = "00:00:00.0";
|
||||
std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
|
||||
<< alt_lim << " degrees):\n";
|
||||
using namespace std::chrono_literals;
|
||||
// auto stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
|
||||
// std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
// float alt_lim = 10.0;
|
||||
// std::string_view ra_str = "06:30:00.0", dec_str = "00:00:00.0";
|
||||
// std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
|
||||
// << alt_lim << " degrees):\n";
|
||||
// using namespace std::chrono_literals;
|
||||
// // auto stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
|
||||
// // std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
|
||||
// auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
|
||||
// std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
|
||||
// std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm) << " minutes\n";
|
||||
// // auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
|
||||
// // std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
|
||||
// // std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm) << " minutes\n";
|
||||
|
||||
alt_lim = 85.0;
|
||||
ra_str = "02:30:00.0", dec_str = "45:00:00.0";
|
||||
std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
|
||||
<< alt_lim << " degrees):\n";
|
||||
// alt_lim = 85.0;
|
||||
// ra_str = "02:30:00.0", dec_str = "45:00:00.0";
|
||||
// std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
|
||||
// << alt_lim << " degrees):\n";
|
||||
|
||||
auto stm =
|
||||
mcc::astrom::mcc_time_to_alt({alt_lim, mcc::mcc_degrees}, {ra_str, mcc::mcc_hms}, dec_str, 43.646711_degs,
|
||||
41.440732_degs, std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
// stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
|
||||
// std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
// auto stm =
|
||||
// mcc::astrom::mcc_time_to_alt({alt_lim, mcc::mcc_degrees}, {ra_str, mcc::mcc_hms}, dec_str, 43.646711_degs,
|
||||
// 41.440732_degs, std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
// // stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
|
||||
// // std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
|
||||
|
||||
// auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
|
||||
// std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
|
||||
std::cout << "STM: " << stm.first << ", " << stm.second << " seconds\n";
|
||||
std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm.first) << ", "
|
||||
<< std::chrono::duration_cast<std::chrono::minutes>(stm.second) << " minutes\n";
|
||||
// // auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
|
||||
// // std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
|
||||
// std::cout << "STM: " << stm.first << ", " << stm.second << " seconds\n";
|
||||
// std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm.first) << ", "
|
||||
// << std::chrono::duration_cast<std::chrono::minutes>(stm.second) << " minutes\n";
|
||||
|
||||
|
||||
std::cout << "\n\n\n";
|
||||
const size_t N = 1000;
|
||||
double mjds[N];
|
||||
now = std::chrono::system_clock::now();
|
||||
st = mcc::astrom::mcc_julday(now, mjds, std::chrono::milliseconds(100));
|
||||
std::cout << std::format("comp time for {} MJDs = {}\n", N, std::chrono::system_clock::now() - now);
|
||||
std::cout << std::format("MIN MJD: {:.16f}; \nMAX MJD: {:.16f}\n", mjds[0], mjds[N - 1]);
|
||||
// std::cout << "\n\n\n";
|
||||
// const size_t N = 1000;
|
||||
// double mjds[N];
|
||||
// now = std::chrono::system_clock::now();
|
||||
// st = mcc::astrom::mcc_julday(now, mjds, std::chrono::milliseconds(100));
|
||||
// std::cout << std::format("comp time for {} MJDs = {}\n", N, std::chrono::system_clock::now() - now);
|
||||
// std::cout << std::format("MIN MJD: {:.16f}; \nMAX MJD: {:.16f}\n", mjds[0], mjds[N - 1]);
|
||||
|
||||
double elong = 43.646711 * std::numbers::pi / 180.0;
|
||||
double phi = 41.440732 * std::numbers::pi / 180.0;
|
||||
double aob, zob, hob, dob, rob, eo;
|
||||
// double elong = 43.646711 * std::numbers::pi / 180.0;
|
||||
// double phi = 41.440732 * std::numbers::pi / 180.0;
|
||||
// double aob, zob, hob, dob, rob, eo;
|
||||
|
||||
now = std::chrono::system_clock::now();
|
||||
// now = std::chrono::system_clock::now();
|
||||
|
||||
for (auto& el : mjds) {
|
||||
st = mcc::astrom::erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi,
|
||||
2100.0, 0.0, 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob, &eo);
|
||||
// st = erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi, 2100.0, 0.0,
|
||||
// 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob, &eo);
|
||||
}
|
||||
std::cout << std::format(
|
||||
"comp time for {} coordinate transf = {}\n", N,
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now));
|
||||
// for (auto& el : mjds) {
|
||||
// st = mcc::astrom::erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi,
|
||||
// 2100.0, 0.0, 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob,
|
||||
// &eo);
|
||||
// // st = erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi, 2100.0,
|
||||
// 0.0,
|
||||
// // 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob, &eo);
|
||||
// }
|
||||
// std::cout << std::format(
|
||||
// "comp time for {} coordinate transf = {}\n", N,
|
||||
// std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now));
|
||||
|
||||
|
||||
std::cout << "\n\n\nMccCoordinate class test:\n";
|
||||
// std::cout << "\n\n\nMccCoordinate class test:\n";
|
||||
|
||||
mcc::MccAngle ra("12:00:00", mcc::mcc_hms);
|
||||
// mcc::MccAngle ra("12:00:00", mcc::mcc_hms);
|
||||
|
||||
std::cout << "sin(12h) = " << std::sin(ra) << "\n";
|
||||
std::cout << "cos(12h) = " << std::cos(ra) << "\n";
|
||||
// std::cout << "sin(12h) = " << std::sin(ra) << "\n";
|
||||
// std::cout << "cos(12h) = " << std::cos(ra) << "\n";
|
||||
|
||||
ra = "18:00:00"_hms;
|
||||
std::cout << "sin(18h) = " << std::sin(ra) << "\n";
|
||||
std::cout << "cos(18h) = " << std::cos(ra) << "\n";
|
||||
// ra = "18:00:00"_hms;
|
||||
// std::cout << "sin(18h) = " << std::sin(ra) << "\n";
|
||||
// std::cout << "cos(18h) = " << std::cos(ra) << "\n";
|
||||
|
||||
ra = mcc::MccAngle{45.0, mcc::mcc_degrees};
|
||||
std::cout << "sin(45) = " << std::sin(ra) << "\n";
|
||||
std::cout << "cos(45) = " << std::cos(ra) << "\n";
|
||||
// ra = mcc::MccAngle{45.0, mcc::mcc_degrees};
|
||||
// std::cout << "sin(45) = " << std::sin(ra) << "\n";
|
||||
// std::cout << "cos(45) = " << std::cos(ra) << "\n";
|
||||
|
||||
std::cout << ra.sexagesimal(false, 4) << "\n";
|
||||
// std::cout << ra.sexagesimal(false, 4) << "\n";
|
||||
|
||||
|
||||
std::cout << "\n\n\n\n";
|
||||
// std::cout << "\n\n\n\n";
|
||||
|
||||
using engine_t = mcc::astrom::erfa::MccMountAstromEngineERFA<>;
|
||||
engine_t::engine_state_t state;
|
||||
@ -169,7 +178,8 @@ int main(int argc, char* argv[])
|
||||
std::cout << "LST(MJD = " << jd.mjd << ") = " << lst.sexagesimal(true) << "\n\n";
|
||||
|
||||
|
||||
mcc::MccAngle ra1{"10:00:00", mcc::mcc_hms}, dec1{"68:25:10.43"}, ra_o, dec_o, ha1, az1, alt1;
|
||||
// mcc::MccAngle ra1{"10:00:00", mcc::mcc_hms}, dec1{"68:25:10.43"}, ra_o, dec_o, ha1, az1, alt1;
|
||||
mcc::MccAngle ra1{"5:00:00", mcc::mcc_hms}, dec1{"38:25:10.43"}, ra_o, dec_o, ha1, az1, alt1;
|
||||
mcc::MccAngle eor;
|
||||
|
||||
std::cout << "RA = " << ra1.sexagesimal(true) << ", DEC = " << dec1.sexagesimal() << "\n";
|
||||
@ -191,5 +201,47 @@ int main(int argc, char* argv[])
|
||||
std::cout << "RA_app_comp = " << (lst - ha1 + eor).sexagesimal(true) << "\n";
|
||||
|
||||
|
||||
std::cout << "\n\n\n\n";
|
||||
|
||||
mcc::MccMinAltPZ minalt_pz(10.0_degs, state.lat);
|
||||
mcc::MccMaxAltPZ maxalt_pz(85.0_degs, state.lat);
|
||||
|
||||
tel_data_t tdata{ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
|
||||
|
||||
bool ask = minalt_pz.inZone(tdata);
|
||||
std::cout << "in zone? " << std::boolalpha << ask << "\n";
|
||||
|
||||
auto tm = minalt_pz.timeTo(tdata);
|
||||
if (std::isinf(tm.count())) {
|
||||
std::cout << "(MINALT) time to zone: the object never reaches the zone!\n";
|
||||
} else {
|
||||
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
|
||||
std::cout << "(MINALT) time to zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
ra1 = "17:00:00"_hms;
|
||||
dec1 = "40:25:10.43"_dms;
|
||||
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
|
||||
std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\n";
|
||||
std::cout << "alt = " << alt1.sexagesimal() << "\n";
|
||||
std::cout << "az = " << az1.sexagesimal() << "\n";
|
||||
|
||||
std::cout << "HA_app = " << ha1.sexagesimal(true) << "\n";
|
||||
std::cout << "RA_app = " << ra_o.sexagesimal(true) << "\n";
|
||||
std::cout << "DEC_app = " << dec_o.sexagesimal() << "\n";
|
||||
|
||||
|
||||
tdata = {ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
|
||||
|
||||
tm = maxalt_pz.timeTo(tdata);
|
||||
if (std::isinf(tm.count())) {
|
||||
std::cout << "(MAXALT) time to zone: the object never reaches the zone!\n";
|
||||
} else {
|
||||
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
|
||||
std::cout << "(MAXALT) time to zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
|
||||
}
|
||||
|
||||
return ecode;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user