From d1e91e1c96f5c786fc7c6cf428262920fc4d1ea6 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Wed, 26 Feb 2025 17:49:18 +0300 Subject: [PATCH] ... --- cxx/mount.h | 32 ++++++++++++- cxx/utils.h | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/cxx/mount.h b/cxx/mount.h index 2d6de35..9f3f443 100644 --- a/cxx/mount.h +++ b/cxx/mount.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace mcc { @@ -15,8 +16,7 @@ enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTA // mount state type concept template concept mcc_mount_state_c = requires(T t, const T t_const) { - typename T::state_id_t; - { t.ident() } -> std::same_as; + { t_const.ident() } -> std::same_as; typename T::context_t; { t.enter(std::declval()) } -> std::same_as; @@ -29,9 +29,37 @@ concept mcc_mount_state_c = requires(T t, const T t_const) { template class MccMount { + typedef double coord_t; + typedef double time_point_t; + public: static constexpr MccMountType mountType = MOUNT_TYPE; + /* mount main-cycle variable quantities */ + struct mount_state_t { + // time-related + time_point_t siderTime; // sideral time + + // target (user-input) current coordinates (in radians) + coord_t tagRA, tagDEC; + coord_t tagHA; + coord_t tagAZ, tagZD; + + // encoder-measured current mount coordinates (in radians) + coord_t mntRA, mntDEC; + coord_t mntHA; + coord_t mntAZ, mntZD; + + // current refraction coefficient + coord_t currRefr; + + // PCS (pointing correction system) corrections + coord_t pcsX, pcsY; // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one + + // mount current state + }; + + MccMount() { diff --git a/cxx/utils.h b/cxx/utils.h index d514f0c..ff22eb3 100644 --- a/cxx/utils.h +++ b/cxx/utils.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #include @@ -140,4 +142,133 @@ static std::optional parsAngleString(R&& r, bool hms = false) return std::nullopt; } + +static constexpr auto deg2radCoeff = std::numbers::pi / 180.0; + +// radians to degrees +template +static double rad2deg(double ang) +{ + auto r = ang / deg2radCoeff; + + if constexpr (NORM) { + return std::fmod(r, 360.0); + } else { + return r; + } +} + + +template R, bool NORM = false> +static R rad2deg_str(double ang, int prec = 2) +{ + R res; + + std::string fmt = "{:0." + std::to_string(prec) + "f}"; + + auto degs = rad2deg(ang); + + std::vformat_to(std::back_inserter(res), {fmt.begin(), fmt.end()}, degs); +} + +template +static std::string rad2deg_str(double ang, int prec = 2) +{ + return rad2deg_str(ang, prec); +} + + +template R, bool NORM = false> +static R rad2deg_str(double ang1, double ang2, std::string_view delim = ",", int prec1 = 2, int prec2 = 2) +{ + R res = rad2deg_str(ang1, prec1); + + R r = rad2deg_str(ang2, prec2); + + std::ranges::copy(std::back_inserter(res), delim); + std::ranges::copy(std::back_inserter(res), r); + + return res; +} + +template +static std::string rad2deg_str(double ang1, double ang2, std::string_view delim = ",", int prec1 = 2, int prec2 = 2) +{ + return rad2deg_str(ang1, ang2, delim, prec1, prec2); +} + +// radians to sexagesimal +template R, bool NORM = false> +static R rad2sxg(double ang, bool hms = false, int prec = 2) +{ + R res; + + std::string fmt = "{:02d}:{:02d}:{:0" + std::to_string(prec + 3) + "." + std::to_string(prec) + "f}"; + + auto degs = rad2deg(std::abs(ang)); + if (hms) { + degs /= 15.0; + } + + auto d = std::trunc(degs); + auto s = (degs - d) * 60.0; + auto m = std::trunc(s); + s = (s - m) * 60.0; + + if (ang < 0) { + std::ranges::copy(std::string_view("-"), std::back_inserter(res)); + } + + std::vformat_to(std::back_inserter(res), {fmt.begin(), fmt.end()}, d, m, s); + + return res; +} + +template +static std::string rad2sxg(double ang, bool hms = false, int prec = 2) +{ + return rad2sxg(ang, hms, prec); +} + + +template R, bool NORM = false> +static R RADEC_rad2sxg(double ra, double dec, std::string_view delim = ",", int ra_prec = 2, int dec_prec = 1) +{ + R res = rad2sxg(ra, true, ra_prec); + + R r = rad2sxg(dec, false, dec_prec); + + std::ranges::copy(std::back_inserter(res), delim); + std::ranges::copy(std::back_inserter(res), r); + + return res; +} + +template +static std::string RADEC_rad2sxg(double ra, double dec, std::string_view delim = ",", int ra_prec = 2, int dec_prec = 1) +{ + return RADEC_rad2sxg(ra, dec, delim, ra_prec, dec_prec); +} + + +template R, bool NORM = false> +static R AZZD_rad2sxg(double az, double zd, std::string_view delim = ",", int az_prec = 2, int zd_prec = 1) +{ + R res = rad2sxg(az, false, az_prec); + + R r = rad2sxg(zd, false, zd_prec); + + std::ranges::copy(std::back_inserter(res), delim); + std::ranges::copy(std::back_inserter(res), r); + + return res; +} + +template +static std::string AZZD_rad2sxg(double az, double zd, std::string_view delim = ",", int az_prec = 2, int zd_prec = 1) +{ + return AZZD_rad2sxg(az, zd, delim, az_prec, zd_prec); +} + + } // namespace mcc::utils