Compare commits

...

10 Commits

Author SHA1 Message Date
1a8e1bbed0 ... 2026-02-17 18:27:57 +03:00
578339fd8b ... 2026-02-17 16:24:33 +03:00
775dedd835 ... 2026-02-17 15:59:14 +03:00
1841664b63 ... 2026-02-17 15:01:16 +03:00
5cfa67d6a1 ... 2026-02-17 15:00:45 +03:00
8dd5e4751c ... 2026-02-17 14:42:48 +03:00
b1c5b64879 ... 2026-02-17 14:41:42 +03:00
c5299d06bb ... 2026-02-17 14:23:10 +03:00
5202f8dc84 ... 2026-02-17 14:13:42 +03:00
ec7b7d8506 ... 2026-02-17 14:08:46 +03:00
6 changed files with 102 additions and 38 deletions

View File

@@ -505,8 +505,14 @@ template <typename T>
concept mcc_skypoint_c = std::derived_from<T, mcc_skypoint_interface_t> && requires(const T t_const) {
{ t_const.epoch() } -> mcc_coord_epoch_c;
// currently stored coordinates pair
// currently stored coordinates pair kind
{ t_const.pairKind() } -> std::same_as<impl::MccCoordPairKind>;
// currently stored co-longitude coordinate
{ t_const.co_lon() } -> std::convertible_to<double>;
// currently stored co-latitude coordinate
{ t_const.co_lat() } -> std::convertible_to<double>;
};
@@ -656,6 +662,14 @@ concept mcc_hardware_c = requires(T t) {
// static const variable with name of hardware
requires std::formattable<decltype(T::hardwareName), char> && std::is_const_v<decltype(T::hardwareName)>;
// the 'T' class must contain static constexpr member of 'MccMountType' type
requires std::same_as<decltype(T::mountType), const MccMountType>;
[]() {
[[maybe_unused]] static constexpr MccMountType val = T::mountType;
}(); // to ensure 'mountType' can be used in compile-time context
// a type that defines at least HW_MOVE_ERROR, HW_MOVE_STOPPING, HW_MOVE_STOPPED, HW_MOVE_SLEWING,
// HW_MOVE_ADJUSTING, HW_MOVE_TRACKING and HW_MOVE_GUIDING compile-time constants. The main purpose of this type is
// a possible tunning of hardware hardwareSetState-related commands and detect the stop and error states from
@@ -804,14 +818,14 @@ struct mcc_telemetry_interface_t {
// set target position
template <std::derived_from<mcc_telemetry_interface_t> SelfT>
RetT setTarget(this SelfT&& self, mcc_skypoint_c auto const& pt)
RetT setPointingTarget(this SelfT&& self, mcc_skypoint_c auto const& pt)
{
return std::forward<SelfT>(self).setTarget(pt);
}
// get entered target position
template <std::derived_from<mcc_telemetry_interface_t> SelfT>
RetT getTarget(this SelfT&& self, mcc_skypoint_c auto* pt)
RetT getPointingTarget(this SelfT&& self, mcc_skypoint_c auto* pt)
{
return std::forward<SelfT>(self).getTarget(pt);
}

View File

@@ -234,7 +234,7 @@ struct MccSkyRADEC_ICRS : MccCoordPair<MccAngleRA_ICRS, MccAngleDEC_ICRS> {
// ignore epoch setting (it is always J2000.0)
void setEpoch(mcc_coord_epoch_c auto const&)
{
static_assert(false, "CANNOT SET EPOCH FOR ICRS-KIND COORDINATE PAIR!!!");
// static_assert(false, "CANNOT SET EPOCH FOR ICRS-KIND COORDINATE PAIR!!!");
}
};
@@ -344,14 +344,24 @@ struct MccSkyAZALT : MccCoordPair<MccAngleAZ, MccAngleALT> {
}
};
using MccGenXY = MccCoordPair<MccAngleX, MccAngleY>;
using MccGeoLONLAT = MccCoordPair<MccAngleLON, MccAngleLAT>;
// utility type definition: deduce a coordinate pair kind according to mount type
// mcc_deduced_coord_pair_t = MccSkyHADEC_OBS for equathorial mounts,
// mcc_deduced_coord_pair_t = MccSkyAZZD for altazimuthal ones and
// mcc_deduced_coord_pair_t = std::nullptr_t otherwise
template <MccMountType MOUNT_TYPE>
using mcc_deduced_coord_pair_t =
std::conditional_t<mccIsEquatorialMount(MOUNT_TYPE),
MccSkyHADEC_OBS,
std::conditional_t<mccIsAltAzMount(MOUNT_TYPE), MccSkyAZZD, std::nullptr_t>>;
static MccSkyHADEC_APP hadec = MccGenXY{};
static MccSkyAZALT azalt{MccSkyAZZD{1.0, 1.1}};
// static MccSkyHADEC_APP hadec = MccGenXY{};
// static MccSkyAZALT azalt{MccSkyAZZD{1.0, 1.1}};
/* MCC-LIBRARY DEFAULT GENERIC SKY POINT CLASS IMPLEMENTATION */
@@ -423,6 +433,17 @@ public:
return _epoch;
}
double co_lon() const
{
return _x;
}
double co_lat() const
{
return _y;
}
template <mcc_coord_pair_c PT>
MccGenericSkyPoint& from(const PT& coord_pair)
{

View File

@@ -53,7 +53,7 @@ struct std::formatter<mcc::impl::MccError, char> {
// _currFmt.push_back(*(++it));
// }
if (it++ != ctx.end() || it++ != '}') {
if (it++ != ctx.end() || *(it++) != '}') {
_delim = *(++it);
}
case '}':

View File

@@ -271,7 +271,7 @@ protected:
private:
std::string _filename;
std::istringstream _st;
std::ostringstream _st;
};
@@ -283,29 +283,33 @@ public:
template <mcc_hardware_c HARDWARE_T,
mcc_generic_mount_c MOUNT_T, // MOUNT_T is mcc_telemetry_c, mcc_pzone_container_c and mcc_logger_c
// (see mcc_concepts.h)
mcc_mount_status_c STATUS_T,
std::invocable<STATUS_T const&> CallbackFuncT = decltype([](STATUS_T const&) {})>
std::invocable<typename MOUNT_T::mount_status_t const&> CallbackFuncT =
decltype([](typename MOUNT_T::mount_status_t const&) {})>
MccSimpleMovementControls(
HARDWARE_T* hardware,
MOUNT_T* mount,
CallbackFuncT&& mode_switch_callback = [](STATUS_T const&) {})
: MccSimpleMovementControls(hardware, mount, mount, mode_switch_callback, *mount)
CallbackFuncT&& mode_switch_callback = [](typename MOUNT_T::mount_status_t const&) {})
: MccSimpleMovementControls(hardware, mount, mount, std::forward<CallbackFuncT>(mode_switch_callback), mount)
{
}
template <mcc_hardware_c HARDWARE_T,
mcc_telemetry_c TELEMETRY_T,
mcc_pzone_container_c PZONE_CONT_T,
mcc_mount_status_c STATUS_T,
std::invocable<STATUS_T const&> CallbackFuncT = decltype([](STATUS_T const&) {}),
typename CallbackFuncT,
mcc_logger_c LOGGER_T = MccNullLogger>
MccSimpleMovementControls(
HARDWARE_T* hardware,
TELEMETRY_T* telemetry,
PZONE_CONT_T* pzone_cont,
CallbackFuncT&& mode_switch_callback = [](STATUS_T const&) {},
LOGGER_T* logger = &details::NullLogger)
MccSimpleMovementControls(HARDWARE_T* hardware,
TELEMETRY_T* telemetry,
PZONE_CONT_T* pzone_cont,
CallbackFuncT&& mode_switch_callback,
LOGGER_T* logger = &details::NullLogger)
{
static_assert(traits::mcc_func_traits<CallbackFuncT>::arity == 1 &&
mcc_mount_status_c<std::decay_t<traits::mcc_func_arg1_t<CallbackFuncT>>>,
"INVALID 'CallbackFuncT' CALLABLE SIGNATURE!");
using STATUS_T = std::decay_t<traits::mcc_func_arg1_t<CallbackFuncT>>;
auto send_to_hardware = [hardware, logger](typename HARDWARE_T::hardware_state_t const& hw_state) -> error_t {
if constexpr (std::derived_from<decltype(hw_state.XY), MccCoordPair<MccAngleX, MccAngleY>>) {
logger->logDebug(std::format("Send to hardware: X = {} degs, Y = {} degs", hw_state.XY.x().degrees(),
@@ -372,14 +376,14 @@ public:
static_assert(!std::is_null_pointer_v<decltype(mount_pos)>, "UNKNOWn MOUNT TYPE");
mount_pos.setX(tdata.hwState.XY.x() + tdata.pcmCorrection.x + dx);
mount_pos.setY(tdata.hwState.XY.y() + tdata.pcmCorrection.y + dy);
mount_pos.setX((double)tdata.hwState.XY.x() + tdata.pcmCorrection.pcmX + dx);
mount_pos.setY((double)tdata.hwState.XY.y() + tdata.pcmCorrection.pcmY + dy);
mount_pos.setEpoch(tdata.hwState.XY.epoch());
logger->logTrace(std::format(" mount: speedX = {}/s, speedY = {}/s", MccAngleFancyString(speedX),
MccAngleFancyString(speedY)));
auto pz_err = pzone_cont->inPZone(mount_pos, &in_zone, &in_zone_vec);
auto pz_err = pzone_cont->inPZone(MccSkyPoint(mount_pos), &in_zone, &in_zone_vec);
if (pz_err) {
return mcc_deduced_err(pz_err, MccSimpleMovementControlsErrorCode::ERROR_PZONE_CONTAINER_COMP);
}
@@ -433,7 +437,7 @@ public:
};
auto log_pos = [logger, this](typename TELEMETRY_T::telemetry_data_t const& tdata) {
auto log_pos = [logger, this](typename TELEMETRY_T::telemetry_data_t const& tdata) -> error_t {
double x_mnt, y_mnt, x_tag, y_tag;
std::conditional_t<mccIsEquatorialMount(HARDWARE_T::mountType), MccSkyHADEC_OBS,
@@ -470,9 +474,11 @@ public:
logger->logTrace(std::format(" current mount: {} = {}, {} = {}", x_str, coord_pair.x().sexagesimal(true),
y_str, coord_pair.y().sexagesimal()));
_pathFile << tdata.mountPos.epoch().UTC.time_since_epoch().count() << " " << x_tag << " " << y_tag << " "
_pathFile << tdata.mountPos.epoch().UTC().time_since_epoch().count() << " " << x_tag << " " << y_tag << " "
<< x_mnt << " " << y_mnt << " " << (x_tag - x_mnt) << " " << (y_tag - y_mnt) << " "
<< (int)tdata.hwState.movementState << "\n";
return MccSimpleMovementControlsErrorCode::ERROR_OK;
};
auto cb_sptr =
@@ -593,8 +599,10 @@ public:
(*cb_sptr)(STATUS_T::MOUNT_STATUS_SLEWING);
auto start_point = tdata.hwState.XY.epoch().UTC(); // needed for trajectory file
auto last_hw_time = start_point;
auto start_point = std::chrono::steady_clock::now();
auto last_hw_time = tdata.hwState.XY.epoch().UTC();
mcc_deduced_coord_pair_t<HARDWARE_T::mountType> tag_cp, mnt_cp;
while (!*_stopMoving) {
t_err = telemetry->telemetryData(&tdata);
@@ -641,8 +649,16 @@ public:
last_hw_time = tdata.hwState.XY.epoch().UTC();
auto dist = utils::distanceOnSphere(tdata.targetPos.x(), tdata.targetPos.y(), tdata.mountPos.x(),
tdata.mountPos.y());
auto ccte_err = tdata.targetPos.to(tag_cp);
if (ccte_err) {
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
}
ccte_err = tdata.mountPos.to(mnt_cp);
if (ccte_err) {
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
}
auto dist = utils::distanceOnSphere(tag_cp.x(), tag_cp.y(), mnt_cp.x(), mnt_cp.y());
logger->logTrace(std::format(" target-to-mount distance: {} (dx = {}, dy = {})",
MccAngleFancyString(std::get<2>(dist)), std::get<0>(dist),
@@ -650,7 +666,7 @@ public:
// stop slewing and exit from the cycle?
if (dist <= _currentParams.slewToleranceRadius) {
if (std::get<2>(dist) <= _currentParams.slewToleranceRadius) {
if (tdata.hwState.movementState == HARDWARE_T::hardware_movement_state_t::HW_MOVE_STOPPED ||
tdata.hwState.movementState == HARDWARE_T::hardware_movement_state_t::HW_MOVE_GUIDING) {
logger->logInfo("target-to-mount distance is lesser than slew acceptable radius - exit!");
@@ -701,8 +717,18 @@ public:
return;
}
auto dist = utils::distanceOnSphere(tdata.targetPos.x(), tdata.targetPos.y(), tdata.mountPos.x(),
tdata.mountPos.y());
auto ccte_err = tdata.targetPos.to(tag_cp);
if (ccte_err) {
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
return;
}
ccte_err = tdata.mountPos.to(mnt_cp);
if (ccte_err) {
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
return;
}
auto dist = utils::distanceOnSphere(tag_cp.x(), tag_cp.y(), mnt_cp.x(), mnt_cp.y());
log_pos(tdata);

View File

@@ -38,6 +38,7 @@
#include "mcc_concepts.h"
#include "mcc_coordinate.h"
#include "mcc_netserver_endpoint.h"
#include "mcc_netserver_proto.h"
#include "mcc_traits.h"
@@ -90,6 +91,8 @@ struct MccGenericMountNetworkServerErrorCategory : std::error_category {
defaut:
return "unknown";
};
return "unknown";
}
static const MccGenericMountNetworkServerErrorCategory& get()
@@ -1088,7 +1091,7 @@ protected:
if (vc) { // set operation
auto m_err = mount_ptr->setPointingTarget(vc.value());
if (m_err) {
err = mcc_deduce_err(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SET_TARGET);
err = mcc_deduced_err(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SET_TARGET);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
}
@@ -1182,10 +1185,10 @@ protected:
auto t_err = mount->telemetryData(&tdata);
if (t_err) {
return mcc_deduce_err(t_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_GET_TELEMETRY);
return mcc_deduced_err(t_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_GET_TELEMETRY);
}
auto get_coords = [&]<mcc_coord_pair_c T>(T& cp) {
auto get_coords = [&]<mcc_coord_pair_c T>(T& cp) -> std::error_code {
cp.setEpoch(tdata.mountPos.epoch());
if (target) {

View File

@@ -315,7 +315,7 @@ public:
}
}
error_t setTarget(mcc_skypoint_c auto const& sp)
error_t setPointingTarget(mcc_skypoint_c auto const& sp)
{
_enteredTargetPos = sp;
@@ -323,7 +323,7 @@ public:
}
error_t getTarget(mcc_skypoint_c auto* sp)
error_t getPointingTarget(mcc_skypoint_c auto* sp)
{
sp = _enteredTargetPos;