mountcontrol/cxx/tests/astrom_test.cpp
Timur A. Fatkhullin 6d65efd0af ...
2025-07-21 00:33:06 +03:00

276 lines
11 KiB
C++

#include <fstream>
#include <iostream>
// #include "../mcc_coord.h"
#include "../mcc_mount_astro_erfa.h"
#include "../mcc_mount_pz.h"
#include "../mount_astrom.h"
// BTA coords from maps.yandex.ru: 43.646711, 41.440732
struct tel_data_t {
typedef mcc::MccAngle coord_t;
typedef std::chrono::system_clock::time_point time_point_t;
coord_t mntRA, mntDEC, mntHA;
coord_t mntAZ, mntALT;
coord_t mntPosX, mntPosY;
};
int main(int argc, char* argv[])
{
int ecode = 0;
// if (argc < 2) {
// std::cerr << "Usage: " << argv[0] << " bulletinA-filename\n";
// exit(1);
// }
// std::ifstream ist(argv[1]);
// if (!ist) {
// std::cerr << "Invalid filename!\n";
// exit(1);
// }
// mcc::astrom::MccIersBulletinA bullA;
// bullA.dump(std::cout);
// std::cout << "\n\n";
// mcc::astrom::MccLeapSeconds lps;
// lps.dump(std::cout);
// std::cout << "\n\n";
// bool ok = bullA.load(ist);
// bullA.dump(std::cerr);
// ist.close();
// std::cout << "\n\n\n------------------\n";
// constexpr auto nnn = mcc::astrom::MccLeapSeconds::real_secs_t{std::numeric_limits<double>::quiet_NaN()};
auto now = std::chrono::system_clock::now();
// // std::cout << "LEAP SECS for now: " << lps[now].value_or(std::numeric_limits<double>::quiet_NaN()) << "\n";
// std::cout << "LEAP SECS for now: " << lps[now].value_or(nnn) << "\n";
// // std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(std::numeric_limits<double>::quiet_NaN()) << " (" <<
// // now
// std::cout << "DUT1 for now: " << bullA.DUT1(now).value_or(nnn) << " (" << now << ")\n";
// double mjd = 61077.4;
// // std::cout << "DUT1 for MJD = " << mjd << ": " <<
// // bullA.DUT1(mjd).value_or(std::numeric_limits<double>::quiet_NaN())
// std::cout << "DUT1 for MJD = " << mjd << ": " << bullA.DUT1(mjd).value_or(nnn) << "\n";
// auto st = mcc::astrom::mcc_julday(now, mjd);
// std::cout << "MJD for now: " << std::setprecision(19) << mjd << " (" << now << ")\n";
// // double pres = 786.6;
// // double temp = 0.0;
// // double hum = 0.8;
// // double A, B;
// // erfa::eraRefco(pres, temp, hum, 0.5, &A, &B);
// // const double rr = 180.0 / std::numbers::pi * 60.0;
// // std::cout << "A(arcmin) = " << A * rr << "; B(arcmin) = " << B * rr << "\n";
// float alt_lim = 10.0;
// std::string_view ra_str = "06:30:00.0", dec_str = "00:00:00.0";
// std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
// << alt_lim << " degrees):\n";
// using namespace std::chrono_literals;
// // auto stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
// // std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
// // auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
// // std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
// // std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm) << " minutes\n";
// alt_lim = 85.0;
// ra_str = "02:30:00.0", dec_str = "45:00:00.0";
// std::cout << "\n\nTimes to object (RA = " << ra_str << ", DEC = " << dec_str << ") sets to given altitude ("
// << alt_lim << " degrees):\n";
// auto stm =
// mcc::astrom::mcc_time_to_alt({alt_lim, mcc::mcc_degrees}, {ra_str, mcc::mcc_hms}, dec_str, 43.646711_degs,
// 41.440732_degs, std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
// // stm = mcc::astrom::mcc_time_to_alt_limit(alt_lim, ra_str, dec_str, 43.646711, 41.440732,
// // std::chrono::system_clock::now(), 0.041s, 32.184s, 37.0s);
// // auto stm_d = mcc::astrom::mcc_chrono_radians{stm};
// // std::cout << "STM: " << stm * 12.0 / std::numbers::pi * 60.0 << " minutes\n";
// std::cout << "STM: " << stm.first << ", " << stm.second << " seconds\n";
// std::cout << "STM: " << std::chrono::duration_cast<std::chrono::minutes>(stm.first) << ", "
// << std::chrono::duration_cast<std::chrono::minutes>(stm.second) << " minutes\n";
// std::cout << "\n\n\n";
// const size_t N = 1000;
// double mjds[N];
// now = std::chrono::system_clock::now();
// st = mcc::astrom::mcc_julday(now, mjds, std::chrono::milliseconds(100));
// std::cout << std::format("comp time for {} MJDs = {}\n", N, std::chrono::system_clock::now() - now);
// std::cout << std::format("MIN MJD: {:.16f}; \nMAX MJD: {:.16f}\n", mjds[0], mjds[N - 1]);
// double elong = 43.646711 * std::numbers::pi / 180.0;
// double phi = 41.440732 * std::numbers::pi / 180.0;
// double aob, zob, hob, dob, rob, eo;
// now = std::chrono::system_clock::now();
// for (auto& el : mjds) {
// st = mcc::astrom::erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi,
// 2100.0, 0.0, 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob,
// &eo);
// // st = erfa::eraAtco13(1.343523, 0.32352345, 0.0, 0.0, 0.0, 0.0, ERFA_DJM0, el, 0.041, elong, phi, 2100.0,
// 0.0,
// // 0.0, 700.0, 10.0, 0.8, 0.5, &aob, &zob, &hob, &dob, &rob, &eo);
// }
// std::cout << std::format(
// "comp time for {} coordinate transf = {}\n", N,
// std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - now));
// std::cout << "\n\n\nMccCoordinate class test:\n";
// mcc::MccAngle ra("12:00:00", mcc::mcc_hms);
// std::cout << "sin(12h) = " << std::sin(ra) << "\n";
// std::cout << "cos(12h) = " << std::cos(ra) << "\n";
// ra = "18:00:00"_hms;
// std::cout << "sin(18h) = " << std::sin(ra) << "\n";
// std::cout << "cos(18h) = " << std::cos(ra) << "\n";
// ra = mcc::MccAngle{45.0, mcc::mcc_degrees};
// std::cout << "sin(45) = " << std::sin(ra) << "\n";
// std::cout << "cos(45) = " << std::cos(ra) << "\n";
// std::cout << ra.sexagesimal(false, 4) << "\n";
// std::cout << "\n\n\n\n";
using engine_t = mcc::astrom::erfa::MccMountAstromEngineERFA<>;
engine_t::engine_state_t state;
state.lon = 41.440732_degs;
state.lat = 43.646711_degs;
state.elev = 2100.0;
state.meteo = {10.0, 0.5, 1010.0};
std::cout << "LON = " << state.lon.sexagesimal() << "\n";
std::cout << "LAT = " << state.lat.sexagesimal() << "\n\n";
engine_t erfa(state);
engine_t::juldate_t jd{60861.72};
now = std::chrono::system_clock::now();
erfa.greg2jul(now, jd);
std::cout << "MJD(" << now << ") = " << jd.mjd << "\n";
mcc::MccAngle lst;
erfa.apparentSiderTime(jd, lst, true);
std::cout << "LST(MJD = " << jd.mjd << ") = " << lst.sexagesimal(true) << "\n\n";
// mcc::MccAngle ra1{"10:00:00", mcc::mcc_hms}, dec1{"68:25:10.43"}, ra_o, dec_o, ha1, az1, alt1;
mcc::MccAngle ra1{"5:00:00", mcc::mcc_hms}, dec1{"38:25:10.43"}, ra_o, dec_o, ha1, az1, alt1;
mcc::MccAngle eor;
std::cout << "RA = " << ra1.sexagesimal(true) << ", DEC = " << dec1.sexagesimal() << "\n";
auto res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
std::cout << "eq of origins (from icrs2obs) = " << eor.sexagesimal(true) << "\n";
std::cout << "ret code (icrs2obs) = " << res.message() << "\n";
std::cout << "alt = " << alt1.sexagesimal() << "\n";
std::cout << "az = " << az1.sexagesimal() << "\n";
std::cout << "HA_app = " << ha1.sexagesimal(true) << "\n";
std::cout << "RA_app = " << ra_o.sexagesimal(true) << "\n";
std::cout << "DEC_app = " << dec_o.sexagesimal() << "\n";
res = erfa.eqOrigins(jd, eor);
std::cout << "eq of origins (from eqOrigins) = " << eor.sexagesimal(true) << "\n";
std::cout << "RA_app_comp = " << (lst - ha1 + eor).sexagesimal(true) << "\n";
std::cout << "\n\n\n\n";
mcc::MccMinAltPZ minalt_pz(10.0_degs, state.lat);
mcc::MccMaxAltPZ maxalt_pz(85.0_degs, state.lat);
tel_data_t tdata{ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
bool ask = minalt_pz.inZone(tdata);
std::cout << "in zone? " << std::boolalpha << ask << "\n";
auto tm = minalt_pz.timeTo(tdata);
if (std::isinf(tm.count())) {
std::cout << "(MINALT) time to zone: the object never reaches the zone!\n";
} else {
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
std::cout << "(MINALT) time to zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
}
tm = minalt_pz.timeFrom(tdata);
if (std::isinf(tm.count())) {
std::cout << "(MINALT) time from zone: the object never reaches the zone!\n";
} else {
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
std::cout << "(MINALT) time from zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
}
std::cout << "\n";
ra1 = "17:00:00"_hms;
dec1 = "40:25:10.43"_dms;
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
std::cout << "ret code (icrs2obs) = " << res.message() << "\n";
std::cout << "alt = " << alt1.sexagesimal() << "\n";
std::cout << "az = " << az1.sexagesimal() << "\n";
std::cout << "HA_app = " << ha1.sexagesimal(true) << "\n";
std::cout << "RA_app = " << ra_o.sexagesimal(true) << "\n";
std::cout << "DEC_app = " << dec_o.sexagesimal() << "\n";
tdata = {ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
jd.mjd += 1.0;
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
std::cout << "RA_app (+24h) = " << ra_o.sexagesimal(true) << "\n";
tm = maxalt_pz.timeTo(tdata);
if (std::isinf(tm.count())) {
std::cout << "(MAXALT) time to zone: the object never reaches the zone!\n";
} else {
// auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(tm);
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
// auto now1 = now + ns;
std::cout << "(MAXALT) time to zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
}
tm = maxalt_pz.timeFrom(tdata);
if (std::isinf(tm.count())) {
std::cout << "(MAXALT) time from zone: the object never reaches the zone!\n";
} else {
auto now1 = now + std::chrono::duration_cast<decltype(now)::duration>(tm);
std::cout << "(MAXALT) time from zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
}
ra_o = 1.0;
dec_o = 2.0;
ha1 = ra_o * dec_o;
std::cout << "mult: " << ha1.degrees() << "\n";
return ecode;
}