...
This commit is contained in:
175
cxx/mount.h
175
cxx/mount.h
@@ -6,11 +6,14 @@
|
||||
#include <chrono>
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
|
||||
#include "mcc_spdlog.h"
|
||||
#include "mount_astrom.h"
|
||||
#include "mount_astrom_default.h"
|
||||
|
||||
// low-level functions
|
||||
namespace lowlevel
|
||||
@@ -23,8 +26,8 @@ namespace lowlevel
|
||||
namespace mcc
|
||||
{
|
||||
|
||||
enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTAZ_TYPE };
|
||||
|
||||
namespace traits
|
||||
{
|
||||
|
||||
// mount state type concept
|
||||
template <typename T>
|
||||
@@ -35,22 +38,24 @@ concept mcc_mount_state_c = requires(T t, const T t_const) {
|
||||
{ t.exit() } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
// meteo parameters (to compute refraction)
|
||||
|
||||
/* SOME BASIC DATA STRUCTURES DEFINITIONS */
|
||||
|
||||
// meteo parameters (e.g. to compute refraction)
|
||||
struct MccMountMeteo {
|
||||
typedef double temp_t; // Temperature in C
|
||||
typedef double humid_t; // humidity in %
|
||||
typedef double press_t; // atmospheric presure in hPa=mB
|
||||
typedef double temp_t;
|
||||
typedef double humid_t;
|
||||
typedef double press_t;
|
||||
|
||||
temp_t temperature;
|
||||
humid_t humidity;
|
||||
press_t pressure;
|
||||
temp_t temperature; // Temperature in C
|
||||
humid_t humidity; // humidity in %
|
||||
press_t pressure; // atmospheric presure in hPa=mB
|
||||
};
|
||||
|
||||
// mount current position and related quantities
|
||||
class MccMountPosition
|
||||
{
|
||||
public:
|
||||
struct MccMountPosition {
|
||||
typedef double mnt_coord_t;
|
||||
typedef double mnt_speed_t;
|
||||
typedef double time_point_t;
|
||||
@@ -81,31 +86,16 @@ public:
|
||||
|
||||
// PCS (pointing correction system) corrections
|
||||
mnt_coord_t pcsX, pcsY; // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one
|
||||
|
||||
bool update(const std::chrono::system_clock::time_point& utc_time)
|
||||
{
|
||||
//
|
||||
|
||||
astro::mcc_julday(utc_time, mjd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateTime(const std::chrono::system_clock::time_point& utc_time)
|
||||
{
|
||||
// UTC to TAI
|
||||
double tai;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* MOUNT BASE TEMPLATED CLASS WITH BASIC FUNCTIONALITY */
|
||||
|
||||
enum class MccMountType : uint8_t { GERMAN_TYPE, FORK_TYPE, CROSSAXIS_TYPE, ALTAZ_TYPE };
|
||||
|
||||
// implements a Finite State Machine Pattern
|
||||
template <MccMountType MOUNT_TYPE>
|
||||
class MccMount
|
||||
class MccMount : public utils::MccSpdlogLogger
|
||||
{
|
||||
typedef double mnt_coord_t;
|
||||
typedef double mnt_speed_t;
|
||||
@@ -114,11 +104,6 @@ class MccMount
|
||||
public:
|
||||
static constexpr MccMountType mountType = MOUNT_TYPE;
|
||||
|
||||
/* low-level hardware related constants */
|
||||
|
||||
// number of attempts to get low-level hardware data before emit an error
|
||||
static constexpr uint8_t LOWLEVEL_HW_POLL_ATTEMPTS = 10;
|
||||
|
||||
/* mount main-cycle variable quantities (mount orientation) */
|
||||
struct mount_orient_t {
|
||||
// time-related
|
||||
@@ -151,19 +136,99 @@ public:
|
||||
|
||||
|
||||
struct mount_config_t {
|
||||
uint8_t hw_poll_attempts = LOWLEVEL_HW_POLL_ATTEMPTS;
|
||||
std::string leap_seconds_filename{}; // empty to use hardcoded default value!
|
||||
std::string earth_orient_filename{}; // empty to use hardcoded default value!
|
||||
};
|
||||
|
||||
|
||||
/* Constructors and destructor */
|
||||
|
||||
MccMount(std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"))
|
||||
: _mountLogger(logger), _exitCurrentState([]() {})
|
||||
MccMount(traits::mcc_input_char_range auto const& logger_mark = "[MOUNT]",
|
||||
std::shared_ptr<spdlog::logger> logger = spdlog::null_logger_mt("NULL"))
|
||||
: utils::MccSpdlogLogger(logger), _exitCurrentState([]() {})
|
||||
{
|
||||
std::istringstream strst;
|
||||
|
||||
addMarkToPatternIdx(logger_mark);
|
||||
|
||||
|
||||
logDebug("Create MccMount class instance: thread = {}", std::this_thread::get_id());
|
||||
|
||||
|
||||
// init time scales related databases to default (pre-defined) state
|
||||
|
||||
logInfo("initializing leap seconds database to default state ...");
|
||||
strst.str(defaults::MCC_DEFAULT_LEAP_SECONDS_FILE);
|
||||
_leapSecondsDB = astro::mcc_parse_leapsecs(strst);
|
||||
logInfo("leap seconds default database expired date: {}", _leapSecondsDB.expireDate);
|
||||
|
||||
logInfo("initializing Earth orientation (pole coordinates, UT1-UTC) database to default state ...");
|
||||
strst.clear();
|
||||
strst.str(defaults::MCC_DEFAULT_IERS_BULLETIN_A_FILE);
|
||||
_earthOrientDB = astro::mcc_parse_bulletinA(strst);
|
||||
logInfo("Earth orientation default database (Bulletin A) date: {}", _earthOrientDB.bulletinDate);
|
||||
|
||||
// load time scales relates databases from files
|
||||
std::ifstream fst;
|
||||
|
||||
logInfo("Load leap seconds and Earth orientation databases ...");
|
||||
|
||||
auto time_db_loader = [&fst, this](const std::string& filename, std::string_view type, auto& db) {
|
||||
if (filename.empty()) {
|
||||
logWarn("An empty {} filename! Skip and keep default values!", type);
|
||||
return;
|
||||
}
|
||||
|
||||
fst.open(filename);
|
||||
if (!fst.is_open()) {
|
||||
logError("CANNOT open {} file '{}'!", type, filename);
|
||||
logWarn("Keep {} database in default state!", type);
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (std::same_as<astro::leapsecond_db_t, std::decay_t<decltype(db)>>) {
|
||||
db = astro::mcc_parse_leapsecs(fst);
|
||||
} else if constexpr (std::same_as<astro::earth_orient_db_t, std::decay_t<decltype(db)>>) {
|
||||
db = astro::mcc_parse_bulletinA(fst);
|
||||
} else {
|
||||
static_assert(false, "INVALID DATABASE TYPE!!!");
|
||||
}
|
||||
|
||||
if (db.state != astro::IERS_DB_STATE_OK) {
|
||||
logError("CANNOT parse {} file '{}'!", type, filename);
|
||||
logWarn("Keep {} database in default state!", type);
|
||||
} else {
|
||||
logInfo("{} database was successfully loaded from '{}' file", type, filename);
|
||||
}
|
||||
|
||||
fst.close();
|
||||
};
|
||||
|
||||
astro::leapsecond_db_t ldb;
|
||||
astro::earth_orient_db_t edb;
|
||||
|
||||
time_db_loader(_mountCurrentConfig.leap_seconds_filename, "leap seconds", ldb);
|
||||
if (ldb.state == astro::IERS_DB_STATE_OK) {
|
||||
_leapSecondsDB = std::move(ldb);
|
||||
logInfo("leap seconds default database expired date: {}", _leapSecondsDB.expireDate);
|
||||
}
|
||||
|
||||
time_db_loader(_mountCurrentConfig.earth_orient_filename, "Earth orientation", edb);
|
||||
if (edb.state == astro::IERS_DB_STATE_OK) {
|
||||
_earthOrientDB = std::move(edb);
|
||||
logInfo("Earth orientation default database (Bulletin A) date: {}", _earthOrientDB.bulletinDate);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~MccMount() {}
|
||||
virtual ~MccMount()
|
||||
{
|
||||
logDebug("Delete MccMount class instance: thread = {}", std::this_thread::get_id());
|
||||
}
|
||||
|
||||
template <mcc_mount_state_c StateT>
|
||||
|
||||
/* Public methods */
|
||||
|
||||
template <traits::mcc_mount_state_c StateT>
|
||||
void setMountState(StateT& state)
|
||||
{
|
||||
_exitCurrentState(); // exit from current state
|
||||
@@ -188,34 +253,16 @@ public:
|
||||
protected:
|
||||
mount_config_t _mountCurrentConfig;
|
||||
|
||||
std::shared_ptr<spdlog::logger> _mountLogger;
|
||||
// std::shared_ptr<spdlog::logger> _mountLogger;
|
||||
std::function<void()> _exitCurrentState;
|
||||
|
||||
// time scales related databases
|
||||
astro::leapsecond_db_t _leapSecondsDB;
|
||||
astro::earth_orient_db_t _earthOrientDB;
|
||||
|
||||
std::atomic<mount_orient_t> _currentMountOrient;
|
||||
|
||||
std::atomic<MccMountMeteo> _currentMeteo;
|
||||
|
||||
void updateMountState()
|
||||
{
|
||||
mount_orient_t orient;
|
||||
lowlevel::mountdata_t hw_mdata;
|
||||
|
||||
// get data from encoders
|
||||
decltype(mount_config_t::hw_poll_attempts) n_attempts = 0;
|
||||
do {
|
||||
auto ret_code = lowlevel::Mount.getMountData(&hw_mdata);
|
||||
if (ret_code != lowlevel::MCC_E_OK) {
|
||||
++n_attempts;
|
||||
}
|
||||
} while (n_attempts < _mountCurrentConfig.hw_poll_attempts);
|
||||
|
||||
if (n_attempts >= _mountCurrentConfig.hw_poll_attempts) {
|
||||
// log error heres
|
||||
return;
|
||||
}
|
||||
|
||||
_currentMountOrient.store(orient);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
Reference in New Issue
Block a user