This commit is contained in:
Timur A. Fatkhullin 2025-07-04 12:24:34 +03:00
parent 08b582b895
commit b3b275edd8
10 changed files with 1342 additions and 47 deletions

View File

@ -130,24 +130,22 @@ add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC})
target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23) target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23)
target_include_directories(${MCC_LIBRARY} INTERFACE ${FITPACK_INCLUDE_DIR}) 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 # 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) # 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) # set(MOUNT_SERVER_APP mount_server)
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC} # add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC})
mcc_finite_state_machine.h # # target_include_directories(${MOUNT_SERVER_APP} PUBLIC ${ERFA_INCLUDE_DIR})
mcc_mount_events_states.h) # target_link_libraries(${MOUNT_SERVER_APP} ${CNTR_PROTO_LIB} spdlog::spdlog_header_only ERFA_LIB)
# 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) if (WITH_TESTS)
set(CNTR_PROTO_TEST_APP cntr_proto_test) # set(CNTR_PROTO_TEST_APP cntr_proto_test)
add_executable(${CNTR_PROTO_TEST_APP} tests/cntr_proto_test.cpp) # 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} spdlog::spdlog_header_only)
# target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB}) # # target_link_libraries(${CNTR_PROTO_TEST_APP} ${CNTR_PROTO_LIB})
# target_include_directories(${CNTR_PROTO_TEST_APP} PUBLIC ${SPDLOG_INCLUDE_DIRS}) # # target_include_directories(${CNTR_PROTO_TEST_APP} PUBLIC ${SPDLOG_INCLUDE_DIRS})
set(CFGFILE_TEST_APP configfile_test) # set(CFGFILE_TEST_APP configfile_test)
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)
@ -163,16 +161,16 @@ if (WITH_TESTS)
# add_executable(${FSM_TEST_APP} tests/fsm_test.cpp) # add_executable(${FSM_TEST_APP} tests/fsm_test.cpp)
set(TESTS_SRC tests/coord.cpp tests/fsm.cpp tests/mount.cpp) # set(TESTS_SRC tests/coord.cpp tests/fsm.cpp tests/mount.cpp)
create_test_sourcelist(Tests common_tests.cpp ${TESTS_SRC}) # create_test_sourcelist(Tests common_tests.cpp ${TESTS_SRC})
add_executable(common_tests ${Tests}) # add_executable(common_tests ${Tests})
target_include_directories(common_tests PRIVATE ${FITPACK_INCLUDE_DIR}) # target_include_directories(common_tests PRIVATE ${FITPACK_INCLUDE_DIR})
target_link_libraries(common_tests fitpack) # target_link_libraries(common_tests fitpack)
foreach (test ${TESTS_SRC}) # foreach (test ${TESTS_SRC})
get_filename_component (TName ${test} NAME_WE) # get_filename_component (TName ${test} NAME_WE)
add_test (NAME ${TName} COMMAND common_tests tests/${TName}) # add_test (NAME ${TName} COMMAND common_tests tests/${TName})
endforeach () # endforeach ()
enable_testing() enable_testing()
endif() endif()

486
cxx/mcc_astrom_iers.h Normal file
View File

