Compare commits

..

No commits in common. "06c8345fc96d918d1fa68ab0ee357dce3b50c057" and "ca74d1dd73dc0e106bed41449297669b111778ad" have entirely different histories.

14 changed files with 1144 additions and 2626 deletions

View File

@ -67,7 +67,7 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
* * * *
* Rapid Service/Prediction of Earth Orientation * * Rapid Service/Prediction of Earth Orientation *
********************************************************************** **********************************************************************
14 August 2025 Vol. XXXVIII No. 033 7 August 2025 Vol. XXXVIII No. 032
______________________________________________________________________ ______________________________________________________________________
GENERAL INFORMATION: GENERAL INFORMATION:
MJD = Julian Date - 2 400 000.5 days MJD = Julian Date - 2 400 000.5 days
@ -116,13 +116,47 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
IERS Rapid Service IERS Rapid Service
MJD x error y error UT1-UTC error MJD x error y error UT1-UTC error
" " " " s s " " " " s s
25 8 8 60895 0.21521 .00009 0.41904 .00009 0.069826 0.000016 25 8 1 60888 0.21017 .00009 0.42717 .00009 0.062125 0.000021
25 8 9 60896 0.21558 .00009 0.41771 .00009 0.070764 0.000016 25 8 2 60889 0.21181 .00009 0.42627 .00009 0.062752 0.000019
25 8 10 60897 0.21616 .00009 0.41640 .00009 0.071442 0.000017 25 8 3 60890 0.21302 .00009 0.42504 .00009 0.063645 0.000016
25 8 11 60898 0.21726 .00009 0.41513 .00009 0.071836 0.000016 25 8 4 60891 0.21368 .00009 0.42383 .00009 0.064781 0.000010
25 8 12 60899 0.21832 .00009 0.41407 .00009 0.071996 0.000017 25 8 5 60892 0.21398 .00009 0.42271 .00009 0.066047 0.000009
25 8 13 60900 0.21871 .00009 0.41314 .00009 0.072040 0.000013 25 8 6 60893 0.21437 .00009 0.42152 .00009 0.067348 0.000008
25 8 14 60901 0.21892 .00009 0.41223 .00009 0.072161 0.000011 25 8 7 60894 0.21485 .00009 0.42038 .00009 0.068615 0.000055
IERS Final Values
MJD x y UT1-UTC
" " s
25 6 2 60828 0.1141 0.4380 0.02903
25 6 3 60829 0.1154 0.4384 0.02896
25 6 4 60830 0.1172 0.4390 0.02885
25 6 5 60831 0.1187 0.4399 0.02874
25 6 6 60832 0.1202 0.4403 0.02868
25 6 7 60833 0.1217 0.4408 0.02871
25 6 8 60834 0.1232 0.4410 0.02891
25 6 9 60835 0.1248 0.4415 0.02936
25 6 10 60836 0.1262 0.4420 0.03004
25 6 11 60837 0.1276 0.4425 0.03086
25 6 12 60838 0.1291 0.4428 0.03178
25 6 13 60839 0.1307 0.4428 0.03273
25 6 14 60840 0.1325 0.4426 0.03360
25 6 15 60841 0.1347 0.4424 0.03430
25 6 16 60842 0.1370 0.4426 0.03479
25 6 17 60843 0.1389 0.4427 0.03506
25 6 18 60844 0.1406 0.4429 0.03512
25 6 19 60845 0.1420 0.4431 0.03504
25 6 20 60846 0.1436 0.4427 0.03492
25 6 21 60847 0.1452 0.4426 0.03489
25 6 22 60848 0.1468 0.4423 0.03515
25 6 23 60849 0.1486 0.4420 0.03583
25 6 24 60850 0.1502 0.4416 0.03682
25 6 25 60851 0.1518 0.4411 0.03797
25 6 26 60852 0.1533 0.4407 0.03919
25 6 27 60853 0.1548 0.4404 0.04037
25 6 28 60854 0.1564 0.4401 0.04139
25 6 29 60855 0.1585 0.4400 0.04222
25 6 30 60856 0.1603 0.4401 0.04287
25 7 1 60857 0.1621 0.4398 0.04342
_______________________________________________________________________ _______________________________________________________________________
@ -130,387 +164,493 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
The following formulas will not reproduce the predictions given below, The following formulas will not reproduce the predictions given below,
but may be used to extend the predictions beyond the end of this table. but may be used to extend the predictions beyond the end of this table.
x = 0.1410 + 0.1141 cos A + 0.0905 sin A - 0.0377 cos C - 0.0594 sin C x = 0.1420 + 0.1046 cos A + 0.1043 sin A - 0.0336 cos C - 0.0648 sin C
y = 0.3821 + 0.0927 cos A - 0.1005 sin A - 0.0594 cos C + 0.0377 sin C y = 0.3838 + 0.1044 cos A - 0.0915 sin A - 0.0648 cos C + 0.0336 sin C
UT1-UTC = 0.0478 + 0.00010 (MJD - 60909) - (UT2-UT1) UT1-UTC = 0.0474 + 0.00010 (MJD - 60902) - (UT2-UT1)
where A = 2*pi*(MJD-60901)/365.25 and C = 2*pi*(MJD-60901)/435. where A = 2*pi*(MJD-60894)/365.25 and C = 2*pi*(MJD-60894)/435.
TAI-UTC(MJD 60902) = 37.0 TAI-UTC(MJD 60895) = 37.0
The accuracy may be estimated from the expressions: The accuracy may be estimated from the expressions:
S x,y = 0.00068 (MJD-60901)**0.80 S t = 0.00025 (MJD-60901)**0.75 S x,y = 0.00068 (MJD-60894)**0.80 S t = 0.00025 (MJD-60894)**0.75
Estimated accuracies are: Predictions 10 d 20 d 30 d 40 d Estimated accuracies are: Predictions 10 d 20 d 30 d 40 d
Polar coord's 0.004 0.007 0.010 0.013 Polar coord's 0.004 0.007 0.010 0.013
UT1-UTC 0.0014 0.0024 0.0032 0.0040 UT1-UTC 0.0014 0.0024 0.0032 0.0040
MJD x(arcsec) y(arcsec) UT1-UTC(sec) MJD x(arcsec) y(arcsec) UT1-UTC(sec)
2025 8 15 60902 0.2191 0.4112 0.07241 2025 8 8 60895 0.2155 0.4191 0.06979
2025 8 16 60903 0.2193 0.4101 0.07289 2025 8 9 60896 0.2161 0.4179 0.07073
2025 8 17 60904 0.2196 0.4090 0.07364 2025 8 10 60897 0.2169 0.4167 0.07137
2025 8 18 60905 0.2200 0.4078 0.07462 2025 8 11 60898 0.2176 0.4154 0.07173
2025 8 19 60906 0.2205 0.4066 0.07573 2025 8 12 60899 0.2184 0.4142 0.07190
2025 8 20 60907 0.2210 0.4054 0.07685 2025 8 13 60900 0.2191 0.4130 0.07200
2025 8 21 60908 0.2215 0.4042 0.07788 2025 8 14 60901 0.2198 0.4117 0.07218
2025 8 22 60909 0.2220 0.4029 0.07870 2025 8 15 60902 0.2204 0.4105 0.07254
2025 8 23 60910 0.2225 0.4018 0.07929 2025 8 16 60903 0.2210 0.4094 0.07316
2025 8 24 60911 0.2229 0.4006 0.07964 2025 8 17 60904 0.2216 0.4082 0.07403
2025 8 25 60912 0.2233 0.3994 0.07982 2025 8 18 60905 0.2222 0.4070 0.07507
2025 8 26 60913 0.2237 0.3982 0.07994 2025 8 19 60906 0.2227 0.4058 0.07619
2025 8 27 60914 0.2241 0.3970 0.08012 2025 8 20 60907 0.2232 0.4046 0.07725
2025 8 28 60915 0.2244 0.3957 0.08043 2025 8 21 60908 0.2237 0.4033 0.07814
2025 8 29 60916 0.2247 0.3945 0.08090 2025 8 22 60909 0.2242 0.4021 0.07878
2025 8 30 60917 0.2250 0.3932 0.08154 2025 8 23 60910 0.2247 0.4008 0.07912
2025 8 31 60918 0.2253 0.3919 0.08233 2025 8 24 60911 0.2251 0.3995 0.07921
2025 9 1 60919 0.2256 0.3907 0.08321 2025 8 25 60912 0.2255 0.3983 0.07914
2025 9 2 60920 0.2258 0.3894 0.08411 2025 8 26 60913 0.2259 0.3970 0.07899
2025 9 3 60921 0.2260 0.3881 0.08494 2025 8 27 60914 0.2263 0.3957 0.07887
2025 9 4 60922 0.2262 0.3868 0.08561 2025 8 28 60915 0.2266 0.3944 0.07884
2025 9 5 60923 0.2263 0.3855 0.08601 2025 8 29 60916 0.2269 0.3931 0.07898
2025 9 6 60924 0.2265 0.3842 0.08608 2025 8 30 60917 0.2272 0.3918 0.07930
2025 9 7 60925 0.2266 0.3829 0.08580 2025 8 31 60918 0.2275 0.3905 0.07979
2025 9 8 60926 0.2267 0.3816 0.08522 2025 9 1 60919 0.2278 0.3892 0.08042
2025 9 9 60927 0.2267 0.3803 0.08448 2025 9 2 60920 0.2280 0.3879 0.08112
2025 9 10 60928 0.2267 0.3790 0.08373 2025 9 3 60921 0.2282 0.3865 0.08182
2025 9 11 60929 0.2267 0.3777 0.08314 2025 9 4 60922 0.2283 0.3852 0.08242
2025 9 12 60930 0.2267 0.3764 0.08283 2025 9 5 60923 0.2285 0.3839 0.08283
2025 9 13 60931 0.2267 0.3751 0.08283 2025 9 6 60924 0.2286 0.3825 0.08295
2025 9 14 60932 0.2266 0.3738 0.08308 2025 9 7 60925 0.2287 0.3812 0.08277
2025 9 15 60933 0.2265 0.3724 0.08349 2025 9 8 60926 0.2287 0.3799 0.08232
2025 9 16 60934 0.2263 0.3711 0.08390 2025 9 9 60927 0.2287 0.3785 0.08173
2025 9 17 60935 0.2262 0.3698 0.08421 2025 9 10 60928 0.2288 0.3772 0.08114
2025 9 18 60936 0.2260 0.3685 0.08434 2025 9 11 60929 0.2287 0.3758 0.08072
2025 9 19 60937 0.2258 0.3672 0.08426 2025 9 12 60930 0.2287 0.3745 0.08056
2025 9 20 60938 0.2256 0.3659 0.08400 2025 9 13 60931 0.2286 0.3731 0.08070
2025 9 21 60939 0.2253 0.3646 0.08360 2025 9 14 60932 0.2285 0.3718 0.08108
2025 9 22 60940 0.2250 0.3633 0.08315 2025 9 15 60933 0.2284 0.3705 0.08159
2025 9 23 60941 0.2247 0.3620 0.08272 2025 9 16 60934 0.2282 0.3691 0.08209
2025 9 24 60942 0.2244 0.3607 0.08239 2025 9 17 60935 0.2281 0.3678 0.08247
2025 9 25 60943 0.2240 0.3595 0.08220 2025 9 18 60936 0.2279 0.3664 0.08265
2025 9 26 60944 0.2236 0.3582 0.08219 2025 9 19 60937 0.2276 0.3651 0.08260
2025 9 27 60945 0.2232 0.3569 0.08235 2025 9 20 60938 0.2274 0.3638 0.08234
2025 9 28 60946 0.2228 0.3556 0.08264 2025 9 21 60939 0.2271 0.3624 0.08194
2025 9 29 60947 0.2223 0.3544 0.08302 2025 9 22 60940 0.2268 0.3611 0.08146
2025 9 30 60948 0.2218 0.3531 0.08339 2025 9 23 60941 0.2264 0.3598 0.08101
2025 10 1 60949 0.2213 0.3519 0.08369 2025 9 24 60942 0.2261 0.3585 0.08064
2025 10 2 60950 0.2208 0.3506 0.08381 2025 9 25 60943 0.2257 0.3571 0.08042
2025 10 3 60951 0.2202 0.3494 0.08367 2025 9 26 60944 0.2253 0.3558 0.08037
2025 10 4 60952 0.2196 0.3482 0.08322 2025 9 27 60945 0.2248 0.3545 0.08049
2025 10 5 60953 0.2190 0.3470 0.08244 2025 9 28 60946 0.2244 0.3532 0.08076
2025 10 6 60954 0.2184 0.3458 0.08143 2025 9 29 60947 0.2239 0.3520 0.08112
2025 10 7 60955 0.2177 0.3446 0.08031 2025 9 30 60948 0.2234 0.3507 0.08148
2025 10 8 60956 0.2171 0.3434 0.07929 2025 10 1 60949 0.2228 0.3494 0.08177
2025 10 9 60957 0.2164 0.3422 0.07851 2025 10 2 60950 0.2223 0.3481 0.08189
2025 10 10 60958 0.2156 0.3410 0.07804 2025 10 3 60951 0.2217 0.3469 0.08176
2025 10 11 60959 0.2149 0.3399 0.07788 2025 10 4 60952 0.2211 0.3456 0.08133
2025 10 12 60960 0.2141 0.3387 0.07790 2025 10 5 60953 0.2204 0.3444 0.08059
2025 10 13 60961 0.2133 0.3376 0.07799 2025 10 6 60954 0.2198 0.3431 0.07962
2025 10 14 60962 0.2125 0.3365 0.07800 2025 10 7 60955 0.2191 0.3419 0.07856
2025 10 15 60963 0.2117 0.3354 0.07785 2025 10 8 60956 0.2184 0.3407 0.07759
2025 10 16 60964 0.2108 0.3343 0.07750 2025 10 9 60957 0.2177 0.3395 0.07687
2025 10 17 60965 0.2100 0.3332 0.07696 2025 10 10 60958 0.2169 0.3383 0.07647
2025 10 18 60966 0.2091 0.3321 0.07629 2025 10 11 60959 0.2161 0.3371 0.07637
2025 10 19 60967 0.2082 0.3311 0.07556 2025 10 12 60960 0.2153 0.3360 0.07648
2025 10 20 60968 0.2072 0.3300 0.07484 2025 10 13 60961 0.2145 0.3348 0.07665
2025 10 21 60969 0.2063 0.3290 0.07422 2025 10 14 60962 0.2137 0.3337 0.07674
2025 10 22 60970 0.2053 0.3280 0.07375 2025 10 15 60963 0.2128 0.3325 0.07667
2025 10 23 60971 0.2043 0.3270 0.07347 2025 10 16 60964 0.2119 0.3314 0.07640
2025 10 24 60972 0.2033 0.3260 0.07337 2025 10 17 60965 0.2110 0.3303 0.07594
2025 10 25 60973 0.2022 0.3250 0.07345 2025 10 18 60966 0.2101 0.3292 0.07535
2025 10 26 60974 0.2012 0.3241 0.07364 2025 10 19 60967 0.2092 0.3281 0.07470
2025 10 27 60975 0.2001 0.3231 0.07388 2025 10 20 60968 0.2082 0.3271 0.07405
2025 10 28 60976 0.1990 0.3222 0.07410 2025 10 21 60969 0.2072 0.3260 0.07350
2025 10 29 60977 0.1979 0.3213 0.07419 2025 10 22 60970 0.2062 0.3250 0.07310
2025 10 30 60978 0.1968 0.3204 0.07409 2025 10 23 60971 0.2052 0.3240 0.07289
2025 10 31 60979 0.1957 0.3196 0.07374 2025 10 24 60972 0.2041 0.3230 0.07287
2025 11 1 60980 0.1945 0.3187 0.07309 2025 10 25 60973 0.2031 0.3220 0.07302
2025 11 2 60981 0.1933 0.3179 0.07220 2025 10 26 60974 0.2020 0.3210 0.07329
2025 11 3 60982 0.1922 0.3171 0.07115 2025 10 27 60975 0.2009 0.3200 0.07360
2025 11 4 60983 0.1910 0.3163 0.07011 2025 10 28 60976 0.1998 0.3191 0.07388
2025 11 5 60984 0.1898 0.3155 0.06924 2025 10 29 60977 0.1986 0.3182 0.07405
2025 11 6 60985 0.1885 0.3147 0.06866 2025 10 30 60978 0.1975 0.3173 0.07402
2025 11 7 60986 0.1873 0.3140 0.06841 2025 10 31 60979 0.1963 0.3164 0.07372
2025 11 8 60987 0.1860 0.3133 0.06842 2025 11 1 60980 0.1951 0.3155 0.07315
2025 11 9 60988 0.1848 0.3126 0.06856 2025 11 2 60981 0.1939 0.3147 0.07232
2025 11 10 60989 0.1835 0.3119 0.06868 2025 11 3 60982 0.1927 0.3139 0.07133
2025 11 11 60990 0.1822 0.3112 0.06866 2025 11 4 60983 0.1915 0.3130 0.07034
2025 11 12 60991 0.1809 0.3106 0.06845 2025 11 5 60984 0.1902 0.3122 0.06953
2025 11 13 60992 0.1796 0.3100 0.06806 2025 11 6 60985 0.1890 0.3115 0.06901
2025 11 14 60993 0.1782 0.3094 0.06755 2025 11 7 60986 0.1877 0.3107 0.06882
2025 11 15 60994 0.1769 0.3088 0.06698 2025 11 8 60987 0.1864 0.3100 0.06889
2025 11 16 60995 0.1755 0.3082 0.06643 2025 11 9 60988 0.1851 0.3093 0.06908
2025 11 17 60996 0.1742 0.3077 0.06596 2025 11 10 60989 0.1838 0.3086 0.06924
2025 11 18 60997 0.1728 0.3072 0.06564 2025 11 11 60990 0.1825 0.3079 0.06927
2025 11 19 60998 0.1714 0.3067 0.06550 2025 11 12 60991 0.1812 0.3072 0.06910
2025 11 20 60999 0.1701 0.3062 0.06555 2025 11 13 60992 0.1798 0.3066 0.06876
2025 11 21 61000 0.1687 0.3058 0.06578 2025 11 14 60993 0.1784 0.3060 0.06828
2025 11 22 61001 0.1673 0.3053 0.06615 2025 11 15 60994 0.1771 0.3054 0.06774
2025 11 23 61002 0.1659 0.3049 0.06660 2025 11 16 60995 0.1757 0.3048 0.06722
2025 11 24 61003 0.1644 0.3045 0.06704 2025 11 17 60996 0.1743 0.3043 0.06677
2025 11 25 61004 0.1630 0.3042 0.06739 2025 11 18 60997 0.1729 0.3038 0.06647
2025 11 26 61005 0.1616 0.3038 0.06759 2025 11 19 60998 0.1715 0.3033 0.06635
2025 11 27 61006 0.1602 0.3035 0.06756 2025 11 20 60999 0.1701 0.3028 0.06642
2025 11 28 61007 0.1587 0.3032 0.06728 2025 11 21 61000 0.1687 0.3023 0.06667
2025 11 29 61008 0.1573 0.3029 0.06677 2025 11 22 61001 0.1672 0.3019 0.06705
2025 11 30 61009 0.1558 0.3027 0.06607 2025 11 23 61002 0.1658 0.3015 0.06751
2025 12 1 61010 0.1544 0.3024 0.06523 2025 11 24 61003 0.1643 0.3011 0.06788
2025 12 2 61011 0.1529 0.3022 0.06448 2025 11 25 61004 0.1629 0.3007 0.06817
2025 12 3 61012 0.1515 0.3020 0.06395 2025 11 26 61005 0.1614 0.3003 0.06829
2025 12 4 61013 0.1500 0.3019 0.06373 2025 11 27 61006 0.1600 0.3000 0.06820
2025 12 5 61014 0.1486 0.3017 0.06379 2025 11 28 61007 0.1585 0.2997 0.06785
2025 12 6 61015 0.1471 0.3016 0.06403 2025 11 29 61008 0.1570 0.2994 0.06727
2025 12 7 61016 0.1456 0.3015 0.06430 2025 11 30 61009 0.1556 0.2992 0.06650
2025 12 8 61017 0.1442 0.3015 0.06446 2025 12 1 61010 0.1541 0.2989 0.06567
2025 12 9 61018 0.1427 0.3014 0.06442 2025 12 2 61011 0.1526 0.2987 0.06494
2025 12 10 61019 0.1413 0.3014 0.06419 2025 12 3 61012 0.1511 0.2985 0.06442
2025 12 11 61020 0.1398 0.3014 0.06380 2025 12 4 61013 0.1496 0.2984 0.06421
2025 12 12 61021 0.1383 0.3014 0.06335 2025 12 5 61014 0.1481 0.2982 0.06429
2025 12 13 61022 0.1369 0.3015 0.06291 2025 12 6 61015 0.1466 0.2981 0.06454
2025 12 14 61023 0.1354 0.3015 0.06256 2025 12 7 61016 0.1451 0.2980 0.06483
2025 12 15 61024 0.1340 0.3016 0.06234 2025 12 8 61017 0.1437 0.2980 0.06500
2025 12 16 61025 0.1325 0.3017 0.06230 2025 12 9 61018 0.1422 0.2979 0.06498
2025 12 17 61026 0.1311 0.3019 0.06246 2025 12 10 61019 0.1407 0.2979 0.06476
2025 12 18 61027 0.1297 0.3020 0.06279 2025 12 11 61020 0.1392 0.2979 0.06439
2025 12 19 61028 0.1282 0.3022 0.06328 2025 12 12 61021 0.1377 0.2979 0.06395
2025 12 20 61029 0.1268 0.3024 0.06386 2025 12 13 61022 0.1362 0.2980 0.06353
2025 12 21 61030 0.1254 0.3027 0.06444 2025 12 14 61023 0.1347 0.2980 0.06319
2025 12 22 61031 0.1239 0.3029 0.06496 2025 12 15 61024 0.1332 0.2981 0.06299
2025 12 23 61032 0.1225 0.3032 0.06533 2025 12 16 61025 0.1318 0.2982 0.06297
2025 12 24 61033 0.1211 0.3035 0.06550 2025 12 17 61026 0.1303 0.2984 0.06315
2025 12 25 61034 0.1197 0.3038 0.06544 2025 12 18 61027 0.1288 0.2985 0.06351
2025 12 26 61035 0.1183 0.3041 0.06515 2025 12 19 61028 0.1274 0.2987 0.06401
2025 12 27 61036 0.1170 0.3045 0.06469 2025 12 20 61029 0.1259 0.2989 0.06461
2025 12 28 61037 0.1156 0.3049 0.06414 2025 12 21 61030 0.1245 0.2992 0.06522
2025 12 29 61038 0.1142 0.3053 0.06364 2025 12 22 61031 0.1230 0.2994 0.06575
2025 12 30 61039 0.1129 0.3057 0.06331 2025 12 23 61032 0.1216 0.2997 0.06614
2025 12 31 61040 0.1115 0.3062 0.06323 2025 12 24 61033 0.1201 0.3000 0.06632
2026 1 1 61041 0.1102 0.3066 0.06342 2025 12 25 61034 0.1187 0.3003 0.06627
2026 1 2 61042 0.1089 0.3071 0.06382 2025 12 26 61035 0.1173 0.3007 0.06599
2026 1 3 61043 0.1076 0.3077 0.06429 2025 12 27 61036 0.1159 0.3011 0.06554
2026 1 4 61044 0.1063 0.3082 0.06469 2025 12 28 61037 0.1145 0.3015 0.06500
2026 1 5 61045 0.1050 0.3087 0.06489 2025 12 29 61038 0.1131 0.3019 0.06451
2026 1 6 61046 0.1037 0.3093 0.06486 2025 12 30 61039 0.1117 0.3023 0.06418
2026 1 7 61047 0.1024 0.3099 0.06463 2025 12 31 61040 0.1103 0.3028 0.06410
2026 1 8 61048 0.1012 0.3105 0.06428 2026 1 1 61041 0.1090 0.3033 0.06429
2026 1 9 61049 0.0999 0.3112 0.06391 2026 1 2 61042 0.1076 0.3038 0.06468
2026 1 10 61050 0.0987 0.3118 0.06361 2026 1 3 61043 0.1063 0.3043 0.06514
2026 1 11 61051 0.0975 0.3125 0.06344 2026 1 4 61044 0.1050 0.3048 0.06553
2026 1 12 61052 0.0963 0.3132 0.06344 2026 1 5 61045 0.1036 0.3054 0.06573
2026 1 13 61053 0.0951 0.3139 0.06364 2026 1 6 61046 0.1023 0.3060 0.06569
2026 1 14 61054 0.0940 0.3147 0.06401 2026 1 7 61047 0.1010 0.3066 0.06545
2026 1 15 61055 0.0928 0.3154 0.06454 2026 1 8 61048 0.0998 0.3072 0.06509
2026 1 16 61056 0.0917 0.3162 0.06517 2026 1 9 61049 0.0985 0.3079 0.06472
2026 1 17 61057 0.0906 0.3170 0.06582 2026 1 10 61050 0.0973 0.3086 0.06441
2026 1 18 61058 0.0895 0.3178 0.06640 2026 1 11 61051 0.0960 0.3093 0.06423
2026 1 19 61059 0.0884 0.3186 0.06684 2026 1 12 61052 0.0948 0.3100 0.06423
2026 1 20 61060 0.0874 0.3195 0.06707 2026 1 13 61053 0.0936 0.3107 0.06442
2026 1 21 61061 0.0863 0.3203 0.06706 2026 1 14 61054 0.0924 0.3115 0.06480
2026 1 22 61062 0.0853 0.3212 0.06680 2026 1 15 61055 0.0912 0.3122 0.06532
2026 1 23 61063 0.0843 0.3221 0.06636 2026 1 16 61056 0.0901 0.3130 0.06595
2026 1 24 61064 0.0833 0.3230 0.06582 2026 1 17 61057 0.0889 0.3138 0.06660
2026 1 25 61065 0.0823 0.3239 0.06531 2026 1 18 61058 0.0878 0.3146 0.06719
2026 1 26 61066 0.0814 0.3249 0.06494 2026 1 19 61059 0.0867 0.3155 0.06763
2026 1 27 61067 0.0804 0.3259 0.06479 2026 1 20 61060 0.0856 0.3164 0.06787
2026 1 28 61068 0.0795 0.3268 0.06489 2026 1 21 61061 0.0846 0.3172 0.06785
2026 1 29 61069 0.0786 0.3278 0.06520 2026 1 22 61062 0.0835 0.3181 0.06761
2026 1 30 61070 0.0778 0.3288 0.06562 2026 1 23 61063 0.0825 0.3191 0.06717
2026 1 31 61071 0.0769 0.3298 0.06599 2026 1 24 61064 0.0815 0.3200 0.06664
2026 2 1 61072 0.0761 0.3309 0.06620 2026 1 25 61065 0.0805 0.3209 0.06615
2026 2 2 61073 0.0753 0.3319 0.06617 2026 1 26 61066 0.0795 0.3219 0.06579
2026 2 3 61074 0.0745 0.3330 0.06589 2026 1 27 61067 0.0786 0.3229 0.06566
2026 2 4 61075 0.0737 0.3341 0.06543 2026 1 28 61068 0.0776 0.3239 0.06578
2026 2 5 61076 0.0730 0.3351 0.06490 2026 1 29 61069 0.0767 0.3249 0.06612
2026 2 6 61077 0.0723 0.3362 0.06439 2026 1 30 61070 0.0758 0.3259 0.06656
2026 2 7 61078 0.0716 0.3373 0.06401 2026 1 31 61071 0.0749 0.3270 0.06697
2026 2 8 61079 0.0709 0.3385 0.06379 2026 2 1 61072 0.0741 0.3280 0.06723
2026 2 9 61080 0.0703 0.3396 0.06378 2026 2 2 61073 0.0733 0.3291 0.06725
2026 2 10 61081 0.0696 0.3407 0.06396 2026 2 3 61074 0.0725 0.3302 0.06704
2026 2 11 61082 0.0690 0.3419 0.06432 2026 2 4 61075 0.0717 0.3313 0.06666
2026 2 12 61083 0.0685 0.3431 0.06481 2026 2 5 61076 0.0709 0.3324 0.06622
2026 2 13 61084 0.0679 0.3442 0.06537 2026 2 6 61077 0.0702 0.3335 0.06583
2026 2 14 61085 0.0674 0.3454 0.06590 2026 2 7 61078 0.0695 0.3346 0.06557
2026 2 15 61086 0.0669 0.3466 0.06634 2026 2 8 61079 0.0688 0.3358 0.06552
2026 2 16 61087 0.0664 0.3478 0.06660 2026 2 9 61080 0.0681 0.3369 0.06570
2026 2 17 61088 0.0659 0.3490 0.06664 2026 2 10 61081 0.0675 0.3381 0.06610
2026 2 18 61089 0.0655 0.3503 0.06646 2026 2 11 61082 0.0668 0.3393 0.06671
2026 2 19 61090 0.0651 0.3515 0.06608 2026 2 12 61083 0.0662 0.3405 0.06747
2026 2 20 61091 0.0647 0.3527 0.06560 2026 2 13 61084 0.0657 0.3417 0.06829
2026 2 21 61092 0.0643 0.3540 0.06514 2026 2 14 61085 0.0651 0.3429 0.06910
2026 2 22 61093 0.0640 0.3552 0.06482 2026 2 15 61086 0.0646 0.3441 0.06977
2026 2 23 61094 0.0637 0.3564 0.06470 2026 2 16 61087 0.0641 0.3453 0.07023
2026 2 24 61095 0.0634 0.3577 0.06483 2026 2 17 61088 0.0636 0.3466 0.07040
2026 2 25 61096 0.0632 0.3590 0.06515 2026 2 18 61089 0.0632 0.3478 0.07026
2026 2 26 61097 0.0629 0.3602 0.06557 2026 2 19 61090 0.0627 0.3491 0.06986
2026 2 27 61098 0.0627 0.3615 0.06596 2026 2 20 61091 0.0623 0.3503 0.06930
2026 2 28 61099 0.0625 0.3628 0.06620 2026 2 21 61092 0.0620 0.3516 0.06869
2026 3 1 61100 0.0624 0.3641 0.06619 2026 2 22 61093 0.0616 0.3529 0.06818
2026 3 2 61101 0.0623 0.3654 0.06591 2026 2 23 61094 0.0613 0.3541 0.06787
2026 3 3 61102 0.0622 0.3666 0.06538 2026 2 24 61095 0.0610 0.3554 0.06779
2026 3 4 61103 0.0621 0.3679 0.06470 2026 2 25 61096 0.0607 0.3567 0.06793
2026 3 5 61104 0.0620 0.3692 0.06398 2026 2 26 61097 0.0605 0.3580 0.06818
2026 3 6 61105 0.0620 0.3705 0.06332 2026 2 27 61098 0.0602 0.3593 0.06844
2026 3 7 61106 0.0620 0.3718 0.06280 2026 2 28 61099 0.0600 0.3606 0.06858
2026 3 8 61107 0.0620 0.3731 0.06247 2026 3 1 61100 0.0599 0.3619 0.06850
2026 3 9 61108 0.0621 0.3744 0.06235 2026 3 2 61101 0.0597 0.3632 0.06818
2026 3 10 61109 0.0621 0.3757 0.06241 2026 3 3 61102 0.0596 0.3646 0.06765
2026 3 11 61110 0.0622 0.3770 0.06263 2026 3 4 61103 0.0595 0.3659 0.06699
2026 3 12 61111 0.0624 0.3783 0.06293 2026 3 5 61104 0.0595 0.3672 0.06631
2026 3 13 61112 0.0625 0.3796 0.06322 2026 3 6 61105 0.0594 0.3685 0.06572
2026 3 14 61113 0.0627 0.3809 0.06341 2026 3 7 61106 0.0594 0.3698 0.06529
2026 3 15 61114 0.0629 0.3821 0.06342 2026 3 8 61107 0.0594 0.3712 0.06505
2026 3 16 61115 0.0631 0.3834 0.06320 2026 3 9 61108 0.0595 0.3725 0.06500
2026 3 17 61116 0.0634 0.3847 0.06271 2026 3 10 61109 0.0595 0.3738 0.06511
2026 3 18 61117 0.0637 0.3860 0.06199 2026 3 11 61110 0.0596 0.3751 0.06533
2026 3 19 61118 0.0640 0.3873 0.06113 2026 3 12 61111 0.0597 0.3765 0.06562
2026 3 20 61119 0.0643 0.3885 0.06024 2026 3 13 61112 0.0599 0.3778 0.06589
2026 3 21 61120 0.0647 0.3898 0.05943 2026 3 14 61113 0.0600 0.3791 0.06606
2026 3 22 61121 0.0651 0.3911 0.05880 2026 3 15 61114 0.0602 0.3804 0.06604
2026 3 23 61122 0.0655 0.3923 0.05842 2026 3 16 61115 0.0604 0.3818 0.06576
2026 3 24 61123 0.0659 0.3936 0.05830 2026 3 17 61116 0.0607 0.3831 0.06516
2026 3 25 61124 0.0664 0.3948 0.05832 2026 3 18 61117 0.0610 0.3844 0.06423
2026 3 26 61125 0.0668 0.3961 0.05841 2026 3 19 61118 0.0613 0.3857 0.06304
2026 3 27 61126 0.0673 0.3973 0.05840 2026 3 20 61119 0.0616 0.3870 0.06180
2026 3 28 61127 0.0679 0.3985 0.05821 2026 3 21 61120 0.0619 0.3883 0.06065
2026 3 29 61128 0.0684 0.3997 0.05777 2026 3 22 61121 0.0623 0.3896 0.05966
2026 3 30 61129 0.0690 0.4010 0.05709 2026 3 23 61122 0.0627 0.3909 0.05895
2026 3 31 61130 0.0696 0.4022 0.05624 2026 3 24 61123 0.0631 0.3922 0.05844
2026 4 1 61131 0.0702 0.4034 0.05523 2026 3 25 61124 0.0636 0.3934 0.05812
2026 4 2 61132 0.0709 0.4045 0.05420 2026 3 26 61125 0.0640 0.3947 0.05791
2026 4 3 61133 0.0715 0.4057 0.05330 2026 3 27 61126 0.0645 0.3960 0.05759
2026 4 4 61134 0.0722 0.4069 0.05257 2026 3 28 61127 0.0651 0.3972 0.05717
2026 4 5 61135 0.0729 0.4080 0.05202 2026 3 29 61128 0.0656 0.3985 0.05646
2026 4 6 61136 0.0737 0.4092 0.05164 2026 3 30 61129 0.0662 0.3997 0.05548
2026 4 7 61137 0.0744 0.4103 0.05137 2026 3 31 61130 0.0668 0.4010 0.05432
2026 4 8 61138 0.0752 0.4114 0.05123 2026 4 1 61131 0.0674 0.4022 0.05306
2026 4 9 61139 0.0760 0.4125 0.05118 2026 4 2 61132 0.0680 0.4034 0.05187
2026 4 10 61140 0.0768 0.4136 0.05105 2026 4 3 61133 0.0687 0.4046 0.05076
2026 4 11 61141 0.0777 0.4147 0.05087 2026 4 4 61134 0.0694 0.4058 0.04986
2026 4 12 61142 0.0786 0.4158 0.05044 2026 4 5 61135 0.0701 0.4070 0.04920
2026 4 13 61143 0.0794 0.4169 0.04970 2026 4 6 61136 0.0708 0.4082 0.04872
2026 4 14 61144 0.0803 0.4179 0.04867 2026 4 7 61137 0.0716 0.4093 0.04838
2026 4 15 61145 0.0813 0.4189 0.04739 2026 4 8 61138 0.0724 0.4105 0.04815
2026 4 16 61146 0.0822 0.4200 0.04601 2026 4 9 61139 0.0732 0.4116 0.04795
2026 4 17 61147 0.0832 0.4210 0.04462 2026 4 10 61140 0.0740 0.4128 0.04768
2026 4 18 61148 0.0842 0.4219 0.04343 2026 4 11 61141 0.0748 0.4139 0.04735
2026 4 19 61149 0.0852 0.4229 0.04254 2026 4 12 61142 0.0757 0.4150 0.04689
2026 4 20 61150 0.0862 0.4239 0.04195 2026 4 13 61143 0.0766 0.4161 0.04620
2026 4 21 61151 0.0872 0.4248 0.04156 2026 4 14 61144 0.0775 0.4172 0.04531
2026 4 22 61152 0.0883 0.4258 0.04129 2026 4 15 61145 0.0784 0.4182 0.04419
2026 4 23 61153 0.0894 0.4267 0.04098 2026 4 16 61146 0.0794 0.4193 0.04299
2026 4 24 61154 0.0905 0.4276 0.04050 2026 4 17 61147 0.0803 0.4203 0.04183
2026 4 25 61155 0.0916 0.4284 0.03988 2026 4 18 61148 0.0813 0.4213 0.04095
2026 4 26 61156 0.0927 0.4293 0.03914 2026 4 19 61149 0.0823 0.4223 0.04036
2026 4 27 61157 0.0939 0.4302 0.03829 2026 4 20 61150 0.0833 0.4233 0.04007
2026 4 28 61158 0.0950 0.4310 0.03744 2026 4 21 61151 0.0844 0.4243 0.04013
2026 4 29 61159 0.0962 0.4318 0.03659 2026 4 22 61152 0.0854 0.4253 0.04026
2026 4 30 61160 0.0974 0.4326 0.03591 2026 4 23 61153 0.0865 0.4262 0.04040
2026 5 1 61161 0.0986 0.4334 0.03540 2026 4 24 61154 0.0876 0.4271 0.04039
2026 5 2 61162 0.0998 0.4341 0.03522 2026 4 25 61155 0.0887 0.4280 0.04013
2026 5 3 61163 0.1010 0.4348 0.03525 2026 4 26 61156 0.0899 0.4289 0.03962
2026 5 4 61164 0.1023 0.4356 0.03547 2026 4 27 61157 0.0910 0.4298 0.03894
2026 5 5 61165 0.1035 0.4363 0.03594 2026 4 28 61158 0.0922 0.4307 0.03819
2026 5 6 61166 0.1048 0.4369 0.03644 2026 4 29 61159 0.0933 0.4315 0.03743
2026 5 7 61167 0.1061 0.4376 0.03697 2026 4 30 61160 0.0945 0.4323 0.03681
2026 5 8 61168 0.1074 0.4382 0.03741 2026 5 1 61161 0.0957 0.4331 0.03639
2026 5 9 61169 0.1087 0.4389 0.03765 2026 5 2 61162 0.0970 0.4339 0.03619
2026 5 10 61170 0.1100 0.4395 0.03762 2026 5 3 61163 0.0982 0.4347 0.03616
2026 5 11 61171 0.1114 0.4400 0.03733 2026 5 4 61164 0.0994 0.4354 0.03629
2026 5 12 61172 0.1127 0.4406 0.03682 2026 5 5 61165 0.1007 0.4362 0.03660
2026 5 13 61173 0.1140 0.4411 0.03611 2026 5 6 61166 0.1020 0.4369 0.03691
2026 5 14 61174 0.1154 0.4416 0.03540 2026 5 7 61167 0.1033 0.4376 0.03721
2026 5 15 61175 0.1168 0.4421 0.03481 2026 5 8 61168 0.1046 0.4382 0.03749
2026 5 16 61176 0.1182 0.4426 0.03447 2026 5 9 61169 0.1059 0.4389 0.03763
2026 5 17 61177 0.1195 0.4431 0.03440 2026 5 10 61170 0.1072 0.4395 0.03762
2026 5 18 61178 0.1209 0.4435 0.03458 2026 5 11 61171 0.1086 0.4401 0.03744
2026 5 19 61179 0.1223 0.4439 0.03496 2026 5 12 61172 0.1099 0.4407 0.03706
2026 5 20 61180 0.1237 0.4443 0.03531 2026 5 13 61173 0.1113 0.4413 0.03652
2026 5 21 61181 0.1252 0.4447 0.03553 2026 5 14 61174 0.1126 0.4418 0.03595
2026 5 22 61182 0.1266 0.4450 0.03563 2026 5 15 61175 0.1140 0.4423 0.03555
2026 5 23 61183 0.1280 0.4453 0.03555 2026 5 16 61176 0.1154 0.4428 0.03545
2026 5 24 61184 0.1294 0.4456 0.03538 2026 5 17 61177 0.1168 0.4433 0.03561
2026 5 25 61185 0.1309 0.4459 0.03522 2026 5 18 61178 0.1182 0.4438 0.03605
2026 5 26 61186 0.1323 0.4462 0.03510 2026 5 19 61179 0.1196 0.4442 0.03672
2026 5 27 61187 0.1337 0.4464 0.03509 2026 5 20 61180 0.1210 0.4446 0.03732
2026 5 28 61188 0.1352 0.4466 0.03526 2026 5 21 61181 0.1224 0.4450 0.03779
2026 5 29 61189 0.1366 0.4468 0.03571 2026 5 22 61182 0.1239 0.4454 0.03807
2026 5 30 61190 0.1381 0.4469 0.03643 2026 5 23 61183 0.1253 0.4457 0.03818
2026 5 31 61191 0.1395 0.4471 0.03730 2026 5 24 61184 0.1267 0.4461 0.03811
2026 6 1 61192 0.1410 0.4472 0.03832 2026 5 25 61185 0.1282 0.4464 0.03802
2026 6 2 61193 0.1425 0.4473 0.03948 2026 5 26 61186 0.1296 0.4466 0.03795
2026 6 3 61194 0.1439 0.4474 0.04058 2026 5 27 61187 0.1311 0.4469 0.03798
2026 6 4 61195 0.1454 0.4474 0.04160 2026 5 28 61188 0.1326 0.4471 0.03820
2026 6 5 61196 0.1468 0.4474 0.04249 2026 5 29 61189 0.1340 0.4473 0.03862
2026 6 6 61197 0.1483 0.4475 0.04322 2026 5 30 61190 0.1355 0.4475 0.03926
2026 6 7 61198 0.1497 0.4474 0.04372 2026 5 31 61191 0.1369 0.4477 0.04005
2026 6 8 61199 0.1512 0.4474 0.04404 2026 6 1 61192 0.1384 0.4478 0.04090
2026 6 9 61200 0.1526 0.4473 0.04420 2026 6 2 61193 0.1399 0.4480 0.04191
2026 6 10 61201 0.1541 0.4472 0.04427 2026 6 3 61194 0.1414 0.4481 0.04298
2026 6 11 61202 0.1555 0.4471 0.04441 2026 6 4 61195 0.1428 0.4481 0.04399
2026 6 12 61203 0.1570 0.4470 0.04471 2026 6 5 61196 0.1443 0.4482 0.04491
2026 6 13 61204 0.1584 0.4468 0.04527 2026 6 6 61197 0.1458 0.4482 0.04568
2026 6 14 61205 0.1598 0.4467 0.04607 2026 6 7 61198 0.1472 0.4482 0.04614
2026 6 15 61206 0.1613 0.4465 0.04699 2026 6 8 61199 0.1487 0.4482 0.04638
2026 6 16 61207 0.1627 0.4462 0.04805 2026 6 9 61200 0.1502 0.4481 0.04649
2026 6 17 61208 0.1641 0.4460 0.04907 2026 6 10 61201 0.1516 0.4481 0.04648
2026 6 18 61209 0.1655 0.4457 0.04991 2026 6 11 61202 0.1531 0.4480 0.04649
2026 6 19 61210 0.1669 0.4454 0.05056 2026 6 12 61203 0.1545 0.4479 0.04661
2026 6 20 61211 0.1683 0.4451 0.05105 2026 6 13 61204 0.1560 0.4477 0.04699
2026 6 21 61212 0.1697 0.4448 0.05136 2026 6 14 61205 0.1574 0.4476 0.04756
2026 6 22 61213 0.1711 0.4444 0.05165 2026 6 15 61206 0.1589 0.4474 0.04835
2026 6 23 61214 0.1725 0.4440 0.05210 2026 6 16 61207 0.1603 0.4472 0.04924
2026 6 24 61215 0.1738 0.4436 0.05266 2026 6 17 61208 0.1618 0.4470 0.05017
2026 6 25 61216 0.1752 0.4432 0.05340 2026 6 18 61209 0.1632 0.4467 0.05089
2026 6 26 61217 0.1765 0.4428 0.05430 2026 6 19 61210 0.1646 0.4464 0.05142
2026 6 27 61218 0.1779 0.4423 0.05539 2026 6 20 61211 0.1660 0.4461 0.05178
2026 6 28 61219 0.1792 0.4418 0.05654 2026 6 21 61212 0.1674 0.4458 0.05200
2026 6 29 61220 0.1805 0.4413 0.05779 2026 6 22 61213 0.1688 0.4455 0.05221
2026 6 30 61221 0.1818 0.4408 0.05910 2026 6 23 61214 0.1702 0.4451 0.05260
2026 7 1 61222 0.1831 0.4402 0.06048 2026 6 24 61215 0.1716 0.4447 0.05320
2026 7 2 61223 0.1844 0.4397 0.06171 2026 6 25 61216 0.1730 0.4443 0.05401
2026 7 3 61224 0.1856 0.4391 0.06280 2026 6 26 61217 0.1743 0.4439 0.05511
2026 7 4 61225 0.1869 0.4385 0.06369 2026 6 27 61218 0.1757 0.4434 0.05647
2026 7 5 61226 0.1881 0.4378 0.06434 2026 6 28 61219 0.1770 0.4430 0.05798
2026 7 6 61227 0.1893 0.4372 0.06480 2026 6 29 61220 0.1783 0.4425 0.05967
2026 7 7 61228 0.1905 0.4365 0.06523 2026 6 30 61221 0.1797 0.4420 0.06128
2026 7 8 61229 0.1917 0.4358 0.06572 2026 7 1 61222 0.1810 0.4414 0.06275
2026 7 9 61230 0.1929 0.4351 0.06633 2026 7 2 61223 0.1823 0.4409 0.06403
2026 7 10 61231 0.1941 0.4344 0.06723 2026 7 3 61224 0.1836 0.4403 0.06505
2026 7 11 61232 0.1952 0.4336 0.06843 2026 7 4 61225 0.1848 0.4397 0.06585
2026 7 12 61233 0.1964 0.4329 0.06985 2026 7 5 61226 0.1861 0.4391 0.06645
2026 7 13 61234 0.1975 0.4321 0.07146 2026 7 6 61227 0.1873 0.4384 0.06686
2026 7 14 61235 0.1986 0.4313 0.07292 2026 7 7 61228 0.1886 0.4378 0.06722
2026 7 15 61236 0.1996 0.4304 0.07413 2026 7 8 61229 0.1898 0.4371 0.06760
2026 7 16 61237 0.2007 0.4296 0.07502 2026 7 9 61230 0.1910 0.4364 0.06810
2026 7 17 61238 0.2018 0.4288 0.07557 2026 7 10 61231 0.1921 0.4357 0.06889
2026 7 18 61239 0.2028 0.4279 0.07596 2026 7 11 61232 0.1933 0.4349 0.06992
2026 7 19 61240 0.2038 0.4270 0.07629 2026 7 12 61233 0.1945 0.4342 0.07122
2026 7 20 61241 0.2048 0.4261 0.07668 2026 7 13 61234 0.1956 0.4334 0.07254
2026 7 21 61242 0.2058 0.4252 0.07728 2026 7 14 61235 0.1967 0.4326 0.07391
2026 7 22 61243 0.2067 0.4242 0.07807 2026 7 15 61236 0.1978 0.4318 0.07504
2026 7 23 61244 0.2076 0.4233 0.07908 2026 7 16 61237 0.1989 0.4310 0.07591
2026 7 24 61245 0.2085 0.4223 0.08036 2026 7 17 61238 0.2000 0.4301 0.07652
2026 7 25 61246 0.2094 0.4213 0.08180 2026 7 18 61239 0.2010 0.4293 0.07702
2026 7 26 61247 0.2103 0.4203 0.08338 2026 7 19 61240 0.2021 0.4284 0.07743
2026 7 27 61248 0.2112 0.4193 0.08491 2026 7 20 61241 0.2031 0.4275 0.07799
2026 7 28 61249 0.2120 0.4183 0.08647 2026 7 21 61242 0.2041 0.4266 0.07873
2026 7 29 61250 0.2128 0.4173 0.08786 2026 7 22 61243 0.2050 0.4256 0.07969
2026 7 30 61251 0.2136 0.4162 0.08904 2026 7 23 61244 0.2060 0.4247 0.08084
2026 7 31 61252 0.2143 0.4151 0.08998 2026 7 24 61245 0.2069 0.4237 0.08212
2026 8 1 61253 0.2151 0.4141 0.09076 2026 7 25 61246 0.2078 0.4227 0.08367
2026 8 2 61254 0.2158 0.4130 0.09130 2026 7 26 61247 0.2087 0.4218 0.08531
2026 8 3 61255 0.2165 0.4119 0.09180 2026 7 27 61248 0.2096 0.4207 0.08702
2026 8 4 61256 0.2172 0.4108 0.09232 2026 7 28 61249 0.2105 0.4197 0.08862
2026 8 5 61257 0.2178 0.4096 0.09294 2026 7 29 61250 0.2113 0.4187 0.09004
2026 8 6 61258 0.2184 0.4085 0.09372 2026 7 30 61251 0.2121 0.4176 0.09130
2026 8 7 61259 0.2190 0.4074 0.09466 2026 7 31 61252 0.2129 0.4166 0.09234
2026 8 8 61260 0.2196 0.4062 0.09591 2026 8 1 61253 0.2136 0.4155 0.09321
2026 8 9 61261 0.2202 0.4050 0.09728 2026 8 2 61254 0.2144 0.4144 0.09386
2026 8 10 61262 0.2207 0.4039 0.09868 2026 8 3 61255 0.2151 0.4133 0.09435
2026 8 11 61263 0.2212 0.4027 0.09988 2026 8 4 61256 0.2158 0.4122 0.09493
2026 8 12 61264 0.2217 0.4015 0.10077 2026 8 5 61257 0.2165 0.4111 0.09554
2026 8 13 61265 0.2221 0.4003 0.10141 2026 8 6 61258 0.2171 0.4099 0.09635
2026 8 14 61266 0.2226 0.3991 0.10182 2026 8 7 61259 0.2177 0.4088 0.09737
These predictions are based on all announced leap seconds. 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)
60868 -116.99 0.86 -10.78 0.21
60869 -117.02 0.86 -10.71 0.30
60870 -117.16 0.86 -10.75 0.30
60871 -117.35 0.86 -10.82 0.34
60872 -117.56 0.83 -10.83 0.29
60873 -117.79 0.83 -10.77 0.29
60874 -118.05 0.83 -10.70 0.29
60875 -118.31 0.78 -10.66 0.17
60876 -118.49 0.83 -10.70 0.16
60877 -118.55 0.83 -10.81 0.16
60878 -118.54 1.09 -10.92 0.16
60879 -118.54 0.94 -10.97 0.15
60880 -118.53 0.94 -10.93 0.15
60881 -118.44 0.94 -10.81 0.15
IERS Celestial Pole Offset Final Series
MJD dpsi deps
(msec. of arc)
60828 -111.0 -11.3
60829 -111.7 -10.9
60830 -112.1 -10.8
60831 -112.0 -10.8
60832 -111.7 -10.8
60833 -111.7 -10.8
60834 -111.9 -10.9
60835 -112.2 -11.2
60836 -112.5 -11.5
60837 -112.7 -11.7
60838 -112.8 -11.7
60839 -112.7 -11.5
60840 -112.6 -11.3
60841 -112.5 -11.3
60842 -112.4 -11.3
60843 -112.3 -11.3
60844 -112.4 -11.2
60845 -112.6 -11.1
60846 -113.0 -10.9
60847 -113.6 -10.7
60848 -114.2 -10.7
60849 -114.6 -10.9
60850 -114.7 -11.2
60851 -114.6 -11.3
60852 -114.5 -11.4
60853 -114.3 -11.3
60854 -114.0 -11.2
60855 -114.1 -11.0
60856 -114.6 -10.6
60857 -115.3 -10.4
IAU2000A Celestial Pole Offset Series
MJD dX error dY error
(msec. of arc)
60868 0.366 0.342 -0.270 0.206
60869 0.360 0.343 -0.284 0.298
60870 0.356 0.343 -0.292 0.298
60871 0.352 0.343 -0.292 0.342
60872 0.347 0.330 -0.282 0.288
60873 0.343 0.330 -0.265 0.288
60874 0.341 0.330 -0.243 0.288
60875 0.342 0.308 -0.222 0.166
60876 0.347 0.331 -0.202 0.164
60877 0.352 0.331 -0.183 0.164
60878 0.357 0.433 -0.166 0.157
60879 0.359 0.375 -0.150 0.149
60880 0.359 0.375 -0.135 0.149
60881 0.358 0.375 -0.120 0.149
IAU2000A Celestial Pole Offset Final Series
MJD dX dY
(msec. of arc)
60828 0.30 -0.23
60829 0.28 -0.26
60830 0.28 -0.28
60831 0.35 -0.27
60832 0.43 -0.24
60833 0.45 -0.20
60834 0.43 -0.18
60835 0.39 -0.16
60836 0.34 -0.15
60837 0.34 -0.19
60838 0.35 -0.25
60839 0.37 -0.30
60840 0.41 -0.34
60841 0.45 -0.35
60842 0.50 -0.35
60843 0.53 -0.34
60844 0.52 -0.32
60845 0.49 -0.29
60846 0.45 -0.27
60847 0.42 -0.25
60848 0.41 -0.25
60849 0.40 -0.26
60850 0.39 -0.27
60851 0.39 -0.29
60852 0.39 -0.32
60853 0.39 -0.33
60854 0.38 -0.28
60855 0.36 -0.19
60856 0.35 -0.10
60857 0.34 -0.03
)--"; )--";

