This commit is contained in:
Timur A. Fatkhullin 2025-07-09 18:47:13 +03:00
parent d663f6b54a
commit 6646ef6aca
7 changed files with 339 additions and 148 deletions

View File

@ -80,7 +80,9 @@ public:
typedef MccAngle coord_t;
typedef MccAngle sideral_time_t;
// typedef juldate_t terr_time_t;
typedef MccAngle pa_t;
typedef MccAngle eo_t;
struct refract_result_t {
double refa, refb;
@ -156,13 +158,38 @@ public:
}
engine_err_t apparentSiderTime(juldate_t juldate, sideral_time_t& gst, bool islocal = false)
engine_err_t terrestialTime(juldate_t juldate, juldate_t& tt)
{
std::lock_guard lock{_stateMutex};
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
double ut1 = juldate.mjd, tt = juldate.mjd;
auto tai_utc = _currentState._leapSeconds[juldate.mjd];
if (tai_utc.has_value()) {
tt.mjd += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
} else {
return ERROR_LEAPSECONDS_OUT_OF_RANGE;
}
auto tt_tai = _currentState._bulletinA.TT_TAI();
tt.mjd = juldate.mjd + std::chrono::duration_cast<real_days_t>(tt_tai).count();
return ERROR_OK;
}
engine_err_t apparentSiderTime(juldate_t juldate, sideral_time_t& gst, bool islocal = false)
{
// std::lock_guard lock{_stateMutex};
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
double ut1 = juldate.mjd;
// double tt = juldate.mjd;
{
std::lock_guard lock{_stateMutex};
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
@ -171,19 +198,27 @@ public:
} else { // out of range
return ERROR_BULLETINA_OUT_OF_RANGE;
}
auto tai_utc = _currentState._leapSeconds[juldate.mjd];
if (tai_utc.has_value()) {
tt += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
} else {
return ERROR_LEAPSECONDS_OUT_OF_RANGE;
}
// auto tai_utc = _currentState._leapSeconds[juldate.mjd];
// if (tai_utc.has_value()) {
// tt += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
// } else {
// return ERROR_LEAPSECONDS_OUT_OF_RANGE;
// }
auto tt_tai = _currentState._bulletinA.TT_TAI();
tt += std::chrono::duration_cast<real_days_t>(tt_tai).count();
gst = eraGst06a(juldate.MJD0, ut1, juldate.MJD0, tt);
// auto tt_tai = _currentState._bulletinA.TT_TAI();
// tt += std::chrono::duration_cast<real_days_t>(tt_tai).count();
// gst = eraGst06a(juldate.MJD0, ut1, juldate.MJD0, tt);
juldate_t tt;
auto err = terrestialTime(juldate, tt);
if (err != ERROR_OK) {
return err;
}
gst = eraGst06a(juldate.MJD0, ut1, juldate.MJD0, tt.mjd);
if (islocal) {
gst += _currentState.lon;
}
@ -192,6 +227,20 @@ public:
}
engine_err_t eqOrigins(juldate_t juldate, eo_t& eo)
{
juldate_t tt;
auto err = terrestialTime(juldate, tt);
if (err != ERROR_OK) {
return err;
}
eo = eraEo06a(tt.MJD0, tt.mjd);
return ERROR_OK;
}
/* atmospheric refraction-related methods */
engine_err_t refraction(refract_result_t& refr)
@ -205,6 +254,18 @@ public:
}
engine_err_t refractCorrection(const coord_t& alt, const refract_result_t& ref_params, coord_t& corr)
{
if (alt <= 0.0) {
corr = 35.4 / 60.0 * std::numbers::pi / 180.0; // 35.4 arcminutes
} else {
auto tanALT = std::tan(alt);
corr = ref_params.refa / tanALT + ref_params.refb / tanALT / tanALT / tanALT;
}
return ERROR_OK;
}
/* coordinates conversional methods */
engine_err_t icrs2obs(coord_t ra,

View File

@ -83,6 +83,10 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) {
std::declval<bool>())
} -> std::same_as<typename T::engine_err_t>;
// equation of origins
{
t.eqOrigins(std::declval<typename T::juldate_t>(), std::declval<typename T::eo_t&>())
} -> std::same_as<typename T::engine_err_t>;
/* atmospheric refraction-related methods */