@ -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 <chrono>
#include <fstream>
#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<double> 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<std::basic_istream<char>> auto& stream, char comment_sym = '#')
{
std::istringstream is;
double mjd;
unsigned day, month;
int year;
double tai_utc;
decltype(_expireDate) edate;
std::vector<leapsecond_db_elem_t> 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<std::chrono::days>(_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<double>(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<double> operator[](const time_point_t& tp) const
std::optional<real_secs_t> 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<std::chrono::days>(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<double> operator[](const double& mjd) const
std::optional<real_secs_t> 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<std::basic_ostream<char>> 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<leapsecond_db_elem_t> _db{};
};
class MccIersBulletinA final
{
public:
typedef std::chrono::system_clock::time_point time_point_t;
typedef std::chrono::duration<double> 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<double> DUT1(const time_point_t& tp) const
std::optional<real_secs_t> DUT1(const time_point_t& tp) const
{
// use of the closest date
std::chrono::year_month_day ymd{std::chrono::round<std::chrono::days>(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<double> DUT1(double mjd) const
std::optional<real_secs_t> 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<pole_pos_t> polarCoords(const time_point_t& tp) const
{
std::chrono::year_month_day ymd{std::chrono::round<std::chrono::days>(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<pole_pos_t> 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<std::basic_istream<char>> auto& stream, char comment_sym = '*')
{
std::vector<earth_orient_db_elem_t> 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<std::basic_ostream<char>> 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<earth_orient_db_elem_t> _db;
};
} // namespace mcc::astrom::iers

View File

@ -0,0 +1,652 @@
#pragma once
#include <string>
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 <http://www.usno.navy.mil/USNO/earth-orientation/
eo-info/general/input-data>. 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

View File

@ -0,0 +1,69 @@
#pragma once
/* MOUNT CONTROL COMPONENTS LIBRARY */
/* ASTROMETRY ENGINE BASED ON ERFA-LIBRARY */
#include <chrono>
// #include <cmath>
#include "mcc_astrom_iers.h"
#include "mcc_mount_coord.h"
namespace mcc::astrom::erfa
{
#include <erfa.h>
#include <erfam.h>
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

View File

@ -8,7 +8,7 @@
#include <concepts> #include <concepts>
#include "mcc_traits.h" // #include "mcc_traits.h"
namespace mcc::traits namespace mcc::traits
{ {
@ -18,48 +18,66 @@ concept mcc_astrom_engine_c = requires(T t) {
typename T::engine_err_t; typename T::engine_err_t;
typename T::engine_state_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<typename T::engine_state_t>()) };
/* coordinates conversional methods */ /* coordinates conversional methods */
// ICRS RA and DEC to observed place: icrs2obs(ra, dec, time_point, ra_app, dec_app, ha, az, alt, eo) // ICRS RA and DEC to observed place: icrs2obs(ra, dec, jd, ra_app, dec_app, ha, az, alt, eo)
{ t.icrs2obs() } -> std::same_as<typename T::engine_err_t>; {
t.icrs2obs(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
std::declval<typename T::juldate_t>(), std::declval<typename T::coord_t&>(),
std::declval<typename T::coord_t&>(), std::declval<typename T::coord_t&>(),
std::declval<typename T::coord_t&>(), std::declval<typename T::coord_t&>(),
std::declval<typename T::eo_t&>())
} -> std::same_as<typename T::engine_err_t>;
// compute hour angle and declination from azimuth and altitude: hadec2azalt(ha, dec, az, alt) // compute hour angle and declination from azimuth and altitude: hadec2azalt(ha, dec, az, alt)
{ {
t.hadec2azalt(std::declval<double>(), std::declval<double>(), std::declval<double&>(), std::declval<double&>()) t.hadec2azalt(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
std::declval<typename T::coord_t&>(), std::declval<typename T::coord_t&>())
} -> std::same_as<typename T::engine_err_t>; } -> std::same_as<typename T::engine_err_t>;
// compute azimuth and altitude from hour angle and declination: azalt2hadec(az, alt, ha, dec) // compute azimuth and altitude from hour angle and declination: azalt2hadec(az, alt, ha, dec)
{ {
t.azalt2hadec(std::declval<double>(), std::declval<double>(), std::declval<double&>(), std::declval<double&>()) t.azalt2hadec(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
std::declval<typename T::coord_t&>(), std::declval<typename T::coord_t&>())
} -> std::same_as<typename T::engine_err_t>; } -> std::same_as<typename T::engine_err_t>;
// compute paralactic angle: hadec2pa(ha, dec, pa) // compute paralactic angle: hadec2pa(ha, dec, pa)
{ {
t.hadec2pa(std::declval<double>(), std::declval<double>(), std::declval<double&>()) t.hadec2pa(std::declval<typename T::coord_t>(), std::declval<typename T::coord_t>(),
std::declval<typename T::pa_t&>())
} -> std::same_as<typename T::engine_err_t>; } -> std::same_as<typename T::engine_err_t>;
/* time-related methods */ /* time-related methods */
// Gregorian Calendar time point to Julian Date: greg2jul(time_point, mjd) // Gregorian Calendar time point to Julian Date: greg2jul(time_point, jd)
// { t.greg2jul() } -> std::same_as<typename T::engine_err_t>; {
requires mcc_systime_c<mcc_func_arg1_t<decltype(&T::greg2jul)>>; t.greg2jul(std::declval<typename T::time_point_t>(), std::declval<typename T::juldate_t&>())
requires std::constructible_from<mcc_func_argN_t<decltype(&T::greg2jul), 2>, double>; } -> std::same_as<typename T::engine_err_t>;
// requires mcc_systime_c<mcc_func_arg1_t<decltype(&T::greg2jul)>>;
// requires mcc_output_arg_c<mcc_func_argN_t<decltype(&T::greg2jul), 2>, typename T::juldate_t>;
// apparent sideral time at given longitude (positive to the East): apparentSiderTime(utc, gst) // apparent sideral time: apparentSiderTime(jd, gst)
{ t.apparentSiderTime(std::declval<const double&>()) } -> std::same_as<typename T::engine_err_t>; {
t.apparentSiderTime(std::declval<typename T::juldate_t&>(), std::declval<typename T::gst_t&>())
} -> std::same_as<typename T::engine_err_t>;
/* atmospheric refraction-related methods */ /* atmospheric refraction-related methods */
typename T::refract_result_t; { t.refraction(std::declval<typename T::refract_result_t&>()) } -> std::same_as<typename T::engine_err_t>;
{
t.refraction(std::declval<const typename T::meteo_t&>(), std::declval<typename T::refract_result_t&>())
} -> std::same_as<typename T::engine_err_t>;
}; };
} // namespace mcc::traits } // namespace mcc::traits

View File

@ -124,15 +124,26 @@ template <typename F>
struct mcc_func_traits<F&&> : mcc_func_traits<F> { struct mcc_func_traits<F&&> : mcc_func_traits<F> {
}; };
// type of the returned value
template <typename T> template <typename T>
using mcc_retval_t = typename mcc_func_traits<T>::ret_t; using mcc_retval_t = typename mcc_func_traits<T>::ret_t;
// type of the first argument of callable
template <typename T> template <typename T>
using mcc_func_arg1_t = typename mcc_func_traits<T>::arg1_t; using mcc_func_arg1_t = typename mcc_func_traits<T>::arg1_t;
// type of the N-th argument of callable
// NOTE: starts from 1 not from 0!!!
template <typename T, size_t N = 1> template <typename T, size_t N = 1>
using mcc_func_argN_t = std:: using mcc_func_argN_t = std::conditional_t<N >= mcc_func_traits<T>::arity,
conditional_t<N >= mcc_func_traits<T>::arity, std::tuple_element_t<N, typename mcc_func_traits<T>::args_t>, void>; std::tuple_element_t<N - 1, typename mcc_func_traits<T>::args_t>,
void>;
// non-const lvalue reference, constructible from CtorArgTs (an output argument of function)
template <typename T, typename... CtorArgTs>
concept mcc_output_arg_c = !std::is_const_v<std::remove_reference_t<T>> && std::is_lvalue_reference_v<T> &&
std::constructible_from<std::remove_reference_t<T>, CtorArgTs...>;
namespace details namespace details
{ {

View File

@ -10,7 +10,7 @@
#include <string_view> #include <string_view>
#include "spdlog/sinks/null_sink.h" #include "spdlog/sinks/null_sink.h"
#include "mcc_coord.h" // #include "mcc_coord.h"
#include "mcc_finite_state_machine.h" #include "mcc_finite_state_machine.h"
#include "mcc_spdlog.h" #include "mcc_spdlog.h"
#include "mcc_traits.h" #include "mcc_traits.h"

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "mcc_coord.h" // #include "mcc_coord.h"
#include "mount_astrom.h" #include "mount_astrom.h"
namespace mcc namespace mcc

View File

@ -1,9 +1,31 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "../mcc_coord.h" // #include "../mcc_coord.h"
#include "../mcc_traits.h"
#include "../mount_astrom.h" #include "../mount_astrom.h"
template <typename T, typename U>
concept ncr_c =
std::is_lvalue_reference_v<T> && !std::is_const_v<T> && std::constructible_from<std::remove_reference_t<T>, U>;
template <typename T>
concept ae_c = requires(T t) {
requires mcc::traits::mcc_systime_c<mcc::traits::mcc_func_arg1_t<decltype(&T::greg2jul)>>;
requires mcc::traits::mcc_output_arg_c<mcc::traits::mcc_func_argN_t<decltype(&T::greg2jul), 2>>;
// requires ncr_c<mcc::traits::mcc_func_argN_t<decltype(&T::greg2jul), 2>, double>;
// requires std::constructible_from<mcc::traits::mcc_func_argN_t<decltype(&T::greg2jul), 2>, double>;
};
struct AE {
// int greg2jul(mcc::traits::mcc_systime_c auto t, double f) {}
int greg2jul(std::chrono::sys_time<std::chrono::nanoseconds> t, double& f)
{
return 0;
}
};
// BTA coords from maps.yandex.ru: 43.646711, 41.440732 // 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 << ra.sexagesimal(false, 4) << "\n";
std::cout << "\n\n\n";
std::cout << "ae_c = " << std::boolalpha << ae_c<AE> << "\n";
return ecode; return ecode;
} }

36
cxx/update_iers_data.sh Executable file
View File

@ -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 <string>\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