View File

@ -165,7 +165,7 @@ public:
_coord2coord(target.coordPairKind, target.x, target.y, target.time_point, _coord2coord(target.coordPairKind, target.x, target.y, target.time_point,
MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec); MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec);
if (!doesObjectReachZone(dec)) { if (!doesObjectReachZone(ha)) {
return infiniteDuration; return infiniteDuration;
} }
@ -189,11 +189,11 @@ public:
_coord2coord(target.coordPairKind, target.x, target.y, target.time_point, _coord2coord(target.coordPairKind, target.x, target.y, target.time_point,
MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec); MccCoordPairKind::COORDS_KIND_HADEC_APP, ha, dec);
if (!doesObjectExitFromZone(dec)) { if (!doesObjectExitFromZone(ha)) {
return infiniteDuration; return infiniteDuration;
} }
if (!doesObjectReachZone(dec)) { if (!doesObjectReachZone(ha)) {
return zeroDuration; return zeroDuration;
} }

View File

@ -39,49 +39,35 @@ find_package(spdlog CONFIG)
# ******* ERFA LIBRARY ******* # ******* ERFA LIBRARY *******
# ExternalProject_Add(erfalib ExternalProject_Add(erfalib1
# PREFIX ${CMAKE_BINARY_DIR}/erfa_lib PREFIX ${CMAKE_BINARY_DIR}/erfa_lib1
# GIT_REPOSITORY "https://github.com/liberfa/erfa.git" GIT_REPOSITORY "https://github.com/liberfa/erfa.git"
# GIT_TAG "v2.0.1" GIT_TAG "v2.0.1"
# UPDATE_COMMAND "" UPDATE_COMMAND ""
# PATCH_COMMAND "" PATCH_COMMAND ""
# # BINARY_DIR erfa_build # BINARY_DIR erfa_build
# # SOURCE_DIR erfa # SOURCE_DIR erfa
# # INSTALL_DIR # INSTALL_DIR
# LOG_CONFIGURE 1 LOG_CONFIGURE 1
# CONFIGURE_COMMAND meson setup --reconfigure -Ddefault_library=static -Dbuildtype=release CONFIGURE_COMMAND meson setup --reconfigure -Ddefault_library=static -Dbuildtype=release
# -Dprefix=${CMAKE_BINARY_DIR}/erfa_lib -Dlibdir= -Dincludedir= -Ddatadir= <SOURCE_DIR> -Dprefix=${CMAKE_BINARY_DIR}/erfa_lib -Dlibdir= -Dincludedir= -Ddatadir= <SOURCE_DIR>
# BUILD_COMMAND ninja -C <BINARY_DIR> # CONFIGURE_COMMAND meson setup --reconfigure -Ddefault_library=static -Dbuildtype=release -Dc_args='-march=native' -Doptimization=3
# INSTALL_COMMAND meson install -C <BINARY_DIR> # -Dprefix=${CMAKE_BINARY_DIR}/erfa_lib -Dlibdir= -Dincludedir= -Ddatadir= <SOURCE_DIR>
# BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/erfa_lib/liberfa.a BUILD_COMMAND ninja -C <BINARY_DIR>
# ) INSTALL_COMMAND meson install -C <BINARY_DIR>
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/erfa_lib1/liberfa.a
)
add_library(ERFA_LIB STATIC IMPORTED) add_library(ERFA_LIB STATIC IMPORTED)
set_target_properties(ERFA_LIB PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/erfa_lib/liberfa.a) set_target_properties(ERFA_LIB PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/erfa_lib1/liberfa.a)
add_dependencies(ERFA_LIB erfalib) add_dependencies(ERFA_LIB erfalib)
set(ERFA_INCLUDE_DIR ${CMAKE_BINARY_DIR}/erfa_lib) set(ERFA_INCLUDE_DIR ${CMAKE_BINARY_DIR}/erfa_lib1)
# include_directories(${ERFA_INCLUDE_DIR}) include_directories(${ERFA_INCLUDE_DIR})
message(STATUS ${ERFA_INCLUDE_DIR})
set(MCC_LIBRARY_SRC1 mcc_generics.h mcc_defaults.h mcc_traits.h mcc_utils.h
mcc_ccte_iers.h mcc_ccte_iers_default.h mcc_ccte_erfa.h mcc_telemetry.h set(MCC_LIBRARY_SRC1 mcc_generics.h mcc_defaults.h mcc_traits.h mcc_utils.h mcc_ccte_iers.h mcc_ccte_iers_default.h mcc_ccte_erfa.h)
mcc_angle.h mcc_pzone.h mcc_pzone_container.h)
set(MCC_LIBRARY1 mcc1) set(MCC_LIBRARY1 mcc1)
add_library(${MCC_LIBRARY1} INTERFACE ${MCC_LIBRARY_SRC1}) add_library(${MCC_LIBRARY1} INTERFACE ${MCC_LIBRARY_SRC1})
target_compile_features(${MCC_LIBRARY1} INTERFACE cxx_std_23) target_compile_features(${MCC_LIBRARY1} INTERFACE cxx_std_23)
target_include_directories(${MCC_LIBRARY1} INTERFACE ${ERFA_INCLUDE_DIR}) target_include_directories(${MCC_LIBRARY1} INTERFACE ${ERFA_INCLUDE_DIR})
# add_subdirectory(fitpack)
# message(STATUS "FITPACK: " ${FITPACK_INCLUDE_DIR})
option(WITH_TESTS "Build tests" ON)
if (WITH_TESTS)
set(CTTE_TEST_APP ccte_test)
add_executable(${CTTE_TEST_APP} tests/ccte_test.cpp)
target_include_directories(${CTTE_TEST_APP} PRIVATE ${ERFA_INCLUDE_DIR})
target_link_libraries(${CTTE_TEST_APP} ERFA_LIB)
enable_testing()
endif()