View File

@ -21,6 +21,36 @@ static constexpr std::string_view MccMountTypeStr = TYPE == MccMountType::GERMAN
: 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;
};
} // namespace mcc
@ -99,108 +129,114 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) {
/* atmospheric refraction-related methods */
// compute refraction-related quantities: refraction(refr_params)
{ t.refraction(std::declval<typename T::refract_result_t&>()) } -> std::same_as<typename T::engine_err_t>;
// compute refraction correction for given altitude: refractCorrection(alt, refr_params, refr_corr)
{
t.refractCorrection(std::declval<typename T::coord_t>(), std::declval<typename T::refract_result_t>(),
std::declval<typename T::coord_t&>())
} -> std::same_as<typename T::engine_err_t>;
};
/* MOUNT AXES AND MOTORS HARDWARE GENERIC ABSTRACTION */
// encoder basic concept (e.g. mount axis encoder or motor shaft one)
template <typename T>
concept mcc_hw_encoder_c = requires(T t, const T t_const) {
typename T::error_t;
// // encoder basic concept (e.g. mount axis encoder or motor shaft one)
// template <typename T>
// concept mcc_hw_encoder_c = requires(T t, const T t_const) {
// requires mcc_error_c<typename T::error_t>;
typename T::time_point_t;
typename T::coord_t;
typename T::speed_t;
typename T::accel_t;
// typename T::time_point_t;
// typename T::coord_t;
// typename T::speed_t;
// typename T::accel_t;
requires requires(typename T::state_t st) {
requires std::same_as<decltype(st.time), typename T::time_point_t>;
requires std::same_as<decltype(st.pos), typename T::coord_t>;
requires std::same_as<decltype(st.speed), typename T::speed_t>;
requires std::same_as<decltype(st.accel), typename T::accel_t>;
};
// requires requires(typename T::state_t st) {
// requires std::same_as<decltype(st.time), typename T::time_point_t>;
// requires std::same_as<decltype(st.pos), typename T::coord_t>;
// requires std::same_as<decltype(st.speed), typename T::speed_t>;
// requires std::same_as<decltype(st.accel), typename T::accel_t>;
// };
{ t_const.errorString(std::declval<typename T::error_t>()) } -> mcc_formattable;
// { t_const.errorString(std::declval<typename T::error_t>()) } -> mcc_formattable;
{ t_const.id() } -> mcc_formattable;
// { t_const.id() } -> mcc_formattable;
{ t.getState(std::declval<typename T::state_t&>()) } -> std::same_as<typename T::error_t>;
};
// { t.getState(std::declval<typename T::state_t&>()) } -> std::same_as<typename T::error_t>;
// };
template <typename T>
concept mcc_hw_motor_c = requires(T t, const T t_const) {
typename T::error_t;
// template <typename T>
// concept mcc_hw_motor_c = requires(T t, const T t_const) {
// requires mcc_error_c<typename T::error_t>;
typename T::coord_t;
typename T::speed_t;
typename T::accel_t;
// typename T::coord_t;
// typename T::speed_t;
// typename T::accel_t;
requires requires(typename T::pos_t st) {
requires std::same_as<decltype(st.pos), typename T::coord_t>;
requires std::same_as<decltype(st.speed), typename T::speed_t>; // means maximal allowed speed
requires std::same_as<decltype(st.accel), typename T::accel_t>; // means a maximal allowed acceleration (jerk)
};
// requires requires(typename T::pos_t st) {
// requires std::same_as<decltype(st.pos), typename T::coord_t>;
// requires std::same_as<decltype(st.speed), typename T::speed_t>; // means maximal allowed speed
// requires std::same_as<decltype(st.accel), typename T::accel_t>; // means a maximal allowed acceleration
// (jerk)
// };
{ t_const.errorString(std::declval<typename T::error_t>()) } -> mcc_formattable;
// { t_const.errorString(std::declval<typename T::error_t>()) } -> mcc_formattable;
{ t_const.id() } -> mcc_formattable;
// { t_const.id() } -> mcc_formattable;
{ t.toPos(std::declval<typename T::pos_t>()) } -> std::same_as<typename T::error_t>;
// { t.toPos(std::declval<typename T::pos_t>()) } -> std::same_as<typename T::error_t>;
{ t.stop() } -> std::same_as<typename T::error_t>;
};
// { t.stop() } -> std::same_as<typename T::error_t>;
// };
namespace details
{
template <typename T>
concept mcc_tuple_enc_ref_c = mcc_tuple_c<T> && requires(T t) {
[]<template <typename...> typename TT, mcc_hw_encoder_c... Ts>(TT<Ts & ...>) {}(t);
};
// namespace details
// {
// template <typename T>
// concept mcc_hw_enc_lvref_c = mcc_nonconst_lvref<T> && mcc_hw_encoder_c<std::remove_reference_t<T>>;
template <typename T>
concept mcc_tuple_enc_cref_c = mcc_tuple_c<T> && requires(T t) {
[]<template <typename...> typename TT, mcc_hw_encoder_c... Ts>(TT<const Ts & ...>) {}(t);
};
// template <typename T>
// concept mcc_hw_motor_lvref_c = mcc_nonconst_lvref<T> && mcc_hw_motor_c<std::remove_reference_t<T>>;
template <typename T>
concept mcc_tuple_motor_ref_c = mcc_tuple_c<T> && requires(T t) {
[]<template <typename...> typename TT, mcc_hw_motor_c... Ts>(TT<Ts & ...>) {}(t);
};
template <typename T>
concept mcc_hw_enc_lref_c = std::is_lvalue_reference_v<T> && mcc_hw_encoder_c<std::remove_reference_t<T>>;
template <typename T>
concept mcc_hw_motor_lref_c = std::is_lvalue_reference_v<T> && mcc_hw_motor_c<std::remove_reference_t<T>>;
} // namespace details
// } // namespace details
// a very generic mount hardware concept
template <typename T>
concept mcc_mount_hardware_c = requires(T t, const T t_const) {
requires mcc_error_c<typename T::error_t>;
typename T::config_t;
typename T::time_point_t;
typename T::coord_t;
{ t_const.id() } -> mcc_formattable;
// access to encoders
{ t_const.encoders() } -> details::mcc_tuple_enc_cref_c;
{ t.encoders() } -> details::mcc_tuple_enc_ref_c;
// hardware configuration
{ t.setConfig(std::declval<typename T::config_t>()) } -> std::same_as<typename T::error_t>;
{ t.getConfig(std::declval<typename T::config_t&>()) } -> std::same_as<typename T::error_t>;
{ t.encoderPosX() } -> details::mcc_hw_enc_lref_c;
{ t.encoderPosY() } -> details::mcc_hw_enc_lref_c;
// at least contains time of measurement and coordinates for x,y axes
requires requires(typename T::axes_pos_t pos) {
requires std::same_as<decltype(pos.time_point), typename T::time_point_t>;
requires std::same_as<decltype(pos.x), typename T::coord_t>;
requires std::same_as<decltype(pos.y), typename T::coord_t>;
};
// access to motors
{ t.motors() } -> details::mcc_tuple_motor_ref_c;
{ t.setPos(std::declval<typename T::axes_pos_t>()) } -> std::same_as<typename T::error_t>;
{ t.getPos(std::declval<typename T::axes_pos_t&>()) } -> std::same_as<typename T::error_t>;
{ t.motorX() } -> details::mcc_hw_motor_lref_c;
{ t.motorY() } -> details::mcc_hw_motor_lref_c;
// // access to encoders
// { t.encoderPosX() } -> details::mcc_hw_enc_lvref_c;
// { t.encoderPosY() } -> details::mcc_hw_enc_lvref_c;
// // access to motors
// { t.motorX() } -> details::mcc_hw_motor_lvref_c;
// { t.motorY() } -> details::mcc_hw_motor_lvref_c;
};
@ -245,5 +281,4 @@ concept mcc_mount_config_c = requires(T t) {
{ t.pec() } -> mcc_mount_pec_c;
{ t.hardware() } -> mcc_mount_hardware_c;
};
} // namespace mcc::traits

