...
This commit is contained in:
parent
138e4bf84d
commit
6315d5e18e
@ -123,9 +123,12 @@ set(CNTR_PROTO_LIB comm_proto)
|
|||||||
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
||||||
|
|
||||||
|
|
||||||
set(MCC_LIBRARY_SRC mcc_mount_concepts.h mcc_fsm_mount.h mcc_mount_coord.h mcc_mount_events_states.h mcc_finite_state_machine.h
|
include_directories(${FITPACK_INCLUDE_DIR})
|
||||||
|
|
||||||
|
|
||||||
|
set(MCC_LIBRARY_SRC mcc_mount_concepts.h mcc_fsm_mount.h mcc_generic_mount.h mcc_mount_coord.h mcc_mount_events_states.h mcc_finite_state_machine.h
|
||||||
mcc_mount_pec.h mcc_mount_pz.h mcc_traits.h mcc_mount_telemetry_astrom.h mcc_mount_telemetry.h mcc_mount_config.h mcc_mount_astro_erfa.h
|
mcc_mount_pec.h mcc_mount_pz.h mcc_traits.h mcc_mount_telemetry_astrom.h mcc_mount_telemetry.h mcc_mount_config.h mcc_mount_astro_erfa.h
|
||||||
mcc_astrom_iers.h mcc_astrom_iers_default.h mcc_slew_model.h mcc_guiding_model.h mcc_utils.h mcc_spdlog.h)
|
mcc_astrom_iers.h mcc_astrom_iers_default.h mcc_slew_model.h mcc_guiding_model.h mcc_slew_guiding_model_common.h mcc_utils.h mcc_spdlog.h)
|
||||||
set(MCC_LIBRARY mcc)
|
set(MCC_LIBRARY mcc)
|
||||||
add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC})
|
add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC})
|
||||||
target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23)
|
target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23)
|
||||||
|
|||||||
@ -29,6 +29,9 @@ typedef mcc::MccMountTelemetry<AsibFM700AstromEngine,
|
|||||||
AsibFM700TelemetryData>
|
AsibFM700TelemetryData>
|
||||||
AsibFM700Telemetry;
|
AsibFM700Telemetry;
|
||||||
|
|
||||||
|
static_assert(std::movable<AsibFM700Telemetry>);
|
||||||
|
static_assert(std::movable<AsibFM700AstromEngine>);
|
||||||
|
static_assert(std::movable<mcc::MccAltLimitPZ<>>);
|
||||||
|
|
||||||
// typedef mcc::MccSimpleSlewModel<> AsibFM700SlewModel;
|
// typedef mcc::MccSimpleSlewModel<> AsibFM700SlewModel;
|
||||||
// typedef mcc::MccSimpleGuidingModel<> AsibFM700GuidingModel;
|
// typedef mcc::MccSimpleGuidingModel<> AsibFM700GuidingModel;
|
||||||
@ -63,7 +66,7 @@ static_assert(mcc::traits::mcc_mount_controls_c<AsibFM700MountControls<mcc::util
|
|||||||
// global mount configuration
|
// global mount configuration
|
||||||
|
|
||||||
struct AsibFM700Config {
|
struct AsibFM700Config {
|
||||||
std::chrono::milliseconds hardwareAskingPeriod{100}; // main cycle period
|
std::chrono::milliseconds hardwarePollingPeriod{100}; // main cycle period
|
||||||
|
|
||||||
// mount hardware config
|
// mount hardware config
|
||||||
AsibFM700Hardware::hardware_config_t hardwareConfig;
|
AsibFM700Hardware::hardware_config_t hardwareConfig;
|
||||||
@ -72,6 +75,10 @@ struct AsibFM700Config {
|
|||||||
|
|
||||||
class AsibFM700Mount : public mcc::MccMount<AsibFM700MountControls<mcc::utils::MccSpdlogLogger>>
|
class AsibFM700Mount : public mcc::MccMount<AsibFM700MountControls<mcc::utils::MccSpdlogLogger>>
|
||||||
{
|
{
|
||||||
|
class InitState : public AsibFM700Mount::MccMountEventBase
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -100,19 +100,26 @@ AsibFM700Hardware::error_t AsibFM700Hardware::setPos(AsibFM700Hardware::axes_pos
|
|||||||
double tp = std::chrono::duration<double>(pos.time_point.time_since_epoch()).count();
|
double tp = std::chrono::duration<double>(pos.time_point.time_since_epoch()).count();
|
||||||
coordval_pair_t hw_posval{.X{.val = pos.x, .t = tp}, .Y{.val = pos.y, .t = tp}};
|
coordval_pair_t hw_posval{.X{.val = pos.x, .t = tp}, .Y{.val = pos.y, .t = tp}};
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNING: The LibSidservo API was chagned! hw_pos is endpoint where mount must
|
||||||
|
// go "after" slewing
|
||||||
|
//
|
||||||
|
|
||||||
switch (pos.moving_type) {
|
switch (pos.moving_type) {
|
||||||
case hw_moving_type_t::HW_MOVE_SLEWING: // slew mount
|
case hw_moving_type_t::HW_MOVE_SLEWING: // slew mount
|
||||||
if (pos.moveAndStop) {
|
if (pos.moveAndStop) {
|
||||||
err = static_cast<AsibFM700HardwareErrorCode>(Mount.moveTo(&hw_pos));
|
// err = static_cast<AsibFM700HardwareErrorCode>(Mount.moveTo(&hw_pos));
|
||||||
|
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval, &hw_pos));
|
||||||
} else {
|
} else {
|
||||||
err = static_cast<AsibFM700HardwareErrorCode>(Mount.slewTo(&hw_pos, pos.flags));
|
// err = static_cast<AsibFM700HardwareErrorCode>(Mount.slewTo(&hw_pos, pos.flags));
|
||||||
|
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval, &hw_pos));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hw_moving_type_t::HW_MOVE_ADJUSTING: // corrections at the end of slewing
|
case hw_moving_type_t::HW_MOVE_ADJUSTING: // corrections at the end of slewing
|
||||||
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval));
|
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval, &hw_pos));
|
||||||
break;
|
break;
|
||||||
case hw_moving_type_t::HW_MOVE_GUIDING: // interpretate as guiding correction
|
case hw_moving_type_t::HW_MOVE_GUIDING: // interpretate as guiding correction
|
||||||
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval));
|
err = static_cast<AsibFM700HardwareErrorCode>(Mount.correctTo(&hw_posval, &hw_pos));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -79,7 +79,7 @@ public:
|
|||||||
coord_t xrate, yrate;
|
coord_t xrate, yrate;
|
||||||
|
|
||||||
hw_moving_type_t moving_type{hw_moving_type_t::HW_MOVE_TRACKING};
|
hw_moving_type_t moving_type{hw_moving_type_t::HW_MOVE_TRACKING};
|
||||||
slewflags_t flags;
|
// slewflags_t flags;
|
||||||
bool moveAndStop{false};
|
bool moveAndStop{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -23,12 +23,33 @@
|
|||||||
namespace mcc
|
namespace mcc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// adaptor class for prohibited zones
|
||||||
|
template <traits::mcc_mount_telemetry_data_c TelemetryDataT>
|
||||||
|
struct MccPZoneWrapper {
|
||||||
|
// a type to which the result of calling prohibited zone class methods 'timeTo' and 'timeFrom' will be converted
|
||||||
|
typedef std::chrono::duration<double> pz_duration_t; // seconds as floating-point number
|
||||||
|
|
||||||
|
static constexpr pz_duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
||||||
|
static constexpr pz_duration_t zeroDuration{0.0};
|
||||||
|
|
||||||
|
typedef std::function<bool(const TelemetryDataT&)> pz_inzone_func_t;
|
||||||
|
typedef std::function<pz_duration_t(const TelemetryDataT&)> pz_timeto_func_t;
|
||||||
|
typedef std::function<pz_duration_t(const TelemetryDataT&)> pz_timefrom_func_t;
|
||||||
|
|
||||||
|
MccCoordPairKind coordPairKind;
|
||||||
|
const std::function<std::string()> name;
|
||||||
|
pz_inzone_func_t inZone;
|
||||||
|
pz_timeto_func_t timeTo;
|
||||||
|
pz_timefrom_func_t timeFrom;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <traits::mcc_mount_controls_c MOUNT_CONTROLS>
|
template <traits::mcc_mount_controls_c MOUNT_CONTROLS>
|
||||||
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger, protected MOUNT_CONTROLS
|
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger, protected MOUNT_CONTROLS
|
||||||
{
|
{
|
||||||
// declare these classes as friends to allow them access protected members 'slewModel' and 'guidingModel'
|
// declare these classes as friends to allow them access protected members 'slewModel' and 'guidingModel'
|
||||||
friend class MccMountStateSlew<MccMount<MOUNT_CONTROLS>>;
|
// friend class MccMountStateSlew<MccMount<MOUNT_CONTROLS>>;
|
||||||
friend class MccMountStateGuiding<MccMount<MOUNT_CONTROLS>>;
|
// friend class MccMountStateGuiding<MccMount<MOUNT_CONTROLS>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef MOUNT_CONTROLS mount_controls_t;
|
typedef MOUNT_CONTROLS mount_controls_t;
|
||||||
@ -43,6 +64,47 @@ public:
|
|||||||
|
|
||||||
// typedef typename slew_model_t::slew_params_t slew_params_t;
|
// typedef typename slew_model_t::slew_params_t slew_params_t;
|
||||||
|
|
||||||
|
/* base classes for event and state */
|
||||||
|
|
||||||
|
class MccMountEventBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
MccMount& _mount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MccMountEventBase(MccMount& mount) : _mount(mount) {}
|
||||||
|
virtual ~MccMountEventBase() = default;
|
||||||
|
|
||||||
|
MccMount& mount() { return _mount; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// The implementation of FSM (see mcc_finite_state_machine.h) requires
|
||||||
|
// state to be a default constructible class, so one needs to hold
|
||||||
|
// a pointer to mount class to guarantee access to its private or protected
|
||||||
|
// members and methods
|
||||||
|
class MccMountStateBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// a pointer to mount class to allow access to private/protected
|
||||||
|
// members/methods of MccMount class from descendent state-classes.
|
||||||
|
// the memory address can be obtained from a call of
|
||||||
|
// MccMountEventBase::mount method (see above)
|
||||||
|
MccMount* _mount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MccMountStateBase() = default;
|
||||||
|
|
||||||
|
MccMountStateBase(const MccMountStateBase&) = delete;
|
||||||
|
MccMountStateBase& operator=(const MccMountStateBase&) = delete;
|
||||||
|
|
||||||
|
// just as an example (ugly but I still cannot find a solution)
|
||||||
|
// template <std::derived_from<MccMountEventBase> EvT>
|
||||||
|
// void enter(EvT& event)
|
||||||
|
// {
|
||||||
|
// _mount = &event.mount();
|
||||||
|
// _mount->forEachPZone(...);
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
/* constructors and destructor */
|
/* constructors and destructor */
|
||||||
|
|
||||||
@ -64,6 +126,8 @@ public:
|
|||||||
logDebug("{}", std::string(r.begin(), r.end()));
|
logDebug("{}", std::string(r.begin(), r.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MccMount(const MccMount&) = delete;
|
||||||
|
MccMount& operator=(const MccMount&) = delete;
|
||||||
|
|
||||||
virtual ~MccMount() { logDebug("Delete MccMount class instance: thread = {}", getThreadId()); }
|
virtual ~MccMount() { logDebug("Delete MccMount class instance: thread = {}", getThreadId()); }
|
||||||
|
|
||||||
@ -103,15 +167,34 @@ public:
|
|||||||
{
|
{
|
||||||
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
||||||
|
|
||||||
|
using d_t = typename MccPZoneWrapper<mount_telemetry_data_t>::pz_duration_t;
|
||||||
|
|
||||||
_pzFuncs.emplace_back(
|
_pzFuncs.emplace_back(
|
||||||
{.coordPairKind = ZT::zoneCoordPairKind,
|
{.coordPairKind = ZT::zoneCoordPairKind,
|
||||||
.name = std::format("{}", zone_ptr->name()),
|
.name = [zone_ptr]() { return std::format("{}", zone_ptr->name()); },
|
||||||
.inZoneFunc = [zone_ptr,
|
.inZone = [zone_ptr](const mount_telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
||||||
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
.timeTo =
|
||||||
.timeToFunc = [zone_ptr,
|
[zone_ptr](const mount_telemetry_data_t& tmry_data) {
|
||||||
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeTo(tmry_data); },
|
auto d = zone_ptr->timeTo(tmry_data);
|
||||||
.timeFromFunc =
|
|
||||||
[zone_ptr, this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeFrom(tmry_data); }});
|
if (d == ZT::infiniteDuration) {
|
||||||
|
return MccPZoneWrapper<mount_telemetry_data_t>::infiniteDuration;
|
||||||
|
} else if (d == ZT::zeroDuration) {
|
||||||
|
return MccPZoneWrapper<mount_telemetry_data_t>::zeroDuration;
|
||||||
|
}
|
||||||
|
return std::chrono::duration_cast<d_t>(d);
|
||||||
|
},
|
||||||
|
.timeFrom =
|
||||||
|
[zone_ptr](const mount_telemetry_data_t& tmry_data) {
|
||||||
|
auto d = zone_ptr->timeFrom(tmry_data);
|
||||||
|
|
||||||
|
if (d == ZT::infiniteDuration) {
|
||||||
|
return MccPZoneWrapper<mount_telemetry_data_t>::infiniteDuration;
|
||||||
|
} else if (d == ZT::zeroDuration) {
|
||||||
|
return MccPZoneWrapper<mount_telemetry_data_t>::zeroDuration;
|
||||||
|
}
|
||||||
|
return std::chrono::duration_cast<d_t>(d);
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
if constexpr (sizeof...(ZTs)) {
|
if constexpr (sizeof...(ZTs)) {
|
||||||
@ -144,8 +227,8 @@ protected:
|
|||||||
pz_timefrom_func_t timeFromFunc;
|
pz_timefrom_func_t timeFromFunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<pz_funcs_t> _pzFuncs{};
|
// std::vector<pz_funcs_t> _pzFuncs{};
|
||||||
|
std::vector<MccPZoneWrapper<mount_telemetry_data_t>> _pzFuncs{};
|
||||||
|
|
||||||
template <typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
template <typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
||||||
auto forEachPZone(FuncT&& func, std::tuple<ZTs...>& zones)
|
auto forEachPZone(FuncT&& func, std::tuple<ZTs...>& zones)
|
||||||
|
|||||||
258
cxx/mcc_generic_mount.h
Normal file
258
cxx/mcc_generic_mount.h
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A GENERIC MOUNT CLASS IMPLEMENTATION */
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "mcc_mount_concepts.h"
|
||||||
|
|
||||||
|
namespace mcc
|
||||||
|
{
|
||||||
|
|
||||||
|
// adaptor class for prohibited zones
|
||||||
|
template <traits::mcc_mount_telemetry_data_c TelemetryDataT>
|
||||||
|
struct MccPZoneWrapper {
|
||||||
|
// a type to which the result of calling prohibited zone class methods 'timeTo' and 'timeFrom' will be converted
|
||||||
|
typedef std::chrono::duration<double> duration_t; // seconds as floating-point number
|
||||||
|
|
||||||
|
static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
||||||
|
static constexpr duration_t zeroDuration{0.0};
|
||||||
|
|
||||||
|
typedef std::function<bool(const TelemetryDataT&)> pz_inzone_func_t;
|
||||||
|
typedef std::function<duration_t(const TelemetryDataT&)> pz_timeto_func_t;
|
||||||
|
typedef std::function<duration_t(const TelemetryDataT&)> pz_timefrom_func_t;
|
||||||
|
|
||||||
|
MccCoordPairKind coordPairKind;
|
||||||
|
const std::function<std::string()> name;
|
||||||
|
pz_inzone_func_t inZone;
|
||||||
|
pz_timeto_func_t timeTo;
|
||||||
|
pz_timefrom_func_t timeFrom;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::mcc_astrom_engine_c ASTROM_ENGINE_T,
|
||||||
|
traits::mcc_mount_hardware_c HARDWARE_T,
|
||||||
|
traits::mcc_mount_pec_c PEC_T,
|
||||||
|
traits::mcc_mount_telemetry_c TELEMETRY_T,
|
||||||
|
traits::mcc_slew_model_c SLEWMODEL_T,
|
||||||
|
traits::mcc_guiding_model_c GUIDEMODEL_T,
|
||||||
|
traits::mcc_logger_c LOGGER_T>
|
||||||
|
class MccGenericMount : public LOGGER_T
|
||||||
|
{
|
||||||
|
typedef LOGGER_T logger_t;
|
||||||
|
|
||||||
|
using logger_t::logDebug;
|
||||||
|
using logger_t::logError;
|
||||||
|
using logger_t::logInfo;
|
||||||
|
using logger_t::logWarn;
|
||||||
|
|
||||||
|
typedef ASTROM_ENGINE_T astrom_engine_t;
|
||||||
|
typedef HARDWARE_T hardware_t;
|
||||||
|
typedef PEC_T pec_t;
|
||||||
|
typedef TELEMETRY_T telemetry_t;
|
||||||
|
typedef typename TELEMETRY_T::telemetry_data_t telemetry_data_t;
|
||||||
|
typedef SLEWMODEL_T slew_model_t;
|
||||||
|
typedef GUIDEMODEL_T guiding_model_t;
|
||||||
|
|
||||||
|
typedef typename MccPZoneWrapper<telemetry_data_t>::duration_t pz_duration_t;
|
||||||
|
|
||||||
|
static constexpr MccMountType mountType = pec_t::mountType;
|
||||||
|
|
||||||
|
virtual ~MccGenericMount() = default;
|
||||||
|
|
||||||
|
// get telemetry data
|
||||||
|
auto mountTelemetryData(telemetry_data_t& data) { return _telemetry.data(data); }
|
||||||
|
|
||||||
|
|
||||||
|
/* prohibited zone related public methods */
|
||||||
|
|
||||||
|
// add zones to mount control system
|
||||||
|
template <traits::mcc_prohibited_zone_c<telemetry_data_t> ZT,
|
||||||
|
traits::mcc_prohibited_zone_c<telemetry_data_t>... ZTs>
|
||||||
|
size_t pzAddZone(ZT zone, ZTs... zones)
|
||||||
|
{
|
||||||
|
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
||||||
|
|
||||||
|
using d_t = typename MccPZoneWrapper<telemetry_data_t>::duration_t;
|
||||||
|
|
||||||
|
_pzFuncs.emplace_back(
|
||||||
|
{.coordPairKind = ZT::zoneCoordPairKind,
|
||||||
|
.name = [zone_ptr]() { return std::format("{}", zone_ptr->name()); },
|
||||||
|
.inZone = [zone_ptr](const telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
||||||
|
.timeTo =
|
||||||
|
[zone_ptr](const telemetry_data_t& tmry_data) {
|
||||||
|
auto d = zone_ptr->timeTo(tmry_data);
|
||||||
|
|
||||||
|
if constexpr (std::same_as<typename ZT::duration_t, d_t>) {
|
||||||
|
return d;
|
||||||
|
} else {
|
||||||
|
if (d == ZT::infiniteDuration) {
|
||||||
|
return MccPZoneWrapper<telemetry_data_t>::infiniteDuration;
|
||||||
|
} else if (d == ZT::zeroDuration) {
|
||||||
|
return MccPZoneWrapper<telemetry_data_t>::zeroDuration;
|
||||||
|
}
|
||||||
|
return std::chrono::duration_cast<d_t>(d);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.timeFrom =
|
||||||
|
[zone_ptr](const telemetry_data_t& tmry_data) {
|
||||||
|
auto d = zone_ptr->timeFrom(tmry_data);
|
||||||
|
|
||||||
|
if constexpr (std::same_as<typename ZT::duration_t, d_t>) {
|
||||||
|
return d;
|
||||||
|
} else {
|
||||||
|
if (d == ZT::infiniteDuration) {
|
||||||
|
return MccPZoneWrapper<telemetry_data_t>::infiniteDuration;
|
||||||
|
} else if (d == ZT::zeroDuration) {
|
||||||
|
return MccPZoneWrapper<telemetry_data_t>::zeroDuration;
|
||||||
|
}
|
||||||
|
return std::chrono::duration_cast<d_t>(d);
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
if constexpr (sizeof...(ZTs)) {
|
||||||
|
pzAddZone(std::move(zones)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _pzFuncs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all zones from mount control system
|
||||||
|
void pzClearZone()
|
||||||
|
{
|
||||||
|
// stop mount here?!!
|
||||||
|
_pzFuncs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prohibited zones timeTo from given time point
|
||||||
|
template <std::ranges::output_range<pz_duration_t> RT, traits::mcc_celestial_point_c CT, traits::mcc_systime_c TPT>
|
||||||
|
RT pzTimeTo(CT coord, const TPT& time_point)
|
||||||
|
requires std::convertible_to<TPT, typename astrom_engine_t::time_point_t>
|
||||||
|
{
|
||||||
|
RT res;
|
||||||
|
|
||||||
|
telemetry_data_t tdata;
|
||||||
|
typename astrom_engine_t::juldate_t jd;
|
||||||
|
|
||||||
|
_astromEngine.greg2jul(time_point, jd);
|
||||||
|
|
||||||
|
if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_XY) { // from encoder's
|
||||||
|
typename pec_t::pec_result_t pec_res;
|
||||||
|
auto pec_err = _pec.compute(coord.x, coord.y, pec_res);
|
||||||
|
if (!pec_err) {
|
||||||
|
if constexpr (mccIsEquatorialMount(mountType)) {
|
||||||
|
tdata.mntHA = coord.x + pec_res.dx;
|
||||||
|
tdata.mntDEC = coord.y + pec_res.dy;
|
||||||
|
_astromEngine.hadec2azalt(tdata.mntHA, tdata.mntDEC, tdata.mntAZ, tdata.mntALT);
|
||||||
|
} else if constexpr (mccIsAltAzMount(mountType)) {
|
||||||
|
tdata.mntAZ = coord.x + pec_res.dx;
|
||||||
|
tdata.mntALT = coord.y + pec_res.dy;
|
||||||
|
_astromEngine.azalt2hadec(tdata.mntAZ, tdata.mntALT, tdata.mntHA, tdata.mntDEC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { // from app RA-DEC
|
||||||
|
typename astrom_engine_t::eo_t eo;
|
||||||
|
typename astrom_engine_t::sideral_time_t lst;
|
||||||
|
|
||||||
|
_astromEngine.apparentSiderTime(jd, lst, true);
|
||||||
|
_astromEngine.eqOrigins(jd, eo);
|
||||||
|
|
||||||
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { // from app HA-DEC
|
||||||
|
tdata.mntHA = coord.x;
|
||||||
|
tdata.mntDEC = coord.y;
|
||||||
|
_astromEngine.hadec2azalt(tdata.mntHA, tdata.mntDEC, tdata.mntAZ, tdata.mntALT);
|
||||||
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_AZALT) { // from app AZ-ALT
|
||||||
|
tdata.mntAZ = coord.x;
|
||||||
|
tdata.mntALT = coord.y;
|
||||||
|
_astromEngine.azalt2hadec(tdata.mntAZ, tdata.mntALT, tdata.mntHA, tdata.mntDEC);
|
||||||
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_AZZD) { // from app AZ-ZD
|
||||||
|
tdata.mntAZ = coord.x;
|
||||||
|
tdata.mntALT = std::numbers::pi / 2.0 - coord.y;
|
||||||
|
_astromEngine.azalt2hadec(tdata.mntAZ, tdata.mntALT, tdata.mntHA, tdata.mntDEC);
|
||||||
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // from ICRS RA-DEC
|
||||||
|
typename astrom_engine_t::coord_t az, alt;
|
||||||
|
typename astrom_engine_t::eo_t eo;
|
||||||
|
typename astrom_engine_t::juldate_t jd;
|
||||||
|
|
||||||
|
_astromEngine.greg2jul(time_point, jd);
|
||||||
|
_astromEngine.icrs2obs(coord.x, coord.y, jd, tdata.mntRA, tdata.mntDEC, tdata.mntHA, tdata.mntAZ,
|
||||||
|
tdata.mntALT, eo);
|
||||||
|
} else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_celestial_point_c CT, traits::mcc_systime_c TPT>
|
||||||
|
auto pzTimeTo(CT point, const TPT& time_point)
|
||||||
|
{
|
||||||
|
return pzTimeTo<std::vector<pz_duration_t>>(std::move(point), time_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prohibited zones timeTo from current mount position
|
||||||
|
template <std::ranges::output_range<pz_duration_t> RT, traits::mcc_celestial_point_c CT>
|
||||||
|
RT pzTimeTo(CT point)
|
||||||
|
{
|
||||||
|
RT result;
|
||||||
|
|
||||||
|
telemetry_data_t data;
|
||||||
|
auto err = _telemetry.data(data);
|
||||||
|
if (err) {
|
||||||
|
// log...
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ranges::for_each(_pzFuncs,
|
||||||
|
[&result, &data](auto& funcs) { std::back_inserter(result) = funcs.timeTo(data); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_celestial_point_c CT>
|
||||||
|
auto pzTimeTo(CT point)
|
||||||
|
{
|
||||||
|
return pzTimeTo<std::vector<pz_duration_t>>(std::move(point));
|
||||||
|
}
|
||||||
|
|
||||||
|
// prohibited zone timeFrom
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ASTROM_ENGINE_T _astromEngine;
|
||||||
|
HARDWARE_T _hardware;
|
||||||
|
PEC_T _pec;
|
||||||
|
TELEMETRY_T _telemetry;
|
||||||
|
SLEWMODEL_T _slewModel;
|
||||||
|
GUIDEMODEL_T _gudingModel;
|
||||||
|
|
||||||
|
std::vector<MccPZoneWrapper<telemetry_data_t>> _pzFuncs{};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace traits
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept mcc_generic_mount_c = requires(T t) {
|
||||||
|
// derived from MccGenericMount
|
||||||
|
[]<typename... Ts>(MccGenericMount<Ts...>*) {}(&t);
|
||||||
|
|
||||||
|
{ t.slewMount(std::declval<typename T::slew_model_t::slew_point_t>()) };
|
||||||
|
{ t.startGuiding(std::declval<typename T::guiding_model_t::guiding_point_t>()) };
|
||||||
|
|
||||||
|
{ t.stop() };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept mcc_generic_fsm_mount_c = mcc_generic_mount_c<T> && std::derived_from<T, fsm::MccFiniteStateMachine>;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace traits
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mcc
|
||||||
@ -164,6 +164,27 @@ public:
|
|||||||
init(telemetry, hardware, prohibited_zone);
|
init(telemetry, hardware, prohibited_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MccSimpleGuidingModel(MccSimpleGuidingModel&& other)
|
||||||
|
: _guidingFunc(std::move(other._guidingFunc)),
|
||||||
|
_doCorrection(other._doCorrection.load()),
|
||||||
|
_stopRequested(other._stopRequested.load())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MccSimpleGuidingModel& operator=(MccSimpleGuidingModel&& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_guidingFunc = std::move(other._guidingFunc);
|
||||||
|
_doCorrection = other._doCorrection.load();
|
||||||
|
_stopRequested = other._stopRequested.load();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~MccSimpleGuidingModel()
|
virtual ~MccSimpleGuidingModel()
|
||||||
{
|
{
|
||||||
logDebug(std::format("Delete 'MccSimpleGuidingModel' class instance ({})", (void*)this));
|
logDebug(std::format("Delete 'MccSimpleGuidingModel' class instance ({})", (void*)this));
|
||||||
@ -333,4 +354,6 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// static_assert(std::movable<MccSimpleGuidingModel<>>);
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
@ -151,15 +151,9 @@ public:
|
|||||||
double mjd{51544.5}; // J2000.0
|
double mjd{51544.5}; // J2000.0
|
||||||
};
|
};
|
||||||
|
|
||||||
// typedef MccAngle coord_t;
|
|
||||||
|
|
||||||
// typedef MccAngle sideral_time_t;
|
/* use of the same type for representation of celestial and geodetic coordinates, celestial angles (e.g. P.A.),
|
||||||
// typedef MccAngle pa_t;
|
* and sideral time */
|
||||||
// typedef MccAngle eo_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* use of the same type fro representation of celestial and geodetic coordinates, celestial angles (e.g. P.A.),
|
|
||||||
* sideral time */
|
|
||||||
typedef AngleT coord_t;
|
typedef AngleT coord_t;
|
||||||
|
|
||||||
typedef AngleT sideral_time_t;
|
typedef AngleT sideral_time_t;
|
||||||
@ -173,40 +167,51 @@ public:
|
|||||||
|
|
||||||
MccMountAstromEngineERFA() = default;
|
MccMountAstromEngineERFA() = default;
|
||||||
|
|
||||||
MccMountAstromEngineERFA(engine_state_t state) : _currentState(std::move(state)) {}
|
MccMountAstromEngineERFA(engine_state_t state) : _currentState(std::move(state)), _stateMutex(new std::mutex) {}
|
||||||
|
|
||||||
MccMountAstromEngineERFA(MccMountAstromEngineERFA&&) = default;
|
|
||||||
MccMountAstromEngineERFA& operator=(MccMountAstromEngineERFA&&) = default;
|
|
||||||
|
|
||||||
MccMountAstromEngineERFA(const MccMountAstromEngineERFA&) = delete;
|
MccMountAstromEngineERFA(const MccMountAstromEngineERFA&) = delete;
|
||||||
MccMountAstromEngineERFA& operator=(const MccMountAstromEngineERFA&) = delete;
|
MccMountAstromEngineERFA& operator=(const MccMountAstromEngineERFA&) = delete;
|
||||||
|
|
||||||
|
MccMountAstromEngineERFA(MccMountAstromEngineERFA&& other)
|
||||||
|
: _currentState(std::move(other._currentState)), _stateMutex(std::move(other._stateMutex)) {};
|
||||||
|
|
||||||
|
MccMountAstromEngineERFA& operator=(MccMountAstromEngineERFA&& other)
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
_currentState = std::move(other._currentState);
|
||||||
|
_stateMutex = std::move(other._stateMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual ~MccMountAstromEngineERFA() = default;
|
virtual ~MccMountAstromEngineERFA() = default;
|
||||||
|
|
||||||
void setState(engine_state_t state)
|
void setState(engine_state_t state)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
_currentState = std::move(state);
|
_currentState = std::move(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine_state_t getState() const
|
engine_state_t getState() const
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
return _currentState;
|
return _currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMeteo(meteo_t meteo)
|
void updateMeteo(meteo_t meteo)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
_currentState.meteo = std::move(meteo);
|
_currentState.meteo = std::move(meteo);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t updateLeapSeconds(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '#')
|
error_t updateLeapSeconds(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '#')
|
||||||
{
|
{
|
||||||
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 MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
||||||
@ -218,7 +223,7 @@ public:
|
|||||||
|
|
||||||
error_t updateLeapSeconds(traits::mcc_input_char_range auto const& filename, char comment_sym = '#')
|
error_t updateLeapSeconds(traits::mcc_input_char_range auto const& filename, char comment_sym = '#')
|
||||||
{
|
{
|
||||||
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 MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_LEAPSECONDS;
|
||||||
@ -230,7 +235,7 @@ public:
|
|||||||
|
|
||||||
error_t updateBulletinA(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '*')
|
error_t updateBulletinA(std::derived_from<std::basic_istream<char>> auto& stream, char comment_sym = '*')
|
||||||
{
|
{
|
||||||
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 MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
||||||
@ -242,7 +247,7 @@ public:
|
|||||||
|
|
||||||
error_t updateBulletinA(traits::mcc_input_char_range auto const& filename, char comment_sym = '*')
|
error_t updateBulletinA(traits::mcc_input_char_range auto const& filename, char comment_sym = '*')
|
||||||
{
|
{
|
||||||
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 MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
return MccMountAstromEngineERFAErrorCode::ERROR_UPDATE_BULLETINA;
|
||||||
@ -299,7 +304,7 @@ public:
|
|||||||
|
|
||||||
error_t terrestrialTime(juldate_t juldate, juldate_t& tt)
|
error_t terrestrialTime(juldate_t juldate, juldate_t& tt)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
|
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
|
||||||
|
|
||||||
@ -320,7 +325,7 @@ public:
|
|||||||
|
|
||||||
error_t apparentSiderTime(juldate_t juldate, sideral_time_t& gst, bool islocal = false)
|
error_t apparentSiderTime(juldate_t juldate, sideral_time_t& gst, bool islocal = false)
|
||||||
{
|
{
|
||||||
// std::lock_guard lock{_stateMutex};
|
// std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
|
using real_days_t = std::chrono::duration<double, std::ratio<86400>>;
|
||||||
|
|
||||||
@ -328,7 +333,7 @@ public:
|
|||||||
// double tt = juldate.mjd;
|
// double tt = juldate.mjd;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
||||||
|
|
||||||
@ -384,7 +389,7 @@ public:
|
|||||||
|
|
||||||
error_t refraction(refract_result_t& refr)
|
error_t refraction(refract_result_t& refr)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
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);
|
||||||
@ -417,7 +422,7 @@ public:
|
|||||||
coord_t& alt,
|
coord_t& alt,
|
||||||
eo_t& eo)
|
eo_t& eo)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
||||||
|
|
||||||
@ -459,7 +464,7 @@ public:
|
|||||||
|
|
||||||
error_t obs2icrs(MccCoordPairKind coord_kind, coord_t x, coord_t y, juldate_t juldate, coord_t ra, coord_t dec)
|
error_t obs2icrs(MccCoordPairKind coord_kind, coord_t x, coord_t y, juldate_t juldate, coord_t ra, coord_t dec)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
auto dut1 = _currentState._bulletinA.DUT1(juldate.mjd);
|
||||||
|
|
||||||
@ -516,7 +521,7 @@ public:
|
|||||||
|
|
||||||
error_t hadec2azalt(coord_t ha, coord_t dec, coord_t& az, coord_t& alt)
|
error_t hadec2azalt(coord_t ha, coord_t dec, coord_t& az, coord_t& alt)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
double r_az, r_alt;
|
double r_az, r_alt;
|
||||||
eraHd2ae(ha, dec, _currentState.lat, &r_az, &r_alt);
|
eraHd2ae(ha, dec, _currentState.lat, &r_az, &r_alt);
|
||||||
@ -529,7 +534,7 @@ public:
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
double r_ha, r_dec;
|
double r_ha, r_dec;
|
||||||
|
|
||||||
@ -544,7 +549,7 @@ public:
|
|||||||
|
|
||||||
error_t hadec2pa(coord_t ha, coord_t dec, pa_t& pa)
|
error_t hadec2pa(coord_t ha, coord_t dec, pa_t& pa)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_stateMutex};
|
std::lock_guard lock{*_stateMutex};
|
||||||
|
|
||||||
pa = eraHd2pa(ha, dec, _currentState.lat);
|
pa = eraHd2pa(ha, dec, _currentState.lat);
|
||||||
|
|
||||||
@ -566,7 +571,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
engine_state_t _currentState{};
|
engine_state_t _currentState{};
|
||||||
|
|
||||||
mutable std::mutex _stateMutex;
|
std::unique_ptr<std::mutex> _stateMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mcc::astrom::erfa
|
} // namespace mcc::astrom::erfa
|
||||||
|
|||||||
@ -297,7 +297,7 @@ concept mcc_mount_pec_c = requires(T t) {
|
|||||||
|
|
||||||
// a class that contains at least celestial (equatorial and horizontal) and harware coordinates
|
// a class that contains at least celestial (equatorial and horizontal) and harware coordinates
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_mount_telemetry_data_c = requires(T telemetry) {
|
concept mcc_mount_telemetry_data_c = std::movable<T> && requires(T telemetry) {
|
||||||
typename T::coord_t;
|
typename T::coord_t;
|
||||||
typename T::time_point_t;
|
typename T::time_point_t;
|
||||||
|
|
||||||
@ -423,8 +423,8 @@ concept mcc_guiding_model_c = requires(T t) {
|
|||||||
template <typename T, typename TelemetryDataT>
|
template <typename T, typename TelemetryDataT>
|
||||||
concept mcc_prohibited_zone_c =
|
concept mcc_prohibited_zone_c =
|
||||||
mcc_mount_telemetry_data_c<TelemetryDataT> && std::movable<T> && requires(T t, const T t_const) {
|
mcc_mount_telemetry_data_c<TelemetryDataT> && std::movable<T> && requires(T t, const T t_const) {
|
||||||
typename T::coord_t;
|
// typename T::coord_t;
|
||||||
typename T::time_point_t;
|
// typename T::time_point_t;
|
||||||
requires mcc_time_duration_c<typename T::duration_t>;
|
requires mcc_time_duration_c<typename T::duration_t>;
|
||||||
|
|
||||||
// static constexpr member to represent inifite duration
|
// static constexpr member to represent inifite duration
|
||||||
@ -436,6 +436,15 @@ concept mcc_prohibited_zone_c =
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// static constexpr member to represent zero duration
|
||||||
|
requires requires {
|
||||||
|
requires std::same_as<decltype(T::zeroDuration), typename T::duration_t>;
|
||||||
|
[]() {
|
||||||
|
constexpr auto val = T::zeroDuration;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// the type 'T' must define a static constexpr member of type MccCoordPairKind
|
// the type 'T' must define a static constexpr member of type MccCoordPairKind
|
||||||
// to declarate type of coordinate pair used to describe the zone.
|
// to declarate type of coordinate pair used to describe the zone.
|
||||||
@ -491,6 +500,11 @@ concept mcc_prohibited_zone_c =
|
|||||||
{ t.timeFrom(std::declval<const TelemetryDataT&>()) } -> std::same_as<typename T::duration_t>;
|
{ t.timeFrom(std::declval<const TelemetryDataT&>()) } -> std::same_as<typename T::duration_t>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// an input range of prohibited zones
|
||||||
|
template <typename T, typename TelemetryDataT>
|
||||||
|
concept mcc_irange_of_pzones_c = mcc_mount_telemetry_data_c<TelemetryDataT> && std::ranges::input_range<T> &&
|
||||||
|
mcc_prohibited_zone_c<std::ranges::range_value_t<T>, TelemetryDataT>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* MOUNT GENERIC CONTROLS */
|
/* MOUNT GENERIC CONTROLS */
|
||||||
@ -511,7 +525,9 @@ concept mcc_mount_controls_c = requires(T t) {
|
|||||||
// []<mcc_prohibited_zone_c<typename decltype(t.telemetry)::mount_telemetry_data_t>... Ts>(std::tuple<Ts...>) {
|
// []<mcc_prohibited_zone_c<typename decltype(t.telemetry)::mount_telemetry_data_t>... Ts>(std::tuple<Ts...>) {
|
||||||
// }(t.prohibitedZones);
|
// }(t.prohibitedZones);
|
||||||
|
|
||||||
requires mcc_tuple_c<decltype(t.prohibitedZones)>;
|
// requires mcc_tuple_c<decltype(t.prohibitedZones)>;
|
||||||
|
requires mcc_irange_of_pzones_c<decltype(t.prohibitedZones),
|
||||||
|
typename decltype(t.telemetry)::mount_telemetry_data_t>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -530,18 +546,24 @@ concept mcc_mount_c = requires(T t) {
|
|||||||
requires mcc_astrom_engine_c<typename T::astrom_engine_t>;
|
requires mcc_astrom_engine_c<typename T::astrom_engine_t>;
|
||||||
requires mcc_mount_pec_c<typename T::pec_t>;
|
requires mcc_mount_pec_c<typename T::pec_t>;
|
||||||
requires mcc_mount_hardware_c<typename T::hardware_t>;
|
requires mcc_mount_hardware_c<typename T::hardware_t>;
|
||||||
// requires mcc_slew_model_c<typename T::slew_model_t, typename T::mount_telemetry_t>;
|
|
||||||
requires mcc_slew_model_c<typename T::slew_model_t>;
|
requires mcc_slew_model_c<typename T::slew_model_t>;
|
||||||
// requires mcc_guiding_model_c<typename T::guiding_model_t, typename T::mount_telemetry_t>;
|
|
||||||
requires mcc_guiding_model_c<typename T::guiding_model_t>;
|
requires mcc_guiding_model_c<typename T::guiding_model_t>;
|
||||||
|
|
||||||
// requires std::same_as<typename T::slew_params_t, typename T::slew_model_t::slew_params_t>;
|
// public methods
|
||||||
|
{
|
||||||
|
t.mountTelemetryData(std::declval<typename T::mount_telemetry_data_t&>())
|
||||||
|
} -> std::same_as<typename T::mount_telemetry_t::error_t>;
|
||||||
|
|
||||||
// public method
|
{
|
||||||
{ t.mountTelemetryData() } -> std::same_as<typename T::mount_telemetry_data_t>;
|
t.slewMount(std::declval<typename T::slew_model_t::slew_point_t>())
|
||||||
|
} -> std::same_as<typename T::slew_model_t::error_t>;
|
||||||
|
|
||||||
|
{
|
||||||
|
t.guidingTarget(std::declval<typename T::guiding_model_t::guiding_point_t>())
|
||||||
|
} -> std::same_as<typename T::guiding_model_t::error_t>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// generic with logging methods
|
// generic with public logging methods
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_log_mount_c = mcc_mount_c<T> && mcc_logger_c<T>;
|
concept mcc_log_mount_c = mcc_mount_c<T> && mcc_logger_c<T>;
|
||||||
|
|
||||||
|
|||||||
@ -23,10 +23,7 @@ enum class MccMountDefaultPECErrorCode : int { ERROR_OK, ERROR_INVALID_INPUTS_BI
|
|||||||
struct MccMountDefaultPECCategory : public std::error_category {
|
struct MccMountDefaultPECCategory : public std::error_category {
|
||||||
MccMountDefaultPECCategory() : std::error_category() {}
|
MccMountDefaultPECCategory() : std::error_category() {}
|
||||||
|
|
||||||
const char* name() const noexcept
|
const char* name() const noexcept { return "ADC_GENERIC_DEVICE"; }
|
||||||
{
|
|
||||||
return "ADC_GENERIC_DEVICE";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string message(int ec) const
|
std::string message(int ec) const
|
||||||
{
|
{
|
||||||
@ -140,14 +137,41 @@ public:
|
|||||||
: _pecData(std::move(pdata)),
|
: _pecData(std::move(pdata)),
|
||||||
_phi(_pecData.siteLatitude),
|
_phi(_pecData.siteLatitude),
|
||||||
_geomCoeffs(_pecData.geomCoefficients),
|
_geomCoeffs(_pecData.geomCoefficients),
|
||||||
_bsplCoeffs(_pecData.bsplineCoefficients)
|
_bsplCoeffs(_pecData.bsplineCoefficients),
|
||||||
|
_pecDataMutex(new std::mutex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MccMountDefaultPEC(const MccMountDefaultPEC&) = delete;
|
||||||
|
MccMountDefaultPEC& operator=(const MccMountDefaultPEC&) = delete;
|
||||||
|
|
||||||
|
MccMountDefaultPEC(MccMountDefaultPEC&& other)
|
||||||
|
: _pecData(std::move(other._pecData)),
|
||||||
|
_phi(_pecData.siteLatitude),
|
||||||
|
_geomCoeffs(_pecData.geomCoefficients),
|
||||||
|
_bsplCoeffs(_pecData.bsplineCoefficients),
|
||||||
|
_pecDataMutex(std::move(other._pecDataMutex))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MccMountDefaultPEC& operator=(MccMountDefaultPEC&& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pecData = std::move(other._pecData);
|
||||||
|
_phi = _pecData.siteLatitude;
|
||||||
|
_geomCoeffs = _pecData.geomCoefficients;
|
||||||
|
_bsplCoeffs = _pecData.bsplineCoefficients;
|
||||||
|
_pecDataMutex = std::move(other._pecDataMutex);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void setData(pec_data_t pdata)
|
void setData(pec_data_t pdata)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_pecDataMutex);
|
std::lock_guard lock(*_pecDataMutex);
|
||||||
|
|
||||||
_pecData = std::move(pdata);
|
_pecData = std::move(pdata);
|
||||||
_phi = _pecData.siteLatitude;
|
_phi = _pecData.siteLatitude;
|
||||||
@ -158,21 +182,21 @@ public:
|
|||||||
|
|
||||||
pec_data_t getData() const
|
pec_data_t getData() const
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_pecDataMutex);
|
std::lock_guard lock(*_pecDataMutex);
|
||||||
|
|
||||||
return _pecData;
|
return _pecData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setType(MccMountDefaultPECType type)
|
void setType(MccMountDefaultPECType type)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_pecDataMutex);
|
std::lock_guard lock(*_pecDataMutex);
|
||||||
|
|
||||||
_pecData.type = type;
|
_pecData.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
MccMountDefaultPECType getType() const
|
MccMountDefaultPECType getType() const
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_pecDataMutex);
|
std::lock_guard lock(*_pecDataMutex);
|
||||||
|
|
||||||
return _pecData.type;
|
return _pecData.type;
|
||||||
}
|
}
|
||||||
@ -183,7 +207,7 @@ public:
|
|||||||
// so, input x and y are assumed to be mount axis encoder coordinates
|
// so, input x and y are assumed to be mount axis encoder coordinates
|
||||||
error_t compute(const coord_t& x, const coord_t& y, pec_result_t& res)
|
error_t compute(const coord_t& x, const coord_t& y, pec_result_t& res)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_pecDataMutex);
|
std::lock_guard lock(*_pecDataMutex);
|
||||||
|
|
||||||
if constexpr (mcc_is_equatorial_mount<MOUNT_TYPE>) { // equatorial
|
if constexpr (mcc_is_equatorial_mount<MOUNT_TYPE>) { // equatorial
|
||||||
if (_pecData.type == MccMountDefaultPECType::PEC_TYPE_GEOMETRY) {
|
if (_pecData.type == MccMountDefaultPECType::PEC_TYPE_GEOMETRY) {
|
||||||
@ -249,70 +273,6 @@ public:
|
|||||||
return MccMountDefaultPECErrorCode::ERROR_OK;
|
return MccMountDefaultPECErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from celestial to encoder (use of iterative scheme)
|
|
||||||
error_t reverseCompute(const coord_t& x, const coord_t& y, pec_result_t& res, coord_t eps, size_t max_iter = 5)
|
|
||||||
{
|
|
||||||
coord_t e2 = eps * eps;
|
|
||||||
|
|
||||||
coord_t xi = x, yi = y;
|
|
||||||
coord_t xe, ye;
|
|
||||||
size_t iter = 1;
|
|
||||||
|
|
||||||
// the first iteration
|
|
||||||
auto err = compute(x, y, res);
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
// 'encoder' cocordinates
|
|
||||||
xe = x - res.dx;
|
|
||||||
ye = y - res.dy;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return MccMountDefaultPECErrorCode::ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (iter < max_iter) {
|
|
||||||
err = compute(xi, yi, res); // to encoder
|
|
||||||
if (err) {
|
|
||||||
return MccMountDefaultPECErrorCode::ERROR_INVALID_INPUTS_BISPLEV;
|
|
||||||
}
|
|
||||||
xe = x - res.dx;
|
|
||||||
ye = y - res.dy;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return MccMountDefaultPECErrorCode::ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = MccMountDefaultPECErrorCode::ERROR_EXCEED_MAX_ITERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pec_data_t _pecData;
|
pec_data_t _pecData;
|
||||||
@ -320,7 +280,7 @@ private:
|
|||||||
pec_geom_coeffs_t& _geomCoeffs;
|
pec_geom_coeffs_t& _geomCoeffs;
|
||||||
pec_bspline_coeffs_t& _bsplCoeffs;
|
pec_bspline_coeffs_t& _bsplCoeffs;
|
||||||
|
|
||||||
mutable std::mutex _pecDataMutex;
|
std::unique_ptr<std::mutex> _pecDataMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -328,6 +288,7 @@ typedef MccMountDefaultPEC<MccMountType::ALTAZ_TYPE> MccMountDefaultAltAzPec;
|
|||||||
typedef MccMountDefaultPEC<MccMountType::FORK_TYPE> MccMountDefaultForkPec;
|
typedef MccMountDefaultPEC<MccMountType::FORK_TYPE> MccMountDefaultForkPec;
|
||||||
|
|
||||||
static_assert(traits::mcc_mount_pec_c<MccMountDefaultForkPec>, "");
|
static_assert(traits::mcc_mount_pec_c<MccMountDefaultForkPec>, "");
|
||||||
|
static_assert(std::movable<MccMountDefaultForkPec>);
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
@ -45,8 +45,6 @@ public:
|
|||||||
static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
static constexpr duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
||||||
static constexpr duration_t zeroDuration{0.0};
|
static constexpr duration_t zeroDuration{0.0};
|
||||||
|
|
||||||
//
|
|
||||||
// TODO: add context (e.g. TT-TAI, UT1-UTC, geo location and so on)!!!
|
|
||||||
MccAltLimitPZ(const MccAngle& alt_limit, const MccAngle& lat)
|
MccAltLimitPZ(const MccAngle& alt_limit, const MccAngle& lat)
|
||||||
// : MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
// : MccProhibitedZone(KIND == MccAltLimitKind::MIN_ALT_LIMIT ? "MINALT-ZONE"
|
||||||
// : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
// : KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||||
|
|||||||
@ -148,6 +148,32 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MccMountTelemetry(MccMountTelemetry&& other)
|
||||||
|
: base_t(std::move(other)),
|
||||||
|
_data(std::move(other._data)),
|
||||||
|
_hardware(other._hardware),
|
||||||
|
_updateMutex(std::move(other._updateMutex)),
|
||||||
|
_updateCondVar(std::move(other._updateCondVar))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MccMountTelemetry& operator=(MccMountTelemetry&& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_t::operator=(std::move(other));
|
||||||
|
|
||||||
|
_data = std::move(other._data);
|
||||||
|
_hardware = other._hardware;
|
||||||
|
_updateMutex = std::move(other._updateMutex);
|
||||||
|
_updateCondVar = std::move(other._updateCondVar);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual ~MccMountTelemetry() = default;
|
virtual ~MccMountTelemetry() = default;
|
||||||
|
|
||||||
|
|
||||||
@ -155,7 +181,7 @@ public:
|
|||||||
template <traits::mcc_celestial_point_c PointT>
|
template <traits::mcc_celestial_point_c PointT>
|
||||||
error_t setTarget(PointT tag_point)
|
error_t setTarget(PointT tag_point)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_updateMutex};
|
std::lock_guard lock{*_updateMutex};
|
||||||
|
|
||||||
auto err = this->toICRS(tag_point, _data.utc, _data.tagRA_ICRS, _data.tagDEC_ICRS);
|
auto err = this->toICRS(tag_point, _data.utc, _data.tagRA_ICRS, _data.tagDEC_ICRS);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
@ -168,7 +194,7 @@ public:
|
|||||||
// target - mount coordinate difference
|
// target - mount coordinate difference
|
||||||
auto targetToMountDiff()
|
auto targetToMountDiff()
|
||||||
{
|
{
|
||||||
std::lock_guard lk(_updateMutex);
|
std::lock_guard lk(*_updateMutex);
|
||||||
|
|
||||||
coord_diff_t result;
|
coord_diff_t result;
|
||||||
|
|
||||||
@ -232,13 +258,16 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// correction for PEC
|
// compute corrections for PEC and celestial apparent coordinates
|
||||||
if constexpr (base_t::equatorialMount) {
|
if constexpr (base_t::equatorialMount) {
|
||||||
res_err = this->toApparent(point_t{.coordPairKind = MccCoordPairKind::COORDS_KIND_XY,
|
res_err = this->toApparent(point_t{.coordPairKind = MccCoordPairKind::COORDS_KIND_XY,
|
||||||
.x = current_data.mntPosX,
|
.x = current_data.mntPosX,
|
||||||
.y = current_data.mntPosY},
|
.y = current_data.mntPosY},
|
||||||
current_data.utc, current_data.mntHA, current_data.mntDEC);
|
current_data.utc, current_data.mntHA, current_data.mntDEC);
|
||||||
if (!res_err) {
|
if (!res_err) {
|
||||||
|
current_data.pecX = current_data.mntHA - current_data.mntPosX;
|
||||||
|
current_data.pecY = current_data.mntDEC - current_data.mntPosY;
|
||||||
|
|
||||||
ast_err = this->_astromEngine.hadec2azalt(current_data.mntHA, current_data.mntDEC, current_data.mntAZ,
|
ast_err = this->_astromEngine.hadec2azalt(current_data.mntHA, current_data.mntDEC, current_data.mntAZ,
|
||||||
current_data.mntALT);
|
current_data.mntALT);
|
||||||
}
|
}
|
||||||
@ -248,6 +277,9 @@ public:
|
|||||||
.y = current_data.mntPosY},
|
.y = current_data.mntPosY},
|
||||||
current_data.utc, current_data.mntAZ, current_data.mntALT);
|
current_data.utc, current_data.mntAZ, current_data.mntALT);
|
||||||
if (!res_err) {
|
if (!res_err) {
|
||||||
|
current_data.pecX = current_data.mntAZ - current_data.mntPosX;
|
||||||
|
current_data.pecY = current_data.mntALT - current_data.mntPosY;
|
||||||
|
|
||||||
ast_err = this->_astromEngine.azalt2hadec(current_data.mntAZ, current_data.mntALT, current_data.mntHA,
|
ast_err = this->_astromEngine.azalt2hadec(current_data.mntAZ, current_data.mntALT, current_data.mntHA,
|
||||||
current_data.mntDEC);
|
current_data.mntDEC);
|
||||||
}
|
}
|
||||||
@ -284,12 +316,12 @@ public:
|
|||||||
return MccMountTelemetryAstromTransformErrorCode::ERROR_ASTROMETRY_COMP;
|
return MccMountTelemetryAstromTransformErrorCode::ERROR_ASTROMETRY_COMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock{_updateMutex};
|
std::lock_guard lock{*_updateMutex};
|
||||||
|
|
||||||
_data = std::move(current_data);
|
_data = std::move(current_data);
|
||||||
|
|
||||||
// notify all threads for new telemetry data
|
// notify all threads for new telemetry data
|
||||||
_updateCondVar.notify_all();
|
_updateCondVar->notify_all();
|
||||||
|
|
||||||
return MccMountTelemetryErrorCode::ERROR_OK;
|
return MccMountTelemetryErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
@ -297,7 +329,7 @@ public:
|
|||||||
|
|
||||||
error_t data(mount_telemetry_data_t& data)
|
error_t data(mount_telemetry_data_t& data)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{_updateMutex};
|
std::lock_guard lock{*_updateMutex};
|
||||||
|
|
||||||
data = _data;
|
data = _data;
|
||||||
|
|
||||||
@ -310,9 +342,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto timeout_tp = std::chrono::steady_clock::now() + timeout;
|
auto timeout_tp = std::chrono::steady_clock::now() + timeout;
|
||||||
|
|
||||||
std::unique_lock lk(_updateMutex);
|
std::unique_lock lk(*_updateMutex);
|
||||||
|
|
||||||
auto res = _updateCondVar.wait_until(
|
auto res = _updateCondVar->wait_until(
|
||||||
lk, timeout_tp, [last_time_point = _data.time_point, this]() { return last_time_point < _data.timepoint; });
|
lk, timeout_tp, [last_time_point = _data.time_point, this]() { return last_time_point < _data.timepoint; });
|
||||||
if (res == std::cv_status::timeout) {
|
if (res == std::cv_status::timeout) {
|
||||||
return MccMountTelemetryErrorCode::ERROR_DATA_TIMEOUT;
|
return MccMountTelemetryErrorCode::ERROR_DATA_TIMEOUT;
|
||||||
@ -327,8 +359,8 @@ protected:
|
|||||||
mount_telemetry_data_t _data{};
|
mount_telemetry_data_t _data{};
|
||||||
hardware_t& _hardware;
|
hardware_t& _hardware;
|
||||||
|
|
||||||
std::mutex _updateMutex;
|
std::unique_ptr<std::mutex> _updateMutex;
|
||||||
std::condition_variable _updateCondVar;
|
std::unique_ptr<std::condition_variable> _updateCondVar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -109,6 +109,41 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MccMountTelemetryAstromTransform(MccMountTelemetryAstromTransform&& other)
|
||||||
|
: _pec(other._pec), _astromEngine(other._astromEngine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MccMountTelemetryAstromTransform& operator=(MccMountTelemetryAstromTransform&& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pec = other._pec;
|
||||||
|
_astromEngine = other._astromEngine;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccMountTelemetryAstromTransform(const MccMountTelemetryAstromTransform& other)
|
||||||
|
: _pec(other._pec), _astromEngine(other._astromEngine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MccMountTelemetryAstromTransform& operator=(const MccMountTelemetryAstromTransform& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pec = other._pec;
|
||||||
|
_astromEngine = other._astromEngine;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~MccMountTelemetryAstromTransform() = default;
|
virtual ~MccMountTelemetryAstromTransform() = default;
|
||||||
|
|
||||||
template <traits::mcc_celestial_point_c CT>
|
template <traits::mcc_celestial_point_c CT>
|
||||||
@ -189,9 +224,12 @@ public:
|
|||||||
}
|
}
|
||||||
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_AZALT) { // from app AZ-ALT
|
} else if (coord.coordPairKind == MccCoordPairKind::COORDS_KIND_AZALT) { // from app AZ-ALT
|
||||||
if constexpr (equatorialMount) {
|
if constexpr (equatorialMount) {
|
||||||
ast_err = azalt2hadec(coord.x, coord.y, X_app, Y_app); // compute HA-DEC
|
ast_err = _astromEngine.azalt2hadec(coord.x, coord.y, X_app, Y_app); // compute HA-DEC
|
||||||
if (!ast_err) { // compute CIO RA (as XX_app)
|
if (!ast_err) { // compute CIO RA (as XX_app)
|
||||||
ast_err = toApparent(X_app, Y_app, X_app, Y_app, XX_app);
|
coord.coordPairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP;
|
||||||
|
coord.x = X_app;
|
||||||
|
coord.y = Y_app;
|
||||||
|
ast_err = toApparent(std::move(coord), std::move(time_point), X_app, Y_app, XX_app);
|
||||||
}
|
}
|
||||||
} else if (altAzMount) {
|
} else if (altAzMount) {
|
||||||
X_app = coord.x;
|
X_app = coord.x;
|
||||||
@ -465,4 +503,5 @@ protected:
|
|||||||
pec_t& _pec;
|
pec_t& _pec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
@ -95,5 +95,29 @@ auto mccCheckInZonePZTuple(const TelemetryDataT& telemetry_data,
|
|||||||
}(std::make_index_sequence<sizeof...(ZTs)>{});
|
}(std::make_index_sequence<sizeof...(ZTs)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <traits::mcc_mount_telemetry_data_c TelemetryDataT,
|
||||||
|
traits::mcc_irange_of_pzones_c<TelemetryDataT> RT,
|
||||||
|
std::ranges::output_range<bool> ResT>
|
||||||
|
auto mccCheckInZonePZRange(const TelemetryDataT& telemetry_data, const RT& pzones, ResT& result)
|
||||||
|
{
|
||||||
|
auto Npz = std::ranges::distance(pzones);
|
||||||
|
if (!Npz) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res_sz = std::ranges::distance(result);
|
||||||
|
|
||||||
|
size_t i = 1;
|
||||||
|
auto res_iter = result.begin();
|
||||||
|
for (auto& el : pzones) {
|
||||||
|
if (i > res_sz) {
|
||||||
|
std::back_inserter(result) = el.inZone(telemetry_data);
|
||||||
|
} else {
|
||||||
|
std::ranges::advance(res_iter, 1);
|
||||||
|
*res_iter = el.inZone(telemetry_data);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
@ -150,10 +150,25 @@ public:
|
|||||||
init(telemetry, hardware, prohibited_zone);
|
init(telemetry, hardware, prohibited_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
MccSimpleSlewModel(MccSimpleSlewModel&&) = default;
|
MccSimpleSlewModel(MccSimpleSlewModel&& other)
|
||||||
MccSimpleSlewModel& operator=(MccSimpleSlewModel&&) = default;
|
: _stopRequested(other._stopRequested.load()), _slewFunc(std::move(other._slewFunc))
|
||||||
MccSimpleSlewModel(const MccSimpleSlewModel&) = default;
|
{
|
||||||
MccSimpleSlewModel& operator=(const MccSimpleSlewModel&) = default;
|
}
|
||||||
|
|
||||||
|
MccSimpleSlewModel& operator=(MccSimpleSlewModel&& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopRequested = other._stopRequested.load();
|
||||||
|
_slewFunc = std::move(_slewFunc);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
MccSimpleSlewModel(const MccSimpleSlewModel&) = delete;
|
||||||
|
MccSimpleSlewModel& operator=(const MccSimpleSlewModel&) = delete;
|
||||||
|
|
||||||
virtual ~MccSimpleSlewModel()
|
virtual ~MccSimpleSlewModel()
|
||||||
{
|
{
|
||||||
@ -422,5 +437,6 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::movable<MccSimpleSlewModel<>>);
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user