View File

@ -403,9 +403,9 @@ template <std::convertible_to<MccAngle> T1, std::convertible_to<MccAngle> T2>
static auto operator*(const T1& v1, const T2& v2) static auto operator*(const T1& v1, const T2& v2)
{ {
if constexpr (std::is_arithmetic_v<T1>) { if constexpr (std::is_arithmetic_v<T1>) {
return T2{(double)v2 * v1}; return v2 *= v1;
} else if constexpr (std::is_arithmetic_v<T2>) { } else if constexpr (std::is_arithmetic_v<T2>) {
return T1{(double)v1 * v2}; return v1 *= v2;
} else { } else {
using res_t = std::conditional_t<std::convertible_to<T1, T2> && std::derived_from<T1, MccAngle>, T1, T2>; using res_t = std::conditional_t<std::convertible_to<T1, T2> && std::derived_from<T1, MccAngle>, T1, T2>;
return res_t{(double)v1 * (double)v2}; return res_t{(double)v1 * (double)v2};
@ -414,14 +414,13 @@ static auto operator*(const T1& v1, const T2& v2)
} }
template <std::convertible_to<MccAngle> T1, typename T2> template <std::convertible_to<MccAngle> T1, typename T2>
static T1 operator/(const T1& v1, const T2& v2) static auto operator/(const T1& v1, const T2& v2)
requires std::is_arithmetic_v<T2> requires std::is_arithmetic_v<T2>
{ {
return (double)v1 / v2; return v1 /= v2;
} }
/* */ /* */
class MccAngleRA_ICRS : public MccAngle class MccAngleRA_ICRS : public MccAngle

View File

@ -5,15 +5,6 @@
/* CELESTIAL COORDINATES TRANSFORMATION ENGINE IMPLEMENTATION BASED ON ERFA LIBRARY */ /* CELESTIAL COORDINATES TRANSFORMATION ENGINE IMPLEMENTATION BASED ON ERFA LIBRARY */
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
// in the ERFA the azimuth is counted from the North through the East!!!
//
// The implementation expects input azimuth as the "South"-defined one and transforms ERFA-outputs
// to the "South"-defined one respectively
#include <erfa.h> #include <erfa.h>
#include <erfam.h> #include <erfam.h>
#include <mutex> #include <mutex>
@ -124,7 +115,7 @@ inline std::error_code make_error_code(MccCCTE_ERFAErrorCode ec)
class MccCCTE_ERFA : public mcc_CCTE_interface_t<std::error_code> class MccCCTE_ERFA
{ {
static constexpr double PI_2 = std::numbers::pi / 2.0; static constexpr double PI_2 = std::numbers::pi / 2.0;
@ -182,12 +173,6 @@ public:
virtual ~MccCCTE_ERFA() = default; virtual ~MccCCTE_ERFA() = default;
std::string_view name() const
{
return "ERFA-CCTE-ENGINE";
}
// engine state related methods // engine state related methods
void setState(engine_state_t state) void setState(engine_state_t state)
@ -263,7 +248,7 @@ public:
error_t timepointToJulday(mcc_time_point_c auto tp, mcc_julday_c auto* julday) error_t timepointToJulday(mcc_time_point_c auto tp, mcc_julday_c auto* julday)
{ {
error_t ret = MccCCTE_ERFAErrorCode::ERROR_OK; auto ret = MccCCTE_ERFAErrorCode::ERROR_OK;
if (julday == nullptr) { if (julday == nullptr) {
return ret; return ret;
@ -272,9 +257,9 @@ public:
auto days = std::chrono::floor<std::chrono::days>(tp); auto days = std::chrono::floor<std::chrono::days>(tp);
std::chrono::year_month_day ymd{days}; std::chrono::year_month_day ymd{days};
double mjd0, mjd; double mjd0;
int err = eraCal2jd((int)ymd.year(), (unsigned)ymd.month(), (unsigned)ymd.day(), &mjd0, &mjd); int err = eraCal2jd(ymd.year(), (unsigned)ymd.month(), (unsigned)ymd.day(), &mjd0, &julday->mjd);
if (err != 0) { if (err != 0) {
ret = err == -1 ? MccCCTE_ERFAErrorCode::ERROR_julday_INVALID_YEAR ret = err == -1 ? MccCCTE_ERFAErrorCode::ERROR_julday_INVALID_YEAR
@ -282,16 +267,17 @@ public:
: err == -3 ? MccCCTE_ERFAErrorCode::ERROR_julday_INVALID_DAY : err == -3 ? MccCCTE_ERFAErrorCode::ERROR_julday_INVALID_DAY
: MccCCTE_ERFAErrorCode::ERROR_UNEXPECTED; : MccCCTE_ERFAErrorCode::ERROR_UNEXPECTED;
} else { // partial part of day } else { // partial part of day
mjd += std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(tp - days).count(); julday->mjd +=
*julday = mjd + mjd0; std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(tp - days).count();
} }
return ret; return ret;
} }
error_t juldayToAppSideral(mcc_julday_c auto jd, mcc_angle_c auto* st, bool islocal = false)
error_t timepointToAppSideral(mcc_time_point_c auto tp, mcc_angle_c auto* st, bool islocal = false)
{ {
error_t ret = MccCCTE_ERFAErrorCode::ERROR_OK; auto ret = MccCCTE_ERFAErrorCode::ERROR_OK;
if (st == nullptr) { if (st == nullptr) {
return ret; return ret;
@ -299,21 +285,19 @@ public:
using real_days_t = std::chrono::duration<double, std::ratio<86400>>; using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
using jd_t = decltype(jd); MccJulianDay julday;
double mjd; ret = timepointToJulday(tp, &julday);
if constexpr (std::floating_point<jd_t>) { if (ret != MccCCTE_ERFAErrorCode::ERROR_OK) {
mjd = jd - ERFA_DJM0; return ret;
} else {
mjd = jd.MJD();
} }
double ut1 = mjd; double ut1 = julday.mjd;
double tt = mjd; double tt = julday.mjd;
std::lock_guard lock{*_stateMutex}; std::lock_guard lock{*_stateMutex};
auto dut1 = _currentState._bulletinA.DUT1(mjd); auto dut1 = _currentState._bulletinA.DUT1(julday.mjd);
if (dut1.has_value()) { if (dut1.has_value()) {
ut1 += std::chrono::duration_cast<real_days_t>(dut1.value()).count(); ut1 += std::chrono::duration_cast<real_days_t>(dut1.value()).count();
@ -321,7 +305,7 @@ public:
return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
} }
auto tai_utc = _currentState._leapSeconds[mjd]; auto tai_utc = _currentState._leapSeconds[julday.mjd];
if (tai_utc.has_value()) { if (tai_utc.has_value()) {
tt += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count(); tt += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
} else { } else {
@ -332,7 +316,7 @@ public:
auto tt_tai = _currentState._bulletinA.TT_TAI(); auto tt_tai = _currentState._bulletinA.TT_TAI();
tt += std::chrono::duration_cast<real_days_t>(tt_tai).count(); tt += std::chrono::duration_cast<real_days_t>(tt_tai).count();
*st = eraGst06a(ERFA_DJM0, ut1, ERFA_DJM0, tt); *st = eraGst06a(julday.MJD0, ut1, julday.MJD0, tt);
if (islocal) { if (islocal) {
*st += _currentState.lon; *st += _currentState.lon;
@ -342,57 +326,6 @@ public:
return ret; return ret;
} }
error_t timepointToAppSideral(mcc_time_point_c auto tp, mcc_angle_c auto* st, bool islocal = false)
{
error_t ret = MccCCTE_ERFAErrorCode::ERROR_OK;
if (st == nullptr) {
return ret;
}
MccJulianDay julday;
ret = timepointToJulday(tp, &julday);
if (ret != MccCCTE_ERFAErrorCode::ERROR_OK) {
return ret;
}
return juldayToAppSideral(julday, st, islocal);
// double ut1 = julday.MJD();
// double tt = julday.MJD();
// std::lock_guard lock{*_stateMutex};
// auto dut1 = _currentState._bulletinA.DUT1(julday.MJD());
// if (dut1.has_value()) {
// ut1 += std::chrono::duration_cast<real_days_t>(dut1.value()).count();
// } else { // out of range
// return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
// }
// auto tai_utc = _currentState._leapSeconds[julday.MJD()];
// if (tai_utc.has_value()) {
// tt += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
// } else {
// return MccCCTE_ERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE;
// }
// auto tt_tai = _currentState._bulletinA.TT_TAI();
// tt += std::chrono::duration_cast<real_days_t>(tt_tai).count();
// *st = eraGst06a(ERFA_DJM0, ut1, ERFA_DJM0, tt);
// if (islocal) {
// *st += _currentState.lon;
// }
// return ret;
}
// coordinates transformations // coordinates transformations
@ -468,9 +401,8 @@ public:
// from apparent to apparent // from apparent to apparent
if (from_pt.time_point != to_pt->time_point) { // first, convert 'from' coordinates to ICRS if (from_pt.time_point != to_pt->time_point) { // first, convert 'from' coordinates to ICRS
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; MccCelestialPoint pt{.time_point = to_pt->time_point,
pt.time_point = to_pt->time_point; .pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
ret = obs2icrs(from_pt, &pt); ret = obs2icrs(from_pt, &pt);
if (!ret) { // from ICRS to required if (!ret) { // from ICRS to required
@ -480,8 +412,7 @@ public:
double eo, lst, ha, dec, az, alt; double eo, lst, ha, dec, az, alt;
auto lst_eo = [&]() { auto lst_eo = [&]() {
// ret = eqOrigins(from_pt.time_point, &eo); ret = eqOrigins(from_pt.time_point, &eo);
ret = equationOrigins(from_pt.time_point, &eo);
if (!ret) { if (!ret) {
ret = timepointToAppSideral(from_pt.time_point, &lst, true); ret = timepointToAppSideral(from_pt.time_point, &lst, true);
} }
@ -497,12 +428,13 @@ public:
} }
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) { if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
from_pt.X = ha; eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
hadec2azalt(from_pt, to_pt); to_pt->X = az;
to_pt->Y = PI_2 - to_pt->Y; to_pt->Y = PI_2 - alt;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
from_pt.X = ha; eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
hadec2azalt(from_pt, to_pt); to_pt->X = az;
to_pt->Y = alt;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
to_pt->X = ha; to_pt->X = ha;
to_pt->Y = from_pt.Y; to_pt->Y = from_pt.Y;
@ -511,10 +443,13 @@ public:
} }
} else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { } else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) { if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
hadec2azalt(from_pt, to_pt); eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
to_pt->Y = PI_2 - to_pt->Y; to_pt->X = az;
to_pt->Y = PI_2 - alt;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
hadec2azalt(from_pt, to_pt); eraHd2ae(ha, from_pt.Y, _currentState.lat, &az, &alt);
to_pt->X = az;
to_pt->Y = alt;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
lst_eo(); lst_eo();
if (!ret) { if (!ret) {
@ -534,15 +469,18 @@ public:
ret = transformCoordinates(std::move(from_pt), to_pt); ret = transformCoordinates(std::move(from_pt), to_pt);
} else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) { } else if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
azalt2hadec(from_pt, to_pt); eraAe2hd(from_pt.X, from_pt.Y, _currentState.lat, &ha, &dec);
to_pt->X = ha;
to_pt->Y = dec;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
to_pt->X = from_pt.X; to_pt->X = from_pt.X;
to_pt->Y = PI_2 - from_pt.Y; to_pt->Y = PI_2 - from_pt.Y;
} else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { } else if (to_pt->pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
azalt2hadec(from_pt, to_pt); eraAe2hd(from_pt.X, from_pt.Y, _currentState.lat, &ha, &dec);
lst_eo(); lst_eo();
if (!ret) { if (!ret) {
to_pt->X = lst - to_pt->X + eo; to_pt->X = lst - ha + eo;
to_pt->Y = dec;
} }
} else { } else {
ret = MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; ret = MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
@ -576,7 +514,7 @@ public:
return icrs2obs(from_pt, to_pt); return icrs2obs(from_pt, to_pt);
} }
// from apparent: copy corresponded coordinates and compute other ones (ignore to_pt->pair_kind) // from apparent: copy corresponded coordinates and compute other ones
if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { if (from_pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
to_pt->RA_APP = from_pt.X; to_pt->RA_APP = from_pt.X;
to_pt->DEC_APP = from_pt.Y; to_pt->DEC_APP = from_pt.Y;
@ -657,58 +595,6 @@ public:
return ret; return ret;
} }
// equation of the origins
error_t equationOrigins(mcc_julday_c auto const& jd, mcc_angle_c auto* eo)
{
if (eo == nullptr) {
return MccCCTE_ERFAErrorCode::ERROR_OK;
}
auto ret = MccCCTE_ERFAErrorCode::ERROR_OK;
double tt, mjd;
if constexpr (std::floating_point<decltype(jd)>) {
mjd = jd - ERFA_DJM0;
} else {
mjd = jd.MJD();
}
std::lock_guard lock{*_stateMutex};
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
auto tai_utc = _currentState._leapSeconds[mjd];
if (tai_utc.has_value()) {
tt = jd.MJD() + std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
auto tt_tai = _currentState._bulletinA.TT_TAI();
tt += +std::chrono::duration_cast<real_days_t>(tt_tai).count();
*eo = eraEo06a(ERFA_DJM0, tt);
} else {
ret = MccCCTE_ERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE;
}
return ret;
}
error_t equationOrigins(mcc_time_point_c auto const& tp, mcc_angle_c auto* eo)
{
if (eo == nullptr) {
return MccCCTE_ERFAErrorCode::ERROR_OK;
}
MccJulianDay jd;
auto ret = timepointToJulday(tp, &jd);
if (ret) {
return ret;
}
return equationOrigins(std::move(jd), eo);
}
// refraction // refraction
@ -796,13 +682,13 @@ protected:
std::lock_guard lock{*_stateMutex}; std::lock_guard lock{*_stateMutex};
auto dut1 = _currentState._bulletinA.DUT1(jd.MJD()); auto dut1 = _currentState._bulletinA.DUT1(jd.mjd);
if (!dut1.has_value()) { if (!dut1.has_value()) {
return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
} }
auto pol_pos = _currentState._bulletinA.polarCoords(jd.MJD()); auto pol_pos = _currentState._bulletinA.polarCoords(jd.mjd);
if (!pol_pos.has_value()) { if (!pol_pos.has_value()) {
return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
} }
@ -814,7 +700,7 @@ protected:
double az, zd, ha, ra, dec, eo; double az, zd, ha, ra, dec, eo;
int err = eraAtco13(pt.X, pt.Y, 0.0, 0.0, 0.0, 0.0, jd.MJD0, jd.MJD(), dut1->count(), _currentState.lon, int err = eraAtco13(pt.X, pt.Y, 0.0, 0.0, 0.0, 0.0, jd.MJD0, jd.mjd, dut1->count(), _currentState.lon,
_currentState.lat, _currentState.elev, pol_pos->x, pol_pos->y, _currentState.meteo.pressure, _currentState.lat, _currentState.elev, pol_pos->x, pol_pos->y, _currentState.meteo.pressure,
_currentState.meteo.temperature, _currentState.meteo.humidity, _currentState.wavelength, _currentState.meteo.temperature, _currentState.meteo.humidity, _currentState.wavelength,
&az, &zd, &ha, &dec, &ra, &eo); &az, &zd, &ha, &dec, &ra, &eo);
@ -825,22 +711,18 @@ protected:
ret = MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE; ret = MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
} }
result->AZ = az;
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
// in the ERFA the azimuth is counted from the North through the East!!!
//
result->AZ = MccAngle(az + std::numbers::pi).normalize<MccAngle::NORM_KIND_0_360>();
result->ZD = zd; result->ZD = zd;
result->HA = ha; result->HA = ha;
result->RA_APP = ra; result->RA_APP = ra;
result->DEC_APP = dec; result->DEC_APP = dec;
result->ALT = MccCCTE_ERFA::PI_2 - zd; result->ALT = std::numbers::pi / 2.0 - zd;
return ret; return ret;
} }
error_t obs2icrs(mcc_celestial_point_c auto from_pt, mcc_celestial_point_c auto* to_pt) error_t obs2icrs(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
{ {
if (to_pt == nullptr) { if (to_pt == nullptr) {
return MccCCTE_ERFAErrorCode::ERROR_OK; return MccCCTE_ERFAErrorCode::ERROR_OK;
@ -855,13 +737,13 @@ protected:
std::lock_guard lock{*_stateMutex}; std::lock_guard lock{*_stateMutex};
auto dut1 = _currentState._bulletinA.DUT1(jd.MJD()); auto dut1 = _currentState._bulletinA.DUT1(jd.mjd);
if (!dut1.has_value()) { if (!dut1.has_value()) {
return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
} }
auto pol_pos = _currentState._bulletinA.polarCoords(jd.MJD()); auto pol_pos = _currentState._bulletinA.polarCoords(jd.mjd);
if (!pol_pos.has_value()) { if (!pol_pos.has_value()) {
return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE; return MccCCTE_ERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
} }
@ -874,18 +756,10 @@ protected:
std::string type; std::string type;
switch (from_pt.pair_kind) { switch (from_pt.pair_kind) {
case mcc::MccCoordPairKind::COORDS_KIND_AZZD: case mcc::MccCoordPairKind::COORDS_KIND_AZZD:
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West,
// but in the ERFA the azimuth is counted from the North through the East!!!
//
from_pt.X += std::numbers::pi;
type = "A"; type = "A";
break; break;
case mcc::MccCoordPairKind::COORDS_KIND_AZALT: case mcc::MccCoordPairKind::COORDS_KIND_AZALT:
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, from_pt.Y = std::numbers::pi / 2.0 - from_pt.Y; // altitude to zenithal distance
// but in the ERFA the azimuth is counted from the North through the East!!!
//
from_pt.X += std::numbers::pi;
from_pt.Y = MccCCTE_ERFA::PI_2 - from_pt.Y; // altitude to zenithal distance
type = "A"; type = "A";
break; break;
case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP: case mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP:
@ -898,47 +772,16 @@ protected:
return MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR; return MccCCTE_ERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
} }
int err = eraAtoc13(type.c_str(), from_pt.X, from_pt.Y, jd.MJD0, jd.MJD(), dut1->count(), _currentState.lon, int err = eraAtoc13(type.c_str(), from_pt.X, from_pt.Y, jd.MJD0, jd.mjd, dut1->count(), _currentState.lon,
_currentState.lat, _currentState.elev, pol_pos->x, pol_pos->y, _currentState.meteo.pressure, _currentState.lat, _currentState.elev, pol_pos->x, pol_pos->y, _currentState.meteo.pressure,
_currentState.meteo.temperature, _currentState.meteo.humidity, _currentState.wavelength, _currentState.meteo.temperature, _currentState.meteo.humidity, _currentState.wavelength,
&to_pt->X, &to_pt->Y); &to_pt->X, &to_pt->Y);
if (err == 1) { if (err == 1) {
ret = MccCCTE_ERFAErrorCode::ERROR_DUBIOUS_YEAR; return MccCCTE_ERFAErrorCode::ERROR_DUBIOUS_YEAR;
} else if (err == -1) { } else if (err == -1) {
ret = MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE; return MccCCTE_ERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
} }
return ret;
}
void azalt2hadec(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
{
double ha, dec;
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
// in the ERFA the azimuth is counted from the North through the East!!!
//
eraAe2hd(from_pt.X + std::numbers::pi, from_pt.Y, _currentState.lat, &ha, &dec);
to_pt->X = ha;
to_pt->Y = dec;
}
void hadec2azalt(mcc_celestial_point_c auto const& from_pt, mcc_celestial_point_c auto* to_pt)
{
double az, alt;
eraHd2ae(from_pt.X, from_pt.Y, _currentState.lat, &az, &alt);
// NOTE: according to definition of astronomical azimuth it is counted from the South through the West, but
// in the ERFA the azimuth is counted from the North through the East!!!
//
// convert it to "from the South through the West"
to_pt->X = MccAngle(az - std::numbers::pi).normalize<MccAngle::NORM_KIND_0_360>();
to_pt->Y = alt;
} }
error_t eqOrigins(mcc_time_point_c auto const& tp, double* eo) error_t eqOrigins(mcc_time_point_c auto const& tp, double* eo)
@ -947,8 +790,7 @@ protected:
return MccCCTE_ERFAErrorCode::ERROR_OK; return MccCCTE_ERFAErrorCode::ERROR_OK;
} }
MccJulianDay jd; MccJulianDay jd, tt;
double tt;
auto ret = timepointToJulday(tp, &jd); auto ret = timepointToJulday(tp, &jd);
if (ret) { if (ret) {
return ret; return ret;
@ -958,14 +800,14 @@ protected:
using real_days_t = std::chrono::duration<double, std::ratio<86400>>; using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
auto tai_utc = _currentState._leapSeconds[jd.MJD()]; auto tai_utc = _currentState._leapSeconds[jd.mjd];
if (tai_utc.has_value()) { if (tai_utc.has_value()) {
tt = jd.MJD() + std::chrono::duration_cast<real_days_t>(tai_utc.value()).count(); tt.mjd = jd.mjd + std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
auto tt_tai = _currentState._bulletinA.TT_TAI(); auto tt_tai = _currentState._bulletinA.TT_TAI();
tt += +std::chrono::duration_cast<real_days_t>(tt_tai).count(); tt.mjd = jd.mjd + std::chrono::duration_cast<real_days_t>(tt_tai).count();
*eo = eraEo06a(jd.MJD0, tt); *eo = eraEo06a(tt.MJD0, tt.mjd);
} else { } else {
ret = MccCCTE_ERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE; ret = MccCCTE_ERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE;
} }
@ -974,6 +816,4 @@ protected:
} }
}; };
static_assert(mcc_ccte_c<MccCCTE_ERFA>, "");
} // namespace mcc::ccte::erfa } // namespace mcc::ccte::erfa

View File

@ -67,7 +67,7 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
* * * *
* Rapid Service/Prediction of Earth Orientation * * Rapid Service/Prediction of Earth Orientation *
********************************************************************** **********************************************************************
14 August 2025 Vol. XXXVIII No. 033 7 August 2025 Vol. XXXVIII No. 032
______________________________________________________________________ ______________________________________________________________________
GENERAL INFORMATION: GENERAL INFORMATION:
MJD = Julian Date - 2 400 000.5 days MJD = Julian Date - 2 400 000.5 days
@ -116,13 +116,47 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
IERS Rapid Service IERS Rapid Service
MJD x error y error UT1-UTC error MJD x error y error UT1-UTC error
" " " " s s " " " " s s
25 8 8 60895 0.21521 .00009 0.41904 .00009 0.069826 0.000016 25 8 1 60888 0.21017 .00009 0.42717 .00009 0.062125 0.000021
25 8 9 60896 0.21558 .00009 0.41771 .00009 0.070764 0.000016 25 8 2 60889 0.21181 .00009 0.42627 .00009 0.062752 0.000019
25 8 10 60897 0.21616 .00009 0.41640 .00009 0.071442 0.000017 25 8 3 60890 0.21302 .00009 0.42504 .00009 0.063645 0.000016
25 8 11 60898 0.21726 .00009 0.41513 .00009 0.071836 0.000016 25 8 4 60891 0.21368 .00009 0.42383 .00009 0.064781 0.000010
25 8 12 60899 0.21832 .00009 0.41407 .00009 0.071996 0.000017 25 8 5 60892 0.21398 .00009 0.42271 .00009 0.066047 0.000009
25 8 13 60900 0.21871 .00009 0.41314 .00009 0.072040 0.000013 25 8 6 60893 0.21437 .00009 0.42152 .00009 0.067348 0.000008
25 8 14 60901 0.21892 .00009 0.41223 .00009 0.072161 0.000011 25 8 7 60894 0.21485 .00009 0.42038 .00009 0.068615 0.000055
IERS Final Values
MJD x y UT1-UTC
" " s
25 6 2 60828 0.1141 0.4380 0.02903
25 6 3 60829 0.1154 0.4384 0.02896
25 6 4 60830 0.1172 0.4390 0.02885
25 6 5 60831 0.1187 0.4399 0.02874
25 6 6 60832 0.1202 0.4403 0.02868
25 6 7 60833 0.1217 0.4408 0.02871
25 6 8 60834 0.1232 0.4410 0.02891
25 6 9 60835 0.1248 0.4415 0.02936
25 6 10 60836 0.1262 0.4420 0.03004
25 6 11 60837 0.1276 0.4425 0.03086
25 6 12 60838 0.1291 0.4428 0.03178
25 6 13 60839 0.1307 0.4428 0.03273
25 6 14 60840 0.1325 0.4426 0.03360
25 6 15 60841 0.1347 0.4424 0.03430
25 6 16 60842 0.1370 0.4426 0.03479
25 6 17 60843 0.1389 0.4427 0.03506
25 6 18 60844 0.1406 0.4429 0.03512
25 6 19 60845 0.1420 0.4431 0.03504
25 6 20 60846 0.1436 0.4427 0.03492
25 6 21 60847 0.1452 0.4426 0.03489
25 6 22 60848 0.1468 0.4423 0.03515
25 6 23 60849 0.1486 0.4420 0.03583
25 6 24 60850 0.1502 0.4416 0.03682
25 6 25 60851 0.1518 0.4411 0.03797
25 6 26 60852 0.1533 0.4407 0.03919
25 6 27 60853 0.1548 0.4404 0.04037
25 6 28 60854 0.1564 0.4401 0.04139
25 6 29 60855 0.1585 0.4400 0.04222
25 6 30 60856 0.1603 0.4401 0.04287
25 7 1 60857 0.1621 0.4398 0.04342
_______________________________________________________________________ _______________________________________________________________________
@ -130,390 +164,495 @@ static std::string MCC_DEFAULT_IERS_BULLETIN_A_FILE = R"--(
The following formulas will not reproduce the predictions given below, The following formulas will not reproduce the predictions given below,
but may be used to extend the predictions beyond the end of this table. but may be used to extend the predictions beyond the end of this table.
x = 0.1410 + 0.1141 cos A + 0.0905 sin A - 0.0377 cos C - 0.0594 sin C x = 0.1420 + 0.1046 cos A + 0.1043 sin A - 0.0336 cos C - 0.0648 sin C
y = 0.3821 + 0.0927 cos A - 0.1005 sin A - 0.0594 cos C + 0.0377 sin C y = 0.3838 + 0.1044 cos A - 0.0915 sin A - 0.0648 cos C + 0.0336 sin C
UT1-UTC = 0.0478 + 0.00010 (MJD - 60909) - (UT2-UT1) UT1-UTC = 0.0474 + 0.00010 (MJD - 60902) - (UT2-UT1)
where A = 2*pi*(MJD-60901)/365.25 and C = 2*pi*(MJD-60901)/435. where A = 2*pi*(MJD-60894)/365.25 and C = 2*pi*(MJD-60894)/435.
TAI-UTC(MJD 60902) = 37.0 TAI-UTC(MJD 60895) = 37.0
The accuracy may be estimated from the expressions: The accuracy may be estimated from the expressions:
S x,y = 0.00068 (MJD-60901)**0.80 S t = 0.00025 (MJD-60901)**0.75 S x,y = 0.00068 (MJD-60894)**0.80 S t = 0.00025 (MJD-60894)**0.75
Estimated accuracies are: Predictions 10 d 20 d 30 d 40 d Estimated accuracies are: Predictions 10 d 20 d 30 d 40 d
Polar coord's 0.004 0.007 0.010 0.013 Polar coord's 0.004 0.007 0.010 0.013
UT1-UTC 0.0014 0.0024 0.0032 0.0040 UT1-UTC 0.0014 0.0024 0.0032 0.0040
MJD x(arcsec) y(arcsec) UT1-UTC(sec) MJD x(arcsec) y(arcsec) UT1-UTC(sec)
2025 8 15 60902 0.2191 0.4112 0.07241 2025 8 8 60895 0.2155 0.4191 0.06979
2025 8 16 60903 0.2193 0.4101 0.07289 2025 8 9 60896 0.2161 0.4179 0.07073
2025 8 17 60904 0.2196 0.4090 0.07364 2025 8 10 60897 0.2169 0.4167 0.07137
2025 8 18 60905 0.2200 0.4078 0.07462 2025 8 11 60898 0.2176 0.4154 0.07173
2025 8 19 60906 0.2205 0.4066 0.07573 2025 8 12 60899 0.2184 0.4142 0.07190
2025 8 20 60907 0.2210 0.4054 0.07685 2025 8 13 60900 0.2191 0.4130 0.07200
2025 8 21 60908 0.2215 0.4042 0.07788 2025 8 14 60901 0.2198 0.4117 0.07218
2025 8 22 60909 0.2220 0.4029 0.07870 2025 8 15 60902 0.2204 0.4105 0.07254
2025 8 23 60910 0.2225 0.4018 0.07929 2025 8 16 60903 0.2210 0.4094 0.07316
2025 8 24 60911 0.2229 0.4006 0.07964 2025 8 17 60904 0.2216 0.4082 0.07403
2025 8 25 60912 0.2233 0.3994 0.07982 2025 8 18 60905 0.2222 0.4070 0.07507
2025 8 26 60913 0.2237 0.3982 0.07994 2025 8 19 60906 0.2227 0.4058 0.07619
2025 8 27 60914 0.2241 0.3970 0.08012 2025 8 20 60907 0.2232 0.4046 0.07725
2025 8 28 60915 0.2244 0.3957 0.08043 2025 8 21 60908 0.2237 0.4033 0.07814
2025 8 29 60916 0.2247 0.3945 0.08090 2025 8 22 60909 0.2242 0.4021 0.07878
2025 8 30 60917 0.2250 0.3932 0.08154 2025 8 23 60910 0.2247 0.4008 0.07912
2025 8 31 60918 0.2253 0.3919 0.08233 2025 8 24 60911 0.2251 0.3995 0.07921
2025 9 1 60919 0.2256 0.3907 0.08321 2025 8 25 60912 0.2255 0.3983 0.07914
2025 9 2 60920 0.2258 0.3894 0.08411 2025 8 26 60913 0.2259 0.3970 0.07899
2025 9 3 60921 0.2260 0.3881 0.08494 2025 8 27 60914 0.2263 0.3957 0.07887
2025 9 4 60922 0.2262 0.3868 0.08561 2025 8 28 60915 0.2266 0.3944 0.07884
2025 9 5 60923 0.2263 0.3855 0.08601 2025 8 29 60916 0.2269 0.3931 0.07898
2025 9 6 60924 0.2265 0.3842 0.08608 2025 8 30 60917 0.2272 0.3918 0.07930
2025 9 7 60925 0.2266 0.3829 0.08580 2025 8 31 60918 0.2275 0.3905 0.07979
2025 9 8 60926 0.2267 0.3816 0.08522 2025 9 1 60919 0.2278 0.3892 0.08042
2025 9 9 60927 0.2267 0.3803 0.08448 2025 9 2 60920 0.2280 0.3879 0.08112
2025 9 10 60928 0.2267 0.3790 0.08373 2025 9 3 60921 0.2282 0.3865 0.08182
2025 9 11 60929 0.2267 0.3777 0.08314 2025 9 4 60922 0.2283 0.3852 0.08242
2025 9 12 60930 0.2267 0.3764 0.08283 2025 9 5 60923 0.2285 0.3839 0.08283
2025 9 13 60931 0.2267 0.3751 0.08283 2025 9 6 60924 0.2286 0.3825 0.08295
2025 9 14 60932 0.2266 0.3738 0.08308 2025 9 7 60925 0.2287 0.3812 0.08277
2025 9 15 60933 0.2265 0.3724 0.08349 2025 9 8 60926 0.2287 0.3799 0.08232
2025 9 16 60934 0.2263 0.3711 0.08390 2025 9 9 60927 0.2287 0.3785 0.08173
2025 9 17 60935 0.2262 0.3698 0.08421 2025 9 10 60928 0.2288 0.3772 0.08114
2025 9 18 60936 0.2260 0.3685 0.08434 2025 9 11 60929 0.2287 0.3758 0.08072
2025 9 19 60937 0.2258 0.3672 0.08426 2025 9 12 60930 0.2287 0.3745 0.08056
2025 9 20 60938 0.2256 0.3659 0.08400 2025 9 13 60931 0.2286 0.3731 0.08070
2025 9 21 60939 0.2253 0.3646 0.08360 2025 9 14 60932 0.2285 0.3718 0.08108
2025 9 22 60940 0.2250 0.3633 0.08315 2025 9 15 60933 0.2284 0.3705 0.08159
2025 9 23 60941 0.2247 0.3620 0.08272 2025 9 16 60934 0.2282 0.3691 0.08209
2025 9 24 60942 0.2244 0.3607 0.08239 2025 9 17 60935 0.2281 0.3678 0.08247
2025 9 25 60943 0.2240 0.3595 0.08220 2025 9 18 60936 0.2279 0.3664 0.08265
2025 9 26 60944 0.2236 0.3582 0.08219 2025 9 19 60937 0.2276 0.3651 0.08260
2025 9 27 60945 0.2232 0.3569 0.08235 2025 9 20 60938 0.2274 0.3638 0.08234
2025 9 28 60946 0.2228 0.3556 0.08264 2025 9 21 60939 0.2271 0.3624 0.08194
2025 9 29 60947 0.2223 0.3544 0.08302 2025 9 22 60940 0.2268 0.3611 0.08146
2025 9 30 60948 0.2218 0.3531 0.08339 2025 9 23 60941 0.2264 0.3598 0.08101
2025 10 1 60949 0.2213 0.3519 0.08369 2025 9 24 60942 0.2261 0.3585 0.08064
2025 10 2 60950 0.2208 0.3506 0.08381 2025 9 25 60943 0.2257 0.3571 0.08042
2025 10 3 60951 0.2202 0.3494 0.08367 2025 9 26 60944 0.2253 0.3558 0.08037
2025 10 4 60952 0.2196 0.3482 0.08322 2025 9 27 60945 0.2248 0.3545 0.08049
2025 10 5 60953 0.2190 0.3470 0.08244 2025 9 28 60946 0.2244 0.3532 0.08076
2025 10 6 60954 0.2184 0.3458 0.08143 2025 9 29 60947 0.2239 0.3520 0.08112
2025 10 7 60955 0.2177 0.3446 0.08031 2025 9 30 60948 0.2234 0.3507 0.08148
2025 10 8 60956 0.2171 0.3434 0.07929 2025 10 1 60949 0.2228 0.3494 0.08177
2025 10 9 60957 0.2164 0.3422 0.07851 2025 10 2 60950 0.2223 0.3481 0.08189
2025 10 10 60958 0.2156 0.3410 0.07804 2025 10 3 60951 0.2217 0.3469 0.08176
2025 10 11 60959 0.2149 0.3399 0.07788 2025 10 4 60952 0.2211 0.3456 0.08133
2025 10 12 60960 0.2141 0.3387 0.07790 2025 10 5 60953 0.2204 0.3444 0.08059
2025 10 13 60961 0.2133 0.3376 0.07799 2025 10 6 60954 0.2198 0.3431 0.07962
2025 10 14 60962 0.2125 0.3365 0.07800 2025 10 7 60955 0.2191 0.3419 0.07856
2025 10 15 60963 0.2117 0.3354 0.07785 2025 10 8 60956 0.2184 0.3407 0.07759
2025 10 16 60964 0.2108 0.3343 0.07750 2025 10 9 60957 0.2177 0.3395 0.07687
2025 10 17 60965 0.2100 0.3332 0.07696 2025 10 10 60958 0.2169 0.3383 0.07647
2025 10 18 60966 0.2091 0.3321 0.07629 2025 10 11 60959 0.2161 0.3371 0.07637
2025 10 19 60967 0.2082 0.3311 0.07556 2025 10 12 60960 0.2153 0.3360 0.07648
2025 10 20 60968 0.2072 0.3300 0.07484 2025 10 13 60961 0.2145 0.3348 0.07665
2025 10 21 60969 0.2063 0.3290 0.07422 2025 10 14 60962 0.2137 0.3337 0.07674
2025 10 22 60970 0.2053 0.3280 0.07375 2025 10 15 60963 0.2128 0.3325 0.07667
2025 10 23 60971 0.2043 0.3270 0.07347 2025 10 16 60964 0.2119 0.3314 0.07640
2025 10 24 60972 0.2033 0.3260 0.07337 2025 10 17 60965 0.2110 0.3303 0.07594
2025 10 25 60973 0.2022 0.3250 0.07345 2025 10 18 60966 0.2101 0.3292 0.07535
2025 10 26 60974 0.2012 0.3241 0.07364 2025 10 19 60967 0.2092 0.3281 0.07470
2025 10 27 60975 0.2001 0.3231 0.07388 2025 10 20 60968 0.2082 0.3271 0.07405
2025 10 28 60976 0.1990 0.3222 0.07410 2025 10 21 60969 0.2072 0.3260 0.07350
2025 10 29 60977 0.1979 0.3213 0.07419 2025 10 22 60970 0.2062 0.3250 0.07310
2025 10 30 60978 0.1968 0.3204 0.07409 2025 10 23 60971 0.2052 0.3240 0.07289
2025 10 31 60979 0.1957 0.3196 0.07374 2025 10 24 60972 0.2041 0.3230 0.07287
2025 11 1 60980 0.1945 0.3187 0.07309 2025 10 25 60973 0.2031 0.3220 0.07302
2025 11 2 60981 0.1933 0.3179 0.07220 2025 10 26 60974 0.2020 0.3210 0.07329
2025 11 3 60982 0.1922 0.3171 0.07115 2025 10 27 60975 0.2009 0.3200 0.07360
2025 11 4 60983 0.1910 0.3163 0.07011 2025 10 28 60976 0.1998 0.3191 0.07388
2025 11 5 60984 0.1898 0.3155 0.06924 2025 10 29 60977 0.1986 0.3182 0.07405
2025 11 6 60985 0.1885 0.3147 0.06866 2025 10 30 60978 0.1975 0.3173 0.07402
2025 11 7 60986 0.1873 0.3140 0.06841 2025 10 31 60979 0.1963 0.3164 0.07372
2025 11 8 60987 0.1860 0.3133 0.06842 2025 11 1 60980 0.1951 0.3155 0.07315
2025 11 9 60988 0.1848 0.3126 0.06856 2025 11 2 60981 0.1939 0.3147 0.07232
2025 11 10 60989 0.1835 0.3119 0.06868 2025 11 3 60982 0.1927 0.3139 0.07133
2025 11 11 60990 0.1822 0.3112 0.06866 2025 11 4 60983 0.1915 0.3130 0.07034
2025 11 12 60991 0.1809 0.3106 0.06845 2025 11 5 60984 0.1902 0.3122 0.06953
2025 11 13 60992 0.1796 0.3100 0.06806 2025 11 6 60985 0.1890 0.3115 0.06901
2025 11 14 60993 0.1782 0.3094 0.06755 2025 11 7 60986 0.1877 0.3107 0.06882
2025 11 15 60994 0.1769 0.3088 0.06698 2025 11 8 60987 0.1864 0.3100 0.06889
2025 11 16 60995 0.1755 0.3082 0.06643 2025 11 9 60988 0.1851 0.3093 0.06908
2025 11 17 60996 0.1742 0.3077 0.06596 2025 11 10 60989 0.1838 0.3086 0.06924
2025 11 18 60997 0.1728 0.3072 0.06564 2025 11 11 60990 0.1825 0.3079 0.06927
2025 11 19 60998 0.1714 0.3067 0.06550 2025 11 12 60991 0.1812 0.3072 0.06910
2025 11 20 60999 0.1701 0.3062 0.06555 2025 11 13 60992 0.1798 0.3066 0.06876
2025 11 21 61000 0.1687 0.3058 0.06578 2025 11 14 60993 0.1784 0.3060 0.06828
2025 11 22 61001 0.1673 0.3053 0.06615 2025 11 15 60994 0.1771 0.3054 0.06774
2025 11 23 61002 0.1659 0.3049 0.06660 2025 11 16 60995 0.1757 0.3048 0.06722
2025 11 24 61003 0.1644 0.3045 0.06704 2025 11 17 60996 0.1743 0.3043 0.06677
2025 11 25 61004 0.1630 0.3042 0.06739 2025 11 18 60997 0.1729 0.3038 0.06647
2025 11 26 61005 0.1616 0.3038 0.06759 2025 11 19 60998 0.1715 0.3033 0.06635
2025 11 27 61006 0.1602 0.3035 0.06756 2025 11 20 60999 0.1701 0.3028 0.06642
2025 11 28 61007 0.1587 0.3032 0.06728 2025 11 21 61000 0.1687 0.3023 0.06667
2025 11 29 61008 0.1573 0.3029 0.06677 2025 11 22 61001 0.1672 0.3019 0.06705
2025 11 30 61009 0.1558 0.3027 0.06607 2025 11 23 61002 0.1658 0.3015 0.06751
2025 12 1 61010 0.1544 0.3024 0.06523 2025 11 24 61003 0.1643 0.3011 0.06788
2025 12 2 61011 0.1529 0.3022 0.06448 2025 11 25 61004 0.1629 0.3007 0.06817
2025 12 3 61012 0.1515 0.3020 0.06395 2025 11 26 61005 0.1614 0.3003 0.06829
2025 12 4 61013 0.1500 0.3019 0.06373 2025 11 27 61006 0.1600 0.3000 0.06820
2025 12 5 61014 0.1486 0.3017 0.06379 2025 11 28 61007 0.1585 0.2997 0.06785
2025 12 6 61015 0.1471 0.3016 0.06403 2025 11 29 61008 0.1570 0.2994 0.06727
2025 12 7 61016 0.1456 0.3015 0.06430 2025 11 30 61009 0.1556 0.2992 0.06650
2025 12 8 61017 0.1442 0.3015 0.06446 2025 12 1 61010 0.1541 0.2989 0.06567
2025 12 9 61018 0.1427 0.3014 0.06442 2025 12 2 61011 0.1526 0.2987 0.06494
2025 12 10 61019 0.1413 0.3014 0.06419 2025 12 3 61012 0.1511 0.2985 0.06442
2025 12 11 61020 0.1398 0.3014 0.06380 2025 12 4 61013 0.1496 0.2984 0.06421
2025 12 12 61021 0.1383 0.3014 0.06335 2025 12 5 61014 0.1481 0.2982 0.06429
2025 12 13 61022 0.1369 0.3015 0.06291 2025 12 6 61015 0.1466 0.2981 0.06454
2025 12 14 61023 0.1354 0.3015 0.06256 2025 12 7 61016 0.1451 0.2980 0.06483
2025 12 15 61024 0.1340 0.3016 0.06234 2025 12 8 61017 0.1437 0.2980 0.06500
2025 12 16 61025 0.1325 0.3017 0.06230 2025 12 9 61018 0.1422 0.2979 0.06498
2025 12 17 61026 0.1311 0.3019 0.06246 2025 12 10 61019 0.1407 0.2979 0.06476
2025 12 18 61027 0.1297 0.3020 0.06279 2025 12 11 61020 0.1392 0.2979 0.06439
2025 12 19 61028 0.1282 0.3022 0.06328 2025 12 12 61021 0.1377 0.2979 0.06395
2025 12 20 61029 0.1268 0.3024 0.06386 2025 12 13 61022 0.1362 0.2980 0.06353
2025 12 21 61030 0.1254 0.3027 0.06444 2025 12 14 61023 0.1347 0.2980 0.06319
2025 12 22 61031 0.1239 0.3029 0.06496 2025 12 15 61024 0.1332 0.2981 0.06299
2025 12 23 61032 0.1225 0.3032 0.06533 2025 12 16 61025 0.1318 0.2982 0.06297
2025 12 24 61033 0.1211 0.3035 0.06550 2025 12 17 61026 0.1303 0.2984 0.06315
2025 12 25 61034 0.1197 0.3038 0.06544 2025 12 18 61027 0.1288 0.2985 0.06351
2025 12 26 61035 0.1183 0.3041 0.06515 2025 12 19 61028 0.1274 0.2987 0.06401
2025 12 27 61036 0.1170 0.3045 0.06469 2025 12 20 61029 0.1259 0.2989 0.06461
2025 12 28 61037 0.1156 0.3049 0.06414 2025 12 21 61030 0.1245 0.2992 0.06522
2025 12 29 61038 0.1142 0.3053 0.06364 2025 12 22 61031 0.1230 0.2994 0.06575
2025 12 30 61039 0.1129 0.3057 0.06331 2025 12 23 61032 0.1216 0.2997 0.06614
2025 12 31 61040 0.1115 0.3062 0.06323 2025 12 24 61033 0.1201 0.3000 0.06632
2026 1 1 61041 0.1102 0.3066 0.06342 2025 12 25 61034 0.1187 0.3003 0.06627
2026 1 2 61042 0.1089 0.3071 0.06382 2025 12 26 61035 0.1173 0.3007 0.06599
2026 1 3 61043 0.1076 0.3077 0.06429 2025 12 27 61036 0.1159 0.3011 0.06554
2026 1 4 61044 0.1063 0.3082 0.06469 2025 12 28 61037 0.1145 0.3015 0.06500
2026 1 5 61045 0.1050 0.3087 0.06489 2025 12 29 61038 0.1131 0.3019 0.06451
2026 1 6 61046 0.1037 0.3093 0.06486 2025 12 30 61039 0.1117 0.3023 0.06418
2026 1 7 61047 0.1024 0.3099 0.06463 2025 12 31 61040 0.1103 0.3028 0.06410
2026 1 8 61048 0.1012 0.3105 0.06428 2026 1 1 61041 0.1090 0.3033 0.06429
2026 1 9 61049 0.0999 0.3112 0.06391 2026 1 2 61042 0.1076 0.3038 0.06468
2026 1 10 61050 0.0987 0.3118 0.06361 2026 1 3 61043 0.1063 0.3043 0.06514
2026 1 11 61051 0.0975 0.3125 0.06344 2026 1 4 61044 0.1050 0.3048 0.06553
2026 1 12 61052 0.0963 0.3132 0.06344 2026 1 5 61045 0.1036 0.3054 0.06573
2026 1 13 61053 0.0951 0.3139 0.06364 2026 1 6 61046 0.1023 0.3060 0.06569
2026 1 14 61054 0.0940 0.3147 0.06401 2026 1 7 61047 0.1010 0.3066 0.06545
2026 1 15 61055 0.0928 0.3154 0.06454 2026 1 8 61048 0.0998 0.3072 0.06509
2026 1 16 61056 0.0917 0.3162 0.06517 2026 1 9 61049 0.0985 0.3079 0.06472
2026 1 17 61057 0.0906 0.3170 0.06582 2026 1 10 61050 0.0973 0.3086 0.06441
2026 1 18 61058 0.0895 0.3178 0.06640 2026 1 11 61051 0.0960 0.3093 0.06423
2026 1 19 61059 0.0884 0.3186 0.06684 2026 1 12 61052 0.0948 0.3100 0.06423
2026 1 20 61060 0.0874 0.3195 0.06707 2026 1 13 61053 0.0936 0.3107 0.06442
2026 1 21 61061 0.0863 0.3203 0.06706 2026 1 14 61054 0.0924 0.3115 0.06480
2026 1 22 61062 0.0853 0.3212 0.06680 2026 1 15 61055 0.0912 0.3122 0.06532
2026 1 23 61063 0.0843 0.3221 0.06636 2026 1 16 61056 0.0901 0.3130 0.06595
2026 1 24 61064 0.0833 0.3230 0.06582 2026 1 17 61057 0.0889 0.3138 0.06660
2026 1 25 61065 0.0823 0.3239 0.06531 2026 1 18 61058 0.0878 0.3146 0.06719
2026 1 26 61066 0.0814 0.3249 0.06494 2026 1 19 61059 0.0867 0.3155 0.06763
2026 1 27 61067 0.0804 0.3259 0.06479 2026 1 20 61060 0.0856 0.3164 0.06787
2026 1 28 61068 0.0795 0.3268 0.06489 2026 1 21 61061 0.0846 0.3172 0.06785
2026 1 29 61069 0.0786 0.3278 0.06520 2026 1 22 61062 0.0835 0.3181 0.06761
2026 1 30 61070 0.0778 0.3288 0.06562 2026 1 23 61063 0.0825 0.3191 0.06717
2026 1 31 61071 0.0769 0.3298 0.06599 2026 1 24 61064 0.0815 0.3200 0.06664
2026 2 1 61072 0.0761 0.3309 0.06620 2026 1 25 61065 0.0805 0.3209 0.06615
2026 2 2 61073 0.0753 0.3319 0.06617 2026 1 26 61066 0.0795 0.3219 0.06579
2026 2 3 61074 0.0745 0.3330 0.06589 2026 1 27 61067 0.0786 0.3229 0.06566
2026 2 4 61075 0.0737 0.3341 0.06543 2026 1 28 61068 0.0776 0.3239 0.06578
2026 2 5 61076 0.0730 0.3351 0.06490 2026 1 29 61069 0.0767 0.3249 0.06612
2026 2 6 61077 0.0723 0.3362 0.06439 2026 1 30 61070 0.0758 0.3259 0.06656
2026 2 7 61078 0.0716 0.3373 0.06401 2026 1 31 61071 0.0749 0.3270 0.06697
2026 2 8 61079 0.0709 0.3385 0.06379 2026 2 1 61072 0.0741 0.3280 0.06723
2026 2 9 61080 0.0703 0.3396 0.06378 2026 2 2 61073 0.0733 0.3291 0.06725
2026 2 10 61081 0.0696 0.3407 0.06396 2026 2 3 61074 0.0725 0.3302 0.06704
2026 2 11 61082 0.0690 0.3419 0.06432 2026 2 4 61075 0.0717 0.3313 0.06666
2026 2 12 61083 0.0685 0.3431 0.06481 2026 2 5 61076 0.0709 0.3324 0.06622
2026 2 13 61084 0.0679 0.3442 0.06537 2026 2 6 61077 0.0702 0.3335 0.06583
2026 2 14 61085 0.0674 0.3454 0.06590 2026 2 7 61078 0.0695 0.3346 0.06557
2026 2 15 61086 0.0669 0.3466 0.06634 2026 2 8 61079 0.0688 0.3358 0.06552
2026 2 16 61087 0.0664 0.3478 0.06660 2026 2 9 61080 0.0681 0.3369 0.06570
2026 2 17 61088 0.0659 0.3490 0.06664 2026 2 10 61081 0.0675 0.3381 0.06610
2026 2 18 61089 0.0655 0.3503 0.06646 2026 2 11 61082 0.0668 0.3393 0.06671
2026 2 19 61090 0.0651 0.3515 0.06608 2026 2 12 61083 0.0662 0.3405 0.06747
2026 2 20 61091 0.0647 0.3527 0.06560 2026 2 13 61084 0.0657 0.3417 0.06829
2026 2 21 61092 0.0643 0.3540 0.06514 2026 2 14 61085 0.0651 0.3429 0.06910
2026 2 22 61093 0.0640 0.3552 0.06482 2026 2 15 61086 0.0646 0.3441 0.06977
2026 2 23 61094 0.0637 0.3564 0.06470 2026 2 16 61087 0.0641 0.3453 0.07023
2026 2 24 61095 0.0634 0.3577 0.06483 2026 2 17 61088 0.0636 0.3466 0.07040
2026 2 25 61096 0.0632 0.3590 0.06515 2026 2 18 61089 0.0632 0.3478 0.07026
2026 2 26 61097 0.0629 0.3602 0.06557 2026 2 19 61090 0.0627 0.3491 0.06986
2026 2 27 61098 0.0627 0.3615 0.06596 2026 2 20 61091 0.0623 0.3503 0.06930
2026 2 28 61099 0.0625 0.3628 0.06620 2026 2 21 61092 0.0620 0.3516 0.06869
2026 3 1 61100 0.0624 0.3641 0.06619 2026 2 22 61093 0.0616 0.3529 0.06818
2026 3 2 61101 0.0623 0.3654 0.06591 2026 2 23 61094 0.0613 0.3541 0.06787
2026 3 3 61102 0.0622 0.3666 0.06538 2026 2 24 61095 0.0610 0.3554 0.06779
2026 3 4 61103 0.0621 0.3679 0.06470 2026 2 25 61096 0.0607 0.3567 0.06793
2026 3 5 61104 0.0620 0.3692 0.06398 2026 2 26 61097 0.0605 0.3580 0.06818
2026 3 6 61105 0.0620 0.3705 0.06332 2026 2 27 61098 0.0602 0.3593 0.06844
2026 3 7 61106 0.0620 0.3718 0.06280 2026 2 28 61099 0.0600 0.3606 0.06858
2026 3 8 61107 0.0620 0.3731 0.06247 2026 3 1 61100 0.0599 0.3619 0.06850
2026 3 9 61108 0.0621 0.3744 0.06235 2026 3 2 61101 0.0597 0.3632 0.06818
2026 3 10 61109 0.0621 0.3757 0.06241 2026 3 3 61102 0.0596 0.3646 0.06765
2026 3 11 61110 0.0622 0.3770 0.06263 2026 3 4 61103 0.0595 0.3659 0.06699
2026 3 12 61111 0.0624 0.3783 0.06293 2026 3 5 61104 0.0595 0.3672 0.06631
2026 3 13 61112 0.0625 0.3796 0.06322 2026 3 6 61105 0.0594 0.3685 0.06572
2026 3 14 61113 0.0627 0.3809 0.06341 2026 3 7 61106 0.0594 0.3698 0.06529
2026 3 15 61114 0.0629 0.3821 0.06342 2026 3 8 61107 0.0594 0.3712 0.06505
2026 3 16 61115 0.0631 0.3834 0.06320 2026 3 9 61108 0.0595 0.3725 0.06500
2026 3 17 61116 0.0634 0.3847 0.06271 2026 3 10 61109 0.0595 0.3738 0.06511
2026 3 18 61117 0.0637 0.3860 0.06199 2026 3 11 61110 0.0596 0.3751 0.06533
2026 3 19 61118 0.0640 0.3873 0.06113 2026 3 12 61111 0.0597 0.3765 0.06562
2026 3 20 61119 0.0643 0.3885 0.06024 2026 3 13 61112 0.0599 0.3778 0.06589
2026 3 21 61120 0.0647 0.3898 0.05943 2026 3 14 61113 0.0600 0.3791 0.06606
2026 3 22 61121 0.0651 0.3911 0.05880 2026 3 15 61114 0.0602 0.3804 0.06604
2026 3 23 61122 0.0655 0.3923 0.05842 2026 3 16 61115 0.0604 0.3818 0.06576
2026 3 24 61123 0.0659 0.3936 0.05830 2026 3 17 61116 0.0607 0.3831 0.06516
2026 3 25 61124 0.0664 0.3948 0.05832 2026 3 18 61117 0.0610 0.3844 0.06423
2026 3 26 61125 0.0668 0.3961 0.05841 2026 3 19 61118 0.0613 0.3857 0.06304
2026 3 27 61126 0.0673 0.3973 0.05840 2026 3 20 61119 0.0616 0.3870 0.06180
2026 3 28 61127 0.0679 0.3985 0.05821 2026 3 21 61120 0.0619 0.3883 0.06065
2026 3 29 61128 0.0684 0.3997 0.05777 2026 3 22 61121 0.0623 0.3896 0.05966
2026 3 30 61129 0.0690 0.4010 0.05709 2026 3 23 61122 0.0627 0.3909 0.05895
2026 3 31 61130 0.0696 0.4022 0.05624 2026 3 24 61123 0.0631 0.3922 0.05844
2026 4 1 61131 0.0702 0.4034 0.05523 2026 3 25 61124 0.0636 0.3934 0.05812
2026 4 2 61132 0.0709 0.4045 0.05420 2026 3 26 61125 0.0640 0.3947 0.05791
2026 4 3 61133 0.0715 0.4057 0.05330 2026 3 27 61126 0.0645 0.3960 0.05759
2026 4 4 61134 0.0722 0.4069 0.05257 2026 3 28 61127 0.0651 0.3972 0.05717
2026 4 5 61135 0.0729 0.4080 0.05202 2026 3 29 61128 0.0656 0.3985 0.05646
2026 4 6 61136 0.0737 0.4092 0.05164 2026 3 30 61129 0.0662 0.3997 0.05548
2026 4 7 61137 0.0744 0.4103 0.05137 2026 3 31 61130 0.0668 0.4010 0.05432
2026 4 8 61138 0.0752 0.4114 0.05123 2026 4 1 61131 0.0674 0.4022 0.05306
2026 4 9 61139 0.0760 0.4125 0.05118 2026 4 2 61132 0.0680 0.4034 0.05187
2026 4 10 61140 0.0768 0.4136 0.05105 2026 4 3 61133 0.0687 0.4046 0.05076
2026 4 11 61141 0.0777 0.4147 0.05087 2026 4 4 61134 0.0694 0.4058 0.04986
2026 4 12 61142 0.0786 0.4158 0.05044 2026 4 5 61135 0.0701 0.4070 0.04920
2026 4 13 61143 0.0794 0.4169 0.04970 2026 4 6 61136 0.0708 0.4082 0.04872
2026 4 14 61144 0.0803 0.4179 0.04867 2026 4 7 61137 0.0716 0.4093 0.04838
2026 4 15 61145 0.0813 0.4189 0.04739 2026 4 8 61138 0.0724 0.4105 0.04815
2026 4 16 61146 0.0822 0.4200 0.04601 2026 4 9 61139 0.0732 0.4116 0.04795
2026 4 17 61147 0.0832 0.4210 0.04462 2026 4 10 61140 0.0740 0.4128 0.04768
2026 4 18 61148 0.0842 0.4219 0.04343 2026 4 11 61141 0.0748 0.4139 0.04735
2026 4 19 61149 0.0852 0.4229 0.04254 2026 4 12 61142 0.0757 0.4150 0.04689
2026 4 20 61150 0.0862 0.4239 0.04195 2026 4 13 61143 0.0766 0.4161 0.04620
2026 4 21 61151 0.0872 0.4248 0.04156 2026 4 14 61144 0.0775 0.4172 0.04531
2026 4 22 61152 0.0883 0.4258 0.04129 2026 4 15 61145 0.0784 0.4182 0.04419
2026 4 23 61153 0.0894 0.4267 0.04098 2026 4 16 61146 0.0794 0.4193 0.04299
2026 4 24 61154 0.0905 0.4276 0.04050 2026 4 17 61147 0.0803 0.4203 0.04183
2026 4 25 61155 0.0916 0.4284 0.03988 2026 4 18 61148 0.0813 0.4213 0.04095
2026 4 26 61156 0.0927 0.4293 0.03914 2026 4 19 61149 0.0823 0.4223 0.04036
2026 4 27 61157 0.0939 0.4302 0.03829 2026 4 20 61150 0.0833 0.4233 0.04007
2026 4 28 61158 0.0950 0.4310 0.03744 2026 4 21 61151 0.0844 0.4243 0.04013
2026 4 29 61159 0.0962 0.4318 0.03659 2026 4 22 61152 0.0854 0.4253 0.04026
2026 4 30 61160 0.0974 0.4326 0.03591 2026 4 23 61153 0.0865 0.4262 0.04040
2026 5 1 61161 0.0986 0.4334 0.03540 2026 4 24 61154 0.0876 0.4271 0.04039
2026 5 2 61162 0.0998 0.4341 0.03522 2026 4 25 61155 0.0887 0.4280 0.04013
2026 5 3 61163 0.1010 0.4348 0.03525 2026 4 26 61156 0.0899 0.4289 0.03962
2026 5 4 61164 0.1023 0.4356 0.03547 2026 4 27 61157 0.0910 0.4298 0.03894
2026 5 5 61165 0.1035 0.4363 0.03594 2026 4 28 61158 0.0922 0.4307 0.03819
2026 5 6 61166 0.1048 0.4369 0.03644 2026 4 29 61159 0.0933 0.4315 0.03743
2026 5 7 61167 0.1061 0.4376 0.03697 2026 4 30 61160 0.0945 0.4323 0.03681
2026 5 8 61168 0.1074 0.4382 0.03741 2026 5 1 61161 0.0957 0.4331 0.03639
2026 5 9 61169 0.1087 0.4389 0.03765 2026 5 2 61162 0.0970 0.4339 0.03619
2026 5 10 61170 0.1100 0.4395 0.03762 2026 5 3 61163 0.0982 0.4347 0.03616
2026 5 11 61171 0.1114 0.4400 0.03733 2026 5 4 61164 0.0994 0.4354 0.03629
2026 5 12 61172 0.1127 0.4406 0.03682 2026 5 5 61165 0.1007 0.4362 0.03660
2026 5 13 61173 0.1140 0.4411 0.03611 2026 5 6 61166 0.1020 0.4369 0.03691
2026 5 14 61174 0.1154 0.4416 0.03540 2026 5 7 61167 0.1033 0.4376 0.03721
2026 5 15 61175 0.1168 0.4421 0.03481 2026 5 8 61168 0.1046 0.4382 0.03749
2026 5 16 61176 0.1182 0.4426 0.03447 2026 5 9 61169 0.1059 0.4389 0.03763
2026 5 17 61177 0.1195 0.4431 0.03440 2026 5 10 61170 0.1072 0.4395 0.03762
2026 5 18 61178 0.1209 0.4435 0.03458 2026 5 11 61171 0.1086 0.4401 0.03744
2026 5 19 61179 0.1223 0.4439 0.03496 2026 5 12 61172 0.1099 0.4407 0.03706
2026 5 20 61180 0.1237 0.4443 0.03531 2026 5 13 61173 0.1113 0.4413 0.03652
2026 5 21 61181 0.1252 0.4447 0.03553 2026 5 14 61174 0.1126 0.4418 0.03595
2026 5 22 61182 0.1266 0.4450 0.03563 2026 5 15 61175 0.1140 0.4423 0.03555
2026 5 23 61183 0.1280 0.4453 0.03555 2026 5 16 61176 0.1154 0.4428 0.03545
2026 5 24 61184 0.1294 0.4456 0.03538 2026 5 17 61177 0.1168 0.4433 0.03561
2026 5 25 61185 0.1309 0.4459 0.03522 2026 5 18 61178 0.1182 0.4438 0.03605
2026 5 26 61186 0.1323 0.4462 0.03510 2026 5 19 61179 0.1196 0.4442 0.03672
2026 5 27 61187 0.1337 0.4464 0.03509 2026 5 20 61180 0.1210 0.4446 0.03732
2026 5 28 61188 0.1352 0.4466 0.03526 2026 5 21 61181 0.1224 0.4450 0.03779
2026 5 29 61189 0.1366 0.4468 0.03571 2026 5 22 61182 0.1239 0.4454 0.03807
2026 5 30 61190 0.1381 0.4469 0.03643 2026 5 23 61183 0.1253 0.4457 0.03818
2026 5 31 61191 0.1395 0.4471 0.03730 2026 5 24 61184 0.1267 0.4461 0.03811
2026 6 1 61192 0.1410 0.4472 0.03832 2026 5 25 61185 0.1282 0.4464 0.03802
2026 6 2 61193 0.1425 0.4473 0.03948 2026 5 26 61186 0.1296 0.4466 0.03795
2026 6 3 61194 0.1439 0.4474 0.04058 2026 5 27 61187 0.1311 0.4469 0.03798
2026 6 4 61195 0.1454 0.4474 0.04160 2026 5 28 61188 0.1326 0.4471 0.03820
2026 6 5 61196 0.1468 0.4474 0.04249 2026 5 29 61189 0.1340 0.4473 0.03862
2026 6 6 61197 0.1483 0.4475 0.04322 2026 5 30 61190 0.1355 0.4475 0.03926
2026 6 7 61198 0.1497 0.4474 0.04372 2026 5 31 61191 0.1369 0.4477 0.04005
2026 6 8 61199 0.1512 0.4474 0.04404 2026 6 1 61192 0.1384 0.4478 0.04090
2026 6 9 61200 0.1526 0.4473 0.04420 2026 6 2 61193 0.1399 0.4480 0.04191
2026 6 10 61201 0.1541 0.4472 0.04427 2026 6 3 61194 0.1414 0.4481 0.04298
2026 6 11 61202 0.1555 0.4471 0.04441 2026 6 4 61195 0.1428 0.4481 0.04399
2026 6 12 61203 0.1570 0.4470 0.04471 2026 6 5 61196 0.1443 0.4482 0.04491
2026 6 13 61204 0.1584 0.4468 0.04527 2026 6 6 61197 0.1458 0.4482 0.04568
2026 6 14 61205 0.1598 0.4467 0.04607 2026 6 7 61198 0.1472 0.4482 0.04614
2026 6 15 61206 0.1613 0.4465 0.04699 2026 6 8 61199 0.1487 0.4482 0.04638
2026 6 16 61207 0.1627 0.4462 0.04805 2026 6 9 61200 0.1502 0.4481 0.04649
2026 6 17 61208 0.1641 0.4460 0.04907 2026 6 10 61201 0.1516 0.4481 0.04648
2026 6 18 61209 0.1655 0.4457 0.04991 2026 6 11 61202 0.1531 0.4480 0.04649
2026 6 19 61210 0.1669 0.4454 0.05056 2026 6 12 61203 0.1545 0.4479 0.04661
2026 6 20 61211 0.1683 0.4451 0.05105 2026 6 13 61204 0.1560 0.4477 0.04699
2026 6 21 61212 0.1697 0.4448 0.05136 2026 6 14 61205 0.1574 0.4476 0.04756
2026 6 22 61213 0.1711 0.4444 0.05165 2026 6 15 61206 0.1589 0.4474 0.04835
2026 6 23 61214 0.1725 0.4440 0.05210 2026 6 16 61207 0.1603 0.4472 0.04924
2026 6 24 61215 0.1738 0.4436 0.05266 2026 6 17 61208 0.1618 0.4470 0.05017
2026 6 25 61216 0.1752 0.4432 0.05340 2026 6 18 61209 0.1632 0.4467 0.05089
2026 6 26 61217 0.1765 0.4428 0.05430 2026 6 19 61210 0.1646 0.4464 0.05142
2026 6 27 61218 0.1779 0.4423 0.05539 2026 6 20 61211 0.1660 0.4461 0.05178
2026 6 28 61219 0.1792 0.4418 0.05654 2026 6 21 61212 0.1674 0.4458 0.05200
2026 6 29 61220 0.1805 0.4413 0.05779 2026 6 22 61213 0.1688 0.4455 0.05221
2026 6 30 61221 0.1818 0.4408 0.05910 2026 6 23 61214 0.1702 0.4451 0.05260
2026 7 1 61222 0.1831 0.4402 0.06048 2026 6 24 61215 0.1716 0.4447 0.05320
2026 7 2 61223 0.1844 0.4397 0.06171 2026 6 25 61216 0.1730 0.4443 0.05401
2026 7 3 61224 0.1856 0.4391 0.06280 2026 6 26 61217 0.1743 0.4439 0.05511
2026 7 4 61225 0.1869 0.4385 0.06369 2026 6 27 61218 0.1757 0.4434 0.05647
2026 7 5 61226 0.1881 0.4378 0.06434 2026 6 28 61219 0.1770 0.4430 0.05798
2026 7 6 61227 0.1893 0.4372 0.06480 2026 6 29 61220 0.1783 0.4425 0.05967
2026 7 7 61228 0.1905 0.4365 0.06523 2026 6 30 61221 0.1797 0.4420 0.06128
2026 7 8 61229 0.1917 0.4358 0.06572 2026 7 1 61222 0.1810 0.4414 0.06275
2026 7 9 61230 0.1929 0.4351 0.06633 2026 7 2 61223 0.1823 0.4409 0.06403
2026 7 10 61231 0.1941 0.4344 0.06723 2026 7 3 61224 0.1836 0.4403 0.06505
2026 7 11 61232 0.1952 0.4336 0.06843 2026 7 4 61225 0.1848 0.4397 0.06585
2026 7 12 61233 0.1964 0.4329 0.06985 2026 7 5 61226 0.1861 0.4391 0.06645
2026 7 13 61234 0.1975 0.4321 0.07146 2026 7 6 61227 0.1873 0.4384 0.06686
2026 7 14 61235 0.1986 0.4313 0.07292 2026 7 7 61228 0.1886 0.4378 0.06722
2026 7 15 61236 0.1996 0.4304 0.07413 2026 7 8 61229 0.1898 0.4371 0.06760
2026 7 16 61237 0.2007 0.4296 0.07502 2026 7 9 61230 0.1910 0.4364 0.06810
2026 7 17 61238 0.2018 0.4288 0.07557 2026 7 10 61231 0.1921 0.4357 0.06889
2026 7 18 61239 0.2028 0.4279 0.07596 2026 7 11 61232 0.1933 0.4349 0.06992
2026 7 19 61240 0.2038 0.4270 0.07629 2026 7 12 61233 0.1945 0.4342 0.07122
2026 7 20 61241 0.2048 0.4261 0.07668 2026 7 13 61234 0.1956 0.4334 0.07254
2026 7 21 61242 0.2058 0.4252 0.07728 2026 7 14 61235 0.1967 0.4326 0.07391
2026 7 22 61243 0.2067 0.4242 0.07807 2026 7 15 61236 0.1978 0.4318 0.07504
2026 7 23 61244 0.2076 0.4233 0.07908 2026 7 16 61237 0.1989 0.4310 0.07591
2026 7 24 61245 0.2085 0.4223 0.08036 2026 7 17 61238 0.2000 0.4301 0.07652
2026 7 25 61246 0.2094 0.4213 0.08180 2026 7 18 61239 0.2010 0.4293 0.07702
2026 7 26 61247 0.2103 0.4203 0.08338 2026 7 19 61240 0.2021 0.4284 0.07743
2026 7 27 61248 0.2112 0.4193 0.08491 2026 7 20 61241 0.2031 0.4275 0.07799
2026 7 28 61249 0.2120 0.4183 0.08647 2026 7 21 61242 0.2041 0.4266 0.07873
2026 7 29 61250 0.2128 0.4173 0.08786 2026 7 22 61243 0.2050 0.4256 0.07969
2026 7 30 61251 0.2136 0.4162 0.08904 2026 7 23 61244 0.2060 0.4247 0.08084
2026 7 31 61252 0.2143 0.4151 0.08998 2026 7 24 61245 0.2069 0.4237 0.08212
2026 8 1 61253 0.2151 0.4141 0.09076 2026 7 25 61246 0.2078 0.4227 0.08367
2026 8 2 61254 0.2158 0.4130 0.09130 2026 7 26 61247 0.2087 0.4218 0.08531
2026 8 3 61255 0.2165 0.4119 0.09180 2026 7 27 61248 0.2096 0.4207 0.08702
2026 8 4 61256 0.2172 0.4108 0.09232 2026 7 28 61249 0.2105 0.4197 0.08862
2026 8 5 61257 0.2178 0.4096 0.09294 2026 7 29 61250 0.2113 0.4187 0.09004
2026 8 6 61258 0.2184 0.4085 0.09372 2026 7 30 61251 0.2121 0.4176 0.09130
2026 8 7 61259 0.2190 0.4074 0.09466 2026 7 31 61252 0.2129 0.4166 0.09234
2026 8 8 61260 0.2196 0.4062 0.09591 2026 8 1 61253 0.2136 0.4155 0.09321
2026 8 9 61261 0.2202 0.4050 0.09728 2026 8 2 61254 0.2144 0.4144 0.09386
2026 8 10 61262 0.2207 0.4039 0.09868 2026 8 3 61255 0.2151 0.4133 0.09435
2026 8 11 61263 0.2212 0.4027 0.09988 2026 8 4 61256 0.2158 0.4122 0.09493
2026 8 12 61264 0.2217 0.4015 0.10077 2026 8 5 61257 0.2165 0.4111 0.09554
2026 8 13 61265 0.2221 0.4003 0.10141 2026 8 6 61258 0.2171 0.4099 0.09635
2026 8 14 61266 0.2226 0.3991 0.10182 2026 8 7 61259 0.2177 0.4088 0.09737
These predictions are based on all announced leap seconds. 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)
60868 -116.99 0.86 -10.78 0.21
60869 -117.02 0.86 -10.71 0.30
60870 -117.16 0.86 -10.75 0.30
60871 -117.35 0.86 -10.82 0.34
60872 -117.56 0.83 -10.83 0.29
60873 -117.79 0.83 -10.77 0.29
60874 -118.05 0.83 -10.70 0.29
60875 -118.31 0.78 -10.66 0.17
60876 -118.49 0.83 -10.70 0.16
60877 -118.55 0.83 -10.81 0.16
60878 -118.54 1.09 -10.92 0.16
60879 -118.54 0.94 -10.97 0.15
60880 -118.53 0.94 -10.93 0.15
60881 -118.44 0.94 -10.81 0.15
IERS Celestial Pole Offset Final Series
MJD dpsi deps
(msec. of arc)
60828 -111.0 -11.3
60829 -111.7 -10.9
60830 -112.1 -10.8
60831 -112.0 -10.8
60832 -111.7 -10.8
60833 -111.7 -10.8
60834 -111.9 -10.9
60835 -112.2 -11.2
60836 -112.5 -11.5
60837 -112.7 -11.7
60838 -112.8 -11.7
60839 -112.7 -11.5
60840 -112.6 -11.3
60841 -112.5 -11.3
60842 -112.4 -11.3
60843 -112.3 -11.3
60844 -112.4 -11.2
60845 -112.6 -11.1
60846 -113.0 -10.9
60847 -113.6 -10.7
60848 -114.2 -10.7
60849 -114.6 -10.9
60850 -114.7 -11.2
60851 -114.6 -11.3
60852 -114.5 -11.4
60853 -114.3 -11.3
60854 -114.0 -11.2
60855 -114.1 -11.0
60856 -114.6 -10.6
60857 -115.3 -10.4
IAU2000A Celestial Pole Offset Series
MJD dX error dY error
(msec. of arc)
60868 0.366 0.342 -0.270 0.206
60869 0.360 0.343 -0.284 0.298
60870 0.356 0.343 -0.292 0.298
60871 0.352 0.343 -0.292 0.342
60872 0.347 0.330 -0.282 0.288
60873 0.343 0.330 -0.265 0.288
60874 0.341 0.330 -0.243 0.288
60875 0.342 0.308 -0.222 0.166
60876 0.347 0.331 -0.202 0.164
60877 0.352 0.331 -0.183 0.164
60878 0.357 0.433 -0.166 0.157
60879 0.359 0.375 -0.150 0.149
60880 0.359 0.375 -0.135 0.149
60881 0.358 0.375 -0.120 0.149
IAU2000A Celestial Pole Offset Final Series
MJD dX dY
(msec. of arc)
60828 0.30 -0.23
60829 0.28 -0.26
60830 0.28 -0.28
60831 0.35 -0.27
60832 0.43 -0.24
60833 0.45 -0.20
60834 0.43 -0.18
60835 0.39 -0.16
60836 0.34 -0.15
60837 0.34 -0.19
60838 0.35 -0.25
60839 0.37 -0.30
60840 0.41 -0.34
60841 0.45 -0.35
60842 0.50 -0.35
60843 0.53 -0.34
60844 0.52 -0.32
60845 0.49 -0.29
60846 0.45 -0.27
60847 0.42 -0.25
60848 0.41 -0.25
60849 0.40 -0.26
60850 0.39 -0.27
60851 0.39 -0.29
60852 0.39 -0.32
60853 0.39 -0.33
60854 0.38 -0.28
60855 0.36 -0.19
60856 0.35 -0.10
60857 0.34 -0.03
)--"; )--";
} // namespace mcc::ccte::iers::defaults } // namespace mcc::ccte::iers::defaults

View File

@ -18,47 +18,23 @@ namespace mcc
typedef std::chrono::system_clock::time_point MccTimePoint; typedef std::chrono::system_clock::time_point MccTimePoint;
template <traits::mcc_time_duration_c DT>
static constexpr DT mcc_infinite_duration_v =
std::floating_point<typename DT::rep> ? DT{std::numeric_limits<typename DT::rep>::infinity()}
: DT{std::numeric_limits<typename DT::rep>::max()};
/* DEFAULT JULIAN DAY CLASS */ /* DEFAULT JULIAN DAY CLASS */
struct MccJulianDay { struct MccJulianDay {
static constexpr double MJD0 = 2400000.5; static constexpr double MJD0 = 2400000.5;
double mjd{51544.5}; // J2000.0
MccJulianDay() = default;
MccJulianDay(double jd) : mjd(jd - MJD0) {}
constexpr operator double() const constexpr operator double() const
{ {
return MccJulianDay::MJD0 + mjd; return MccJulianDay::MJD0 + mjd;
} }
MccJulianDay& operator=(double jd)
{
mjd = jd - MJD0;
return *this;
}
double MJD() const
{
return mjd;
}
constexpr auto operator<=>(const MccJulianDay&) const = default; constexpr auto operator<=>(const MccJulianDay&) const = default;
constexpr auto operator<=>(double v) const constexpr auto operator<=>(double v) const
{ {
return v <=> (MccJulianDay::MJD0 + mjd); return v <=> (MccJulianDay::MJD0 + mjd);
}; };
protected:
double mjd{51544.5}; // J2000.0
}; };
@ -85,8 +61,6 @@ template <mcc_angle_c CoordT>
struct MccGenericEqtHrzCoords : MccGenericCelestialPoint<CoordT> { struct MccGenericEqtHrzCoords : MccGenericCelestialPoint<CoordT> {
using typename MccGenericCelestialPoint<CoordT>::coord_t; using typename MccGenericCelestialPoint<CoordT>::coord_t;
using MccGenericCelestialPoint<CoordT>::time_point;
coord_t RA_APP{}, DEC_APP{}, HA{}, AZ{}, ZD{}, ALT{}; coord_t RA_APP{}, DEC_APP{}, HA{}, AZ{}, ZD{}, ALT{};
}; };

View File

@ -21,46 +21,6 @@ namespace mcc
// mount construction type (only the most common ones) // mount construction type (only the most common ones)
enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTAZ_TYPE }; enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTAZ_TYPE };
template <MccMountType TYPE>
static constexpr std::string_view MccMountTypeStr = TYPE == MccMountType::GERMAN_TYPE ? "GERMAN"
: TYPE == MccMountType::FORK_TYPE ? "FORK"
: TYPE == MccMountType::CROSSAXIS_TYPE ? "CROSSAXIS"
: TYPE == MccMountType::ALTAZ_TYPE ? "ALTAZ"
: "UNKNOWN";
template <MccMountType TYPE>
static constexpr bool mcc_is_equatorial_mount = TYPE == MccMountType::GERMAN_TYPE ? true
: TYPE == MccMountType::FORK_TYPE ? true
: TYPE == MccMountType::CROSSAXIS_TYPE ? true
: TYPE == MccMountType::ALTAZ_TYPE ? false
: false;
template <MccMountType TYPE>
static constexpr bool mcc_is_altaz_mount = TYPE == MccMountType::GERMAN_TYPE ? false
: TYPE == MccMountType::FORK_TYPE ? false
: TYPE == MccMountType::CROSSAXIS_TYPE ? false
: TYPE == MccMountType::ALTAZ_TYPE ? true
: false;
static consteval bool mccIsEquatorialMount(const MccMountType type)
{
return type == MccMountType::GERMAN_TYPE ? true
: type == MccMountType::FORK_TYPE ? true
: type == MccMountType::CROSSAXIS_TYPE ? true
: type == MccMountType::ALTAZ_TYPE ? false
: false;
};
static consteval bool mccIsAltAzMount(const MccMountType type)
{
return type == MccMountType::GERMAN_TYPE ? false
: type == MccMountType::FORK_TYPE ? false
: type == MccMountType::CROSSAXIS_TYPE ? false
: type == MccMountType::ALTAZ_TYPE ? true
: false;
};
// enum MccCoordPairKind : size_t { // enum MccCoordPairKind : size_t {
// COORDS_KIND_GENERIC, // COORDS_KIND_GENERIC,
// COORDS_KIND_RADEC_ICRS, // COORDS_KIND_RADEC_ICRS,
@ -85,19 +45,11 @@ concept mcc_fp_type_like_c =
template <typename T> template <typename T>
concept mcc_angle_c = mcc_fp_type_like_c<T> && requires(T v, double vd) { concept mcc_angle_c = mcc_fp_type_like_c<T> && requires(T v, double vd) {
// mandatory arithmetic operations
{ v + v } -> std::same_as<T>; { v + v } -> std::same_as<T>;
{ v - v } -> std::same_as<T>; { v - v } -> std::same_as<T>;
{ v += v } -> std::same_as<T&>; { v += v } -> std::same_as<T&>;
{ v -= v } -> std::same_as<T&>; { v -= v } -> std::same_as<T&>;
{ vd + v } -> std::same_as<T>;
{ vd - v } -> std::same_as<T>;
{ v + vd } -> std::same_as<T>;
{ v - vd } -> std::same_as<T>;
{ v += vd } -> std::same_as<T&>;
{ v -= vd } -> std::same_as<T&>;
{ v * vd } -> std::same_as<T>; { v * vd } -> std::same_as<T>;
{ v / vd } -> std::same_as<T>; { v / vd } -> std::same_as<T>;
}; };
@ -109,16 +61,13 @@ concept mcc_angle_c = mcc_fp_type_like_c<T> && requires(T v, double vd) {
* USE OF STL std::chrono::time_point * USE OF STL std::chrono::time_point
*/ */
template <typename T> template <typename T>
concept mcc_time_point_c = traits::mcc_systime_c<T>; concept mcc_time_point_c = requires(T t) { []<typename CT, typename DT>(std::chrono::time_point<CT, DT>) {}(t); };
// concept mcc_time_point_c = requires(T t) { []<typename CT, typename DT>(std::chrono::time_point<CT, DT>) {}(t); };
/* JULIAN DAY CLASS CONCEPT */ /* JULIAN DAY CLASS CONCEPT */
template <typename T> template <typename T>
concept mcc_julday_c = mcc_fp_type_like_c<T> && requires(const T v) { concept mcc_julday_c = mcc_fp_type_like_c<T> && requires(const T v) {
// modified Julian Day
{ v.MJD() } -> std::convertible_to<double>;
// comparison operators // comparison operators
v <=> v; v <=> v;
}; };
@ -132,18 +81,6 @@ concept mcc_error_c = std::convertible_to<T, bool> || requires(const T t) {
}; };
template <mcc_error_c ErrT, typename DErrT>
static constexpr ErrT mcc_deduce_error(const DErrT& err, const ErrT& default_err)
{
if constexpr (std::same_as<ErrT, DErrT>) {
return err;
} else {
return default_err;
}
}
/* ATMOSPHERIC REFRACTION MODEL CLASS CONCEPT */ /* ATMOSPHERIC REFRACTION MODEL CLASS CONCEPT */
template <typename T> template <typename T>
@ -165,29 +102,6 @@ concept mcc_celestial_point_c = requires(T t) {
}; };
static constexpr void mcc_copy_celestial_point(mcc_celestial_point_c auto const& from_pt,
mcc_celestial_point_c auto* to_pt)
{
if (to_pt == nullptr) {
return;
}
using from_pt_t = std::remove_cvref_t<decltype(from_pt)>;
using to_pt_t = std::remove_cvref_t<decltype(*to_pt)>;
if constexpr (std::derived_from<to_pt_t, from_pt_t> && std::copyable<to_pt_t>) {
*to_pt = from_pt;
return;
}
to_pt->pair_kind = from_pt.pair_kind;
to_pt->time_point =
std::chrono::time_point_cast<typename decltype(to_pt->time_point)::duration>(from_pt.time_point);
to_pt->X = (double)from_pt.X;
to_pt->Y = (double)from_pt.Y;
}
/* CELESTIAL POINT WITH APPARENT EQUATORIAL AND HORIZONTAL CLASS CONCEPT */ /* CELESTIAL POINT WITH APPARENT EQUATORIAL AND HORIZONTAL CLASS CONCEPT */
template <typename T> template <typename T>
@ -195,42 +109,12 @@ concept mcc_eqt_hrz_coord_c = mcc_celestial_point_c<T> && requires(T t) {
requires mcc_angle_c<decltype(t.RA_APP)>; // right ascension requires mcc_angle_c<decltype(t.RA_APP)>; // right ascension
requires mcc_angle_c<decltype(t.DEC_APP)>; // declination requires mcc_angle_c<decltype(t.DEC_APP)>; // declination
requires mcc_angle_c<decltype(t.HA)>; // hour angle requires mcc_angle_c<decltype(t.HA)>; // hour angle
requires mcc_angle_c<decltype(t.AZ)>; // azimuth (NOTE: ASSUMING THE AZINUTH IS COUNTED FROM THE SOUTH THROUGH THE requires mcc_angle_c<decltype(t.AZ)>; // azimuth
// WEST!!!) requires mcc_angle_c<decltype(t.ZD)>; // zenithal distance
requires mcc_angle_c<decltype(t.ZD)>; // zenithal distance requires mcc_angle_c<decltype(t.ALT)>; // altitude
requires mcc_angle_c<decltype(t.ALT)>; // altitude
}; };
static constexpr void mcc_copy_eqt_hrz_coord(mcc_eqt_hrz_coord_c auto const& from_pt, mcc_eqt_hrz_coord_c auto* to_pt)
{
if (to_pt == nullptr) {
return;
}
using from_pt_t = std::remove_cvref_t<decltype(from_pt)>;
using to_pt_t = std::remove_cvref_t<decltype(*to_pt)>;
if constexpr (std::derived_from<to_pt_t, from_pt_t> && std::copyable<to_pt_t>) {
*to_pt = from_pt;
return;
}
to_pt->pair_kind = from_pt.pair_kind;
to_pt->time_point =
std::chrono::time_point_cast<typename decltype(to_pt->time_point)::duration>(from_pt.time_point);
to_pt->X = (double)from_pt.X;
to_pt->Y = (double)from_pt.Y;
to_pt->RA_APP = (double)from_pt.RA_APP;
to_pt->DEC_APP = (double)from_pt.DEC_APP;
to_pt->HA = (double)from_pt.HA;
to_pt->AZ = (double)from_pt.AZ;
to_pt->ZD = (double)from_pt.ZD;
to_pt->ALT = (double)from_pt.ALT;
}
/* CELESTIAL COORDINATES TRANSFORMATION ENGINE */ /* CELESTIAL COORDINATES TRANSFORMATION ENGINE */
@ -252,20 +136,12 @@ struct mcc_CCTE_interface_t {
return std::forward<SelfT>(self).timepointToAppSideral(std::move(tp), st, islocal); return std::forward<SelfT>(self).timepointToAppSideral(std::move(tp), st, islocal);
} }
template <std::derived_from<mcc_CCTE_interface_t> SelfT>
RetT juldayToAppSideral(this SelfT&& self, mcc_julday_c auto jd, mcc_angle_c auto* st, bool islocal = false)
{
return std::forward<SelfT>(self).timepointToAppSideral(std::move(jd), st, islocal);
}
// NOTE: ASSUMING THE AZINUTH IS COUNTED FROM THE SOUTH THROUGH THE WEST!!!
template <std::derived_from<mcc_CCTE_interface_t> SelfT> template <std::derived_from<mcc_CCTE_interface_t> SelfT>
RetT transformCoordinates(this SelfT&& self, mcc_celestial_point_c auto from_pt, mcc_celestial_point_c auto* to_pt) RetT transformCoordinates(this SelfT&& self, mcc_celestial_point_c auto from_pt, mcc_celestial_point_c auto* to_pt)
{ {
return std::forward<SelfT>(self).transformCoordinates(std::move(from_pt), to_pt); return std::forward<SelfT>(self).transformCoordinates(std::move(from_pt), to_pt);
} }
// NOTE: ASSUMING THE AZIMUTH IS COUNTED FROM THE SOUTH THROUGH THE WEST!!!
template <std::derived_from<mcc_CCTE_interface_t> SelfT> template <std::derived_from<mcc_CCTE_interface_t> SelfT>
RetT transformCoordinates(this SelfT&& self, mcc_celestial_point_c auto from_pt, mcc_eqt_hrz_coord_c auto* to_pt) RetT transformCoordinates(this SelfT&& self, mcc_celestial_point_c auto from_pt, mcc_eqt_hrz_coord_c auto* to_pt)
{ {
@ -308,44 +184,8 @@ concept mcc_pointing_target_coord_c = mcc_eqt_hrz_coord_c<T> && requires(T t) {
requires mcc_angle_c<decltype(t.DEC_ICRS)>; // ICRS declination requires mcc_angle_c<decltype(t.DEC_ICRS)>; // ICRS declination
}; };
static constexpr void mcc_copy_pointing_target_coord(mcc_pointing_target_coord_c auto const& from_pt,
mcc_pointing_target_coord_c auto* to_pt)
{
if (to_pt == nullptr) {
return;
}
using from_pt_t = std::remove_cvref_t<decltype(from_pt)>;
using to_pt_t = std::remove_cvref_t<decltype(*to_pt)>;
if constexpr (std::derived_from<to_pt_t, from_pt_t> && std::copyable<to_pt_t>) {
*to_pt = from_pt;
return;
}
to_pt->pair_kind = from_pt.pair_kind;
to_pt->time_point =
std::chrono::time_point_cast<typename decltype(to_pt->time_point)::duration>(from_pt.time_point);
to_pt->X = (double)from_pt.X;
to_pt->Y = (double)from_pt.Y;
to_pt->RA_ICRS = (double)from_pt.RA_ICRS;
to_pt->DEC_ICRS = (double)from_pt.DEC_ICRS;
to_pt->RA_APP = (double)from_pt.RA_APP;
to_pt->DEC_APP = (double)from_pt.DEC_APP;
to_pt->HA = (double)from_pt.HA;
to_pt->AZ = (double)from_pt.AZ;
to_pt->ZD = (double)from_pt.ZD;
to_pt->ALT = (double)from_pt.ALT;
}
template <typename T> template <typename T>
concept mcc_telemetry_data_c = mcc_eqt_hrz_coord_c<T> && std::default_initializable<T> && requires(T t) { concept mcc_telemetry_data_c = mcc_eqt_hrz_coord_c<T> && requires(T t) {
// target target coordinates // target target coordinates
requires mcc_pointing_target_coord_c<decltype(t.target)>; requires mcc_pointing_target_coord_c<decltype(t.target)>;
@ -363,47 +203,6 @@ concept mcc_telemetry_data_c = mcc_eqt_hrz_coord_c<T> && std::default_initializa
}; };
static constexpr void mcc_copy_telemetry_data(mcc_telemetry_data_c auto const& from_pt,
mcc_telemetry_data_c auto* to_pt)
{
if (to_pt == nullptr) {
return;
}
using from_pt_t = std::remove_cvref_t<decltype(from_pt)>;
using to_pt_t = std::remove_cvref_t<decltype(*to_pt)>;
if constexpr (std::derived_from<to_pt_t, from_pt_t> && std::copyable<to_pt_t>) {
*to_pt = from_pt;
return;
}
to_pt->pair_kind = from_pt.pair_kind;
to_pt->time_point =
std::chrono::time_point_cast<typename decltype(to_pt->time_point)::duration>(from_pt.time_point);
to_pt->X = (double)from_pt.X;
to_pt->Y = (double)from_pt.Y;
to_pt->speedX = (double)from_pt.speedX;
to_pt->speedY = (double)from_pt.speedY;
to_pt->RA_APP = (double)from_pt.RA_APP;
to_pt->DEC_APP = (double)from_pt.DEC_APP;
to_pt->HA = (double)from_pt.HA;
to_pt->AZ = (double)from_pt.AZ;
to_pt->ZD = (double)from_pt.ZD;
to_pt->ALT = (double)from_pt.ALT;
to_pt->pcmX = (double)from_pt.pcmX;
to_pt->pcmY = (double)from_pt.pcmY;
to_pt->refCorr = (double)from_pt.refCorr;
mcc_copy_pointing_target_coord(from_pt.target, &to_pt->target);
}
/* MOUNT TELEMETRY MANAGER CLASS CONCEPT */ /* MOUNT TELEMETRY MANAGER CLASS CONCEPT */
@ -472,7 +271,7 @@ concept mcc_hardware_c = requires(T t, const T t_const) {
// a class that contains at least time point of measurement, coordinates for x,y axes and its moving rates // a class that contains at least time point of measurement, coordinates for x,y axes and its moving rates
requires requires(typename T::axes_pos_t pos) { requires requires(typename T::axes_pos_t pos) {
requires mcc_time_point_c<decltype(pos.time_point)>; // time point requires mcc_time_point_c<typename T::time_point_t>; // time point
requires mcc_angle_c<decltype(pos.X)>; // target or current co-longitude coordinate requires mcc_angle_c<decltype(pos.X)>; // target or current co-longitude coordinate
requires mcc_angle_c<decltype(pos.Y)>; // target or current co-latitude coordinate requires mcc_angle_c<decltype(pos.Y)>; // target or current co-latitude coordinate
@ -527,10 +326,6 @@ struct mcc_pzone_interface_t {
return std::forward<SelfT>(self).timeFromPZone(std::move(coords), res_time); return std::forward<SelfT>(self).timeFromPZone(std::move(coords), res_time);
} }
//
// NOTE: the method must return:
// point = mcc_celestial_point_c{.pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC, .X = NaN, .Y = NaN}
// if there is no intersection with the zone for given coordinates!
template <std::derived_from<mcc_pzone_interface_t> SelfT, typename InputT> template <std::derived_from<mcc_pzone_interface_t> SelfT, typename InputT>
RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point) RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) && requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
@ -581,10 +376,10 @@ struct mcc_pzone_container_interface_t {
template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT> template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT>
RetT inPZone(this SelfT&& self, InputT coords, bool* common_result, std::ranges::output_range<bool> auto* result) RetT inPZone(this SelfT&& self, InputT coords, std::ranges::output_range<bool> auto* result)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{ {
return std::forward<SelfT>(self).InPZone(std::move(coords), common_result, result); return std::forward<SelfT>(self).InPZone(std::move(coords), result);
} }
@ -602,14 +397,6 @@ struct mcc_pzone_container_interface_t {
return std::forward<SelfT>(self).timeFromPZone(std::move(coords), res_time); return std::forward<SelfT>(self).timeFromPZone(std::move(coords), res_time);
} }
template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT, mcc_celestial_point_c CPT>
RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range<CPT> auto* result)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{
return std::forward<SelfT>(self).intersectPZone(std::move(coords), result);
}
protected: protected:
mcc_pzone_container_interface_t() = default; mcc_pzone_container_interface_t() = default;
}; };

