...
This commit is contained in:
@@ -560,9 +560,11 @@ concept mcc_pcm_c = std::derived_from<T, mcc_pcm_interface_t<typename T::error_t
|
||||
requires mcc_error_c<typename T::error_t>;
|
||||
|
||||
// the 'T' class must contain static constexpr member of 'MccMountType' type
|
||||
requires std::same_as<decltype(T::mountType), const MccMountType>;
|
||||
requires std::same_as<decltype(T::pcmMountType), const MccMountType>;
|
||||
// requires std::same_as<decltype(T::mountType), const MccMountType>;
|
||||
[]() {
|
||||
[[maybe_unused]] static constexpr MccMountType val = T::mountType;
|
||||
// [[maybe_unused]] static constexpr MccMountType val = T::mountType;
|
||||
[[maybe_unused]] static constexpr MccMountType val = T::pcmMountType;
|
||||
}(); // to ensure 'mountType' can be used in compile-time context
|
||||
|
||||
// static const variable with name of PCM
|
||||
@@ -664,9 +666,9 @@ concept mcc_hardware_c = requires(T t) {
|
||||
|
||||
|
||||
// the 'T' class must contain static constexpr member of 'MccMountType' type
|
||||
requires std::same_as<decltype(T::mountType), const MccMountType>;
|
||||
requires std::same_as<decltype(T::hwMountType), const MccMountType>;
|
||||
[]() {
|
||||
[[maybe_unused]] static constexpr MccMountType val = T::mountType;
|
||||
[[maybe_unused]] static constexpr MccMountType val = T::hwMountType;
|
||||
}(); // to ensure 'mountType' can be used in compile-time context
|
||||
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ protected:
|
||||
|
||||
std::string formatError(error_t const& err, std::string_view prefix = "") const
|
||||
{
|
||||
return std::format("{}{} (category: {}, code: {})", prefix, err.message(), err.value(), err.category().name());
|
||||
return std::format("{}{} (category: {}, code: {})", prefix, err.message(), err.category().name(), err.value());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#include "mcc/mcc_coordinate.h"
|
||||
#include "mcc_concepts.h"
|
||||
@@ -370,8 +371,8 @@ public:
|
||||
// calculate coordinates at current speed '_currentParams.minTimeToPZone' seconds ahead
|
||||
// and check them for getting into the prohibited zones
|
||||
|
||||
std::conditional_t<mccIsEquatorialMount(HARDWARE_T::mountType), MccSkyHADEC_OBS,
|
||||
std::conditional_t<mccIsAltAzMount(HARDWARE_T::mountType), MccSkyAZZD, std::nullptr_t>>
|
||||
std::conditional_t<mccIsEquatorialMount(HARDWARE_T::hwMountType), MccSkyHADEC_OBS,
|
||||
std::conditional_t<mccIsAltAzMount(HARDWARE_T::hwMountType), MccSkyAZZD, std::nullptr_t>>
|
||||
mount_pos;
|
||||
|
||||
static_assert(!std::is_null_pointer_v<decltype(mount_pos)>, "UNKNOWn MOUNT TYPE");
|
||||
@@ -440,17 +441,17 @@ public:
|
||||
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,
|
||||
std::conditional_t<mccIsAltAzMount(HARDWARE_T::mountType), MccSkyAZZD, std::nullptr_t>>
|
||||
std::conditional_t<mccIsEquatorialMount(HARDWARE_T::hwMountType), MccSkyHADEC_OBS,
|
||||
std::conditional_t<mccIsAltAzMount(HARDWARE_T::hwMountType), MccSkyAZZD, std::nullptr_t>>
|
||||
coord_pair;
|
||||
|
||||
static_assert(!std::is_null_pointer_v<decltype(coord_pair)>, "UNKNOWN MOUNT TYPE!");
|
||||
|
||||
const std::string_view x_str = mccIsEquatorialMount(HARDWARE_T::mountType) ? "HA"
|
||||
: mccIsAltAzMount(HARDWARE_T::mountType) ? "AZ"
|
||||
const std::string_view x_str = mccIsEquatorialMount(HARDWARE_T::hwMountType) ? "HA"
|
||||
: mccIsAltAzMount(HARDWARE_T::hwMountType) ? "AZ"
|
||||
: "GEN_X";
|
||||
const std::string_view y_str = mccIsEquatorialMount(HARDWARE_T::mountType) ? "DEC"
|
||||
: mccIsAltAzMount(HARDWARE_T::mountType) ? "ZD"
|
||||
const std::string_view y_str = mccIsEquatorialMount(HARDWARE_T::hwMountType) ? "DEC"
|
||||
: mccIsAltAzMount(HARDWARE_T::hwMountType) ? "ZD"
|
||||
: "GEN_Y";
|
||||
;
|
||||
|
||||
@@ -529,7 +530,7 @@ public:
|
||||
if (!_currentParams.slewingPathFilename.empty()) { // open slewing trajectory file
|
||||
_pathFile.setFilename(_currentParams.slewingPathFilename);
|
||||
} else {
|
||||
logger->logError("Slewing path filename is empty! Do not save it!");
|
||||
logger->logWarn("Slewing path filename is empty! Do not save it!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,7 +603,7 @@ public:
|
||||
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;
|
||||
mcc_deduced_coord_pair_t<HARDWARE_T::hwMountType> tag_cp, mnt_cp;
|
||||
|
||||
while (!*_stopMoving) {
|
||||
t_err = telemetry->telemetryData(&tdata);
|
||||
@@ -695,6 +696,9 @@ public:
|
||||
if (_lastError->load()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// sleep here
|
||||
std::this_thread::sleep_for(_currentParams.slewingTelemetryInterval);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,11 +724,15 @@ public:
|
||||
auto ccte_err = tdata.targetPos.to(tag_cp);
|
||||
if (ccte_err) {
|
||||
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
|
||||
(*cb_sptr)(STATUS_T::MOUNT_STATUS_ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
ccte_err = tdata.mountPos.to(mnt_cp);
|
||||
if (ccte_err) {
|
||||
*_lastError = mcc_deduced_err(ccte_err, MccSimpleMovementControlsErrorCode::ERROR_CCTE_COMP);
|
||||
(*cb_sptr)(STATUS_T::MOUNT_STATUS_ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -742,6 +750,152 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_trackingFunc = [telemetry, cb_sptr, logger, this]() {
|
||||
double braking_accelX, braking_accelY;
|
||||
double min_time_to_pzone_in_secs;
|
||||
|
||||
|
||||
{
|
||||
// std::lock_guard lock{*_currentParamsMutex};
|
||||
if (mcc::utils::isEqual(_currentParams.brakingAccelX, 0.0)) {
|
||||
braking_accelX = std::numeric_limits<double>::min();
|
||||
} else {
|
||||
braking_accelX = std::abs(_currentParams.brakingAccelX);
|
||||
}
|
||||
|
||||
if (mcc::utils::isEqual(_currentParams.brakingAccelY, 0.0)) {
|
||||
braking_accelY = std::numeric_limits<double>::min();
|
||||
} else {
|
||||
braking_accelY = std::abs(_currentParams.brakingAccelY);
|
||||
}
|
||||
|
||||
min_time_to_pzone_in_secs =
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(_currentParams.minTimeToPZone).count();
|
||||
|
||||
if (!_currentParams.trackingPathFilename.empty()) { // open slewing trajectory file
|
||||
_pathFile.setFilename(_currentParams.trackingPathFilename);
|
||||
} else {
|
||||
logger->logWarn("Tracking path filename is empty! Do not save it!");
|
||||
}
|
||||
}
|
||||
|
||||
logger->logInfo("Start tracking");
|
||||
logger->logInfo(std::format(" braking acceleration X: {} degs/s^2 (in config: {} rads/s^2)",
|
||||
MccAngle(braking_accelX).degrees(), _currentParams.brakingAccelX));
|
||||
logger->logInfo(std::format(" braking acceleration Y: {} degs/s^2 (in config: {} rads/s^2)",
|
||||
MccAngle(braking_accelY).degrees(), _currentParams.brakingAccelY));
|
||||
logger->logInfo(std::format(" min time to prohibited zone: {} seconds", min_time_to_pzone_in_secs));
|
||||
|
||||
|
||||
_pathFile << "# \n";
|
||||
_pathFile << "# Tracking trajectory, " << std::chrono::system_clock::now() << "\n";
|
||||
_pathFile << "# \n";
|
||||
_pathFile << "# Format (time is in nanoseconds, coordinates are in radians): \n";
|
||||
_pathFile << "# <UNIXTIME> <target X> <target Y> <mount X> <mount Y> <dX_{target-mount}> "
|
||||
"<dY_{target-mount}> <moving state>\n";
|
||||
|
||||
|
||||
typename TELEMETRY_T::telemetry_data_t tdata;
|
||||
typename HARDWARE_T::hardware_state_t hw_state;
|
||||
|
||||
auto t_err = telemetry->telemetryData(&tdata);
|
||||
if (t_err) {
|
||||
*_lastError = mcc_deduced_err(t_err, MccSimpleMovementControlsErrorCode::ERROR_GET_TELEMETRY);
|
||||
(*cb_sptr)(STATUS_T::MOUNT_STATUS_ERROR);
|
||||
|
||||
_pathFile.save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
*_lastError = check_pzones(tdata, min_time_to_pzone_in_secs, braking_accelX, braking_accelY);
|
||||
if (_lastError->load()) {
|
||||
_pathFile.save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
hw_state.movementState = HARDWARE_T::hardware_movement_state_t::HW_MOVE_TRACKING;
|
||||
|
||||
auto last_hw_time = tdata.hwState.XY.epoch().UTC();
|
||||
|
||||
mcc_deduced_coord_pair_t<HARDWARE_T::hwMountType> tag_cp, mnt_cp;
|
||||
|
||||
|
||||
while (!_stopMoving->load()) {
|
||||
t_err = telemetry->telemetryData(&tdata);
|
||||
if (t_err) {
|
||||
*_lastError = mcc_deduced_err(t_err, MccSimpleMovementControlsErrorCode::ERROR_GET_TELEMETRY);
|
||||
(*cb_sptr)(STATUS_T::MOUNT_STATUS_ERROR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
log_pos(tdata);
|
||||
|
||||
if (*_stopMoving) {
|
||||
*_lastError = MccSimpleMovementControlsErrorCode::ERROR_STOPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
*_lastError = check_pzones(tdata, min_time_to_pzone_in_secs, braking_accelX, braking_accelY);
|
||||
if (_lastError->load()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (last_hw_time == tdata.hwState.XY.epoch().UTC()) {
|
||||
logger->logTrace("Same hardware timepoint! Just continue to polling!\n\n\n\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
last_hw_time = tdata.hwState.XY.epoch().UTC();
|
||||
|
||||
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),
|
||||
std::get<1>(dist)));
|
||||
|
||||
// resend new position since target coordinates are changed in time
|
||||
hw_state.movementState = HARDWARE_T::hardware_movement_state_t::HW_MOVE_TRACKING;
|
||||
hw_state.XY.setX(tdata.targetXY.x());
|
||||
hw_state.XY.setY(tdata.targetXY.y());
|
||||
|
||||
*_lastError = send_to_hardware(hw_state);
|
||||
if (_lastError->load()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*_stopMoving) {
|
||||
*_lastError = MccSimpleMovementControlsErrorCode::ERROR_STOPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
// sleep here
|
||||
std::this_thread::sleep_for(_currentParams.trackingTelemetryInterval);
|
||||
}
|
||||
|
||||
*_stopMoving = true;
|
||||
|
||||
logger->logInfo("Tracking finished");
|
||||
auto err = _lastError->load();
|
||||
logger->logInfo(std::format(" exit code: {} {} {}", err.value(), err.category().name(), err.message()));
|
||||
|
||||
_pathFile.save();
|
||||
};
|
||||
}
|
||||
|
||||
virtual ~MccSimpleMovementControls() = default;
|
||||
|
||||
@@ -37,7 +37,7 @@ struct MccDefaultPCMCategory : public std::error_category {
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
return "ADC_GENERIC_DEVICE";
|
||||
return "MCC-DEFAULT-PCM-ERROR-CATEGORY";
|
||||
}
|
||||
|
||||
std::string message(int ec) const
|
||||
@@ -112,7 +112,8 @@ template <MccMountType MOUNT_TYPE>
|
||||
class MccDefaultPCM : public mcc_pcm_interface_t<std::error_code>
|
||||
{
|
||||
public:
|
||||
static constexpr MccMountType mountType = MOUNT_TYPE;
|
||||
// static constexpr MccMountType mountType = MOUNT_TYPE;
|
||||
static constexpr MccMountType pcmMountType = MOUNT_TYPE;
|
||||
|
||||
#ifdef USE_BSPLINE_PCM
|
||||
static constexpr std::string_view pcmName{"MCC-GEOMETRY-BSPLINES-PCM"};
|
||||
@@ -417,7 +418,8 @@ private:
|
||||
res->pcmY = geom_coeffs->zeroPointY + geom_coeffs->misalignErr1 * sinX + geom_coeffs->misalignErr2 * cosX +
|
||||
geom_coeffs->tubeFlexure * (_cosPhi * cosX * std::sin(y) - _sinPhi * cosY);
|
||||
|
||||
if constexpr (mountType == MccMountType::FORK_TYPE) {
|
||||
// if constexpr (mountType == MccMountType::FORK_TYPE) {
|
||||
if constexpr (pcmMountType == MccMountType::FORK_TYPE) {
|
||||
if (!utils::isEqual(cosX, 0.0)) {
|
||||
res->pcmY += geom_coeffs->forkFlexure / cosX;
|
||||
}
|
||||
|
||||
@@ -501,7 +501,7 @@ struct MccSerializer<VT> : MccSerializerBase {
|
||||
|
||||
// quantities in degree representation
|
||||
MccSerializerBase::angleFormatFromCoordPairType<MccCoordPairKind::COORDS_KIND_RADEC_ICRS,
|
||||
MccSerializerBase::CO_LON>(pars_d);
|
||||
MccSerializerBase::CO_LAT>(pars_d);
|
||||
|
||||
MccSerializer<MccAngle> ang_sr;
|
||||
|
||||
|
||||
@@ -113,17 +113,17 @@ public:
|
||||
|
||||
|
||||
struct telemetry_data_t {
|
||||
MccSkyPoint targetPos{};
|
||||
MccSkyPoint targetPos{}; // celestial coordinates
|
||||
|
||||
MccGenXY targetXY{};
|
||||
MccGenXY targetXY{}; // encoder coordinates
|
||||
|
||||
struct {
|
||||
double pcmX{}, pcmY{};
|
||||
} pcmReverseCorrection{};
|
||||
|
||||
MccSkyPoint mountPos{};
|
||||
MccSkyPoint mountPos{}; // celestial coordinates
|
||||
|
||||
typename HARDWARE_T::hardware_state_t hwState{};
|
||||
typename HARDWARE_T::hardware_state_t hwState{}; // here encoder coordinates
|
||||
|
||||
struct {
|
||||
double pcmX{}, pcmY{};
|
||||
@@ -216,8 +216,8 @@ public:
|
||||
mcc_deduced_err(hw_err, MccTelemetryErrorCode::ERROR_HARDWARE_GETSTATE);
|
||||
} else {
|
||||
// compute PCM corrections and observed (corrected for PCM) mount coordinates
|
||||
auto pcm_err = pcm_ptr->computePCM(_tdataPtr->hwState.XY, &_tdataPtr->pcmCorrection,
|
||||
&_tdataPtr->mountPos);
|
||||
auto pcm_err = pcm_ptr->computePCM(_tdataPtr->hwState.XY, &(_tdataPtr->pcmCorrection),
|
||||
&(_tdataPtr->mountPos));
|
||||
|
||||
if (!pcm_err) {
|
||||
// set target coordinates
|
||||
@@ -246,8 +246,9 @@ public:
|
||||
// _tdataPtr->targetPos = _enteredTargetPos;
|
||||
using pcm_t = std::remove_pointer_t<decltype(pcm_ptr)>;
|
||||
|
||||
std::conditional_t<mcc_is_equatorial_mount<pcm_t::mountType>, MccSkyHADEC_OBS,
|
||||
std::conditional_t<mcc_is_altaz_mount<pcm_t::mountType>,
|
||||
std::conditional_t<mcc_is_equatorial_mount<pcm_t::pcmMountType>,
|
||||
MccSkyHADEC_OBS,
|
||||
std::conditional_t<mcc_is_altaz_mount<pcm_t::pcmMountType>,
|
||||
MccSkyAZZD, std::nullptr_t>>
|
||||
cp;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ static std::uniform_real_distribution<double> xs_distrib(100, 700);
|
||||
static std::uniform_real_distribution<double> ys_distrib(100, 700);
|
||||
|
||||
struct hw_t {
|
||||
static constexpr mcc::MccMountType mountType{mcc::MccMountType::ALTAZ_TYPE};
|
||||
static constexpr mcc::MccMountType hwMountType{mcc::MccMountType::ALTAZ_TYPE};
|
||||
static constexpr std::string_view hardwareName{"HW-TEST"};
|
||||
|
||||
typedef int error_t;
|
||||
|
||||
Reference in New Issue
Block a user