From b3b275edd88c0675dcc87f96961ce74583d5504f Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 4 Jul 2025 12:24:34 +0300 Subject: [PATCH] ... --- cxx/CMakeLists.txt | 46 ++- cxx/mcc_astrom_iers.h | 486 +++++++++++++++++++++++++ cxx/mcc_astrom_iers_default.h | 652 ++++++++++++++++++++++++++++++++++ cxx/mcc_mount_astro_erfa.h | 69 ++++ cxx/mcc_mount_astrom.h | 54 ++- cxx/mcc_traits.h | 15 +- cxx/mount.h | 2 +- cxx/mount_pz.h | 2 +- cxx/tests/astrom_test.cpp | 27 +- cxx/update_iers_data.sh | 36 ++ 10 files changed, 1342 insertions(+), 47 deletions(-) create mode 100644 cxx/mcc_astrom_iers.h create mode 100644 cxx/mcc_astrom_iers_default.h create mode 100644 cxx/mcc_mount_astro_erfa.h create mode 100755 cxx/update_iers_data.sh diff --git a/cxx/CMakeLists.txt b/cxx/CMakeLists.txt index fbdf671..b969070 100644 --- a/cxx/CMakeLists.txt +++ b/cxx/CMakeLists.txt @@ -130,24 +130,22 @@ add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC}) target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23) target_include_directories(${MCC_LIBRARY} INTERFACE ${FITPACK_INCLUDE_DIR}) -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_pz.h mcc_fsm.h mcc_fsm_utils.h) -set(MOUNT_SERVER_APP mount_server) -add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC} - mcc_finite_state_machine.h - mcc_mount_events_states.h) -# target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR}) -target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only ERFA_LIB) +# 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_pz.h mcc_fsm.h mcc_fsm_utils.h mcc_finite_state_machine.h mcc_mount_events_states.h) +# set(MOUNT_SERVER_APP mount_server) +# add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}) +# # target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR}) +# target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only ERFA_LIB) if (WITH_TESTS) - set(CNTR_PROTO_TEST_APP cntr_proto_test) - add_executable(${CNTR_PROTO_TEST_APP} tests/cntr_proto_test.cpp) - target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only) - # target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB}) - # target_include_directories(${CNTR_PROTO_TEST_APP} PUBLIC ${SPDLOG_INCLUDE_DIRS}) + # set(CNTR_PROTO_TEST_APP cntr_proto_test) + # add_executable(${CNTR_PROTO_TEST_APP} tests/cntr_proto_test.cpp) + # target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only) + # # target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB}) + # # target_include_directories(${CNTR_PROTO_TEST_APP} PUBLIC ${SPDLOG_INCLUDE_DIRS}) - set(CFGFILE_TEST_APP configfile_test) - add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp) + # set(CFGFILE_TEST_APP configfile_test) + # add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp) set(ASTROM_TEST_APP astrom_test) add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp) @@ -163,16 +161,16 @@ if (WITH_TESTS) # add_executable(${FSM_TEST_APP} tests/fsm_test.cpp) - set(TESTS_SRC tests/coord.cpp tests/fsm.cpp tests/mount.cpp) - create_test_sourcelist(Tests common_tests.cpp ${TESTS_SRC}) - add_executable(common_tests ${Tests}) - target_include_directories(common_tests PRIVATE ${FITPACK_INCLUDE_DIR}) - target_link_libraries(common_tests fitpack) + # set(TESTS_SRC tests/coord.cpp tests/fsm.cpp tests/mount.cpp) + # create_test_sourcelist(Tests common_tests.cpp ${TESTS_SRC}) + # add_executable(common_tests ${Tests}) + # target_include_directories(common_tests PRIVATE ${FITPACK_INCLUDE_DIR}) + # target_link_libraries(common_tests fitpack) - foreach (test ${TESTS_SRC}) - get_filename_component (TName ${test} NAME_WE) - add_test (NAME ${TName} COMMAND common_tests tests/${TName}) - endforeach () + # foreach (test ${TESTS_SRC}) + # get_filename_component (TName ${test} NAME_WE) + # add_test (NAME ${TName} COMMAND common_tests tests/${TName}) + # endforeach () enable_testing() endif() diff --git a/cxx/mcc_astrom_iers.h b/cxx/mcc_astrom_iers.h new file mode 100644 index 0000000..93fb29e --- /dev/null +++ b/cxx/mcc_astrom_iers.h @@ -0,0 +1,486 @@ +#pragma once + +/* MOUNT CONTROL COMPONENTS LIBRARY */ + + +/* Classes to represent IERS bulletins + * + * BULLETIN A: https://datacenter.iers.org/data/latestVersion/bulletinA.txt + * leapseconds: https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat + * + */ + +#include +#include + +#include "mcc_astrom_iers_default.h" +#include "mcc_traits.h" +#include "utils.h" + +namespace mcc::astrom::iers +{ + +class MccLeapSeconds final +{ +public: + typedef std::chrono::system_clock::time_point time_point_t; + typedef std::chrono::duration real_secs_t; // seconds duration in double + + MccLeapSeconds() + { + // create default values + std::istringstream ist(defaults::MCC_DEFAULT_LEAP_SECONDS_FILE); + + load(ist); + } + + ~MccLeapSeconds() = default; + + + time_point_t expireDate() const + { + return _expireDate; + } + + // load from stream + bool load(std::derived_from> auto& stream, char comment_sym = '#') + { + std::istringstream is; + double mjd; + unsigned day, month; + int year; + double tai_utc; + + decltype(_expireDate) edate; + std::vector db; + + for (std::string line; std::getline(stream, line);) { + auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_LEFT); + + if (sv.size()) { + if (sv[0] == comment_sym) { // comment string + if (std::regex_match(line, expr_date_rx)) { + auto pos = line.find("on"); + sv = utils::trimSpaces(std::string_view{line.begin() + pos + 2, line.end()}, + utils::TrimType::TRIM_LEFT); + is.str({sv.begin(), sv.end()}); + is >> std::chrono::parse("%d %B %Y", edate); + is.clear(); + } + continue; + } + } else { + continue; + } + + if (std::regex_match(line, data_rx)) { + is.str(line); + is >> mjd >> day >> month >> year >> tai_utc; + db.emplace_back(mjd, std::chrono::year_month_day{std::chrono::year{year} / month / day}, tai_utc); + // db.emplace_back(mjd, + // std::chrono::year_month_day{std::chrono::year{year}, std::chrono::month{month}, + // std::chrono::day{day}}, + // tai_utc); + is.clear(); + + continue; + } + } + + if (db.empty()) { // keep previous data + return false; + } + + _expireDate = std::move(edate); + + // compute expire Julian Day + using namespace std::literals::chrono_literals; + + std::chrono::year_month_day ymd{std::chrono::floor(_expireDate)}; + + static constexpr std::chrono::year MIN_YEAR = -4799y; + + if (ymd.year() < MIN_YEAR) { + return -1; + } + if (!ymd.month().ok()) { + return -2; + } + + int64_t im = (unsigned)ymd.month(); + int64_t id = (unsigned)ymd.day(); + int64_t iy = (int)ymd.year(); + + int64_t my = (im - 14LL) / 12LL; + int64_t iypmy = iy + my; + + // integer part of result MJD + int64_t mjd_int = (1461LL * (iypmy + 4800LL)) / 4LL + (367LL * (im - 2LL - 12LL * my)) / 12LL - + (3LL * ((iypmy + 4900LL) / 100LL)) / 4LL + id - 2432076LL; + + _expireJulDate = static_cast(mjd_int); + + + _db = std::move(db); + + return true; + } + + + bool load(traits::mcc_input_char_range auto const& filename, char comment_sym = '#') + { + std::ifstream fst(filename); + + bool ok = fst.is_open(); + if (!ok) { + return false; + } + + ok = load(fst, comment_sym); + + fst.close(); + + return ok; + } + + + // std::optional operator[](const time_point_t& tp) const + std::optional operator[](const time_point_t& tp) const + { + if (tp > _expireDate) { // ???????!!!!!!!!!!! + return std::nullopt; + // return _db.back().tai_utc; + } + + std::chrono::year_month_day ymd{std::chrono::floor(tp)}; + + for (auto const& el : _db | std::views::reverse) { + if (ymd >= el.ymd) { + // return el.tai_utc; + return real_secs_t{el.tai_utc}; + } + } + + return std::nullopt; + } + + // std::optional operator[](const double& mjd) const + std::optional operator[](const double& mjd) const + { + double e_mjd; + + if (mjd > _expireJulDate) { // ???????!!!!!!!!!!! + return std::nullopt; + // return _db.back().tai_utc; + } + + for (auto const& el : _db | std::views::reverse) { + if (mjd >= el.mjd) { + return real_secs_t{el.tai_utc}; + } + } + + return std::nullopt; + } + + + void dump(std::derived_from> auto& stream) const + { + stream << std::format("Leap seconds database expire date: {}", _expireDate) << '\n'; + for (auto const& el : _db) { + stream << std::format("{} {} {}", el.mjd, el.ymd, el.tai_utc) << '\n'; + } + } + + +private: + inline static const std::regex expr_date_rx{ + "^ *# *File +expires +on +[0-8]{1,2} " + "+(January|February|March|April|May|June|July|August|September|October|November|December) +[0-9]{4} *$"}; + + inline static const std::regex data_rx{"^ *[0-9]{5,}(\\.?[0-9]+) +[0-9]{1,2} +[0-9]{1,2} +[0-9]{4} +[0-9]{1,} *$"}; + + time_point_t _expireDate{}; + double _expireJulDate{}; + + struct leapsecond_db_elem_t { + double mjd; + std::chrono::year_month_day ymd; + double tai_utc; // TAI-UTC in seconds + }; + + std::vector _db{}; +}; + + + +class MccIersBulletinA final +{ +public: + typedef std::chrono::system_clock::time_point time_point_t; + typedef std::chrono::duration real_secs_t; // seconds duration in double + + struct pole_pos_t { + double x, y; + }; + + struct date_range_t { + std::chrono::year_month_day begin; + std::chrono::year_month_day end; + }; + + struct date_range_mjd_t { + double begin; + double end; + }; + + MccIersBulletinA() + { + // create pre-defined (default-state) database + std::istringstream ist(defaults::MCC_DEFAULT_IERS_BULLETIN_A_FILE); + + load(ist); + } + + ~MccIersBulletinA() = default; + + std::chrono::system_clock::time_point bulletinDate() const + { + return _date; + } + + + date_range_t dateRange() const + { + return {_db.front().ymd, _db.back().ymd}; + } + + date_range_mjd_t dateRangeMJD() const + { + return {_db.front().mjd, _db.back().mjd}; + } + + + // double TT_TAI() const + real_secs_t TT_TAI() const + { + return real_secs_t{_tt_tai}; + } + + // DUT1 = UT1 - UTC + // std::optional DUT1(const time_point_t& tp) const + std::optional DUT1(const time_point_t& tp) const + { + // use of the closest date + std::chrono::year_month_day ymd{std::chrono::round(tp)}; + + if (ymd < _db.front().ymd) { + return std::nullopt; + } + + if (ymd > _db.back().ymd) { + return std::nullopt; + } + + for (auto const& el : _db) { + if (ymd <= el.ymd) { + return real_secs_t{el.dut1}; + } + } + + return std::nullopt; + } + + // std::optional DUT1(double mjd) const + std::optional DUT1(double mjd) const + { + mjd = std::round(mjd); // round to closest integer MJD + + if (mjd < _db.front().mjd) { + return std::nullopt; + } + + if (mjd > _db.back().mjd) { + return std::nullopt; + } + + for (auto const& el : _db) { + if (mjd <= el.mjd) { + return real_secs_t{el.dut1}; + } + } + + return std::nullopt; + } + + std::optional polarCoords(const time_point_t& tp) const + { + std::chrono::year_month_day ymd{std::chrono::round(tp)}; + + if (ymd < _db.front().ymd) { + return std::nullopt; + } + + if (ymd > _db.back().ymd) { + return std::nullopt; + } + + for (auto const& el : _db) { + if (ymd <= el.ymd) { + return pole_pos_t{el.x, el.y}; + } + } + + return std::nullopt; + } + + std::optional polarCoords(double mjd) const + { + mjd = std::round(mjd); // round to closest integer MJD + + if (mjd < _db.front().mjd) { + return std::nullopt; + } + + if (mjd > _db.back().mjd) { + return std::nullopt; + } + + for (auto const& el : _db) { + if (mjd <= el.mjd) { + return pole_pos_t{el.x, el.y}; + } + } + + return std::nullopt; + } + + bool load(std::derived_from> auto& stream, char comment_sym = '*') + { + std::vector db; + enum { TAB_STATE_SEEK, TAB_STATE_START }; + int tab_state = TAB_STATE_SEEK; + + int year; + unsigned month, day; + double mjd, x, y, dut1; + std::istringstream is; + decltype(_date) bdate; + double tt_tai; + + for (std::string line; std::getline(stream, line);) { + if (line.empty()) { + continue; + } + + auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_LEFT); + + if (sv.size()) { + if (sv[0] == comment_sym) { // comment string + continue; + } + + if (tab_state == TAB_STATE_START) { + if (std::regex_match(sv.begin(), sv.end(), bull_tab_vals_rx)) { + // is.str({sv.begin(), sv.end()}); + is.str(line); + is >> year >> month >> day >> mjd >> x >> y >> dut1; + db.emplace_back(mjd, std::chrono::year_month_day{std::chrono::year{year} / month / day}, x, y, + dut1); + is.clear(); + } else { // end of the table - just stop parsing + break; + } + + continue; + } + + if (std::regex_match(sv.begin(), sv.end(), bull_date_rx)) { + is.str({sv.begin(), sv.end()}); + is >> std::chrono::parse("%d %B %Y", bdate); + continue; + } + + if (std::regex_match(sv.begin(), sv.end(), bull_tt_tai_rx)) { + is.str({sv.begin(), sv.end()}); + std::string dummy; + is >> dummy >> dummy >> dummy >> dummy >> tt_tai; + continue; + } + + if (std::regex_match(sv.begin(), sv.end(), bull_tab_title_rx)) { + tab_state = TAB_STATE_START; + continue; + } + + } else { // empty string (only spaces) + continue; + } + } + + if (db.empty()) { + return false; + } + + _date = std::move(bdate); + _tt_tai = tt_tai; + _db = std::move(db); + + return true; + } + + bool load(traits::mcc_input_char_range auto const& filename, char comment_sym = '*') + { + std::ifstream fst(filename); + + bool ok = fst.is_open(); + if (!ok) { + return false; + } + + ok = load(fst, comment_sym); + + fst.close(); + + return ok; + } + + + void dump(std::derived_from> auto& stream) const + { + stream << std::format("Bulletin A issue date: {}", _date) << '\n'; + stream << std::format("TT-TAI: {}", _tt_tai) << '\n'; + for (auto const& el : _db) { + stream << std::format("{} {} {:6.4f} {:6.4f} {:7.5f}", el.mjd, el.ymd, el.x, el.y, el.dut1) << '\n'; + } + } + +private: + inline static const std::regex bull_date_rx{ + "^ *[0-9]{1,2} +(January|February|March|April|May|June|July|August|September|October|November|December) " + "+[0-9]{4,} +Vol\\. +[XMLCDVI]+ +No\\. +[0-9]+ *$"}; + + inline static const std::regex bull_tt_tai_rx{"^ *TT += +TAI +\\+ +[0-9]+\\.[0-9]+ +seconds *$"}; + + inline static const std::regex bull_tab_title_rx{"^ *MJD +x\\(arcsec\\) +y\\(arcsec\\) +UT1-UTC\\(sec\\) *$"}; + + inline static const std::regex bull_tab_vals_rx{ + "^ *[0-9]{4,} +[0-9]{1,2} +[0-9]{1,2} +[0-9]{5,} +[0-9]+\\.[0-9]+ +[0-9]+\\.[0-9]+ +[0-9]+\\.[0-9]+ *$"}; + + + time_point_t _date; + double _tt_tai; + + struct earth_orient_db_elem_t { + double mjd; + std::chrono::year_month_day ymd; + double x, y; // Polar coordinates in arcsecs + double dut1; // UT1-UTC in seconds + }; + + std::vector _db; +}; + + + +} // namespace mcc::astrom::iers diff --git a/cxx/mcc_astrom_iers_default.h b/cxx/mcc_astrom_iers_default.h new file mode 100644 index 0000000..cb6d5d6 --- /dev/null +++ b/cxx/mcc_astrom_iers_default.h @@ -0,0 +1,652 @@ +#pragma once + + +#include + + +namespace mcc::astrom::iers::defaults + +{ + +// https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat + +static std::string MCC_DEFAULT_LEAP_SECONDS_FILE = R"--( + +# Value of TAI-UTC in second valid beetween the initial value until +# the epoch given on the next line. The last line reads that NO +# leap second was introduced since the corresponding date +# Updated through IERS Bulletin 69 issued in January 2025 +# +# +# File expires on 28 December 2025 +# +# +# MJD Date TAI-UTC (s) +# day month year +# --- -------------- ------ +# + 41317.0 1 1 1972 10 + 41499.0 1 7 1972 11 + 41683.0 1 1 1973 12 + 42048.0 1 1 1974 13 + 42413.0 1 1 1975 14 + 42778.0 1 1 1976 15 + 43144.0 1 1 1977 16 + 43509.0 1 1 1978 17 + 43874.0 1 1 1979 18 + 44239.0 1 1 1980 19 + 44786.0 1 7 1981 20 + 45151.0 1 7 1982 21 + 45516.0 1 7 1983 22 + 46247.0 1 7 1985 23 + 47161.0 1 1 1988 24 + 47892.0 1 1 1990 25 + 48257.0 1 1 1991 26 + 48804.0 1 7 1992 27 + 49169.0 1 7 1993 28 + 49534.0 1 7 1994 29 + 50083.0 1 1 1996 30 + 50630.0 1 7 1997 31 + 51179.0 1 1 1999 32 + 53736.0 1 1 2006 33 + 54832.0 1 1 2009 34 + 56109.0 1 7 2012 35 + 57204.0 1 7 2015 36 + 57754.0 1 1 2017 37 +)--"; + + +// https://datacenter.iers.org/data/latestVersion/bulletinA.txt + +static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--( + + + ********************************************************************** + * * + * I E R S B U L L E T I N - A * + * * + * Rapid Service/Prediction of Earth Orientation * + ********************************************************************** + 3 July 2025 Vol. XXXVIII No. 027 + ______________________________________________________________________ + GENERAL INFORMATION: + MJD = Julian Date - 2 400 000.5 days + UT2-UT1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) + - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T) + where pi = 3.14159265... and T is the date in Besselian years. + TT = TAI + 32.184 seconds + DUT1= (UT1-UTC) transmitted with time signals + = 0.0 seconds beginning 26 December 2024 at 0000 UTC + = +0.1 seconds beginning 10 July 2025 at 0000 UTC + Beginning 1 January 2017: + TAI-UTC = 37.000 000 seconds + *********************************************************************** + * ANNOUNCEMENTS: * + * * + * The primary source for IERS Rapid Service/Prediction Center (RS/PC) * + * data products is the official IERS RS/PC website: * + * https://maia.usno.navy.mil * + * * + * IERS RS/PC products are also available from: * + * NASA CDDIS: https://cddis.nasa.gov/archive/products/iers/ * + * NASA CDDIS: ftps://gdc.cddis.eosdis.nasa.gov/products/iers/ * + * IERS Central Bureau: https://datacenter.iers.org/eop.php * + * * + * Questions about IERS RS/PC products can be emailed to: * + * eopcp@us.navy.mil * + * * + * Distribution statement A: * + * Approved for public release: distribution unlimited. * + * * + *********************************************************************** + ________________________________________________________________________ + The contributed observations used in the preparation of this Bulletin + are available at . The contributed analysis results are based + on data from Very Long Baseline Interferometry (VLBI), Satellite Laser + Ranging (SLR), the Global Positioning System (GPS) satellites, Lunar + Laser Ranging (LLR), and meteorological predictions of variations in + Atmospheric Angular Momentum (AAM). + ________________________________________________________________________ + + COMBINED EARTH ORIENTATION PARAMETERS: + + IERS Rapid Service + MJD x error y error UT1-UTC error + " " " " s s + 25 6 27 60853 0.15472 .00009 0.44036 .00009 0.040354 0.000022 + 25 6 28 60854 0.15644 .00009 0.44013 .00009 0.041389 0.000023 + 25 6 29 60855 0.15844 .00009 0.44006 .00009 0.042204 0.000024 + 25 6 30 60856 0.16029 .00009 0.44003 .00009 0.042854 0.000016 + 25 7 1 60857 0.16204 .00009 0.43988 .00009 0.043427 0.000013 + 25 7 2 60858 0.16365 .00009 0.43965 .00009 0.043890 0.000012 + 25 7 3 60859 0.16516 .00009 0.43931 .00009 0.044366 0.000009 + + IERS Final Values + MJD x y UT1-UTC + " " s + 25 5 2 60797 0.0865 0.4180 0.03007 + 25 5 3 60798 0.0873 0.4191 0.03031 + 25 5 4 60799 0.0882 0.4202 0.03039 + 25 5 5 60800 0.0889 0.4212 0.03031 + 25 5 6 60801 0.0898 0.4221 0.03006 + 25 5 7 60802 0.0907 0.4232 0.02970 + 25 5 8 60803 0.0915 0.4238 0.02932 + 25 5 9 60804 0.0925 0.4244 0.02898 + 25 5 10 60805 0.0939 0.4247 0.02874 + 25 5 11 60806 0.0955 0.4251 0.02855 + 25 5 12 60807 0.0970 0.4259 0.02849 + 25 5 13 60808 0.0980 0.4268 0.02857 + 25 5 14 60809 0.0990 0.4277 0.02880 + 25 5 15 60810 0.1001 0.4288 0.02915 + 25 5 16 60811 0.1008 0.4299 0.02958 + 25 5 17 60812 0.1012 0.4309 0.02999 + 25 5 18 60813 0.1016 0.4316 0.03034 + 25 5 19 60814 0.1027 0.4318 0.03056 + 25 5 20 60815 0.1040 0.4321 0.03061 + 25 5 21 60816 0.1052 0.4328 0.03042 + 25 5 22 60817 0.1063 0.4338 0.02998 + 25 5 23 60818 0.1073 0.4346 0.02931 + 25 5 24 60819 0.1081 0.4356 0.02856 + 25 5 25 60820 0.1086 0.4365 0.02791 + 25 5 26 60821 0.1096 0.4368 0.02748 + 25 5 27 60822 0.1106 0.4373 0.02744 + 25 5 28 60823 0.1114 0.4375 0.02772 + 25 5 29 60824 0.1116 0.4380 0.02813 + 25 5 30 60825 0.1120 0.4375 0.02851 + 25 5 31 60826 0.1127 0.4374 0.02881 + 25 6 1 60827 0.1132 0.4377 0.02899 + + _______________________________________________________________________ + + PREDICTIONS: + The following formulas will not reproduce the predictions given below, + but may be used to extend the predictions beyond the end of this table. + + x = 0.1314 + 0.0400 cos A + 0.1547 sin A - 0.0075 cos C - 0.0886 sin C + y = 0.3810 + 0.1454 cos A - 0.0330 sin A - 0.0886 cos C + 0.0075 sin C + UT1-UTC = 0.0606 + 0.00011 (MJD - 60867) - (UT2-UT1) + + where A = 2*pi*(MJD-60859)/365.25 and C = 2*pi*(MJD-60859)/435. + + TAI-UTC(MJD 60860) = 37.0 + The accuracy may be estimated from the expressions: + S x,y = 0.00068 (MJD-60859)**0.80 S t = 0.00025 (MJD-60859)**0.75 + Estimated accuracies are: Predictions 10 d 20 d 30 d 40 d + Polar coord's 0.004 0.007 0.010 0.013 + UT1-UTC 0.0014 0.0024 0.0032 0.0040 + + MJD x(arcsec) y(arcsec) UT1-UTC(sec) + 2025 7 4 60860 0.1666 0.4389 0.04491 + 2025 7 5 60861 0.1680 0.4385 0.04561 + 2025 7 6 60862 0.1694 0.4380 0.04651 + 2025 7 7 60863 0.1708 0.4375 0.04762 + 2025 7 8 60864 0.1721 0.4369 0.04889 + 2025 7 9 60865 0.1734 0.4364 0.05025 + 2025 7 10 60866 0.1747 0.4359 0.05163 + 2025 7 11 60867 0.1760 0.4353 0.05295 + 2025 7 12 60868 0.1772 0.4347 0.05411 + 2025 7 13 60869 0.1785 0.4341 0.05505 + 2025 7 14 60870 0.1797 0.4335 0.05573 + 2025 7 15 60871 0.1809 0.4329 0.05615 + 2025 7 16 60872 0.1821 0.4322 0.05641 + 2025 7 17 60873 0.1832 0.4315 0.05666 + 2025 7 18 60874 0.1844 0.4308 0.05701 + 2025 7 19 60875 0.1855 0.4301 0.05759 + 2025 7 20 60876 0.1867 0.4294 0.05843 + 2025 7 21 60877 0.1878 0.4286 0.05953 + 2025 7 22 60878 0.1889 0.4278 0.06082 + 2025 7 23 60879 0.1899 0.4271 0.06216 + 2025 7 24 60880 0.1910 0.4263 0.06342 + 2025 7 25 60881 0.1920 0.4254 0.06451 + 2025 7 26 60882 0.1931 0.4246 0.06536 + 2025 7 27 60883 0.1941 0.4237 0.06600 + 2025 7 28 60884 0.1951 0.4229 0.06647 + 2025 7 29 60885 0.1960 0.4220 0.06686 + 2025 7 30 60886 0.1970 0.4211 0.06726 + 2025 7 31 60887 0.1979 0.4201 0.06774 + 2025 8 1 60888 0.1988 0.4192 0.06835 + 2025 8 2 60889 0.1997 0.4182 0.06912 + 2025 8 3 60890 0.2006 0.4173 0.07005 + 2025 8 4 60891 0.2015 0.4163 0.07113 + 2025 8 5 60892 0.2023 0.4153 0.07233 + 2025 8 6 60893 0.2031 0.4143 0.07357 + 2025 8 7 60894 0.2039 0.4132 0.07478 + 2025 8 8 60895 0.2047 0.4122 0.07584 + 2025 8 9 60896 0.2054 0.4111 0.07666 + 2025 8 10 60897 0.2062 0.4101 0.07718 + 2025 8 11 60898 0.2069 0.4090 0.07742 + 2025 8 12 60899 0.2075 0.4079 0.07746 + 2025 8 13 60900 0.2082 0.4068 0.07741 + 2025 8 14 60901 0.2089 0.4057 0.07742 + 2025 8 15 60902 0.2095 0.4045 0.07762 + 2025 8 16 60903 0.2101 0.4034 0.07809 + 2025 8 17 60904 0.2106 0.4022 0.07884 + 2025 8 18 60905 0.2112 0.4011 0.07981 + 2025 8 19 60906 0.2117 0.3999 0.08088 + 2025 8 20 60907 0.2122 0.3987 0.08193 + 2025 8 21 60908 0.2127 0.3975 0.08285 + 2025 8 22 60909 0.2132 0.3963 0.08355 + 2025 8 23 60910 0.2136 0.3951 0.08403 + 2025 8 24 60911 0.2140 0.3939 0.08432 + 2025 8 25 60912 0.2144 0.3927 0.08451 + 2025 8 26 60913 0.2147 0.3915 0.08467 + 2025 8 27 60914 0.2151 0.3902 0.08488 + 2025 8 28 60915 0.2154 0.3890 0.08522 + 2025 8 29 60916 0.2157 0.3877 0.08573 + 2025 8 30 60917 0.2159 0.3865 0.08641 + 2025 8 31 60918 0.2162 0.3852 0.08727 + 2025 9 1 60919 0.2164 0.3840 0.08825 + 2025 9 2 60920 0.2165 0.3827 0.08931 + 2025 9 3 60921 0.2167 0.3814 0.09034 + 2025 9 4 60922 0.2168 0.3802 0.09125 + 2025 9 5 60923 0.2169 0.3789 0.09195 + 2025 9 6 60924 0.2170 0.3776 0.09236 + 2025 9 7 60925 0.2171 0.3763 0.09245 + 2025 9 8 60926 0.2171 0.3750 0.09226 + 2025 9 9 60927 0.2171 0.3738 0.09190 + 2025 9 10 60928 0.2171 0.3725 0.09154 + 2025 9 11 60929 0.2171 0.3712 0.09134 + 2025 9 12 60930 0.2170 0.3699 0.09141 + 2025 9 13 60931 0.2169 0.3686 0.09178 + 2025 9 14 60932 0.2168 0.3673 0.09239 + 2025 9 15 60933 0.2167 0.3661 0.09314 + 2025 9 16 60934 0.2165 0.3648 0.09389 + 2025 9 17 60935 0.2163 0.3635 0.09452 + 2025 9 18 60936 0.2161 0.3622 0.09495 + 2025 9 19 60937 0.2158 0.3609 0.09516 + 2025 9 20 60938 0.2156 0.3597 0.09517 + 2025 9 21 60939 0.2153 0.3584 0.09503 + 2025 9 22 60940 0.2150 0.3571 0.09484 + 2025 9 23 60941 0.2146 0.3559 0.09466 + 2025 9 24 60942 0.2142 0.3546 0.09458 + 2025 9 25 60943 0.2139 0.3534 0.09465 + 2025 9 26 60944 0.2134 0.3521 0.09489 + 2025 9 27 60945 0.2130 0.3509 0.09530 + 2025 9 28 60946 0.2125 0.3497 0.09585 + 2025 9 29 60947 0.2120 0.3484 0.09649 + 2025 9 30 60948 0.2115 0.3472 0.09713 + 2025 10 1 60949 0.2110 0.3460 0.09770 + 2025 10 2 60950 0.2104 0.3448 0.09809 + 2025 10 3 60951 0.2099 0.3436 0.09823 + 2025 10 4 60952 0.2093 0.3424 0.09807 + 2025 10 5 60953 0.2086 0.3412 0.09759 + 2025 10 6 60954 0.2080 0.3401 0.09687 + 2025 10 7 60955 0.2073 0.3389 0.09605 + 2025 10 8 60956 0.2066 0.3378 0.09532 + 2025 10 9 60957 0.2059 0.3366 0.09483 + 2025 10 10 60958 0.2052 0.3355 0.09464 + 2025 10 11 60959 0.2044 0.3344 0.09475 + 2025 10 12 60960 0.2036 0.3333 0.09504 + 2025 10 13 60961 0.2028 0.3322 0.09538 + 2025 10 14 60962 0.2020 0.3311 0.09563 + 2025 10 15 60963 0.2012 0.3300 0.09571 + 2025 10 16 60964 0.2003 0.3290 0.09557 + 2025 10 17 60965 0.1994 0.3280 0.09524 + 2025 10 18 60966 0.1985 0.3269 0.09475 + 2025 10 19 60967 0.1976 0.3259 0.09419 + 2025 10 20 60968 0.1967 0.3249 0.09361 + 2025 10 21 60969 0.1957 0.3239 0.09312 + 2025 10 22 60970 0.1947 0.3230 0.09276 + 2025 10 23 60971 0.1937 0.3220 0.09259 + 2025 10 24 60972 0.1927 0.3211 0.09259 + 2025 10 25 60973 0.1917 0.3202 0.09276 + 2025 10 26 60974 0.1906 0.3193 0.09305 + 2025 10 27 60975 0.1896 0.3184 0.09337 + 2025 10 28 60976 0.1885 0.3175 0.09366 + 2025 10 29 60977 0.1874 0.3166 0.09383 + 2025 10 30 60978 0.1863 0.3158 0.09380 + 2025 10 31 60979 0.1851 0.3150 0.09350 + 2025 11 1 60980 0.1840 0.3142 0.09291 + 2025 11 2 60981 0.1828 0.3134 0.09206 + 2025 11 3 60982 0.1817 0.3126 0.09105 + 2025 11 4 60983 0.1805 0.3119 0.09004 + 2025 11 5 60984 0.1793 0.3112 0.08919 + 2025 11 6 60985 0.1781 0.3105 0.08864 + 2025 11 7 60986 0.1768 0.3098 0.08841 + 2025 11 8 60987 0.1756 0.3091 0.08843 + 2025 11 9 60988 0.1743 0.3085 0.08858 + 2025 11 10 60989 0.1731 0.3078 0.08870 + 2025 11 11 60990 0.1718 0.3072 0.08868 + 2025 11 12 60991 0.1705 0.3066 0.08847 + 2025 11 13 60992 0.1692 0.3061 0.08807 + 2025 11 14 60993 0.1679 0.3055 0.08754 + 2025 11 15 60994 0.1666 0.3050 0.08696 + 2025 11 16 60995 0.1652 0.3045 0.08638 + 2025 11 17 60996 0.1639 0.3040 0.08589 + 2025 11 18 60997 0.1626 0.3035 0.08554 + 2025 11 19 60998 0.1612 0.3031 0.08537 + 2025 11 20 60999 0.1598 0.3027 0.08539 + 2025 11 21 61000 0.1585 0.3023 0.08559 + 2025 11 22 61001 0.1571 0.3019 0.08593 + 2025 11 23 61002 0.1557 0.3015 0.08634 + 2025 11 24 61003 0.1543 0.3012 0.08675 + 2025 11 25 61004 0.1529 0.3009 0.08707 + 2025 11 26 61005 0.1515 0.3006 0.08724 + 2025 11 27 61006 0.1501 0.3004 0.08718 + 2025 11 28 61007 0.1487 0.3001 0.08688 + 2025 11 29 61008 0.1473 0.2999 0.08634 + 2025 11 30 61009 0.1459 0.2997 0.08562 + 2025 12 1 61010 0.1445 0.2995 0.08484 + 2025 12 2 61011 0.1431 0.2994 0.08414 + 2025 12 3 61012 0.1417 0.2993 0.08368 + 2025 12 4 61013 0.1402 0.2991 0.08352 + 2025 12 5 61014 0.1388 0.2991 0.08365 + 2025 12 6 61015 0.1374 0.2990 0.08395 + 2025 12 7 61016 0.1360 0.2990 0.08429 + 2025 12 8 61017 0.1345 0.2990 0.08452 + 2025 12 9 61018 0.1331 0.2990 0.08456 + 2025 12 10 61019 0.1317 0.2990 0.08439 + 2025 12 11 61020 0.1303 0.2991 0.08408 + 2025 12 12 61021 0.1288 0.2991 0.08369 + 2025 12 13 61022 0.1274 0.2993 0.08332 + 2025 12 14 61023 0.1260 0.2994 0.08304 + 2025 12 15 61024 0.1246 0.2995 0.08289 + 2025 12 16 61025 0.1232 0.2997 0.08293 + 2025 12 17 61026 0.1218 0.2999 0.08316 + 2025 12 18 61027 0.1204 0.3001 0.08357 + 2025 12 19 61028 0.1190 0.3004 0.08414 + 2025 12 20 61029 0.1176 0.3006 0.08479 + 2025 12 21 61030 0.1162 0.3009 0.08546 + 2025 12 22 61031 0.1149 0.3012 0.08606 + 2025 12 23 61032 0.1135 0.3016 0.08651 + 2025 12 24 61033 0.1121 0.3019 0.08676 + 2025 12 25 61034 0.1108 0.3023 0.08678 + 2025 12 26 61035 0.1094 0.3027 0.08657 + 2025 12 27 61036 0.1081 0.3031 0.08620 + 2025 12 28 61037 0.1068 0.3035 0.08575 + 2025 12 29 61038 0.1055 0.3040 0.08535 + 2025 12 30 61039 0.1042 0.3045 0.08513 + 2025 12 31 61040 0.1029 0.3050 0.08516 + 2026 1 1 61041 0.1016 0.3055 0.08548 + 2026 1 2 61042 0.1003 0.3061 0.08601 + 2026 1 3 61043 0.0990 0.3067 0.08663 + 2026 1 4 61044 0.0978 0.3072 0.08720 + 2026 1 5 61045 0.0966 0.3079 0.08759 + 2026 1 6 61046 0.0953 0.3085 0.08776 + 2026 1 7 61047 0.0941 0.3091 0.08775 + 2026 1 8 61048 0.0929 0.3098 0.08763 + 2026 1 9 61049 0.0917 0.3105 0.08749 + 2026 1 10 61050 0.0906 0.3112 0.08742 + 2026 1 11 61051 0.0894 0.3120 0.08746 + 2026 1 12 61052 0.0883 0.3127 0.08766 + 2026 1 13 61053 0.0871 0.3135 0.08801 + 2026 1 14 61054 0.0860 0.3143 0.08852 + 2026 1 15 61055 0.0849 0.3151 0.08915 + 2026 1 16 61056 0.0838 0.3159 0.08984 + 2026 1 17 61057 0.0828 0.3168 0.09052 + 2026 1 18 61058 0.0817 0.3176 0.09108 + 2026 1 19 61059 0.0807 0.3185 0.09145 + 2026 1 20 61060 0.0797 0.3194 0.09156 + 2026 1 21 61061 0.0787 0.3203 0.09138 + 2026 1 22 61062 0.0777 0.3212 0.09092 + 2026 1 23 61063 0.0768 0.3222 0.09023 + 2026 1 24 61064 0.0758 0.3232 0.08943 + 2026 1 25 61065 0.0749 0.3241 0.08864 + 2026 1 26 61066 0.0740 0.3251 0.08797 + 2026 1 27 61067 0.0731 0.3261 0.08752 + 2026 1 28 61068 0.0723 0.3272 0.08730 + 2026 1 29 61069 0.0715 0.3282 0.08730 + 2026 1 30 61070 0.0706 0.3293 0.08740 + 2026 1 31 61071 0.0698 0.3303 0.08748 + 2026 2 1 61072 0.0691 0.3314 0.08742 + 2026 2 2 61073 0.0683 0.3325 0.08715 + 2026 2 3 61074 0.0676 0.3336 0.08668 + 2026 2 4 61075 0.0669 0.3347 0.08606 + 2026 2 5 61076 0.0662 0.3359 0.08538 + 2026 2 6 61077 0.0655 0.3370 0.08476 + 2026 2 7 61078 0.0649 0.3381 0.08430 + 2026 2 8 61079 0.0643 0.3393 0.08405 + 2026 2 9 61080 0.0637 0.3405 0.08401 + 2026 2 10 61081 0.0631 0.3417 0.08423 + 2026 2 11 61082 0.0625 0.3429 0.08462 + 2026 2 12 61083 0.0620 0.3441 0.08513 + 2026 2 13 61084 0.0615 0.3453 0.08570 + 2026 2 14 61085 0.0610 0.3465 0.08618 + 2026 2 15 61086 0.0606 0.3478 0.08646 + 2026 2 16 61087 0.0601 0.3490 0.08651 + 2026 2 17 61088 0.0597 0.3502 0.08629 + 2026 2 18 61089 0.0594 0.3515 0.08575 + 2026 2 19 61090 0.0590 0.3528 0.08502 + 2026 2 20 61091 0.0587 0.3540 0.08419 + 2026 2 21 61092 0.0584 0.3553 0.08335 + 2026 2 22 61093 0.0581 0.3566 0.08261 + 2026 2 23 61094 0.0578 0.3579 0.08206 + 2026 2 24 61095 0.0576 0.3592 0.08182 + 2026 2 25 61096 0.0574 0.3605 0.08174 + 2026 2 26 61097 0.0572 0.3618 0.08178 + 2026 2 27 61098 0.0570 0.3631 0.08189 + 2026 2 28 61099 0.0569 0.3644 0.08189 + 2026 3 1 61100 0.0568 0.3657 0.08172 + 2026 3 2 61101 0.0567 0.3670 0.08136 + 2026 3 3 61102 0.0567 0.3683 0.08079 + 2026 3 4 61103 0.0566 0.3697 0.08008 + 2026 3 5 61104 0.0566 0.3710 0.07935 + 2026 3 6 61105 0.0567 0.3723 0.07875 + 2026 3 7 61106 0.0567 0.3736 0.07836 + 2026 3 8 61107 0.0568 0.3749 0.07813 + 2026 3 9 61108 0.0569 0.3763 0.07808 + 2026 3 10 61109 0.0570 0.3776 0.07827 + 2026 3 11 61110 0.0571 0.3789 0.07855 + 2026 3 12 61111 0.0573 0.3802 0.07886 + 2026 3 13 61112 0.0575 0.3815 0.07917 + 2026 3 14 61113 0.0577 0.3828 0.07941 + 2026 3 15 61114 0.0580 0.3841 0.07945 + 2026 3 16 61115 0.0583 0.3855 0.07926 + 2026 3 17 61116 0.0586 0.3868 0.07879 + 2026 3 18 61117 0.0589 0.3881 0.07805 + 2026 3 19 61118 0.0592 0.3893 0.07714 + 2026 3 20 61119 0.0596 0.3906 0.07617 + 2026 3 21 61120 0.0600 0.3919 0.07528 + 2026 3 22 61121 0.0604 0.3932 0.07457 + 2026 3 23 61122 0.0609 0.3945 0.07407 + 2026 3 24 61123 0.0614 0.3957 0.07389 + 2026 3 25 61124 0.0619 0.3970 0.07393 + 2026 3 26 61125 0.0624 0.3982 0.07404 + 2026 3 27 61126 0.0629 0.3995 0.07410 + 2026 3 28 61127 0.0635 0.4007 0.07400 + 2026 3 29 61128 0.0641 0.4020 0.07359 + 2026 3 30 61129 0.0647 0.4032 0.07292 + 2026 3 31 61130 0.0653 0.4044 0.07215 + 2026 4 1 61131 0.0660 0.4056 0.07125 + 2026 4 2 61132 0.0667 0.4068 0.07037 + 2026 4 3 61133 0.0674 0.4080 0.06956 + 2026 4 4 61134 0.0681 0.4091 0.06893 + 2026 4 5 61135 0.0689 0.4103 0.06842 + 2026 4 6 61136 0.0697 0.4114 0.06812 + 2026 4 7 61137 0.0705 0.4126 0.06802 + 2026 4 8 61138 0.0713 0.4137 0.06814 + 2026 4 9 61139 0.0721 0.4148 0.06828 + 2026 4 10 61140 0.0730 0.4159 0.06842 + 2026 4 11 61141 0.0739 0.4170 0.06844 + 2026 4 12 61142 0.0748 0.4180 0.06820 + 2026 4 13 61143 0.0757 0.4191 0.06770 + 2026 4 14 61144 0.0766 0.4201 0.06699 + 2026 4 15 61145 0.0776 0.4212 0.06611 + 2026 4 16 61146 0.0786 0.4222 0.06511 + 2026 4 17 61147 0.0796 0.4232 0.06423 + 2026 4 18 61148 0.0806 0.4242 0.06358 + 2026 4 19 61149 0.0816 0.4251 0.06321 + 2026 4 20 61150 0.0827 0.4261 0.06322 + 2026 4 21 61151 0.0837 0.4270 0.06337 + 2026 4 22 61152 0.0848 0.4279 0.06356 + 2026 4 23 61153 0.0859 0.4288 0.06364 + 2026 4 24 61154 0.0871 0.4297 0.06349 + 2026 4 25 61155 0.0882 0.4306 0.06314 + 2026 4 26 61156 0.0894 0.4314 0.06257 + 2026 4 27 61157 0.0905 0.4322 0.06185 + 2026 4 28 61158 0.0917 0.4331 0.06111 + 2026 4 29 61159 0.0929 0.4339 0.06040 + 2026 4 30 61160 0.0941 0.4346 0.05980 + 2026 5 1 61161 0.0954 0.4354 0.05946 + 2026 5 2 61162 0.0966 0.4361 0.05933 + 2026 5 3 61163 0.0979 0.4368 0.05942 + 2026 5 4 61164 0.0991 0.4375 0.05971 + 2026 5 5 61165 0.1004 0.4382 0.06017 + 2026 5 6 61166 0.1017 0.4388 0.06065 + 2026 5 7 61167 0.1030 0.4395 0.06110 + 2026 5 8 61168 0.1043 0.4401 0.06146 + 2026 5 9 61169 0.1057 0.4407 0.06171 + 2026 5 10 61170 0.1070 0.4413 0.06171 + 2026 5 11 61171 0.1084 0.4418 0.06155 + 2026 5 12 61172 0.1097 0.4423 0.06119 + 2026 5 13 61173 0.1111 0.4428 0.06070 + 2026 5 14 61174 0.1125 0.4433 0.06014 + 2026 5 15 61175 0.1139 0.4438 0.05964 + 2026 5 16 61176 0.1153 0.4442 0.05948 + 2026 5 17 61177 0.1167 0.4446 0.05963 + 2026 5 18 61178 0.1181 0.4450 0.06010 + 2026 5 19 61179 0.1195 0.4454 0.06068 + 2026 5 20 61180 0.1209 0.4458 0.06123 + 2026 5 21 61181 0.1224 0.4461 0.06169 + 2026 5 22 61182 0.1238 0.4464 0.06196 + 2026 5 23 61183 0.1252 0.4467 0.06208 + 2026 5 24 61184 0.1267 0.4469 0.06202 + 2026 5 25 61185 0.1281 0.4472 0.06187 + 2026 5 26 61186 0.1296 0.4474 0.06184 + 2026 5 27 61187 0.1311 0.4476 0.06187 + 2026 5 28 61188 0.1325 0.4477 0.06209 + 2026 5 29 61189 0.1340 0.4479 0.06251 + 2026 5 30 61190 0.1355 0.4480 0.06313 + 2026 5 31 61191 0.1369 0.4481 0.06394 + 2026 6 1 61192 0.1384 0.4482 0.06487 + 2026 6 2 61193 0.1399 0.4482 0.06591 + 2026 6 3 61194 0.1413 0.4482 0.06694 + 2026 6 4 61195 0.1428 0.4482 0.06790 + 2026 6 5 61196 0.1443 0.4482 0.06877 + 2026 6 6 61197 0.1457 0.4482 0.06950 + 2026 6 7 61198 0.1472 0.4481 0.07002 + 2026 6 8 61199 0.1487 0.4480 0.07030 + 2026 6 9 61200 0.1501 0.4479 0.07051 + 2026 6 10 61201 0.1516 0.4477 0.07062 + 2026 6 11 61202 0.1530 0.4476 0.07078 + 2026 6 12 61203 0.1545 0.4474 0.07103 + 2026 6 13 61204 0.1559 0.4472 0.07158 + 2026 6 14 61205 0.1574 0.4469 0.07239 + 2026 6 15 61206 0.1588 0.4467 0.07343 + 2026 6 16 61207 0.1602 0.4464 0.07452 + 2026 6 17 61208 0.1616 0.4461 0.07551 + 2026 6 18 61209 0.1631 0.4458 0.07621 + 2026 6 19 61210 0.1645 0.4454 0.07668 + 2026 6 20 61211 0.1659 0.4450 0.07691 + 2026 6 21 61212 0.1673 0.4446 0.07694 + 2026 6 22 61213 0.1686 0.4442 0.07699 + 2026 6 23 61214 0.1700 0.4438 0.07723 + 2026 6 24 61215 0.1714 0.4433 0.07764 + 2026 6 25 61216 0.1727 0.4428 0.07823 + 2026 6 26 61217 0.1741 0.4423 0.07906 + 2026 6 27 61218 0.1754 0.4418 0.08011 + 2026 6 28 61219 0.1768 0.4412 0.08129 + 2026 6 29 61220 0.1781 0.4406 0.08253 + 2026 6 30 61221 0.1794 0.4400 0.08379 + 2026 7 1 61222 0.1807 0.4394 0.08503 + 2026 7 2 61223 0.1819 0.4388 0.08607 + 2026 7 3 61224 0.1832 0.4381 0.08690 + These predictions are based on all announced leap seconds. + + CELESTIAL POLE OFFSET SERIES: + NEOS Celestial Pole Offset Series + MJD dpsi error deps error + (msec. of arc) + 60837 -112.47 0.89 -11.70 0.14 + 60838 -112.54 0.89 -11.60 0.14 + 60839 -112.51 0.89 -11.35 0.14 + 60840 -112.45 0.32 -11.16 0.16 + 60841 -112.45 1.48 -11.11 0.30 + 60842 -112.49 1.48 -11.13 0.30 + 60843 -112.49 1.48 -11.15 0.30 + 60844 -112.49 1.20 -11.12 0.28 + 60845 -112.62 1.20 -11.03 0.28 + 60846 -112.97 1.20 -10.87 0.28 + + IERS Celestial Pole Offset Final Series + MJD dpsi deps + (msec. of arc) + 60797 -109.8 -11.9 + 60798 -109.1 -12.1 + 60799 -108.8 -12.0 + 60800 -108.9 -11.6 + 60801 -109.3 -11.1 + 60802 -109.7 -10.8 + 60803 -109.8 -10.7 + 60804 -109.8 -10.6 + 60805 -109.7 -10.6 + 60806 -109.6 -10.8 + 60807 -109.5 -11.3 + 60808 -109.5 -11.7 + 60809 -109.6 -11.9 + 60810 -109.7 -11.8 + 60811 -109.7 -11.6 + 60812 -109.6 -11.6 + 60813 -109.5 -11.6 + 60814 -109.3 -11.6 + 60815 -109.2 -11.6 + 60816 -109.3 -11.6 + 60817 -109.4 -11.6 + 60818 -109.7 -11.4 + 60819 -110.2 -11.0 + 60820 -111.0 -10.7 + 60821 -111.6 -10.8 + 60822 -111.9 -11.1 + 60823 -111.8 -11.3 + 60824 -111.5 -11.6 + 60825 -110.9 -11.7 + 60826 -110.5 -11.8 + 60827 -110.5 -11.7 + + IAU2000A Celestial Pole Offset Series + MJD dX error dY error + (msec. of arc) + 60837 0.432 0.352 -0.216 0.145 + 60838 0.439 0.352 -0.218 0.145 + 60839 0.448 0.352 -0.222 0.145 + 60840 0.457 0.128 -0.227 0.160 + 60841 0.465 0.588 -0.235 0.303 + 60842 0.472 0.588 -0.243 0.303 + 60843 0.476 0.588 -0.251 0.303 + 60844 0.476 0.476 -0.260 0.282 + 60845 0.472 0.476 -0.267 0.282 + 60846 0.467 0.476 -0.275 0.282 + + + IAU2000A Celestial Pole Offset Final Series + MJD dX dY + (msec. of arc) + 60797 0.44 -0.19 + 60798 0.51 -0.19 + 60799 0.53 -0.19 + 60800 0.52 -0.18 + 60801 0.49 -0.17 + 60802 0.41 -0.16 + 60803 0.33 -0.14 + 60804 0.31 -0.16 + 60805 0.34 -0.21 + 60806 0.39 -0.26 + 60807 0.44 -0.30 + 60808 0.49 -0.33 + 60809 0.48 -0.26 + 60810 0.45 -0.17 + 60811 0.42 -0.09 + 60812 0.42 -0.07 + 60813 0.43 -0.10 + 60814 0.44 -0.14 + 60815 0.45 -0.18 + 60816 0.43 -0.21 + 60817 0.40 -0.22 + 60818 0.37 -0.22 + 60819 0.37 -0.21 + 60820 0.38 -0.19 + 60821 0.39 -0.16 + 60822 0.40 -0.14 + 60823 0.41 -0.12 + 60824 0.41 -0.11 + 60825 0.41 -0.11 + 60826 0.39 -0.14 + 60827 0.34 -0.18 + +)--"; + + + +} // namespace mcc::astrom::iers::defaults + diff --git a/cxx/mcc_mount_astro_erfa.h b/cxx/mcc_mount_astro_erfa.h new file mode 100644 index 0000000..ef7084f --- /dev/null +++ b/cxx/mcc_mount_astro_erfa.h @@ -0,0 +1,69 @@ +#pragma once + +/* MOUNT CONTROL COMPONENTS LIBRARY */ + + +/* ASTROMETRY ENGINE BASED ON ERFA-LIBRARY */ + +#include +// #include + + +#include "mcc_astrom_iers.h" +#include "mcc_mount_coord.h" + +namespace mcc::astrom::erfa +{ + +#include +#include + +class MccMountAstromEngineERFA +{ +public: + typedef int engine_err_t; + + // meteo parameters (to compute refraction) + struct meteo_t { + typedef double temp_t; + typedef double humid_t; + typedef double press_t; + + temp_t temperature; // Temperature in C + humid_t humidity; // humidity in % ([0.0, 1.0]) + press_t pressure; // atmospheric presure in hPa=mB + }; + + struct engine_state_t { + meteo_t meteo{.temperature = 0.0, .humidity = 0.5, .pressure = 1010.0}; + + double wavelength = 0.55; // observed wavelength in mkm + + MccAngleLAT lat = "00:00:00"_dms; // site latitude + MccAngleLON lon = "00:00:00"_dms; // site longitude + + mcc::astrom::iers::MccLeapSeconds _leapSeconds{}; + mcc::astrom::iers::MccIersBulletinA _bulletinA{}; + }; + + typedef std::chrono::system_clock::time_point time_point_t; + + struct juldate_t { + static constexpr double MJD0 = ERFA_DJM0; + double mjd{51544.5}; // J2000.0 + }; + + typedef MccAngle coord_t; + typedef MccAngle gst_t; + typedef MccAngle pa_t; + typedef double eo_t; + + struct refract_result_t { + double refa, refb; + }; + +protected: + engine_state_t _currentState; +}; + +} // namespace mcc::astrom::erfa diff --git a/cxx/mcc_mount_astrom.h b/cxx/mcc_mount_astrom.h index f5c9f34..388b793 100644 --- a/cxx/mcc_mount_astrom.h +++ b/cxx/mcc_mount_astrom.h @@ -8,7 +8,7 @@ #include -#include "mcc_traits.h" +// #include "mcc_traits.h" namespace mcc::traits { @@ -18,48 +18,66 @@ concept mcc_astrom_engine_c = requires(T t) { typename T::engine_err_t; typename T::engine_state_t; - typename T::meteo_t; + typename T::coord_t; + typename T::time_point_t; + typename T::juldate_t; + typename T::gst_t; + typename T::pa_t; + typename T::eo_t; - { t.updateState() }; + typename T::refract_result_t; + + + { t.updateState(std::declval()) }; /* coordinates conversional methods */ - // ICRS RA and DEC to observed place: icrs2obs(ra, dec, time_point, ra_app, dec_app, ha, az, alt, eo) - { t.icrs2obs() } -> std::same_as; + // ICRS RA and DEC to observed place: icrs2obs(ra, dec, jd, ra_app, dec_app, ha, az, alt, eo) + { + t.icrs2obs(std::declval(), std::declval(), + std::declval(), std::declval(), + std::declval(), std::declval(), + std::declval(), std::declval(), + std::declval()) + } -> std::same_as; // compute hour angle and declination from azimuth and altitude: hadec2azalt(ha, dec, az, alt) { - t.hadec2azalt(std::declval(), std::declval(), std::declval(), std::declval()) + t.hadec2azalt(std::declval(), std::declval(), + std::declval(), std::declval()) } -> std::same_as; // compute azimuth and altitude from hour angle and declination: azalt2hadec(az, alt, ha, dec) { - t.azalt2hadec(std::declval(), std::declval(), std::declval(), std::declval()) + t.azalt2hadec(std::declval(), std::declval(), + std::declval(), std::declval()) } -> std::same_as; // compute paralactic angle: hadec2pa(ha, dec, pa) { - t.hadec2pa(std::declval(), std::declval(), std::declval()) + t.hadec2pa(std::declval(), std::declval(), + std::declval()) } -> std::same_as; /* time-related methods */ - // Gregorian Calendar time point to Julian Date: greg2jul(time_point, mjd) - // { t.greg2jul() } -> std::same_as; - requires mcc_systime_c>; - requires std::constructible_from, double>; + // Gregorian Calendar time point to Julian Date: greg2jul(time_point, jd) + { + t.greg2jul(std::declval(), std::declval()) + } -> std::same_as; + // requires mcc_systime_c>; + // requires mcc_output_arg_c, typename T::juldate_t>; - // apparent sideral time at given longitude (positive to the East): apparentSiderTime(utc, gst) - { t.apparentSiderTime(std::declval()) } -> std::same_as; + // apparent sideral time: apparentSiderTime(jd, gst) + { + t.apparentSiderTime(std::declval(), std::declval()) + } -> std::same_as; /* atmospheric refraction-related methods */ - typename T::refract_result_t; - { - t.refraction(std::declval(), std::declval()) - } -> std::same_as; + { t.refraction(std::declval()) } -> std::same_as; }; } // namespace mcc::traits diff --git a/cxx/mcc_traits.h b/cxx/mcc_traits.h index 347e31f..a1b5e9a 100644 --- a/cxx/mcc_traits.h +++ b/cxx/mcc_traits.h @@ -124,15 +124,26 @@ template struct mcc_func_traits : mcc_func_traits { }; +// type of the returned value template using mcc_retval_t = typename mcc_func_traits::ret_t; +// type of the first argument of callable template using mcc_func_arg1_t = typename mcc_func_traits::arg1_t; +// type of the N-th argument of callable +// NOTE: starts from 1 not from 0!!! template -using mcc_func_argN_t = std:: - conditional_t= mcc_func_traits::arity, std::tuple_element_t::args_t>, void>; +using mcc_func_argN_t = std::conditional_t= mcc_func_traits::arity, + std::tuple_element_t::args_t>, + void>; + + +// non-const lvalue reference, constructible from CtorArgTs (an output argument of function) +template +concept mcc_output_arg_c = !std::is_const_v> && std::is_lvalue_reference_v && + std::constructible_from, CtorArgTs...>; namespace details { diff --git a/cxx/mount.h b/cxx/mount.h index 082eda4..db45f05 100644 --- a/cxx/mount.h +++ b/cxx/mount.h @@ -10,7 +10,7 @@ #include #include "spdlog/sinks/null_sink.h" -#include "mcc_coord.h" +// #include "mcc_coord.h" #include "mcc_finite_state_machine.h" #include "mcc_spdlog.h" #include "mcc_traits.h" diff --git a/cxx/mount_pz.h b/cxx/mount_pz.h index 85c9943..628e90a 100644 --- a/cxx/mount_pz.h +++ b/cxx/mount_pz.h @@ -1,6 +1,6 @@ #pragma once -#include "mcc_coord.h" +// #include "mcc_coord.h" #include "mount_astrom.h" namespace mcc diff --git a/cxx/tests/astrom_test.cpp b/cxx/tests/astrom_test.cpp index 38bba03..d5d8899 100644 --- a/cxx/tests/astrom_test.cpp +++ b/cxx/tests/astrom_test.cpp @@ -1,9 +1,31 @@ #include #include -#include "../mcc_coord.h" +// #include "../mcc_coord.h" +#include "../mcc_traits.h" #include "../mount_astrom.h" +template +concept ncr_c = + std::is_lvalue_reference_v && !std::is_const_v && std::constructible_from, U>; + + +template +concept ae_c = requires(T t) { + requires mcc::traits::mcc_systime_c>; + requires mcc::traits::mcc_output_arg_c>; + // requires ncr_c, double>; + // requires std::constructible_from, double>; +}; + + +struct AE { + // int greg2jul(mcc::traits::mcc_systime_c auto t, double f) {} + int greg2jul(std::chrono::sys_time t, double& f) + { + return 0; + } +}; // BTA coords from maps.yandex.ru: 43.646711, 41.440732 @@ -139,5 +161,8 @@ int main(int argc, char* argv[]) std::cout << ra.sexagesimal(false, 4) << "\n"; + std::cout << "\n\n\n"; + std::cout << "ae_c = " << std::boolalpha << ae_c << "\n"; + return ecode; } diff --git a/cxx/update_iers_data.sh b/cxx/update_iers_data.sh new file mode 100755 index 0000000..aaad175 --- /dev/null +++ b/cxx/update_iers_data.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# +# $1 - output filename +# + +if [[ $# -eq 0 ]]; then + res_file="mcc_astrom_iers_default.h" +else + res_file=$1 +fi + + +echo -e '#pragma once\n + +#include \n + +namespace mcc::astrom::iers::defaults\n +{ + +// https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat\n +static std::string MCC_DEFAULT_LEAP_SECONDS_FILE = R"--(\n' > $res_file + +wget --quiet https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat -O - >> $res_file + +echo -e ')--";\n\n' >> $res_file + +echo -e '// https://datacenter.iers.org/data/latestVersion/bulletinA.txt\n +static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(\n' >> $res_file + +wget --quiet https://datacenter.iers.org/data/latestVersion/bulletinA.txt -O - >> $res_file + +echo -e ')--";\n + + +} // namespace mcc::astrom::iers::defaults\n' >> $res_file