View File

@ -5,7 +5,6 @@
/* IMPLEMENTATION OF SOME SIMPLE PROHIBITED ZONES */ /* IMPLEMENTATION OF SOME SIMPLE PROHIBITED ZONES */
#include "mcc_defaults.h"
#include "mcc_generics.h" #include "mcc_generics.h"
namespace mcc namespace mcc
@ -14,106 +13,33 @@ namespace mcc
static constexpr double mcc_sideral_to_UT1_ratio = 1.002737909350795; // sideral/UT1 static constexpr double mcc_sideral_to_UT1_ratio = 1.002737909350795; // sideral/UT1
enum MccAltLimitPZErrorCode : int { ERROR_OK, ERROR_COORD_TRANSFROM };
} // namespace mcc
namespace std
{
template <>
class is_error_code_enum<mcc::MccAltLimitPZErrorCode> : public true_type
{
};
} // namespace std
namespace mcc
{
/* MINIMAL OR MAXIMAL ALTITUDE PROHIBITED ZONES */ /* MINIMAL OR MAXIMAL ALTITUDE PROHIBITED ZONES */
/* error category definition */
// error category
struct MccAltLimitPZCategory : public std::error_category {
MccAltLimitPZCategory() : std::error_category() {}
const char* name() const noexcept
{
return "ALTITUDE-LIMIT-PZ";
}
std::string message(int ec) const
{
MccAltLimitPZErrorCode err = static_cast<MccAltLimitPZErrorCode>(ec);
switch (err) {
case MccAltLimitPZErrorCode::ERROR_OK:
return "OK";
case MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM:
return "coordinate transformation error";
default:
return "UNKNOWN";
}
}
static const MccAltLimitPZCategory& get()
{
static const MccAltLimitPZCategory constInst;
return constInst;
}
};
inline std::error_code make_error_code(MccAltLimitPZErrorCode ec)
{
return std::error_code(static_cast<int>(ec), MccAltLimitPZCategory::get());
}
enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT }; enum class MccAltLimitKind { MIN_ALT_LIMIT, MAX_ALT_LIMIT };
template <MccAltLimitKind KIND = MccAltLimitKind::MIN_ALT_LIMIT> template <mcc_ccte_c CCTE_T, MccAltLimitKind KIND = MccAltLimitKind::MIN_ALT_LIMIT>
class MccAltLimitPZ : public mcc_pzone_interface_t<std::error_code> class MccAltLimitPZ : public mcc_pzone_interface_t<std::error_code>
{ {
protected: protected:
static constexpr auto pi2 = std::numbers::pi * 2.0; double _altLimit, _cosALim, _sinAlim;
double _cosLat, _sinLat, _absLat;
CCTE_T* _ccteEngine;
public: public:
typedef std::error_code error_t; typedef std::error_code error_t;
MccAltLimitPZ(mcc_angle_c auto const& alt_limit, mcc_angle_c auto const& latitude, mcc_ccte_c auto* ccte_engine) MccAltLimitPZ(mcc_angle_c auto const& alt_limit, mcc_angle_c auto const& latitude, CCTE_T* ccte_engine)
: _altLimit(MccAngle(alt_limit).normalize<MccAngle::NORM_KIND_90_90>()), : _altLimit(alt_limit),
_cosALim(cos(_altLimit)), _cosALim(cos(_altLimit)),
_sinAlim(sin(_altLimit)), _sinAlim(sin(_altLimit)),
_cosLat(cos(latitude)), _cosLat(cos(latitude)),
_sinLat(sin(latitude)), _sinLat(sin(latitude)),
_absLat(abs(latitude)), _absLat(abs(latitude)),
_latLim(MccAltLimitPZ::pi2 - _altLimit) _ccteEngine(ccte_engine)
{ {
_transformCoordinates = [ccte_engine](MccCelestialPoint from_pt, MccCelestialPoint* to_pt) -> error_t {
auto err = ccte_engine->transformCoordinates(from_pt, to_pt);
if (!err) {
return MccAltLimitPZErrorCode::ERROR_OK;
}
if (std::same_as<decltype(err), error_t>) {
return err;
} else {
return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM;
}
};
} }
MccAltLimitPZ(MccAltLimitPZ&&) = default;
MccAltLimitPZ(const MccAltLimitPZ&) = default;
consteval std::string_view name() const consteval std::string_view name() const
{ {
return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE" return KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
@ -126,299 +52,26 @@ public:
error_t inPZone(InputT coords, bool* result) error_t inPZone(InputT coords, bool* result)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{ {
double alt; // auto ret =
// return ret;
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
alt = coords.ALT;
} else {
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .time_point = coords.time_point};
ret = getCoord(coords, &to_pt);
if (ret) {
return ret;
}
alt = to_pt.Y;
}
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
*result = alt <= _altLimit;
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
*result = alt >= _altLimit;
}
return ret;
} }
template <typename InputT> template <typename InputT>
error_t timeToPZone(InputT coords, traits::mcc_time_duration_c auto* res_time) error_t timeToPZone(InputT coords, traits::mcc_time_duration_c auto* res_time)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{ {
using res_t = std::remove_cvref_t<decltype(*res_time)>;
double ha, dec;
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
bool inzone;
ret = inPZone(coords, &inzone);
if (ret) {
return ret;
}
if (inzone) {
*res_time = res_t{0};
return ret;
}
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
ha = coords.HA;
dec = coords.DEC_APP;
} else {
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP,
.time_point = coords.time_point};
ret = getCoord(coords, &to_pt);
if (ret) {
return ret;
}
ha = to_pt.X;
dec = to_pt.Y;
}
if (!doesObjectReachZone(dec)) {
*res_time = mcc_infinite_duration_v<res_t>;
return ret;
}
if constexpr (KIND ==
MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one after upper culmination
compute(ha, dec, false, res_time);
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one before upper
// culmination
compute(ha, dec, true, res_time);
}
return ret;
} }
template <typename InputT> template <typename InputT>
error_t timeFromPZone(InputT coords, traits::mcc_time_duration_c auto* res_time) error_t timeFromPZone(InputT coords, traits::mcc_time_duration_c auto* res_time)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{ {
using res_t = std::remove_cvref_t<decltype(*res_time)>;
double ha, dec;
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
bool inzone;
ret = inPZone(coords, &inzone);
if (ret) {
return ret;
}
if (!inzone) {
*res_time = res_t{0};
return ret;
}
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
ha = coords.HA;
dec = coords.DEC_APP;
} else {
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP,
.time_point = coords.time_point};
ret = getCoord(coords, &to_pt);
if (ret) {
return ret;
}
ha = to_pt.X;
dec = to_pt.Y;
}
if (!doesObjectExitFromZone(dec)) {
*res_time = mcc_infinite_duration_v<res_t>;
return ret;
}
if (!doesObjectReachZone(dec)) {
*res_time = res_t{0};
return ret;
}
if constexpr (KIND ==
MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one before upper culmination
compute(ha, dec, true, res_time);
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one after upper
// culmination
compute(ha, dec, false, res_time);
}
return ret;
} }
template <typename InputT> template <typename InputT>
error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point) error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{ {
double ha, dec, az;
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
ha = coords.HA;
dec = coords.DEC_APP;
} else {
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP,
.time_point = coords.time_point};
ret = getCoord(coords, &to_pt);
if (ret) {
return ret;
}
ha = to_pt.X;
dec = to_pt.Y;
}
double sinDec = sin(dec), cosDec = cos(dec);
auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat;
if (cos_ha > 1.0) { // no intersection
point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC;
point->X = std::numeric_limits<double>::quiet_NaN();
point->Y = std::numeric_limits<double>::quiet_NaN();
return ret;
}
// WARNNIG: THE EXPRESSION ASSUMES THAT AZIMUTH IS COUNTED FROM THE SOUTH THROUGH THE WEST!!!
double cosA = (-sinDec * _cosLat + cosDec * _sinLat * cos_ha) / _cosALim;
if constexpr (KIND ==
MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one after upper culmination
az = std::acos(cosA);
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one before upper
// culmination
az = -std::acos(cosA);
}
MccCelestialPoint pt{
.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .time_point = coords.time_point, .X = az, .Y = _altLimit},
to_pt{.pair_kind = point->pair_kind, .time_point = point->time_point};
ret = _transformCoordinates(pt, &to_pt);
if (!ret) {
point->X = to_pt.X;
point->Y = to_pt.Y;
}
return ret;
}
protected:
double _altLimit, _cosALim, _sinAlim;
double _cosLat, _sinLat, _absLat, _latLim;
std::function<error_t(MccCelestialPoint, MccCelestialPoint*)> _transformCoordinates{};
error_t getCoord(mcc_celestial_point_c auto const& from_pt, MccCelestialPoint* to_pt)
{
MccCelestialPoint pt{
.pair_kind = from_pt.pair_kind, .time_point = from_pt.time_point, .X = from_pt.X, .Y = from_pt.Y};
return _transformCoordinates(pt, to_pt);
}
bool doesObjectReachZone(const double& dec_app)
{
// check for limit conditions
auto dd = std::abs(dec_app);
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
dd += _altLimit;
if (dd > _latLim) { // never fall below altitude limit
return false;
}
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
auto z = std::numbers::pi / 2.0 - _altLimit;
if ((dd < (_absLat - z)) || (dd > (_absLat + z))) { // never rise above altitude limit
return false;
}
// if ((dd < (_absLat - _altLimit)) || (dd > (_absLat + _altLimit))) { // never rise above altitude limit
// return false;
// }
} else {
static_assert(false, "UNKNOWN ALTITUDE LIMIT TYPE!");
}
return true;
}
bool doesObjectExitFromZone(const double& dec_app)
{
// check for limit conditions
auto dd = std::abs(dec_app);
if constexpr (KIND == MccAltLimitKind::MIN_ALT_LIMIT) {
dd -= _altLimit;
if (-dd <= -_latLim) { // always below altitude limit
return false;
}
} else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) {
if ((dd >= (_absLat - _altLimit)) || (dd <= (_absLat + _altLimit))) { // always above altitude limit
return false;
}
} else {
static_assert(false, "UNKNOWN ALTITUDE LIMIT TYPE!");
}
return true;
}
void compute(const double& ha_app,
const double& dec_app,
bool before_upper_culm,
traits::mcc_time_duration_c auto* result)
{
using res_t = std::remove_cvref_t<decltype(*result)>;
using period_t = typename res_t::period;
double cos_ha = (_sinAlim - std::sin(dec_app) * _sinLat) / std::cos(dec_app) / _cosLat;
if (cos_ha > 1.0) { // should not be!
*result = mcc_infinite_duration_v<res_t>;
return;
}
double ha;
// WARNING: what about south hemisphere?!!!
if (before_upper_culm) {
ha = -std::acos(cos_ha); // HA before upper culmination
} else {
ha = std::acos(cos_ha); // HA after upper culmination!!
}
auto time_ang = ha - ha_app; // in sideral time scale
if (time_ang < 0.0) { // next day
time_ang += MccAltLimitPZ::pi2;
}
time_ang /= mcc_sideral_to_UT1_ratio; // to UT1 time scale
std::chrono::nanoseconds ns{
static_cast<std::chrono::nanoseconds::rep>(time_ang * 43200.0 / std::numbers::pi * 1.0E9)};
period_t rat;
*result = res_t{static_cast<typename res_t::rep>(time_ang * 43200.0 / std::numbers::pi * rat.den / rat.num)};
} }
}; };