View File

@ -9,27 +9,28 @@
#include <mutex>
#include "fitpack/fitpack.h"
#include "mcc_mount_concepts.h"
#include "mcc_mount_coord.h"
namespace mcc
{
namespace traits
{
// namespace traits
// {
template <typename T, typename XT, typename YT>
concept mcc_mount_pec_c = requires(T t, const T t_const, XT x, YT y) {
typename T::pec_data_t;
typename T::pec_result_t;
// template <typename T, typename XT, typename YT>
// concept mcc_mount_pec_c = requires(T t, const T t_const, XT x, YT y) {
// typename T::pec_data_t;
// typename T::pec_result_t;
{ t.setData(std::declval<typename T::pec_data_t>()) };
{ t_const.getData() } -> std::same_as<typename T::pec_data_t>;
// { t.setData(std::declval<typename T::pec_data_t>()) };
// { t_const.getData() } -> std::same_as<typename T::pec_data_t>;
{ t.compute(std::declval<const XT&>(), std::declval<const YT&>()) } -> std::same_as<typename T::pec_result_t>;
};
// { t.compute(std::declval<const XT&>(), std::declval<const YT&>()) } -> std::same_as<typename T::pec_result_t>;
// };
} // namespace traits
// } // namespace traits
// type of PEC corrections (algorithm used):
// PEC_TYPE_GEOMETRY - "classic" geometry-based correction coefficients
@ -37,9 +38,14 @@ concept mcc_mount_pec_c = requires(T t, const T t_const, XT x, YT y) {
// PEC_TYPE_BSPLINE - pure 2D B-spline corrections
enum class MccMountDefaultPECType { PEC_TYPE_GEOMETRY, PEC_TYPE_GEOMETRY_BSPLINE, PEC_TYPE_BSPLINE };
template <MccMountType MOUNT_TYPE>
class MccMountDefaultPEC
{
public:
static constexpr MccMountType mountType = MOUNT_TYPE;
typedef MccAngle coord_t;
struct pec_result_t {
MccAngle dx, dy;
};
@ -128,16 +134,13 @@ public:
}
// X and Y axis encoder coordinates
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
pec_result_t compute(const XT& x, const YT& y)
pec_result_t compute(const coord_t& x, const coord_t& y)
{
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
pec_result_t res{0.0, 0.0};
std::lock_guard lock(_pecDataMutex);
if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
if constexpr (mcc_is_equatorial_mount<MOUNT_TYPE>) { // equatorial
if (_pecData.type == MccMountDefaultPECType::PEC_TYPE_GEOMETRY) {
const auto cosPhi = std::cos(_phi);
const auto sinPhi = std::sin(_phi);
@ -190,7 +193,7 @@ public:
res.dx += spl_valX;
res.dy += spl_valY;
}
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
} else if constexpr (mcc_is_altaz_mount<MOUNT_TYPE>) {
} else {
static_assert(false, "UNSUPPORTED");
}
@ -199,22 +202,6 @@ public:
}
// X and Y apparent equatorial/altazimuthal coordinates (not corrected for refraction)
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
pec_result_t computeInverse(const XT& x, const YT& y)
{
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
pec_result_t res{0.0, 0.0};
if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
} else {
static_assert(false, "UNSUPPORTED");
}
return res;
}
private:
pec_data_t _pecData;

View File

@ -5,7 +5,7 @@
/* MOUNT TELEMETRY OBJECT CONCEPT AND POSSIBLE IMPLEMENTATION */
#include <chrono>
#include <functional>
#include <mutex>
// #include "mcc_mount_config.h"
@ -32,73 +32,166 @@ namespace mcc
// } // namespace traits
template <traits::mcc_astrom_engine_c ASTROM_ENGINE_T,
traits::mcc_mount_pec_c PEC_T,
traits::mcc_mount_hardware_c HARDWARE_T>
class MccMountTelemetry
{
public:
typedef ASTROM_ENGINE_T astrom_engine_t;
typedef PEC_T pec_t;
typedef HARDWARE_T hardware_t;
enum error_t : int { TEL_ERROR_OK = 0, TEL_ERROR_HARDWARE, TEL_ERROR_ASTROMETRY_COMP };
// check for coordinate types consistency
static_assert(std::convertible_to<typename hardware_t::coord_t, typename astrom_engine_t::coord_t>,
"HARDWARE COORDINATE TYPE MUST BE CONVERTIBLE TO ASTROMETRY ENGINE ONE!");
static_assert(std::convertible_to<typename astrom_engine_t::coord_t, typename pec_t::coord_t>,
"ASTROMETRY ENGINE COORDINATE TYPE MUST BE CONVERTIBLE TO PEC ONE!");
static_assert(std::same_as<typename astrom_engine_t::time_point_t, typename hardware_t::time_point_t>,
"TIME-POINT TYPE IN ASTROMETRY ENGINE AND HARDWARE MUST BE THE SAME!");
// mount current telemetry data: time, position and related quantities
struct mount_telemetry_data_t {
typedef double mnt_coord_t;
typedef double mnt_speed_t;
typedef double time_point_t;
typedef std::vector<double> refr_coeff_t;
typedef astrom_engine_t::coord_t mnt_coord_t;
// typedef astrom_engine_t::coord_t mnt_speed_t;
// time-related
std::chrono::system_clock::time_point utc;
time_point_t mjd; // modified Julian date
time_point_t ut1;
time_point_t tt;
time_point_t siderTime; // sideral time (in radians)
typename astrom_engine_t::time_point_t utc; // time point of measurements, UTC
typename astrom_engine_t::juldate_t jd; // Julian date
typename astrom_engine_t::sideral_time_t siderTime; // local apperant sideral time
// astrom_engine_t::time_point_t ut1; // Universal time
// astrom_engine_t::time_point_t tt; // Terrestial time
// apparent target (user-input) current coordinates (in radians)
mnt_coord_t tagRA, tagDEC;
mnt_coord_t tagHA;
mnt_coord_t tagAZ, tagZD;
mnt_coord_t tagAZ, tagALT;
mnt_coord_t tagPA; // paralactic angle
// encoder-measured current mount coordinates (in radians)
mnt_coord_t mntRA, mntDEC;
mnt_coord_t mntHA;
mnt_coord_t mntAZ, mntZD;
mnt_coord_t mntPA;
mnt_coord_t mntAZ, mntALT;
typename astrom_engine_t::pa_t mntPA;
// encoder-measured (non-corrected for PCS) current mount position and moving speed (in radians, radians/s)
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one
mnt_coord_t mntPosX, mntPosY;
mnt_speed_t mntSpeedX, mntSpeedY;
// mnt_speed_t mntSpeedX, mntSpeedY;
// current refraction coefficients
refr_coeff_t currRefrCoeffs;
// current refraction correction (for tagZD)
typename pec_t::pec_result_t currRefrCoeffs;
// current refraction correction (for mntALT)
mnt_coord_t currRefr;
// PCS (pointing correction system) corrections
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one
mnt_coord_t pcsX, pcsY;
// PEC (pointing error correction):
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one
mnt_coord_t pecX, pecY;
};
template <MccMountType MOUNT_TYPE>
MccMountTelemetry(MccMountConfig<MOUNT_TYPE>& mount_config)
MccMountTelemetry(astrom_engine_t& astrom_engine, pec_t& pec, hardware_t& hardware)
{
// to be sure that mount_config is captured by reference
const auto config_ptr = &mount_config;
// to be sure that arguments are captured by reference
const auto astrom_engine_ptr = &astrom_engine;
const auto pec_ptr = &pec;
const auto hardware_ptr = &hardware;
_updateImpl = [config_ptr, this]() {
_updateImpl = [astrom_engine_ptr, pec_ptr, hardware_ptr, this]() {
mount_telemetry_data_t current_data;
// computing ...
typename hardware_t::axes_pos_t ax_pos;
auto err = hardware_ptr->getPos(ax_pos);
if (err) {
// logging?!!!
return TEL_ERROR_HARDWARE;
}
_data.utc = ax_pos.time_point;
_data.mntPosX = ax_pos.x;
_data.mntPosY = ax_pos.y;
// compute Julian date
auto ast_err = astrom_engine_ptr->greg2jul(_data.utc, _data.jd);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
// compute local apparent sideral time
ast_err = astrom_engine_ptr->apparentSiderTime(_data.jd, _data.siderTime, true);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
// compute equation of origins
typename astrom_engine_t::eo_t eo;
ast_err = astrom_engine_ptr->eqOrigins(_data.jd, eo);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
typename pec_t::pec_result_t pec_res;
pec_res = pec_ptr->compute(ax_pos.x, ax_pos.y);
if constexpr (mccIsEquatorialMount(pec_t::mountType)) {
_data.mntHA = pec_res.x + ax_pos.x;
_data.mntDEC = pec_res.y + ax_pos.y;
ast_err = astrom_engine_ptr->hadec2azalt(_data.mntHA, _data.mntDEC, _data.mntAZ, _data.mntALT);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) {
_data.mntAZ = pec_res.x + ax_pos.x;
_data.mntALT = pec_res.y + ax_pos.x;
ast_err = astrom_engine_ptr->azalt2hadec(_data.mntAZ, _data.mntALT, _data.mntHA, _data.mntDEC);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
} else {
static_assert(false, "UNSUPPORTED MOUNT TYPE!");
}
// compute CIO-based apparent RA
_data.mntRA = _data.siderTime - _data.mntHA + eo;
// compute PA
ast_err = astrom_engine_ptr->hadec2pa(_data.mntHA, _data.mntDEC, _data.mntPA);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
ast_err = astrom_engine_ptr->refraction(_data.currRefrCoeffs);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
ast_err = astrom_engine_ptr->refractCorrection(_data.mntALT, _data.currRefrCoeffs, _data.currRefr);
if (ast_err) {
return TEL_ERROR_ASTROMETRY_COMP;
}
std::lock_guard lock{_updateMutex};
_data = current_data;
_data = std::move(current_data);
};
}
virtual ~MccMountTelemetry() = default;
// update current data method
void update()
error_t update()
{
_updateImpl();
}
@ -116,7 +209,7 @@ public:
protected:
mount_telemetry_data_t _data{};
std::function<void()> _updateImpl{};
std::function<error_t()> _updateImpl{};
std::mutex _updateMutex;
};

View File

@ -160,9 +160,12 @@ concept mcc_tuple_c = requires {
template <typename T>
concept mcc_nonconst_ref = std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>;
concept mcc_nonconst_lvref = std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>;
template <typename T>
concept mcc_error_c = std::convertible_to<T, bool> && mcc_formattable<T>;
namespace details
{

View File

@ -163,9 +163,9 @@ int main(int argc, char* argv[])
erfa.greg2jul(now, jd);
std::cout << "MJD(" << now << ") = " << jd.mjd << "\n";
mcc::MccAngle gst;
erfa.apparentSiderTime(jd, gst, true);
std::cout << "GST(MJD = " << jd.mjd << ") = " << gst.sexagesimal(true) << "\n\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;
@ -173,13 +173,21 @@ int main(int argc, char* argv[])
auto res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1);
mcc::MccAngle eor;
std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\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 = " << eor.sexagesimal(true) << "\n";
std::cout << "RA_app_comp = " << (lst - ha1 + eor).sexagesimal(true) << "\n";
return ecode;
}