This commit is contained in:
2025-08-08 23:50:55 +03:00
parent c45d17b236
commit b99263a014
11 changed files with 709 additions and 197 deletions

View File

@@ -107,11 +107,6 @@ inline std::error_code make_error_code(MccMountAstromEngineERFAErrorCode ec)
/* A concept for ERFA-library compatible type to represent anglular quantities */
template <typename T>
concept mcc_erfa_angle_t = std::constructible_from<T, double> && std::convertible_to<T, double>;
template <mcc_erfa_angle_t AngleT = MccAngle>
class MccMountAstromEngineERFA
{
public:
@@ -119,6 +114,9 @@ public:
typedef std::error_code error_t;
/* use of the same type for representation of celestial and geodetic coordinates, celestial angles (e.g. P.A.),
* and sideral time */
typedef double coord_t;
// meteo parameters (to compute refraction)
struct meteo_t {
@@ -136,9 +134,9 @@ public:
double wavelength = DEFAULT_WAVELENGTH; // observed wavelength in mkm
AngleT lat = "00:00:00"_dms; // site latitude
AngleT lon = "00:00:00"_dms; // site longitude
double elev = 0.0; // site elevation (in meters)
coord_t lat = "00:00:00"_dms; // site latitude
coord_t lon = "00:00:00"_dms; // site longitude
double elev = 0.0; // site elevation (in meters)
mcc::astrom::iers::MccLeapSeconds _leapSeconds{};
mcc::astrom::iers::MccIersBulletinA _bulletinA{};
@@ -152,13 +150,10 @@ public:
};
/* use of the same type for representation of celestial and geodetic coordinates, celestial angles (e.g. P.A.),
* and sideral time */
typedef AngleT coord_t;
typedef AngleT sideral_time_t;
typedef AngleT pa_t;
typedef AngleT eo_t;
typedef coord_t sideral_time_t;
typedef coord_t pa_t;
typedef coord_t eo_t;
struct refract_result_t {
double refa, refb;
@@ -556,6 +551,170 @@ public:
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
}
error_t coord2coord(MccCoordPairKind coord_from_kind,
coord_t x_from,
coord_t y_from,
time_point_t time_point_from,
MccCoordPairKind coord_to_kind,
coord_t& x_to,
coord_t& y_to,
time_point_t time_point_to)
{
error_t ret = MccMountAstromEngineERFAErrorCode::ERROR_OK;
// no convertion
if (time_point_from == time_point_to && coord_from_kind == coord_to_kind) {
x_to = x_from;
y_to = y_from;
return ret;
}
juldate_t jd;
eo_t eo;
coord_t ra, dec, ha, az, alt;
sideral_time_t lst;
auto lst_eo = [&]() {
ret = greg2jul(time_point_from, jd);
if (!ret) {
ret = apparentSiderTime(jd, lst, true);
if (!ret) {
ret = eqOrigins(jd, eo);
}
}
};
// special case: to ICRS from apparent
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZALT ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
//
ret = greg2jul(time_point_from, jd);
if (!ret) {
ret = obs2icrs(coord_from_kind, x_from, y_from, jd, x_to, y_to);
}
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
return ret;
}
// special case: from ICRS to apparent
if (coord_from_kind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) {
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZALT ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP ||
coord_to_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
//
ret = greg2jul(time_point_to, jd);
if (!ret) {
ret = icrs2obs(x_from, y_from, jd, ra, dec, ha, az, alt, eo);
if (!ret) {
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
x_to = az;
y_to = alt;
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
x_to = az;
y_to = std::numbers::pi / 2.0 - alt;
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
x_to = ra;
y_to = dec;
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
x_to = ha;
y_to = dec;
}
}
}
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
return ret;
}
// from apparent to apparent
if (time_point_from != time_point_to) { // first, convert 'from' coordinates to ICRS
ret = greg2jul(time_point_from, jd);
if (!ret) {
ret = obs2icrs(coord_from_kind, x_from, y_from, jd, ra, dec);
if (!ret) { // from ICRS to required
return coord2coord(MccCoordPairKind::COORDS_KIND_RADEC_ICRS, ra, dec, time_point_from,
coord_to_kind, x_to, y_to, time_point_to);
}
}
} else { // same time points
if (coord_from_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
// first, compute HA from CIO-based RA!!!
lst_eo();
if (!ret) {
ha = lst - x_from + eo;
} else {
return ret;
}
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
ret = hadec2azalt(ha, y_from, x_to, y_to);
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
ret = hadec2azalt(ha, y_from, x_to, y_to);
if (!ret) {
y_to = std::numbers::pi / 2.0 - y_to;
}
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
x_to = ha;
y_to = y_from;
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
} else if (coord_from_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
ret = hadec2azalt(x_from, y_from, x_to, y_to);
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
ret = hadec2azalt(x_from, y_from, x_to, y_to);
if (!ret) {
y_to = std::numbers::pi / 2.0 - y_to;
}
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
lst_eo();
if (!ret) {
x_to = lst - x_from + eo;
y_to = y_from;
}
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
} else if (coord_from_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
if (coord_to_kind == MccCoordPairKind::COORDS_KIND_RADEC_APP) {
ret = azalt2hadec(x_from, y_from, x_to, y_to);
if (!ret) {
lst_eo();
if (!ret) {
x_to = lst - x_to + eo;
}
}
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
x_to = x_from;
y_to = std::numbers::pi / 2.0 - y_from;
} else if (coord_to_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
ret = azalt2hadec(x_from, y_from, x_to, y_to);
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
} else if (coord_from_kind == MccCoordPairKind::COORDS_KIND_AZZD) {
return coord2coord(MccCoordPairKind::COORDS_KIND_AZALT, std::move(x_from),
std::numbers::pi / 2.0 - y_to, time_point_from, coord_to_kind, x_to, y_to,
time_point_to);
} else {
ret = MccMountAstromEngineERFAErrorCode::ERROR_UNSUPPORTED_COORD_PAIR;
}
}
return ret;
}
/* helper mathods */
@@ -577,4 +736,4 @@ protected:
} // namespace mcc::astrom::erfa
static_assert(mcc::traits::mcc_astrom_engine_c<mcc::astrom::erfa::MccMountAstromEngineERFA<>>, "");
static_assert(mcc::traits::mcc_astrom_engine_c<mcc::astrom::erfa::MccMountAstromEngineERFA>, "");