View File

@ -1,386 +0,0 @@
#pragma once
#pragma once
/* MOUNT CONTROL COMPONENTS LIBRARY */
/* IMPLEMENTATION OF PROHIBITED ZONES CONTAINER */
#include "mcc_defaults.h"
namespace mcc
{
enum class MccPZoneContainerErrorCode : int {
ERROR_OK,
ERROR_NULLPTR,
ERROR_INZONE_FUNC,
ERROR_TIMETO_FUNC,
ERROR_TIMEFROM_FUNC,
ERROR_INTERSECT_FUNC
};
} // namespace mcc
namespace std
{
template <>
class is_error_code_enum<mcc::MccPZoneContainerErrorCode> : public true_type
{
};
} // namespace std
namespace mcc
{
/* error category definition */
// error category
struct MccPZoneContainerCategory : public std::error_category {
MccPZoneContainerCategory() : std::error_category() {}
const char* name() const noexcept
{
return "ALTITUDE-LIMIT-PZ";
}
std::string message(int ec) const
{
MccPZoneContainerErrorCode err = static_cast<MccPZoneContainerErrorCode>(ec);
switch (err) {
case MccPZoneContainerErrorCode::ERROR_OK:
return "OK";
case MccPZoneContainerErrorCode::ERROR_NULLPTR:
return "nullptr argument";
case MccPZoneContainerErrorCode::ERROR_INZONE_FUNC:
return "inPZone method error";
case MccPZoneContainerErrorCode::ERROR_TIMETO_FUNC:
return "timeToPZone method error";
case MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC:
return "timeFromPZone method error";
case MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC:
return "intersectPZone method error";
default:
return "UNKNOWN";
}
}
static const MccPZoneContainerCategory& get()
{
static const MccPZoneContainerCategory constInst;
return constInst;
}
};
inline std::error_code make_error_code(MccPZoneContainerErrorCode ec)
{
return std::error_code(static_cast<int>(ec), MccPZoneContainerCategory::get());
}
template <traits::mcc_time_duration_c DurT>
class MccPZoneContainer : public mcc_pzone_container_interface_t<std::error_code>
{
public:
typedef std::error_code error_t;
typedef DurT duration_t;
MccPZoneContainer() = default;
MccPZoneContainer(MccPZoneContainer&&) = default;
MccPZoneContainer(const MccPZoneContainer&) = default;
MccPZoneContainer& operator=(MccPZoneContainer&&) = default;
MccPZoneContainer& operator=(const MccPZoneContainer&) = default;
virtual ~MccPZoneContainer() = default;
size_t addPZone(mcc_prohibited_zone_c auto zone)
{
auto sptr = std::make_shared<decltype(zone)>(std::move(zone));
_inZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, bool* res) {
auto ret = sptr->inPZone(pt, res);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INZONE_FUNC));
});
_inZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, bool* res) {
auto ret = sptr->inPZone(pt, res);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INZONE_FUNC));
});
_timeToZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, duration_t* res_time) {
auto ret = sptr->timeToPZone(pt, res_time);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMETO_FUNC));
});
_timeToZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, duration_t* res_time) {
auto ret = sptr->timeToPZone(pt, res_time);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMETO_FUNC));
});
_timeFromZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, duration_t* res_time) {
auto ret = sptr->timeFromPZone(pt, res_time);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC));
});
_timeFromZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, duration_t* res_time) {
auto ret = sptr->timeFromPZone(pt, res_time);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC));
});
_intersectZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) {
auto ret = sptr->intersectPZone(pt, res_pt);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
});
_intersectZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) {
auto ret = sptr->intersectPZone(pt, res_pt);
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
});
return _inZoneFuncCPT.size();
}
void clearPZones()
{
_inZoneFuncCPT.clear();
_inZoneFuncEHC.clear();
_timeToZoneFuncCPT.clear();
_timeToZoneFuncEHC.clear();
_timeFromZoneFuncCPT.clear();
_timeFromZoneFuncEHC.clear();
_intersectZoneFuncCPT.clear();
_intersectZoneFuncEHC.clear();
}
size_t sizePZones() const
{
return _inZoneFuncCPT.size();
}
template <typename InputT>
error_t inPZone(InputT coords, bool* common_result, std::ranges::output_range<bool> auto* result = nullptr)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
{
if (common_result == nullptr) {
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
}
*common_result = false;
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
bool res;
error_t ret = func(pt_arg, &res);
if (!ret) {
*common_result |= res;
if (result) {
if (traits::mcc_range_size(*result) == i) {
std::back_inserter(*result) = res;
} else {
auto ptr = result->begin();
std::ranges::advance(ptr, i);
*ptr = res;
}
}
}
return ret;
};
return forEach(coords, apply_func, _inZoneFuncCPT, _inZoneFuncEHC);
}
// template <typename InputT, traits::mcc_time_duration_c DT>
// error_t timeToPZone(InputT coords, std::ranges::output_range<DT> auto* res_time)
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
template <typename InputT, typename R>
error_t timeToPZone(InputT coords, R* res_time)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) && traits::mcc_output_duration_range_c<R>
{
if (res_time == nullptr) {
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
}
using DT = std::ranges::range_value_t<R>;
duration_t res;
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
error_t ret = func(pt_arg, &res);
DT val;
if (res == mcc_infinite_duration_v<duration_t>) {
val = mcc_infinite_duration_v<DT>;
} else {
val = std::chrono::duration_cast<DT>(res);
}
if (!ret) {
if (traits::mcc_range_size(*res_time) == i) {
std::back_inserter(*res_time) = val;
} else {
auto ptr = res_time->begin();
std::ranges::advance(ptr, i);
*ptr = val;
}
}
return ret;
};
return forEach(coords, apply_func, _timeToZoneFuncCPT, _timeToZoneFuncEHC);
}
// template <typename InputT, traits::mcc_time_duration_c DT>
// error_t timeFromPZone(InputT coords, std::ranges::output_range<DT> auto* res_time)
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
template <typename InputT, typename R>
error_t timeFromPZone(InputT coords, R* res_time)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) && traits::mcc_output_duration_range_c<R>
{
if (res_time == nullptr) {
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
}
using DT = std::ranges::range_value_t<R>;
duration_t res;
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
error_t ret = func(pt_arg, &res);
if (!ret) {
if (traits::mcc_range_size(*res_time) == i) {
std::back_inserter(*res_time) = std::chrono::duration_cast<DT>(res);
} else {
auto ptr = res_time->begin();
std::ranges::advance(ptr, i);
*ptr = std::chrono::duration_cast<DT>(res);
}
}
return ret;
};
return forEach(coords, apply_func, _timeFromZoneFuncCPT, _timeFromZoneFuncEHC);
}
// template <typename InputT, mcc_celestial_point_c CPT>
// error_t intersectPZone(InputT coords, std::ranges::output_range<CPT> auto* result)
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
template <typename InputT, typename R>
error_t intersectPZone(InputT coords, R* result)
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
std::ranges::output_range<R, std::ranges::range_value_t<R>> &&
mcc_celestial_point_c<std::ranges::range_value_t<R>>
{
if (result == nullptr) {
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
}
using CPT = std::ranges::range_value_t<R>;
MccCelestialPoint pt;
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
error_t ret = func(pt_arg, &pt);
if (!ret) {
if (traits::mcc_range_size(*result) == i) {
std::back_inserter(*result) = CPT();
}
auto ptr = result->begin();
std::ranges::advance(ptr, i);
mcc_copy_celestial_point(pt, &(*ptr));
}
return ret;
};
return forEach(coords, apply_func, _intersectZoneFuncCPT, _intersectZoneFuncEHC);
}
protected:
std::vector<std::function<error_t(MccCelestialPoint const&, bool*)>> _inZoneFuncCPT;
std::vector<std::function<error_t(MccEqtHrzCoords const&, bool*)>> _inZoneFuncEHC;
std::vector<std::function<error_t(MccCelestialPoint const&, duration_t*)>> _timeToZoneFuncCPT;
std::vector<std::function<error_t(MccEqtHrzCoords const&, duration_t*)>> _timeToZoneFuncEHC;
std::vector<std::function<error_t(MccCelestialPoint const&, duration_t*)>> _timeFromZoneFuncCPT;
std::vector<std::function<error_t(MccEqtHrzCoords const&, duration_t*)>> _timeFromZoneFuncEHC;
std::vector<std::function<error_t(MccCelestialPoint const&, MccCelestialPoint*)>> _intersectZoneFuncCPT;
std::vector<std::function<error_t(MccEqtHrzCoords const&, MccCelestialPoint*)>> _intersectZoneFuncEHC;
error_t forEach(auto const& coords, auto& apply_func, auto& containerCPT, auto& containerEHC)
{
using coords_t = std::remove_cvref_t<decltype(coords)>;
error_t ret = MccPZoneContainerErrorCode::ERROR_OK;
size_t i = 0;
if constexpr (mcc_eqt_hrz_coord_c<coords_t>) {
MccEqtHrzCoords pt;
mcc_copy_eqt_hrz_coord(coords, &pt);
for (auto& func : containerEHC) {
ret = apply_func(func, pt, i);
if (ret) {
break;
}
++i;
}
} else {
MccCelestialPoint pt;
mcc_copy_celestial_point(coords, &pt);
for (auto& func : containerCPT) {
ret = apply_func(func, pt, i);
if (ret) {
break;
}
++i;
}
}
return ret;
}
};
} // namespace mcc

