...
This commit is contained in:
parent
9cd52267d6
commit
6d65efd0af
@ -10,40 +10,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "mcc_astrom_iers.h"
|
#include "mcc_astrom_iers.h"
|
||||||
|
#include "mcc_mount_concepts.h"
|
||||||
#include "mcc_mount_coord.h"
|
#include "mcc_mount_coord.h"
|
||||||
|
|
||||||
// #include "mcc_mount_astrom.h"
|
|
||||||
#include "mcc_mount_concepts.h"
|
|
||||||
|
|
||||||
namespace mcc::astrom::erfa
|
namespace mcc::astrom::erfa
|
||||||
{
|
{
|
||||||
|
enum class MccMountAstromEngineERFAErrorCode : int {
|
||||||
#include <erfa.h>
|
|
||||||
#include <erfam.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
static constexpr std::array engineErrorString = {"OK",
|
|
||||||
"invalid argument",
|
|
||||||
"invalid year",
|
|
||||||
"invalid month",
|
|
||||||
"time point is out of range",
|
|
||||||
"time point is out of range",
|
|
||||||
"dubious year",
|
|
||||||
"unacceptable year",
|
|
||||||
"leap seconds update error",
|
|
||||||
"bulletin A update error"};
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr double DEFAULT_WAVELENGTH = 0.55; // default observed wavelength in mkm
|
|
||||||
enum error_t : size_t {
|
|
||||||
ERROR_OK = 0,
|
ERROR_OK = 0,
|
||||||
ERROR_INVALID_INPUT_ARG,
|
ERROR_INVALID_INPUT_ARG,
|
||||||
ERROR_JULDATE_INVALID_YEAR,
|
ERROR_JULDATE_INVALID_YEAR,
|
||||||
@ -56,6 +29,96 @@ public:
|
|||||||
ERROR_UPDATE_BULLETINA,
|
ERROR_UPDATE_BULLETINA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class is_error_code_enum<mcc::astrom::erfa::MccMountAstromEngineERFAErrorCode> : public true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace mcc::astrom::erfa
|
||||||
|
{
|
||||||
|
|
||||||
|
#include <erfa.h>
|
||||||
|
#include <erfam.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* error category definition */
|
||||||
|
|
||||||
|
// error category
|
||||||
|
struct MccMountAstromEngineERFACategory : public std::error_category {
|
||||||
|
MccMountAstromEngineERFACategory() : std::error_category() {}
|
||||||
|
|
||||||
|
const char* name() const noexcept
|
||||||
|
{
|
||||||
|
return "ADC_GENERIC_DEVICE";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string message(int ec) const
|
||||||
|
{
|
||||||
|
MccMountAstromEngineERFAErrorCode err = static_cast<MccMountAstromEngineERFAErrorCode>(ec);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_OK:
|
||||||
|
return "OK";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_INVALID_INPUT_ARG:
|
||||||
|
return "invalid argument";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_YEAR:
|
||||||
|
return "invalid year number";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_MONTH:
|
||||||
|
return "invalid month number";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE:
|
||||||
|
return "time point is out of range";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE:
|
||||||
|
return "time point is out of range";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_DUBIOUS_YEAR:
|
||||||
|
return "dubious year";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_UNACCEPTABLE_DATE:
|
||||||
|
return "unacceptable date";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS:
|
||||||
|
return "leap seconds update error";
|
||||||
|
case MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA:
|
||||||
|
return "bulletin A update error";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MccMountAstromEngineERFACategory& get()
|
||||||
|
{
|
||||||
|
static const MccMountAstromEngineERFACategory constInst;
|
||||||
|
return constInst;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::error_code make_error_code(MccMountAstromEngineERFAErrorCode ec)
|
||||||
|
{
|
||||||
|
return std::error_code(static_cast<int>(ec), MccMountAstromEngineERFACategory::get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
static constexpr double DEFAULT_WAVELENGTH = 0.55; // default observed wavelength in mkm
|
||||||
|
|
||||||
|
typedef std::error_code error_t;
|
||||||
|
|
||||||
|
|
||||||
// meteo parameters (to compute refraction)
|
// meteo parameters (to compute refraction)
|
||||||
struct meteo_t {
|
struct meteo_t {
|
||||||
@ -140,10 +203,10 @@ public:
|
|||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{_stateMutex};
|
||||||
|
|
||||||
if (!_currentState._leapSeconds.load(stream, comment_sym)) {
|
if (!_currentState._leapSeconds.load(stream, comment_sym)) {
|
||||||
return ERROR_UPDATE_LEAPSECONDS;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -152,10 +215,10 @@ public:
|
|||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{_stateMutex};
|
||||||
|
|
||||||
if (!_currentState._leapSeconds.load(filename, comment_sym)) {
|
if (!_currentState._leapSeconds.load(filename, comment_sym)) {
|
||||||
return ERROR_UPDATE_LEAPSECONDS;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -164,10 +227,10 @@ public:
|
|||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{_stateMutex};
|
||||||
|
|
||||||
if (!_currentState._bulletinA.load(stream, comment_sym)) {
|
if (!_currentState._bulletinA.load(stream, comment_sym)) {
|
||||||
return ERROR_UPDATE_BULLETINA;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,19 +239,13 @@ public:
|
|||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{_stateMutex};
|
||||||
|
|
||||||
if (!_currentState._bulletinA.load(filename, comment_sym)) {
|
if (!_currentState._bulletinA.load(filename, comment_sym)) {
|
||||||
return ERROR_UPDATE_BULLETINA;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string errorString(error_t err) const
|
|
||||||
{
|
|
||||||
return engineErrorString[err];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* time-related methods */
|
/* time-related methods */
|
||||||
|
|
||||||
// templated generic version
|
// templated generic version
|
||||||
@ -203,10 +260,10 @@ public:
|
|||||||
static constexpr std::chrono::year MIN_YEAR = -4799y;
|
static constexpr std::chrono::year MIN_YEAR = -4799y;
|
||||||
|
|
||||||
if (ymd.year() < MIN_YEAR) {
|
if (ymd.year() < MIN_YEAR) {
|
||||||
return ERROR_JULDATE_INVALID_YEAR;
|
return MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_YEAR;
|
||||||
}
|
}
|
||||||
if (!ymd.month().ok()) {
|
if (!ymd.month().ok()) {
|
||||||
return ERROR_JULDATE_INVALID_MONTH;
|
return MccMountAstromEngineERFAErrorCode::ERROR_JULDATE_INVALID_MONTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t im = (unsigned)ymd.month();
|
int64_t im = (unsigned)ymd.month();
|
||||||
@ -223,7 +280,7 @@ public:
|
|||||||
using fd_t = std::chrono::duration<double, std::ratio<86400>>; // fraction of day
|
using fd_t = std::chrono::duration<double, std::ratio<86400>>; // fraction of day
|
||||||
juldate.mjd = static_cast<double>(mjd_int) + std::chrono::duration_cast<fd_t>(time_point - dd).count();
|
juldate.mjd = static_cast<double>(mjd_int) + std::chrono::duration_cast<fd_t>(time_point - dd).count();
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t greg2jul(time_point_t time_point, juldate_t& juldate)
|
error_t greg2jul(time_point_t time_point, juldate_t& juldate)
|
||||||
@ -242,14 +299,14 @@ public:
|
|||||||
if (tai_utc.has_value()) {
|
if (tai_utc.has_value()) {
|
||||||
tt.mjd += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
|
tt.mjd += std::chrono::duration_cast<real_days_t>(tai_utc.value()).count();
|
||||||
} else {
|
} else {
|
||||||
return ERROR_LEAPSECONDS_OUT_OF_RANGE;
|
return MccMountAstromEngineERFAErrorCode::ERROR_LEAPSECONDS_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto tt_tai = _currentState._bulletinA.TT_TAI();
|
auto tt_tai = _currentState._bulletinA.TT_TAI();
|
||||||
tt.mjd = juldate.mjd + std::chrono::duration_cast<real_days_t>(tt_tai).count();
|
tt.mjd = juldate.mjd + std::chrono::duration_cast<real_days_t>(tt_tai).count();
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -270,7 +327,7 @@ public:
|
|||||||
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();
|
||||||
} else { // out of range
|
} else { // out of range
|
||||||
return ERROR_BULLETINA_OUT_OF_RANGE;
|
return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +345,7 @@ public:
|
|||||||
|
|
||||||
juldate_t tt;
|
juldate_t tt;
|
||||||
auto err = terrestrialTime(juldate, tt);
|
auto err = terrestrialTime(juldate, tt);
|
||||||
if (err != ERROR_OK) {
|
if (err != MccMountAstromEngineERFAErrorCode::ERROR_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +354,7 @@ public:
|
|||||||
gst += _currentState.lon;
|
gst += _currentState.lon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -306,13 +363,13 @@ public:
|
|||||||
juldate_t tt;
|
juldate_t tt;
|
||||||
|
|
||||||
auto err = terrestrialTime(juldate, tt);
|
auto err = terrestrialTime(juldate, tt);
|
||||||
if (err != ERROR_OK) {
|
if (err != MccMountAstromEngineERFAErrorCode::ERROR_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
eo = eraEo06a(tt.MJD0, tt.mjd);
|
eo = eraEo06a(tt.MJD0, tt.mjd);
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* atmospheric refraction-related methods */
|
/* atmospheric refraction-related methods */
|
||||||
@ -324,7 +381,7 @@ public:
|
|||||||
eraRefco(_currentState.meteo.pressure, _currentState.meteo.temperature, _currentState.meteo.humidity,
|
eraRefco(_currentState.meteo.pressure, _currentState.meteo.temperature, _currentState.meteo.humidity,
|
||||||
_currentState.wavelength, &refr.refa, &refr.refb);
|
_currentState.wavelength, &refr.refa, &refr.refb);
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -337,7 +394,7 @@ public:
|
|||||||
corr = ref_params.refa / tanALT + ref_params.refb / tanALT / tanALT / tanALT;
|
corr = ref_params.refa / tanALT + ref_params.refb / tanALT / tanALT / tanALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* coordinates conversional methods */
|
/* coordinates conversional methods */
|
||||||
@ -357,12 +414,12 @@ public:
|
|||||||
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
||||||
|
|
||||||
if (!dut1.has_value()) {
|
if (!dut1.has_value()) {
|
||||||
return ERROR_BULLETINA_OUT_OF_RANGE;
|
return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pol_pos = _currentState._bulletinA.polarCoords(juldate.mjd);
|
auto pol_pos = _currentState._bulletinA.polarCoords(juldate.mjd);
|
||||||
if (!pol_pos.has_value()) {
|
if (!pol_pos.has_value()) {
|
||||||
return ERROR_BULLETINA_OUT_OF_RANGE;
|
return MccMountAstromEngineERFAErrorCode::ERROR_BULLETINA_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
const auto arcsec2rad = std::numbers::pi / 180 / 3600;
|
const auto arcsec2rad = std::numbers::pi / 180 / 3600;
|
||||||
pol_pos->x *= arcsec2rad;
|
pol_pos->x *= arcsec2rad;
|
||||||
@ -376,9 +433,9 @@ public:
|
|||||||
&oaz, &ozd, &oha, &odec, &ora, &eo_);
|
&oaz, &ozd, &oha, &odec, &ora, &eo_);
|
||||||
|
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
return ERROR_DUBIOUS_YEAR;
|
return MccMountAstromEngineERFAErrorCode::ERROR_DUBIOUS_YEAR;
|
||||||
} else if (ret == -1) {
|
} else if (ret == -1) {
|
||||||
return ERROR_UNACCEPTABLE_DATE;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UNACCEPTABLE_DATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ra_app = ora;
|
ra_app = ora;
|
||||||
@ -388,7 +445,7 @@ public:
|
|||||||
ha = oha;
|
ha = oha;
|
||||||
eo = eo_;
|
eo = eo_;
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -402,7 +459,7 @@ public:
|
|||||||
az = r_az;
|
az = r_az;
|
||||||
alt = r_alt;
|
alt = r_alt;
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t azalt2hadec(coord_t az, coord_t alt, coord_t& ha, coord_t& dec)
|
error_t azalt2hadec(coord_t az, coord_t alt, coord_t& ha, coord_t& dec)
|
||||||
@ -416,7 +473,7 @@ public:
|
|||||||
ha = r_ha;
|
ha = r_ha;
|
||||||
dec = r_dec;
|
dec = r_dec;
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -426,7 +483,7 @@ public:
|
|||||||
|
|
||||||
pa = eraHd2pa(ha, dec, _currentState.lat);
|
pa = eraHd2pa(ha, dec, _currentState.lat);
|
||||||
|
|
||||||
return ERROR_OK;
|
return MccMountAstromEngineERFAErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -97,12 +97,6 @@ concept mcc_astrom_engine_c = requires(T t, const T t_const) {
|
|||||||
typename T::refract_result_t;
|
typename T::refract_result_t;
|
||||||
|
|
||||||
|
|
||||||
// { t.setState(std::declval<typename T::engine_state_t>()) };
|
|
||||||
|
|
||||||
// { t_const.getState() } -> std::same_as<typename T::engine_state_t>;
|
|
||||||
|
|
||||||
{ t_const.errorString(std::declval<typename T::error_t>()) } -> mcc_formattable;
|
|
||||||
|
|
||||||
/* coordinates conversional methods */
|
/* coordinates conversional methods */
|
||||||
|
|
||||||
// ICRS RA and DEC to observed place: icrs2obs(ra, dec, jd, ra_app, dec_app, ha, az, alt, eo)
|
// ICRS RA and DEC to observed place: icrs2obs(ra, dec, jd, ra_app, dec_app, ha, az, alt, eo)
|
||||||
@ -249,7 +243,7 @@ concept mcc_mount_telemetry_data_c = requires(T telemetry) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_mount_telemetry_c = requires(T t, const T t_const) {
|
concept mcc_mount_telemetry_c = requires(T t, const T t_const) {
|
||||||
typename T::error_t;
|
requires mcc_error_c<typename T::error_t>;
|
||||||
|
|
||||||
// // a class that at least contains celestial (equatorial and horizontal) coordinates
|
// // a class that at least contains celestial (equatorial and horizontal) coordinates
|
||||||
// requires requires(typename T::mount_telemetry_data_t telemetry) {
|
// requires requires(typename T::mount_telemetry_data_t telemetry) {
|
||||||
|
|||||||
@ -12,6 +12,65 @@
|
|||||||
#include "mcc_mount_concepts.h"
|
#include "mcc_mount_concepts.h"
|
||||||
#include "mcc_mount_coord.h"
|
#include "mcc_mount_coord.h"
|
||||||
|
|
||||||
|
namespace mcc
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class MccMountDefaultPECErrorCode : int { ERROR_OK, ERROR_INVALID_INPUTS_BISPLEV, ERROR_EXCEED_MAX_ITERS };
|
||||||
|
|
||||||
|
/* error category definition */
|
||||||
|
|
||||||
|
// error category
|
||||||
|
struct MccMountDefaultPECCategory : public std::error_category {
|
||||||
|
MccMountDefaultPECCategory() : std::error_category() {}
|
||||||
|
|
||||||
|
const char* name() const noexcept
|
||||||
|
{
|
||||||
|
return "ADC_GENERIC_DEVICE";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string message(int ec) const
|
||||||
|
{
|
||||||
|
MccMountDefaultPECErrorCode err = static_cast<MccMountDefaultPECErrorCode>(ec);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case MccMountDefaultPECErrorCode::ERROR_OK:
|
||||||
|
return "OK";
|
||||||
|
case MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV:
|
||||||
|
return "invalid input arguments for bispev";
|
||||||
|
case MccMountDefaultPECErrorCode::ERROR_EXCEED_MAX_ITERS:
|
||||||
|
return "exceed maximum of iterations number";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MccMountDefaultPECCategory& get()
|
||||||
|
{
|
||||||
|
static const MccMountDefaultPECCategory constInst;
|
||||||
|
return constInst;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::error_code make_error_code(MccMountDefaultPECErrorCode ec)
|
||||||
|
{
|
||||||
|
return std::error_code(static_cast<int>(ec), MccMountDefaultPECCategory::get());
|
||||||
|
}
|
||||||
|
} // namespace mcc
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class is_error_code_enum<mcc::MccMountDefaultPECErrorCode> : public true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace mcc
|
namespace mcc
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -165,7 +224,7 @@ public:
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
res.dx = std::numeric_limits<double>::quiet_NaN();
|
res.dx = std::numeric_limits<double>::quiet_NaN();
|
||||||
res.dy = std::numeric_limits<double>::quiet_NaN();
|
res.dy = std::numeric_limits<double>::quiet_NaN();
|
||||||
return std::error_code(); // !!!!!!!!!!!!!!
|
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -175,7 +234,7 @@ public:
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
res.dx = std::numeric_limits<double>::quiet_NaN();
|
res.dx = std::numeric_limits<double>::quiet_NaN();
|
||||||
res.dy = std::numeric_limits<double>::quiet_NaN();
|
res.dy = std::numeric_limits<double>::quiet_NaN();
|
||||||
return std::error_code(); // !!!!!!!!!!!!!!
|
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -187,7 +246,7 @@ public:
|
|||||||
static_assert(false, "UNSUPPORTED");
|
static_assert(false, "UNSUPPORTED");
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::error_code();
|
return MccMountDefaultPECErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from celestial to encoder (use of iterative scheme)
|
// from celestial to encoder (use of iterative scheme)
|
||||||
@ -196,35 +255,59 @@ public:
|
|||||||
coord_t e2 = eps * eps;
|
coord_t e2 = eps * eps;
|
||||||
|
|
||||||
coord_t xi = x, yi = y;
|
coord_t xi = x, yi = y;
|
||||||
coord_t xp, yp;
|
coord_t xe, ye;
|
||||||
size_t iter = 1;
|
size_t iter = 1;
|
||||||
|
|
||||||
// the first iteration
|
// the first iteration
|
||||||
auto err = compute(x, y, res);
|
auto err = compute(x, y, res);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
xp = x - res.dx;
|
// 'encoder' cocordinates
|
||||||
yp = y - res.dy;
|
xe = x - res.dx;
|
||||||
|
ye = y - res.dy;
|
||||||
|
|
||||||
bool ok = ((xp - x) * (xp - x) + (yp - y) * (yp - y)) <= e2;
|
err = compute(xe, ye, res); // to celestial
|
||||||
|
if (err) {
|
||||||
|
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
xi = xe + res.dx; // celestial
|
||||||
|
yi = ye + res.dy;
|
||||||
|
|
||||||
|
auto rx = (x - xi);
|
||||||
|
auto ry = (y - yi);
|
||||||
|
auto d = rx * rx + ry * ry;
|
||||||
|
|
||||||
|
bool ok = d <= e2;
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return std::error_code();
|
return MccMountDefaultPECErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (iter < max_iter) {
|
while (iter < max_iter) {
|
||||||
xi = xp;
|
err = compute(xi, yi, res); // to encoder
|
||||||
yi = xp;
|
if (err) {
|
||||||
err = compute(xi, yi, res);
|
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
||||||
xp -= res.dx;
|
}
|
||||||
yp -= res.dy;
|
xe = x - res.dx;
|
||||||
|
ye = y - res.dy;
|
||||||
|
|
||||||
ok = ((xp - xi) * (xp - xi) + (yp - yi) * (yp - yi)) <= e2;
|
err = compute(xe, ye, res); // to celestial
|
||||||
|
if (err) {
|
||||||
|
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
xi = xe + res.dx; // celestial
|
||||||
|
yi = ye + res.dy;
|
||||||
|
|
||||||
|
ok = ((x - xi) * (x - xi) + (y - yi) * (y - yi)) <= e2;
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return std::error_code();
|
return MccMountDefaultPECErrorCode::ERROR_OK;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// err = "exceed max iterations";!!!
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = MccMountDefaultPECErrorCode::ERROR_EXCEED_MAX_ITERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@ -139,42 +139,6 @@ public:
|
|||||||
|
|
||||||
typedef DATA_T mount_telemetry_data_t;
|
typedef DATA_T mount_telemetry_data_t;
|
||||||
|
|
||||||
// mount current telemetry data: time, position and related quantities
|
|
||||||
// struct mount_telemetry_data_t {
|
|
||||||
// typedef typename astrom_engine_t::coord_t coord_t;
|
|
||||||
|
|
||||||
// // time-related
|
|
||||||
// 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
|
|
||||||
// // typename astrom_engine_t::time_point_t ut1; // Universal time
|
|
||||||
// // typename astrom_engine_t::time_point_t tt; // Terrestial time
|
|
||||||
|
|
||||||
// // apparent target (user-input) current coordinates (in radians)
|
|
||||||
// coord_t tagRA, tagDEC;
|
|
||||||
// coord_t tagHA;
|
|
||||||
// coord_t tagAZ, tagALT;
|
|
||||||
// coord_t tagPA; // paralactic angle
|
|
||||||
|
|
||||||
// // encoder-measured current mount coordinates (in radians)
|
|
||||||
// coord_t mntRA, mntDEC;
|
|
||||||
// coord_t mntHA;
|
|
||||||
// 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 - ALT for horizontal-type one
|
|
||||||
// coord_t mntPosX, mntPosY;
|
|
||||||
|
|
||||||
// // current refraction coefficients
|
|
||||||
// typename pec_t::pec_result_t currRefrCoeffs;
|
|
||||||
// // current refraction correction (for mntALT)
|
|
||||||
// coord_t currRefr;
|
|
||||||
|
|
||||||
// // PEC (pointing error correction):
|
|
||||||
// // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one
|
|
||||||
// coord_t pecX, pecY;
|
|
||||||
// };
|
|
||||||
|
|
||||||
MccMountTelemetry(astrom_engine_t& astrom_engine, pec_t& pec, hardware_t& hardware)
|
MccMountTelemetry(astrom_engine_t& astrom_engine, pec_t& pec, hardware_t& hardware)
|
||||||
: _astromEngine(astrom_engine), _pec(pec), _hardware(hardware)
|
: _astromEngine(astrom_engine), _pec(pec), _hardware(hardware)
|
||||||
|
|||||||
@ -19,7 +19,6 @@ namespace mcc
|
|||||||
* [azimuth, zenithal distance] (see sources code below)
|
* [azimuth, zenithal distance] (see sources code below)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <traits::mcc_mount_telemetry_c TELEMETRY_T>
|
|
||||||
class MccSimpleSlewModel
|
class MccSimpleSlewModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -37,26 +36,47 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <traits::mcc_mount_hardware_c HARDWARE_T,
|
template <traits::mcc_mount_controls_c MOUNT_CONTROLS_T>
|
||||||
traits::mcc_astrom_engine_c ASTROM_T,
|
MccSimpleSlewModel(MOUNT_CONTROLS_T& mount_controls)
|
||||||
traits::mcc_mount_pec_c PEC_T>
|
|
||||||
MccSimpleSlewModel(HARDWARE_T& hardware, ASTROM_T& astrom_engine, PEC_T& pec)
|
|
||||||
{
|
{
|
||||||
const auto p_hardware = &hardware;
|
// deduce controls types
|
||||||
const auto p_astrom_engine = &astrom_engine;
|
using astrom_engine_t = decltype(mount_controls.astrometryEngine);
|
||||||
const auto p_pec = &pec;
|
using hardware_t = decltype(mount_controls.hardware);
|
||||||
|
using pec_t = decltype(mount_controls.PEC);
|
||||||
|
using telemetry_t = decltype(mount_controls.telemetry);
|
||||||
|
using tpl_pz_t = decltype(mount_controls.prohibitedZones);
|
||||||
|
|
||||||
|
static constexpr size_t Nzones = std::tuple_size_v<tpl_pz_t>;
|
||||||
|
|
||||||
|
const auto p_mount_controls = &mount_controls;
|
||||||
|
|
||||||
|
// prohibited zones related lambdas
|
||||||
|
auto check_zones = [p_mount_controls]<size_t... Is>(std::array<bool, sizeof...(Is)>& result,
|
||||||
|
std::index_sequence<Is...>) {
|
||||||
|
((result[Is] = std::get<Is>(p_mount_controls->prohibitedZones).inZone(p_mount_controls->telemetry.data())),
|
||||||
|
...);
|
||||||
|
|
||||||
|
bool flag = false;
|
||||||
|
((flag |= result[Is]), ...);
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_slewFunc = [p_mount_controls](this auto&& self, const slew_params_t& slew_pars) {
|
||||||
|
auto& astrom_engine = p_mount_controls->astrometryEngine;
|
||||||
|
auto& hardware = p_mount_controls->hardware;
|
||||||
|
auto& pec = p_mount_controls->PEC;
|
||||||
|
auto& telemetry = p_mount_controls->telemetry;
|
||||||
|
|
||||||
_slewFunc = [p_hardware, p_astrom_engine, p_pec](this auto&& self, const slew_params_t& slew_pars,
|
using coord_t = typename astrom_engine_t::coord_t;
|
||||||
TELEMETRY_T& telemetry) {
|
using jd_t = typename astrom_engine_t::juldate_t;
|
||||||
using coord_t = typename ASTROM_T::coord_t;
|
|
||||||
using jd_t = typename ASTROM_T::juldate_t;
|
|
||||||
|
|
||||||
typename HARDWARE_T::axes_pos_t ax_pos;
|
typename hardware_t::axes_pos_t ax_pos;
|
||||||
|
|
||||||
error_t res_err;
|
error_t res_err;
|
||||||
typename ASTROM_T::error_t ast_err;
|
typename astrom_engine_t::error_t ast_err;
|
||||||
|
typename pec_t::error_t pec_err;
|
||||||
|
|
||||||
if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_XY) {
|
if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_XY) {
|
||||||
// trivial case (the pair is interpretated as raw encoder coordinates)
|
// trivial case (the pair is interpretated as raw encoder coordinates)
|
||||||
@ -66,26 +86,24 @@ public:
|
|||||||
mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // catalog coordinates
|
mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // catalog coordinates
|
||||||
jd_t jd;
|
jd_t jd;
|
||||||
coord_t ra_app, dec_app, ha, az, alt;
|
coord_t ra_app, dec_app, ha, az, alt;
|
||||||
typename ASTROM_T::eo_t eo;
|
typename astrom_engine_t::eo_t eo;
|
||||||
|
|
||||||
ast_err = p_astrom_engine->greg2jul(std::chrono::system_clock::now(), jd);
|
ast_err = astrom_engine->greg2jul(std::chrono::system_clock::now(), jd);
|
||||||
|
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
ast_err = p_astrom_engine->icrs2obs(slew_pars.x, slew_pars.y, jd, ra_app, dec_app, ha, az, alt, eo);
|
ast_err = astrom_engine->icrs2obs(slew_pars.x, slew_pars.y, jd, ra_app, dec_app, ha, az, alt, eo);
|
||||||
|
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
if constexpr (mccIsEquatorialMount(PEC_T::mountType)) {
|
if constexpr (mccIsEquatorialMount(pec_t::mountType)) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||||
.x = ha,
|
.x = ha,
|
||||||
.y = dec_app,
|
.y = dec_app,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) {
|
||||||
} else if constexpr (mccIsAltAzMount(PEC_T::mountType)) {
|
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||||
.x = az,
|
.x = az,
|
||||||
.y = alt,
|
.y = alt,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
} else {
|
} else {
|
||||||
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
||||||
}
|
}
|
||||||
@ -94,78 +112,73 @@ public:
|
|||||||
|
|
||||||
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP) { // apparent
|
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_RADEC_APP) { // apparent
|
||||||
jd_t jd;
|
jd_t jd;
|
||||||
typename ASTROM_T::eo_t eo;
|
typename astrom_engine_t::eo_t eo;
|
||||||
|
|
||||||
ast_err = p_astrom_engine->greg2jul(std::chrono::system_clock::now(), jd);
|
ast_err = astrom_engine->greg2jul(std::chrono::system_clock::now(), jd);
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
typename ASTROM_T::sideral_time_t lst;
|
typename astrom_engine_t::sideral_time_t lst;
|
||||||
ast_err = p_astrom_engine->apparentSiderTime(jd, lst, true);
|
ast_err = astrom_engine->apparentSiderTime(jd, lst, true);
|
||||||
|
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
ast_err = p_astrom_engine->eqOrigins(jd, eo);
|
ast_err = astrom_engine->eqOrigins(jd, eo);
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||||
.x = lst - slew_pars.x + eo, // HA = LST - RA_APP + EO
|
.x = lst - slew_pars.x + eo, // HA = LST - RA_APP + EO
|
||||||
.y = slew_pars.y,
|
.y = slew_pars.y,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP) { // apparent
|
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP) { // apparent
|
||||||
if constexpr (mccIsEquatorialMount(PEC_T::mountType)) { // compute encoder coordinates
|
if constexpr (mccIsEquatorialMount(pec_t::mountType)) { // compute encoder coordinates
|
||||||
coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0;
|
coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0;
|
||||||
|
|
||||||
typename PEC_T::pec_result_t pec_res;
|
typename pec_t::pec_result_t pec_res;
|
||||||
|
|
||||||
auto err = p_pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
||||||
if (!err) {
|
if (!pec_err) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
||||||
.x = slew_pars.x - pec_res.dx,
|
.x = slew_pars.x - pec_res.dx,
|
||||||
.y = slew_pars.y - pec_res.dy,
|
.y = slew_pars.y - pec_res.dy,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
} else if constexpr (mccIsAltAzMount(PEC_T::mountType)) {
|
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) {
|
||||||
coord_t az, alt;
|
coord_t az, alt;
|
||||||
|
|
||||||
ast_err = p_astrom_engine->hadec2azalt(slew_pars.x, slew_pars.y, az, alt);
|
ast_err = astrom_engine->hadec2azalt(slew_pars.x, slew_pars.y, az, alt);
|
||||||
|
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||||
.x = az,
|
.x = az,
|
||||||
.y = alt,
|
.y = alt,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
||||||
}
|
}
|
||||||
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_AZALT) {
|
} else if (slew_pars.coordPairKind == mcc::MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||||
if constexpr (mccIsEquatorialMount(PEC_T::mountType)) {
|
if constexpr (mccIsEquatorialMount(pec_t::mountType)) {
|
||||||
coord_t ha, dec;
|
coord_t ha, dec;
|
||||||
|
|
||||||
ast_err = p_astrom_engine->azalt2hadec(slew_pars.x, slew_pars.y, ha, dec);
|
ast_err = astrom_engine->azalt2hadec(slew_pars.x, slew_pars.y, ha, dec);
|
||||||
|
|
||||||
if (!ast_err) {
|
if (!ast_err) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||||
.x = ha,
|
.x = ha,
|
||||||
.y = dec,
|
.y = dec,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
} else if constexpr (mccIsAltAzMount(PEC_T::mountType)) { // compute encoder coordinates
|
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) { // compute encoder coordinates
|
||||||
coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0;
|
coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0;
|
||||||
|
|
||||||
typename PEC_T::pec_result_t pec_res;
|
typename pec_t::pec_result_t pec_res;
|
||||||
|
|
||||||
auto err = p_pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
||||||
if (!err) {
|
if (!pec_err) {
|
||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
||||||
.x = slew_pars.x - pec_res.dx,
|
.x = slew_pars.x - pec_res.dx,
|
||||||
.y = slew_pars.y - pec_res.dy,
|
.y = slew_pars.y - pec_res.dy,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -178,32 +191,57 @@ public:
|
|||||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||||
.x = slew_pars.x,
|
.x = slew_pars.x,
|
||||||
.y = std::numbers::pi / 2.0 - slew_pars.y,
|
.y = std::numbers::pi / 2.0 - slew_pars.y,
|
||||||
.stop = slew_pars.stop},
|
.stop = slew_pars.stop});
|
||||||
telemetry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res_err) {
|
if (res_err) {
|
||||||
return res_err;
|
return res_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ast_err) {
|
if (pec_err) {
|
||||||
auto err = p_hardware->setPos(std::move(ax_pos));
|
// ???????????
|
||||||
|
return std::error_code(); // !!!!!!!!!!!!!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ast_err) {
|
||||||
|
typename telemetry_t::error_t t_err;
|
||||||
|
typename telemetry_t::mount_telemetry_data_t t_data;
|
||||||
|
|
||||||
|
// move mount (it is assumed this is asynchronous operation!!!)
|
||||||
|
typename hardware_t::error_t err = hardware->setPos(std::move(ax_pos));
|
||||||
|
|
||||||
|
std::array<bool, Nzones> pz_result;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
//
|
||||||
|
// what is the condition for mount reaches given position?!!
|
||||||
|
//
|
||||||
while (true) {
|
while (true) {
|
||||||
|
t_err = telemetry.data(t_data);
|
||||||
|
if (t_err) {
|
||||||
|
// ?????????!!!!!!!!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
// check prohibited zones
|
||||||
|
if (check_zones(pz_result, std::make_index_sequence<Nzones>{})) {
|
||||||
|
// stop mount ?!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
// return in-zone-error-code
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t slew(const slew_params_t& pars, TELEMETRY_T& telemetry)
|
error_t slew(const slew_params_t& pars)
|
||||||
{
|
{
|
||||||
error_t res_err = _slewFunc(pars, telemetry);
|
error_t res_err = _slewFunc(pars);
|
||||||
|
|
||||||
return res_err;
|
return res_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<error_t(const slew_params_t&, TELEMETRY_T&)> _slewFunc{};
|
std::function<error_t(const slew_params_t&)> _slewFunc{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
struct tel_data_t {
|
struct tel_data_t {
|
||||||
typedef mcc::MccAngle coord_t;
|
typedef mcc::MccAngle coord_t;
|
||||||
|
typedef std::chrono::system_clock::time_point time_point_t;
|
||||||
|
|
||||||
coord_t mntRA, mntDEC, mntHA;
|
coord_t mntRA, mntDEC, mntHA;
|
||||||
coord_t mntAZ, mntALT;
|
coord_t mntAZ, mntALT;
|
||||||
@ -187,7 +188,7 @@ int main(int argc, char* argv[])
|
|||||||
auto res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
|
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 << "eq of origins (from icrs2obs) = " << eor.sexagesimal(true) << "\n";
|
||||||
|
|
||||||
std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\n";
|
std::cout << "ret code (icrs2obs) = " << res.message() << "\n";
|
||||||
std::cout << "alt = " << alt1.sexagesimal() << "\n";
|
std::cout << "alt = " << alt1.sexagesimal() << "\n";
|
||||||
std::cout << "az = " << az1.sexagesimal() << "\n";
|
std::cout << "az = " << az1.sexagesimal() << "\n";
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ int main(int argc, char* argv[])
|
|||||||
ra1 = "17:00:00"_hms;
|
ra1 = "17:00:00"_hms;
|
||||||
dec1 = "40:25:10.43"_dms;
|
dec1 = "40:25:10.43"_dms;
|
||||||
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
|
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
|
||||||
std::cout << "ret code (icrs2obs) = " << erfa.errorString(res) << "\n";
|
std::cout << "ret code (icrs2obs) = " << res.message() << "\n";
|
||||||
std::cout << "alt = " << alt1.sexagesimal() << "\n";
|
std::cout << "alt = " << alt1.sexagesimal() << "\n";
|
||||||
std::cout << "az = " << az1.sexagesimal() << "\n";
|
std::cout << "az = " << az1.sexagesimal() << "\n";
|
||||||
|
|
||||||
@ -265,5 +266,10 @@ int main(int argc, char* argv[])
|
|||||||
std::cout << "(MAXALT) time from zone: " << std::chrono::hh_mm_ss(tm) << " (" << now1 << ")\n";
|
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;
|
return ecode;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user