...
This commit is contained in:
parent
743ade7916
commit
2faa3f0aca
@ -125,7 +125,7 @@ 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
|
||||
mcc_mount_pec.h mcc_mount_pz.h mcc_traits.h mcc_mount_telemetry.h mcc_mount_config.h mcc_mount_astro_erfa.h mcc_astrom_iers.h mcc_astrom_iers_default.h
|
||||
mcc_utils.h mcc_spdlog.h)
|
||||
mcc_slew_model.h mcc_utils.h mcc_spdlog.h)
|
||||
set(MCC_LIBRARY mcc)
|
||||
add_library(${MCC_LIBRARY} INTERFACE ${MCC_LIBRARY_SRC})
|
||||
target_compile_features(${MCC_LIBRARY} INTERFACE cxx_std_23)
|
||||
|
||||
@ -119,6 +119,8 @@ AsibFM700Hardware::error_t AsibFM700Hardware::getPos(AsibFM700Hardware::axes_pos
|
||||
// according to hardware configuration (encoders pins (Eddy said)) X is DEC-axis and Y is HA-axis
|
||||
pos.x = data.encposition.Y;
|
||||
pos.y = data.encposition.X;
|
||||
|
||||
// ERROR: how can I get rates?!!!!!!!!!!
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
@ -69,6 +69,7 @@ public:
|
||||
struct axes_pos_t {
|
||||
time_point_t time_point;
|
||||
coord_t x, y;
|
||||
coord_t xrate, yrate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -171,11 +171,15 @@ concept mcc_mount_hardware_c = !std::copyable<T> && std::movable<T> && requires(
|
||||
|
||||
{ t_const.id() } -> mcc_formattable;
|
||||
|
||||
// a class that contains at least time of measurement and coordinates for x,y axes
|
||||
// a class that contains at least time of measurement, coordinates for x,y axes and its moving rates
|
||||
requires requires(typename T::axes_pos_t pos) {
|
||||
requires std::same_as<decltype(pos.time_point), typename T::time_point_t>;
|
||||
|
||||
requires std::same_as<decltype(pos.x), typename T::coord_t>;
|
||||
requires std::same_as<decltype(pos.y), typename T::coord_t>;
|
||||
|
||||
requires std::same_as<decltype(pos.xrate), typename T::coord_t>;
|
||||
requires std::same_as<decltype(pos.yrate), typename T::coord_t>;
|
||||
};
|
||||
|
||||
{ t.setPos(std::declval<typename T::axes_pos_t>()) } -> std::same_as<typename T::error_t>;
|
||||
@ -223,21 +227,20 @@ concept mcc_mount_telemetry_data_c = requires(T telemetry) {
|
||||
typename T::coord_t;
|
||||
typename T::time_point_t;
|
||||
|
||||
// // target current coordinates
|
||||
// requires std::same_as<decltype(telemetry.tagRA), typename T::coord_t>; // apparent RA
|
||||
// requires std::same_as<decltype(telemetry.tagDEC), typename T::coord_t>; // apparent DEC
|
||||
// requires std::same_as<decltype(telemetry.tagHA), typename T::coord_t>; // hour angle
|
||||
// requires std::same_as<decltype(telemetry.tagAZ), typename T::coord_t>; // azimuth
|
||||
// requires std::same_as<decltype(telemetry.tagALT), typename T::coord_t>; // altitude
|
||||
// time point
|
||||
requires std::same_as<decltype(telemetry.time_point), typename T::time_point_t>;
|
||||
|
||||
// mount current coordinates
|
||||
requires std::same_as<decltype(telemetry.mntRA), typename T::coord_t>; // apparent RA
|
||||
requires std::same_as<decltype(telemetry.mntDEC), typename T::coord_t>; // apparent DEC
|
||||
requires std::same_as<decltype(telemetry.mntHA), typename T::coord_t>; // hour angle
|
||||
requires std::same_as<decltype(telemetry.mntAZ), typename T::coord_t>; // azimuth
|
||||
requires std::same_as<decltype(telemetry.mntALT), typename T::coord_t>; // altitude
|
||||
requires std::same_as<decltype(telemetry.mntPosX), typename T::coord_t>; // hardware encoder X-axis position
|
||||
requires std::same_as<decltype(telemetry.mntPosY), typename T::coord_t>; // hardware encoder Y-axis position
|
||||
requires std::same_as<decltype(telemetry.mntRA), typename T::coord_t>; // apparent RA
|
||||
requires std::same_as<decltype(telemetry.mntDEC), typename T::coord_t>; // apparent DEC
|
||||
requires std::same_as<decltype(telemetry.mntHA), typename T::coord_t>; // hour angle
|
||||
requires std::same_as<decltype(telemetry.mntAZ), typename T::coord_t>; // azimuth
|
||||
requires std::same_as<decltype(telemetry.mntALT), typename T::coord_t>; // altitude
|
||||
|
||||
requires std::same_as<decltype(telemetry.mntPosX), typename T::coord_t>; // hardware encoder X-axis position
|
||||
requires std::same_as<decltype(telemetry.mntPosY), typename T::coord_t>; // hardware encoder Y-axis position
|
||||
requires std::same_as<decltype(telemetry.mntRateX), typename T::coord_t>; // hardware encoder X-axis rate
|
||||
requires std::same_as<decltype(telemetry.mntRateY), typename T::coord_t>; // hardware encoder Y-axis rate
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -47,6 +47,8 @@ concept mcc_mount_telemetry_enh_data_c = mcc_mount_telemetry_data_c<T> && requir
|
||||
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one
|
||||
requires std::same_as<decltype(t.mntPosX), typename T::coord_t>;
|
||||
requires std::same_as<decltype(t.mntPosY), typename T::coord_t>;
|
||||
requires std::same_as<decltype(t.mntRateX), typename T::coord_t>;
|
||||
requires std::same_as<decltype(t.mntRateY), typename T::coord_t>;
|
||||
|
||||
// current refraction coefficients
|
||||
requires std::same_as<decltype(t.currRefrCoeffs), typename PEC_T::pec_result_t>;
|
||||
@ -72,7 +74,7 @@ struct MccMountTelemetryData {
|
||||
typedef typename ASTROM_ENGINE_T::pa_t pa_t;
|
||||
|
||||
// time-related
|
||||
time_point_t utc; // time point of measurements, UTC
|
||||
time_point_t time_point; // time point of measurements, UTC
|
||||
juldate_t jd; // Julian date
|
||||
sideral_time_t siderTime; // local apperant sideral time
|
||||
|
||||
@ -82,9 +84,10 @@ struct MccMountTelemetryData {
|
||||
coord_t mntAZ, mntALT;
|
||||
pa_t mntPA;
|
||||
|
||||
// encoder-measured (non-corrected for PCS) current mount position
|
||||
// encoder-measured (non-corrected for PCS) current mount position and axes rates
|
||||
// X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ALT for horizontal-type one
|
||||
coord_t mntPosX, mntPosY;
|
||||
coord_t mntRateX, mntRateY;
|
||||
|
||||
// current refraction coefficients
|
||||
typename PEC_T::pec_result_t currRefrCoeffs;
|
||||
@ -163,9 +166,11 @@ public:
|
||||
_data.utc = ax_pos.time_point;
|
||||
_data.mntPosX = static_cast<typename astrom_engine_t::coord_t>(ax_pos.x);
|
||||
_data.mntPosY = static_cast<typename astrom_engine_t::coord_t>(ax_pos.y);
|
||||
_data.mntRateX = static_cast<typename astrom_engine_t::coord_t>(ax_pos.xrate);
|
||||
_data.mntRateY = static_cast<typename astrom_engine_t::coord_t>(ax_pos.yrate);
|
||||
|
||||
// compute Julian date
|
||||
auto ast_err = _astromEngine.greg2jul(_data.utc, _data.jd);
|
||||
auto ast_err = _astromEngine.greg2jul(_data.time_point, _data.jd);
|
||||
if (ast_err) {
|
||||
return TEL_ERROR_ASTROMETRY_COMP;
|
||||
}
|
||||
|
||||
@ -19,7 +19,8 @@ enum class MccSimpleSlewModelErrorCode : int {
|
||||
ERROR_ASTROM_COMP,
|
||||
ERROR_TELEMETRY_DATA,
|
||||
ERROR_PEC_COMP,
|
||||
ERROR_HARDWARE_SETPOS
|
||||
ERROR_HARDWARE_SETPOS,
|
||||
ERROR_SLEW_TIMEOUT
|
||||
};
|
||||
|
||||
} // namespace mcc
|
||||
@ -105,12 +106,29 @@ public:
|
||||
coord_t x{0.0};
|
||||
coord_t y{0.0};
|
||||
|
||||
// if <= 0 then hardware must assume default rate
|
||||
coord_t xrate{-1};
|
||||
coord_t yrate{-1};
|
||||
|
||||
bool stop{false};
|
||||
};
|
||||
|
||||
|
||||
struct context_t {
|
||||
// double eps{0.01};
|
||||
// size_t maxIter{5};
|
||||
|
||||
slew_params_t::coord_t guidingRateX;
|
||||
slew_params_t::coord_t guidingRateY;
|
||||
slew_params_t::coord_t guidingRateEps;
|
||||
size_t maxRateCycles{5};
|
||||
|
||||
std::chrono::seconds timeout{300};
|
||||
};
|
||||
|
||||
|
||||
template <traits::mcc_mount_controls_c MOUNT_CONTROLS_T>
|
||||
MccSimpleSlewModel(MOUNT_CONTROLS_T& mount_controls)
|
||||
MccSimpleSlewModel(MOUNT_CONTROLS_T& mount_controls, context_t context)
|
||||
{
|
||||
// deduce controls types
|
||||
using astrom_engine_t = decltype(mount_controls.astrometryEngine);
|
||||
@ -159,7 +177,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
_slewFunc = [p_mount_controls, check_zones](this auto&& self, const slew_params_t& slew_pars) {
|
||||
_slewFunc = [p_mount_controls, context = std::move(context), check_zones](this auto&& self,
|
||||
slew_params_t slew_pars) {
|
||||
auto& astrom_engine = p_mount_controls->astrometryEngine;
|
||||
auto& hardware = p_mount_controls->hardware;
|
||||
auto& pec = p_mount_controls->PEC;
|
||||
@ -178,6 +197,9 @@ public:
|
||||
// trivial case (the pair is interpretated as raw encoder coordinates)
|
||||
ax_pos.x = slew_pars.x;
|
||||
ax_pos.y = slew_pars.y;
|
||||
ax_pos.xrate = slew_pars.xrate;
|
||||
ax_pos.yrate = slew_pars.yrate;
|
||||
|
||||
} else if (slew_pars.coordPairKind ==
|
||||
mcc::MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { // catalog coordinates
|
||||
jd_t jd;
|
||||
@ -191,15 +213,17 @@ public:
|
||||
|
||||
if (!ast_err) {
|
||||
if constexpr (mccIsEquatorialMount(pec_t::mountType)) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||
.x = ha,
|
||||
.y = dec_app,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP;
|
||||
slew_pars.x = ha;
|
||||
slew_pars.y = dec_app;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||
.x = az,
|
||||
.y = alt,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT;
|
||||
slew_pars.x = az;
|
||||
slew_pars.y = alt;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
} else {
|
||||
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
||||
}
|
||||
@ -218,10 +242,10 @@ public:
|
||||
if (!ast_err) {
|
||||
ast_err = astrom_engine->eqOrigins(jd, eo);
|
||||
if (!ast_err) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||
.x = lst - slew_pars.x + eo, // HA = LST - RA_APP + EO
|
||||
.y = slew_pars.y,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP;
|
||||
slew_pars.x = lst - slew_pars.x + eo; // HA = LST - RA_APP + EO
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -231,12 +255,14 @@ public:
|
||||
|
||||
typename pec_t::pec_result_t pec_res;
|
||||
|
||||
pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
||||
// pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, context.eps, context.maxIter);
|
||||
pec_err = pec->compute(slew_pars.x, slew_pars.y, pec_res);
|
||||
if (!pec_err) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
||||
.x = slew_pars.x - pec_res.dx,
|
||||
.y = slew_pars.y - pec_res.dy,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY;
|
||||
slew_pars.x -= pec_res.dx;
|
||||
slew_pars.y -= pec_res.dy;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) {
|
||||
coord_t az, alt;
|
||||
@ -244,10 +270,11 @@ public:
|
||||
ast_err = astrom_engine->hadec2azalt(slew_pars.x, slew_pars.y, az, alt);
|
||||
|
||||
if (!ast_err) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||
.x = az,
|
||||
.y = alt,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT;
|
||||
slew_pars.x = az;
|
||||
slew_pars.y = alt;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
} else {
|
||||
static_assert(false, "UNKNOWN MOUNT TYPE!");
|
||||
@ -259,22 +286,25 @@ public:
|
||||
ast_err = astrom_engine->azalt2hadec(slew_pars.x, slew_pars.y, ha, dec);
|
||||
|
||||
if (!ast_err) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP,
|
||||
.x = ha,
|
||||
.y = dec,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_HADEC_APP;
|
||||
slew_pars.x = ha;
|
||||
slew_pars.y = dec;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
} else if constexpr (mccIsAltAzMount(pec_t::mountType)) { // compute encoder coordinates
|
||||
coord_t eps = 1.0 / 3600.0 * std::numbers::pi / 180.0;
|
||||
|
||||
typename pec_t::pec_result_t pec_res;
|
||||
|
||||
pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, eps, 10);
|
||||
// pec_err = pec->reverseCompute(slew_pars.x, slew_pars.y, pec_res, context.eps, context.maxIter);
|
||||
pec_err = pec->compute(slew_pars.x, slew_pars.y, pec_res);
|
||||
if (!pec_err) {
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY,
|
||||
.x = slew_pars.x - pec_res.dx,
|
||||
.y = slew_pars.y - pec_res.dy,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_XY;
|
||||
slew_pars.x -= pec_res.dx;
|
||||
slew_pars.y -= pec_res.dy;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -284,10 +314,9 @@ public:
|
||||
//
|
||||
// WARNING: it is assumed that coordinates are in radians!
|
||||
//
|
||||
res_err = self({.coordPairKind = mcc::MccCoordPairKind::COORDS_KIND_AZALT,
|
||||
.x = slew_pars.x,
|
||||
.y = std::numbers::pi / 2.0 - slew_pars.y,
|
||||
.stop = slew_pars.stop});
|
||||
slew_pars.y = std::numbers::pi / 2.0 - slew_pars.y;
|
||||
|
||||
res_err = self(std::move(slew_pars));
|
||||
}
|
||||
|
||||
if (res_err) {
|
||||
@ -324,9 +353,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// what is the condition for mount reaches given position?!!
|
||||
//
|
||||
size_t i_iter = 0;
|
||||
|
||||
context.guidingRateEps *= context.guidingRateEps;
|
||||
|
||||
typename telemetry_t::mount_telemetry_data_t::time_point_t prev_time_point{};
|
||||
typename telemetry_t::mount_telemetry_data_t::coord_t xrate, yrate, mount_rate2;
|
||||
|
||||
auto start_poll_tm = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (true) {
|
||||
// check prohibited zones
|
||||
res_err = check_zones(std::make_index_sequence<Nzones>{});
|
||||
@ -347,6 +382,40 @@ public:
|
||||
return MccSimpleSlewModelErrorCode::ERROR_TELEMETRY_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_time_point == t_data.time_point) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slew_pars.stop) { // slew and stop, so mount moving rate must be 0 at the end
|
||||
mount_rate2 = t_data.mntRateX * t_data.mntRateX + t_data.mntRateY * t_data.mntRateY;
|
||||
|
||||
if (utils::isEqual((double)mount_rate2, 0.0)) {
|
||||
++i_iter;
|
||||
} else {
|
||||
i_iter = 0;
|
||||
}
|
||||
} else { // slew and guiding, so mount rate must be near guiding rate at the end
|
||||
xrate = t_data.mntRateX - context.guidingRateX;
|
||||
yrate = t_data.mntRateY - context.guidingRateY;
|
||||
mount_rate2 = xrate * xrate + yrate * yrate;
|
||||
|
||||
if (mount_rate2 <= context.guidingRateEps) {
|
||||
++i_iter;
|
||||
} else {
|
||||
i_iter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_iter >= context.maxRateCycles) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev_time_point = t_data.time_point;
|
||||
|
||||
if ((std::chrono::high_resolution_clock::now() - start_poll_tm) > context.timeout) {
|
||||
return MccSimpleSlewModelErrorCode::ERROR_SLEW_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -354,9 +423,9 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
error_t slew(const slew_params_t& pars)
|
||||
error_t slew(slew_params_t pars)
|
||||
{
|
||||
error_t res_err = _slewFunc(pars);
|
||||
error_t res_err = _slewFunc(std::move(pars));
|
||||
|
||||
return res_err;
|
||||
}
|
||||
|
||||
@ -12,9 +12,11 @@ struct tel_data_t {
|
||||
typedef mcc::MccAngle coord_t;
|
||||
typedef std::chrono::system_clock::time_point time_point_t;
|
||||
|
||||
time_point_t time_point;
|
||||
coord_t mntRA, mntDEC, mntHA;
|
||||
coord_t mntAZ, mntALT;
|
||||
coord_t mntPosX, mntPosY;
|
||||
coord_t mntRateX, mntRateY;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
@ -207,7 +209,7 @@ int main(int argc, char* argv[])
|
||||
mcc::MccMinAltPZ minalt_pz(10.0_degs, state.lat);
|
||||
mcc::MccMaxAltPZ maxalt_pz(85.0_degs, state.lat);
|
||||
|
||||
tel_data_t tdata{ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
|
||||
tel_data_t tdata{std::chrono::system_clock::now(), ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
bool ask = minalt_pz.inZone(tdata);
|
||||
std::cout << "in zone? " << std::boolalpha << ask << "\n";
|
||||
@ -242,7 +244,7 @@ int main(int argc, char* argv[])
|
||||
std::cout << "DEC_app = " << dec_o.sexagesimal() << "\n";
|
||||
|
||||
|
||||
tdata = {ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0};
|
||||
tdata = {std::chrono::system_clock::now(), ra_o, dec_o, ha1, az1, alt1, 0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
jd.mjd += 1.0;
|
||||
res = erfa.icrs2obs(ra1, dec1, jd, ra_o, dec_o, ha1, az1, alt1, eor);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user