View File

@ -1,448 +0,0 @@
#pragma once
/* MOUNT CONTROL COMPONENTS LIBRARY */
/* IMPLEMENTATION OF TELEMETRY CLASS */
#include <condition_variable>
#include <mutex>
#include <thread>
#include "mcc_defaults.h"
namespace mcc
{
static constexpr double mcc_sideral_to_UT1_ratio = 1.002737909350795; // sideral/UT1
enum MccTelemetryErrorCode : int {
ERROR_OK,
ERROR_NULLPTR,
ERROR_COORD_TRANSFORM,
ERROR_PCM_COMP,
ERROR_HARDWARE_GETPOS,
ERROR_DATA_TIMEOUT
};
} // namespace mcc
namespace std
{
template <>
class is_error_code_enum<mcc::MccTelemetryErrorCode> : public true_type
{
};
} // namespace std
namespace mcc
{
/* error category definition */
// error category
struct MccTelemetryCategory : public std::error_category {
MccTelemetryCategory() : std::error_category() {}
const char* name() const noexcept
{
return "ALTITUDE-LIMIT-PZ";
}
std::string message(int ec) const
{
MccTelemetryErrorCode err = static_cast<MccTelemetryErrorCode>(ec);
switch (err) {
case MccTelemetryErrorCode::ERROR_OK:
return "OK";
case MccTelemetryErrorCode::ERROR_NULLPTR:
return "nullptr input argument";
case MccTelemetryErrorCode::ERROR_COORD_TRANSFORM:
return "coordinate transformation error";
case MccTelemetryErrorCode::ERROR_PCM_COMP:
return "PCM computation error";
case MccTelemetryErrorCode::ERROR_HARDWARE_GETPOS:
return "cannot get hardware position";
case MccTelemetryErrorCode::ERROR_DATA_TIMEOUT:
return "a timeout occured while waiting for new data";
default:
return "UNKNOWN";
}
}
static const MccTelemetryCategory& get()
{
static const MccTelemetryCategory constInst;
return constInst;
}
};
inline std::error_code make_error_code(MccTelemetryErrorCode ec)
{
return std::error_code(static_cast<int>(ec), MccTelemetryCategory::get());
}
/* TELEMETRY UPDATE POLICY */
enum class MccTelemetryUpdatePolicy : int { TEMETRY_UPDATE_INNER, TEMETRY_UPDATE_EXTERNAL };
template <MccTelemetryUpdatePolicy UPDATE_POLICY = MccTelemetryUpdatePolicy::TEMETRY_UPDATE_INNER>
class MccTelemetry : public mcc_telemetry_interface_t<std::error_code>
{
public:
static constexpr MccTelemetryUpdatePolicy updatePolicy = UPDATE_POLICY;
typedef std::error_code error_t;
MccTelemetry(mcc_ccte_c auto* ccte, mcc_PCM_c auto* pcm, mcc_hardware_c auto* hardware)
: _updated(false), _data(), _updateMutex(new std::mutex), _updateCondVar(new std::condition_variable)
{
_data.target.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS;
using ccte_t = std::remove_cvref_t<decltype(*ccte)>;
using pcm_t = std::remove_cvref_t<decltype(*pcm)>;
using hardware_t = std::remove_cvref_t<decltype(*hardware)>;
_updateTargetFunc = [ccte, pcm, this](bool only_hw) -> error_t {
if (!only_hw) {
//
// compute apparent coordinates
// ICRS coordinates of the taget must be already set
//
_data.target.time_point =
std::chrono::time_point_cast<typename decltype(_data.target.time_point)::duration>(
_data.time_point);
_data.target.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS;
_data.target.X = _data.target.RA_ICRS;
_data.target.Y = _data.target.DEC_ICRS;
// update apparent cordinates
auto ccte_err = ccte->transformCoordinates(_data.target, &_data.target);
if (ccte_err) {
return mcc_deduce_error<error_t>(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM);
}
}
// compute hardware coordinates
// WARNING: It is assumed here that PCM corrections have small (arcseconds-arcminutes) values
// since ususaly there is no reverse transformation for "hardware-to-apparent" relation!
typename pcm_t::error_t pcm_err;
struct {
double dx, dy;
} pcm_res;
MccCelestialPoint pt;
pt.time_point =
std::chrono::time_point_cast<typename decltype(pt.time_point)::duration>(_data.target.time_point);
if constexpr (mccIsEquatorialMount(pcm_t::mountType)) {
pt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
pt.X = _data.target.HA;
pt.Y = _data.target.DEC_APP;
pcm_err = pcm->compute(std::move(pt), &pcm_res);
if (!pcm_err) {
_data.target.X = _data.target.HA - pcm_res.dx;
_data.target.Y = _data.target.DEC_APP - pcm_res.dy;
}
} else if constexpr (mccIsAltAzMount(pcm_t::mountType)) {
pt.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT;
pt.X = _data.target.AZ;
pt.Y = _data.target.ALT;
pcm_err = pcm->compute(std::move(pt), &pcm_res);
if (!pcm_err) {
_data.target.X = _data.target.AZ - pcm_res.dx;
_data.target.Y = _data.target.ALT - pcm_res.dy;
}
} else {
static_assert(false, "UNKNOWN MOUNT TYPE!");
}
if (pcm_err) {
return mcc_deduce_error<error_t>(pcm_err, MccTelemetryErrorCode::ERROR_PCM_COMP);
}
return MccTelemetryErrorCode::ERROR_OK;
};
_updateFunc = [ccte, pcm, hardware, this]() {
// first, update mount quantities
typename hardware_t::axes_pos_t hw_pos;
auto hw_err = hardware->getPos(&hw_pos);
if (hw_err) {
return mcc_deduce_error(hw_err, MccTelemetryErrorCode::ERROR_HARDWARE_GETPOS);
}
double eo;
_data.time_point =
std::chrono::time_point_cast<typename decltype(_data.time_point)::duration>(hw_pos.time_point);
auto ccte_err = ccte->timepointToJulday(_data.time_point, &_data.JD);
if (!ccte_err) {
ccte_err = ccte->juldayToAppSideral(_data.JD, &_data.LST, true);
if (!ccte_err) {
ccte_err = ccte->equationOrigins(_data.JD, &eo);
}
}
if (ccte_err) {
return mcc_deduce_error(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM);
}
_data.speedX = (double)hw_pos.speedX;
_data.speedY = (double)hw_pos.speedY;
struct {
double dx, dy;
} pcm_res;
auto pcm_err = pcm->computePCM(_data, &pcm_res);
if (pcm_err) {
return mcc_deduce_error(pcm_err, MccTelemetryErrorCode::ERROR_PCM_COMP);
}
_data.pcmX = pcm_res.dx;
_data.pcmY = pcm_res.dy;
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .time_point = _data.time_point};
if constexpr (mccIsEquatorialMount(pcm_t::mountType)) {
_data.HA = (double)hw_pos.X + pcm_res.dx;
_data.DEC_APP = (double)hw_pos.Y + pcm_res.dy;
_data.RA_APP = (double)_data.LST - (double)_data.HA + eo;
_data.X = _data.HA;
_data.Y = _data.DEC_APP;
_data.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
ccte_err = ccte->transformCoordinates(_data, &pt);
if (!ccte_err) {
_data.AZ = pt.X;
_data.ALT = pt.Y;
_data.ZD = std::numbers::pi / 2.0 - _data.ALT;
}
} else if constexpr (mccIsAltAzMount(pcm_t::mountType)) {
_data.AZ = (double)hw_pos.X + pcm_res.dx;
_data.ALT = (double)hw_pos.Y + pcm_res.dy;
_data.ZD = std::numbers::pi / 2.0 - _data.ALT;
_data.X = _data.AZ;
_data.Y = _data.ALT;
_data.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT;
pt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
ccte_err = ccte->transformCoordinates(_data, &pt);
if (!ccte) {
_data.HA = pt.X;
_data.DEC_APP = pt.Y;
_data.RA_APP = (double)_data.LST - (double)_data.HA + eo;
}
} else {
static_assert(false, "UNKNOWN MOUNT TYPE!");
}
if (!ccte_err) {
_data.pair_kind = MccCoordPairKind::COORDS_KIND_AZZD;
_data.X = _data.AZ;
_data.Y = _data.ZD;
ccte_err = ccte->refractionCorrection(_data, &_data.refCorr);
if (!ccte_err) {
// restore hardware encoders coordinates
_data.X = (double)hw_pos.X;
_data.Y = (double)hw_pos.Y;
// update target (assuming target ICRS coordinates are already set)
auto ret = _updateTargetFunc(false);
if (ret) {
return ret;
}
}
}
if (ccte_err) {
return mcc_deduce_error(ccte_err, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM);
}
if constexpr (mccIsEquatorialMount(pcm_t::mountType)) {
_data.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
} else if constexpr (mccIsAltAzMount(pcm_t::mountType)) {
_data.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT;
} else {
static_assert(false, "UNKNOWN MOUNT TYPE!");
}
_updated = true;
return MccTelemetryErrorCode::ERROR_OK;
};
_setTargetFunc = [ccte, this](MccCelestialPoint const& pt) {
// in the case of apparent input coordinates
// one must ensure the same time points
_data.target.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS;
_data.target.time_point =
std::chrono::time_point_cast<typename decltype(_data.target.time_point)::duration>(pt.time_point);
auto ret = ccte->transformCoordinates(pt, &_data.target);
if (!ret) {
if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
_data.target.RA_ICRS = _data.target.X;
_data.target.DEC_ICRS = _data.target.Y;
// update apparent coordinates
ret = _updateTargetFunc(false);
} else { // apparent coordinates were computed above
// compute ICRS coordinates
MccCelestialPoint cpt{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
ret = ccte->transformCoordinates(pt, &cpt);
_data.target.RA_ICRS = cpt.X;
_data.target.DEC_ICRS = cpt.Y;
// compute only hardware coordinates
ret = _updateTargetFunc(true);
}
}
return mcc_deduce_error<error_t>(ret, MccTelemetryErrorCode::ERROR_COORD_TRANSFORM);
};
}
virtual ~MccTelemetry() = default;
error_t updateTelemetryData(traits::mcc_time_duration_c auto const& period)
{
using d_t = typename std::remove_cvref_t<decltype(period)>::rep;
bool is_zero;
if (std::floating_point<d_t>) {
is_zero = utils::isEqual(period.count(), d_t::zero());
} else {
is_zero = period.count() == d_t::zero();
}
if (is_zero) { // just update once
return _updateFunc();
} else {
// try to update once
auto ret = _updateFunc();
if (ret) {
return ret;
}
_lastUpdateError = MccTelemetryErrorCode::ERROR_OK;
_timerThread = [period, this](std::stop_token st) {
while (!st.stop_requested()) {
{
std::lock_guard thread_lock{*_updateMutex};
_lastUpdateError = _updateFunc();
_updateCondVar->notify_all();
if (_lastUpdateError) {
return;
}
}
std::this_thread::sleep_for(period);
}
};
_timerThread.detach();
return MccTelemetryErrorCode::ERROR_OK;
}
}
// block the thread and wait for data to be ready (external synchronization)
error_t waitForTelemetryData(mcc_telemetry_data_c auto* tdata, traits::mcc_time_duration_c auto const& timeout)
{
if (tdata == nullptr) {
return MccTelemetryErrorCode::ERROR_NULLPTR;
}
std::unique_lock ulock(*_updateMutex);
auto res = _updateCondVar->wait_for(ulock, timeout, [this]() { return _updated; });
if (res == std::cv_status::timeout) {
return MccTelemetryErrorCode::ERROR_DATA_TIMEOUT;
}
std::lock_guard thread_lock{*_updateMutex};
if (!_lastUpdateError) {
mcc_copy_telemetry_data(_data, tdata);
}
return _lastUpdateError;
}
// update and get data as soon as possible
error_t telemetryData(mcc_telemetry_data_c auto* tdata)
{
if (tdata == nullptr) {
return MccTelemetryErrorCode::ERROR_NULLPTR;
}
std::lock_guard thread_lock{*_updateMutex};
error_t ret = _updateFunc();
if (!ret) {
mcc_copy_telemetry_data(_data, tdata);
}
return ret;
}
error_t setPointingTarget(mcc_celestial_point_c auto pt)
{
std::lock_guard lock{*_updateMutex};
return _setTargetFunc(pt);
}
protected:
std::atomic_bool _updated;
MccTelemetryData _data;
std ::function<error_t(bool)> _updateTargetFunc{};
std::function<error_t()> _updateFunc{};
std::function<error_t()> _setTargetFunc{};
std::unique_ptr<std::mutex> _updateMutex;
std::unique_ptr<std::condition_variable> _updateCondVar;
error_t _lastUpdateError{MccTelemetryErrorCode::ERROR_OK};
std::jthread _timerThread;
};
} // namespace mcc

View File

@ -7,18 +7,6 @@
namespace mcc::traits namespace mcc::traits
{ {
template <std::ranges::range R>
static constexpr size_t mcc_range_size(const R& r)
{
if constexpr (std::ranges::sized_range<R>) {
return r.size();
} else {
return std::ranges::distance(r.begin(), r.end());
}
}
template <typename R> template <typename R>
concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>; concept mcc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
@ -71,16 +59,6 @@ concept mcc_systime_c = requires {
}; };
template <typename R>
concept mcc_output_duration_range_c =
std::ranges::output_range<R, std::ranges::range_value_t<R>> && mcc_time_duration_c<std::ranges::range_value_t<R>>;
// concept mcc_output_duration_range_c = std::ranges::range<R> && requires(R r) {
// []<class Rep, class Period>(std::type_identity<std::chrono::duration<Rep, Period>>) {
// }(std::ranges::range_value_t<R>());
// };
/* a callable concept and its signature traits */ /* a callable concept and its signature traits */
template <typename T> template <typename T>

View File

@ -1,108 +0,0 @@
#include <iostream>
#include <list>
#include "../mcc_ccte_erfa.h"
#include "../mcc_pzone.h"
#include "../mcc_pzone_container.h"
using namespace mcc::ccte::erfa;
int main()
{
MccCCTE_ERFA::engine_state_t state{.lat = 43.646711_degs, .lon = 41.440732_degs, .elev = 2100.0};
state.meteo = {10.0, 0.5, 1010.0};
MccCCTE_ERFA erfa(state);
std::cout << "LAT = " << mcc::MccAngle(state.lat).sexagesimal() << "\n";
std::cout << "LON = " << mcc::MccAngle(state.lon).sexagesimal() << "\n";
auto now = std::chrono::system_clock::now();
mcc::MccCelestialPoint cp{
.pair_kind = mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS, .X = "10:20:30.44"_hms, .Y = "20:30:40.55"_dms};
mcc::MccEqtHrzCoords eqhrz;
eqhrz.time_point = now;
auto ret = erfa.transformCoordinates(cp, &eqhrz);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "RA_ICRS = " << mcc::MccAngle(cp.X).sexagesimal(true) << "\n";
std::cout << "DEC_ICRS = " << mcc::MccAngle(cp.Y).sexagesimal() << "\n\n";
std::cout << "time point = " << eqhrz.time_point << "\n";
std::cout << "RA_APP = " << mcc::MccAngle(eqhrz.RA_APP).sexagesimal(true) << "\n";
std::cout << "DEC_APP = " << mcc::MccAngle(eqhrz.DEC_APP).sexagesimal() << "\n";
std::cout << "HA = " << mcc::MccAngle(eqhrz.HA).sexagesimal(true) << "\n";
std::cout << "AZ = " << mcc::MccAngle(eqhrz.AZ).sexagesimal() << "\n";
std::cout << "ZD = " << mcc::MccAngle(eqhrz.ZD).sexagesimal() << "\n";
std::cout << "ALT = " << mcc::MccAngle(eqhrz.ALT).sexagesimal() << "\n";
std::cout << "\n\n";
mcc::MccJulianDay jd;
ret = erfa.timepointToJulday(now, &jd);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "JD = " << std::setprecision(12) << (double)jd << "\n";
mcc::MccAngle lst, eo;
ret = erfa.timepointToAppSideral(now, &lst, true);
std::cout << "LST = " << lst.sexagesimal(true) << "\n";
ret = erfa.equationOrigins(now, &eo);
std::cout << "EO = " << eo.sexagesimal(true) << "\n";
std::cout << "\n\n";
mcc::MccAltLimitPZ<mcc::MccAltLimitKind::MIN_ALT_LIMIT> altmin(10.0_degs, state.lat, &erfa);
bool inzone;
std::cout << "time point = " << eqhrz.time_point << "\n";
ret = altmin.inPZone(eqhrz, &inzone);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "ALTMIN: inZone = " << std::boolalpha << inzone << "\n";
std::chrono::duration<double> dsec;
ret = altmin.timeToPZone(eqhrz, &dsec);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "TIME TO ZONE: " << dsec << " ("
<< now + std::chrono::duration_cast<std::chrono::system_clock::duration>(dsec) << ")\n";
mcc::MccCelestialPoint icp{.pair_kind = mcc::MccCoordPairKind::COORDS_KIND_AZALT, .time_point = now};
ret = altmin.intersectPZone(eqhrz, &icp);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "INTERSEC AZ = " << mcc::MccAngle(icp.X).sexagesimal() << "\n";
std::cout << "INTERSEC ALT = " << mcc::MccAngle(icp.Y).sexagesimal() << "\n";
mcc::MccAltLimitPZ<mcc::MccAltLimitKind::MAX_ALT_LIMIT> altmax(80.0_degs, state.lat, &erfa);
mcc::MccPZoneContainer<std::chrono::duration<double>> pzcont;
pzcont.addPZone(altmin);
pzcont.addPZone(altmax);
// std::vector<std::chrono::duration<double, std::ratio<60>>> vm;
std::vector<std::chrono::minutes> vm;
std::list<bool> lb;
bool cf;
ret = pzcont.inPZone(eqhrz, &cf, &lb);
std::cout << "ret = " << ret.message() << "\n";
std::cout << std::boolalpha;
std::cout << "IN ZONE 1: " << lb.front() << "\n";
std::cout << "IN ZONE 2: " << lb.back() << "\n";
std::cout << "COMMON IN ZONE 1,2: " << cf << "\n";
ret = pzcont.timeToPZone(eqhrz, &vm);
std::cout << "ret = " << ret.message() << "\n";
std::cout << "TIME TO ZONE 1: " << vm[0] << "\n";
std::cout << "TIME TO ZONE 2: " << vm[1] << "\n";
return 0;
}

View File

@ -1,36 +0,0 @@
#!/bin/bash
#
# $1 - output filename
#
if [[ $# -eq 0 ]]; then
res_file="mcc_ccte_iers_default.h"
else
res_file=$1
fi
echo -e '#pragma once\n
#include <string>\n
namespace mcc::ccte::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::ccte::iers::defaults\n' >> $res_file