...
This commit is contained in:
parent
3d3b57a311
commit
de80acf315
@ -157,9 +157,10 @@ concept mcc_julday_c = mcc_fp_type_like_c<T> && requires(const T v) {
|
|||||||
/* ERROR CLASS CONCEPT */
|
/* ERROR CLASS CONCEPT */
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_error_c = std::convertible_to<T, bool> || requires(const T t) {
|
concept mcc_error_c = std::default_initializable<T> && (std::convertible_to<T, bool> || requires(const T t) {
|
||||||
{ t.operator bool() };
|
{ t.operator bool() };
|
||||||
};
|
(bool)T() == false; // default constucted value must be a "non-error"!
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
template <mcc_error_c ErrT, typename DErrT>
|
template <mcc_error_c ErrT, typename DErrT>
|
||||||
@ -716,13 +717,21 @@ struct mcc_pzone_interface_t {
|
|||||||
// NOTE: the method must return:
|
// NOTE: the method must return:
|
||||||
// point = mcc_celestial_point_c{.pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC, .X = NaN, .Y = NaN}
|
// point = mcc_celestial_point_c{.pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC, .X = NaN, .Y = NaN}
|
||||||
// if there is no intersection with the zone for given coordinates!
|
// if there is no intersection with the zone for given coordinates!
|
||||||
template <std::derived_from<mcc_pzone_interface_t> SelfT, typename InputT>
|
template <std::derived_from<mcc_pzone_interface_t> SelfT, typename InputT, typename ResultT>
|
||||||
RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point)
|
RetT intersectPZone(this SelfT&& self, InputT coords, ResultT* point)
|
||||||
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
requires((mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
|
(mcc_eqt_hrz_coord_c<ResultT> || mcc_celestial_point_c<ResultT>)) &&
|
||||||
requires { self.intersectPZone(coords, point); }
|
requires { self.intersectPZone(coords, point); }
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).intersectPZone(std::move(coords), point);
|
return std::forward<SelfT>(self).intersectPZone(std::move(coords), point);
|
||||||
}
|
}
|
||||||
|
// template <std::derived_from<mcc_pzone_interface_t> SelfT, typename InputT>
|
||||||
|
// RetT intersectPZone(this SelfT&& self, InputT coords, mcc_celestial_point_c auto* point)
|
||||||
|
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
|
// requires { self.intersectPZone(coords, point); }
|
||||||
|
// {
|
||||||
|
// return std::forward<SelfT>(self).intersectPZone(std::move(coords), point);
|
||||||
|
// }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mcc_pzone_interface_t() = default;
|
mcc_pzone_interface_t() = default;
|
||||||
@ -788,9 +797,17 @@ struct mcc_pzone_container_interface_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT, mcc_celestial_point_c CPT>
|
// template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT, mcc_celestial_point_c CPT>
|
||||||
RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range<CPT> auto* result)
|
// RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range<CPT> auto* result)
|
||||||
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
|
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
|
||||||
|
// {
|
||||||
|
// return std::forward<SelfT>(self).intersectPZone(std::move(coords), result);
|
||||||
|
// }
|
||||||
|
|
||||||
|
template <std::derived_from<mcc_pzone_container_interface_t> SelfT, typename InputT, typename ResultT>
|
||||||
|
RetT intersectPZone(this SelfT&& self, InputT coords, std::ranges::output_range<ResultT> auto* result)
|
||||||
|
requires((mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
|
(mcc_eqt_hrz_coord_c<ResultT> || mcc_celestial_point_c<ResultT>))
|
||||||
{
|
{
|
||||||
return std::forward<SelfT>(self).intersectPZone(std::move(coords), result);
|
return std::forward<SelfT>(self).intersectPZone(std::move(coords), result);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,37 +54,66 @@ public:
|
|||||||
typedef MccSimpleMovingModelParams guiding_params_t;
|
typedef MccSimpleMovingModelParams guiding_params_t;
|
||||||
|
|
||||||
|
|
||||||
template <mcc_telemetry_data_c TelemetryT, mcc_hardware_c HardwareT, mcc_pzone_container_c PZoneContT>
|
template <mcc_telemetry_data_c TelemetryT,
|
||||||
MccSimpleGuidingModel(TelemetryT* telemetry, HardwareT* hardware, PZoneContT* pz_cont)
|
mcc_hardware_c HardwareT,
|
||||||
|
mcc_PCM_c PcmT,
|
||||||
|
mcc_pzone_container_c PZoneContT>
|
||||||
|
MccSimpleGuidingModel(TelemetryT* telemetry, HardwareT* hardware, PcmT* pcm, PZoneContT* pz_cont)
|
||||||
: _stopGuiding(new std::atomic_bool()), _currentParamsMutex(new std::mutex())
|
: _stopGuiding(new std::atomic_bool()), _currentParamsMutex(new std::mutex())
|
||||||
{
|
{
|
||||||
_guidingFunc = [telemetry, hardware, pz_cont, this]() -> error_t {
|
_guidingFunc = [telemetry, hardware, pcm, pz_cont, this]() -> error_t {
|
||||||
typename TelemetryT::error_t t_err;
|
|
||||||
|
|
||||||
MccCelestialPoint cpt;
|
|
||||||
typename HardwareT::hardware_state_t hw_state;
|
typename HardwareT::hardware_state_t hw_state;
|
||||||
|
|
||||||
|
MccTelemetryData tdata;
|
||||||
|
MccEqtHrzCoords intsc_coords;
|
||||||
|
double dist;
|
||||||
|
|
||||||
|
auto t_err = telemetry->waitForTelemetryData(&tdata, _currentParams.telemetryTimeout);
|
||||||
|
if (t_err) {
|
||||||
|
return mcc_deduce_error<error_t>(t_err, MccSimpleGuidingModelErrorCode::ERROR_GET_TELEMETRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// compute intersection points with the prohibited zones
|
||||||
|
auto pz_err = mcc_find_closest_pzone(pz_cont, tdata, &intsc_coords);
|
||||||
|
if (pz_err) {
|
||||||
|
return mcc_deduce_error<error_t>(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool no_intersects = false;
|
||||||
|
|
||||||
if constexpr (mccIsEquatorialMount(HardwareT::mountType)) {
|
if constexpr (mccIsEquatorialMount(HardwareT::mountType)) {
|
||||||
cpt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
|
if (std::isfinite(intsc_coords.HA)) {
|
||||||
|
intsc_coords.X = intsc_coords.HA;
|
||||||
|
intsc_coords.Y = intsc_coords.DEC_APP;
|
||||||
|
} else {
|
||||||
|
no_intersects = true;
|
||||||
|
intsc_coords.X = tdata.HA + 710.0_mins; // 12h - 10min
|
||||||
|
intsc_coords.Y = tdata.DEC_APP;
|
||||||
|
}
|
||||||
} else if constexpr (mccIsAltAzMount(HardwareT::mountType)) {
|
} else if constexpr (mccIsAltAzMount(HardwareT::mountType)) {
|
||||||
cpt.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT;
|
if (std::isfinite(intsc_coords.AZ)) {
|
||||||
static_assert(false, "NOT IMPLEMENTED!");
|
intsc_coords.X = intsc_coords.AZ;
|
||||||
|
intsc_coords.Y = intsc_coords.ZD;
|
||||||
|
} else {
|
||||||
|
no_intersects = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
static_assert(false, "UNKNOW MOUNT TYPE!");
|
static_assert(false, "UNKNOW MOUNT TYPE!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute position in future
|
||||||
|
auto hw_err = hardware->hardwareGetState(&hw_state);
|
||||||
|
if (hw_err) {
|
||||||
|
return mcc_deduce_error<error_t>(hw_err, MccSimpleGuidingModelErrorCode::ERROR_HW_GETSTATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
MccPCMResult pcm_inv_res;
|
||||||
|
|
||||||
MccTelemetryData tdata;
|
// endpoint of the mount moving
|
||||||
|
auto pcm_err = pcm->computeInversePCM(intsc_coords, &pcm_inv_res, &hw_state);
|
||||||
std::vector<std::chrono::duration<double>> pz_timeto; // in seconds
|
if (pcm_err) {
|
||||||
std::chrono::duration<double> min_time{0.0};
|
return mcc_deduce_error<error_t>(pcm_err, MccSimpleGuidingModelErrorCode::ERROR_PCM_COMP);
|
||||||
std::vector<MccCelestialPoint> intsc_pt(pz_cont->sizePZones(), cpt);
|
|
||||||
|
|
||||||
// compute intersection points with the prohibited zones
|
|
||||||
auto pz_err = pz_cont->intersectPZone(tdata, &intsc_pt);
|
|
||||||
if (pz_err) {
|
|
||||||
return mcc_deduce_error<error_t>(pz_err, MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*_stopGuiding) {
|
while (*_stopGuiding) {
|
||||||
@ -99,21 +128,22 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*_stopGuiding) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// control prohibited zones
|
// control prohibited zones
|
||||||
pz_err = pz_cont->timeToPZone(tdata, &pz_timeto);
|
if (mcc_is_near_pzones(pz_cont, tdata, _currentParams.minTimeToPZone, pz_err)) {
|
||||||
|
return MccSimpleGuidingModelErrorCode::ERROR_NEAR_PZONE;
|
||||||
|
}
|
||||||
if (pz_err) {
|
if (pz_err) {
|
||||||
return mcc_deduce_error<error_t>(pz_err,
|
return mcc_deduce_error<error_t>(pz_err,
|
||||||
MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP);
|
MccSimpleGuidingModelErrorCode::ERROR_PZONE_CONTAINER_COMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
min_time = std::chrono::duration<double>{0};
|
t_err = telemetry->targetToMountDist(&dist);
|
||||||
for (size_t i = 0; i < pz_cont->sizePZones(); ++i) {
|
if (t_err) {
|
||||||
if (pz_timeto[i] < _currentParams.minTimeToPZone) {
|
return mcc_deduce_error<error_t>(t_err, MccSimpleGuidingModelErrorCode::ERROR_DIST_TELEMETRY);
|
||||||
return MccSimpleGuidingModelErrorCode::ERROR_NEAR_PZONE;
|
|
||||||
}
|
|
||||||
if (pz_timeto[i] < min_time) {
|
|
||||||
min_time = pz_timeto[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include "mcc_angle.h"
|
#include "mcc_angle.h"
|
||||||
|
#include "mcc_generics.h"
|
||||||
|
|
||||||
namespace mcc
|
namespace mcc
|
||||||
{
|
{
|
||||||
@ -60,4 +61,80 @@ struct MccSimpleMovingModelParams {
|
|||||||
bool dualAxisGuiding{true}; // mount must be of an equatorial type: false means guiding along only HA-axis
|
bool dualAxisGuiding{true}; // mount must be of an equatorial type: false means guiding along only HA-axis
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_pzone_container_c PZoneContT>
|
||||||
|
bool mcc_is_near_pzones(PZoneContT* pz_cont,
|
||||||
|
mcc_telemetry_c auto const& tdata,
|
||||||
|
traits::mcc_time_duration_c auto const& min_timeto,
|
||||||
|
typename PZoneContT::error_t& err)
|
||||||
|
{
|
||||||
|
using res_t = std::decay_t<decltype(min_timeto)>;
|
||||||
|
|
||||||
|
std::vector<res_t> pz_timeto; // in seconds
|
||||||
|
|
||||||
|
err = pz_cont->timeToPZone(tdata, &pz_timeto);
|
||||||
|
if (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& t : pz_timeto) {
|
||||||
|
if (t <= min_timeto) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_pzone_container_c PZoneContT>
|
||||||
|
typename PZoneContT::error_t mcc_find_closest_pzone(PZoneContT* pz_cont,
|
||||||
|
mcc_telemetry_c auto const& tdata,
|
||||||
|
mcc_eqt_hrz_coord_c auto* closest_coords)
|
||||||
|
{
|
||||||
|
using res_t = std::decay_t<decltype(*closest_coords)>;
|
||||||
|
|
||||||
|
if (closest_coords == nullptr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
res_t c;
|
||||||
|
|
||||||
|
mcc_tp2tp(tdata.time_point, c.time_point);
|
||||||
|
|
||||||
|
mcc_tp2tp(tdata.time_point, closest_coords->time_point);
|
||||||
|
closest_coords->X = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->Y = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->RA_APP = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->DEC_APP = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->HA = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->AZ = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->ZD = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
closest_coords->ALT = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
std::vector<res_t> pz_coords(c, pz_cont->sizePZones());
|
||||||
|
|
||||||
|
double dha, dha_min = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
auto err = pz_cont->intersectPZone(tdata, &pz_coords);
|
||||||
|
if (!err) {
|
||||||
|
for (auto const& rpt : pz_coords) {
|
||||||
|
if (std::isfinite(rpt.X) && std::isfinite(rpt.Y)) {
|
||||||
|
dha = rpt.HA - tdata.HA;
|
||||||
|
if (dha < 0.0) {
|
||||||
|
dha += std::numbers::pi * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dha < dha_min) {
|
||||||
|
dha_min = dha;
|
||||||
|
mcc_copy_eqt_hrz_coord(rpt, closest_coords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace mcc
|
} // namespace mcc
|
||||||
|
|||||||
120
mcc/mcc_pzone.h
120
mcc/mcc_pzone.h
@ -114,6 +114,24 @@ public:
|
|||||||
return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM;
|
return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_transformCoordinatesEqtHrzCoords = [ccte_engine](MccCelestialPoint from_pt,
|
||||||
|
MccEqtHrzCoords* to_pt) -> error_t {
|
||||||
|
if (to_pt == nullptr) {
|
||||||
|
return MccAltLimitPZErrorCode::ERROR_NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto err = ccte_engine->transformCoordinates(from_pt, to_pt);
|
||||||
|
if (!err) {
|
||||||
|
return MccAltLimitPZErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::same_as<decltype(err), error_t>) {
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
return MccAltLimitPZErrorCode::ERROR_COORD_TRANSFROM;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,11 +296,79 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputT>
|
// template <typename InputT>
|
||||||
error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point)
|
// error_t intersectPZone(InputT coords, mcc_celestial_point_c auto* point)
|
||||||
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
|
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
|
||||||
|
// {
|
||||||
|
// // double ha, dec, az;
|
||||||
|
// double dec, az;
|
||||||
|
|
||||||
|
// if (point == nullptr) {
|
||||||
|
// return MccAltLimitPZErrorCode::ERROR_NULLPTR;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
|
||||||
|
|
||||||
|
// if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
|
||||||
|
// // ha = coords.HA;
|
||||||
|
// dec = coords.DEC_APP;
|
||||||
|
// } else {
|
||||||
|
// MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP};
|
||||||
|
// mcc_tp2tp(coords.time_point, to_pt.time_point);
|
||||||
|
|
||||||
|
// ret = getCoord(coords, &to_pt);
|
||||||
|
// if (ret) {
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // ha = to_pt.X;
|
||||||
|
// dec = to_pt.Y;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// double sinDec = sin(dec), cosDec = cos(dec);
|
||||||
|
|
||||||
|
// auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat;
|
||||||
|
|
||||||
|
// if (cos_ha > 1.0) { // no intersection
|
||||||
|
// // point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC;
|
||||||
|
// point->X = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
// point->Y = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // WARNNIG: THE EXPRESSION ASSUMES THAT AZIMUTH IS COUNTED FROM THE SOUTH THROUGH THE WEST!!!
|
||||||
|
// double cosA = (-sinDec * _cosLat + cosDec * _sinLat * cos_ha) / _cosALim;
|
||||||
|
|
||||||
|
// if constexpr (KIND ==
|
||||||
|
// MccAltLimitKind::MIN_ALT_LIMIT) { // the closest time point is one after upper culmination
|
||||||
|
// az = std::acos(cosA);
|
||||||
|
// } else if constexpr (KIND == MccAltLimitKind::MAX_ALT_LIMIT) { // the closest time point is one before upper
|
||||||
|
// // culmination
|
||||||
|
// az = -std::acos(cosA);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .X = az, .Y = _altLimit};
|
||||||
|
// mcc_tp2tp(coords.time_point, pt.time_point);
|
||||||
|
|
||||||
|
// MccCelestialPoint to_pt{.pair_kind = point->pair_kind};
|
||||||
|
// mcc_tp2tp(point->time_point, to_pt.time_point);
|
||||||
|
|
||||||
|
// ret = _transformCoordinates(pt, &to_pt);
|
||||||
|
// if (!ret) {
|
||||||
|
// point->X = MccAngle(to_pt.X).normalize<MccAngle::NORM_KIND_0_360>();
|
||||||
|
// point->Y = MccAngle(to_pt.Y).normalize<MccAngle::NORM_KIND_90_90>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
template <typename InputT, typename ResultT>
|
||||||
|
error_t intersectPZone(InputT coords, ResultT* point)
|
||||||
|
requires((mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
|
(mcc_eqt_hrz_coord_c<ResultT> || mcc_celestial_point_c<ResultT>))
|
||||||
{
|
{
|
||||||
double ha, dec, az;
|
double dec, az;
|
||||||
|
|
||||||
if (point == nullptr) {
|
if (point == nullptr) {
|
||||||
return MccAltLimitPZErrorCode::ERROR_NULLPTR;
|
return MccAltLimitPZErrorCode::ERROR_NULLPTR;
|
||||||
@ -291,7 +377,7 @@ public:
|
|||||||
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
|
error_t ret = MccAltLimitPZErrorCode::ERROR_OK;
|
||||||
|
|
||||||
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
|
if constexpr (mcc_eqt_hrz_coord_c<InputT>) {
|
||||||
ha = coords.HA;
|
// ha = coords.HA;
|
||||||
dec = coords.DEC_APP;
|
dec = coords.DEC_APP;
|
||||||
} else {
|
} else {
|
||||||
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP};
|
MccCelestialPoint to_pt{.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP};
|
||||||
@ -302,7 +388,7 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha = to_pt.X;
|
// ha = to_pt.X;
|
||||||
dec = to_pt.Y;
|
dec = to_pt.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,11 +396,20 @@ public:
|
|||||||
|
|
||||||
auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat;
|
auto cos_ha = (_sinAlim - sinDec * _sinLat) / cosDec / _cosLat;
|
||||||
|
|
||||||
if (cos_ha > 1.0) { // no intersection
|
if (cos_ha > 1.0) { // no intersection (outputs are all NaN)
|
||||||
// point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC;
|
// point->pair_kind = MccCoordPairKind::COORDS_KIND_GENERIC;
|
||||||
point->X = std::numeric_limits<double>::quiet_NaN();
|
point->X = std::numeric_limits<double>::quiet_NaN();
|
||||||
point->Y = std::numeric_limits<double>::quiet_NaN();
|
point->Y = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
if constexpr (mcc_eqt_hrz_coord_c<ResultT>) {
|
||||||
|
point->HA = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
point->RA_APP = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
point->DEC_APP = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
point->AZ = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
point->ZD = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
point->ALT = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +427,15 @@ public:
|
|||||||
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .X = az, .Y = _altLimit};
|
MccCelestialPoint pt{.pair_kind = MccCoordPairKind::COORDS_KIND_AZALT, .X = az, .Y = _altLimit};
|
||||||
mcc_tp2tp(coords.time_point, pt.time_point);
|
mcc_tp2tp(coords.time_point, pt.time_point);
|
||||||
|
|
||||||
|
if constexpr (mcc_eqt_hrz_coord_c<ResultT>) {
|
||||||
|
MccEqtHrzCoords to_pt;
|
||||||
|
mcc_tp2tp(point->time_point, to_pt.time_point);
|
||||||
|
ret = _transformCoordinates(pt, &to_pt);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
mcc_copy_eqt_hrz_coord(to_pt, point);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
MccCelestialPoint to_pt{.pair_kind = point->pair_kind};
|
MccCelestialPoint to_pt{.pair_kind = point->pair_kind};
|
||||||
mcc_tp2tp(point->time_point, to_pt.time_point);
|
mcc_tp2tp(point->time_point, to_pt.time_point);
|
||||||
|
|
||||||
@ -340,6 +444,7 @@ public:
|
|||||||
point->X = MccAngle(to_pt.X).normalize<MccAngle::NORM_KIND_0_360>();
|
point->X = MccAngle(to_pt.X).normalize<MccAngle::NORM_KIND_0_360>();
|
||||||
point->Y = MccAngle(to_pt.Y).normalize<MccAngle::NORM_KIND_90_90>();
|
point->Y = MccAngle(to_pt.Y).normalize<MccAngle::NORM_KIND_90_90>();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -349,6 +454,7 @@ protected:
|
|||||||
double _cosLat, _sinLat, _absLat, _latLim;
|
double _cosLat, _sinLat, _absLat, _latLim;
|
||||||
|
|
||||||
std::function<error_t(MccCelestialPoint, MccCelestialPoint*)> _transformCoordinates{};
|
std::function<error_t(MccCelestialPoint, MccCelestialPoint*)> _transformCoordinates{};
|
||||||
|
std::function<error_t(MccCelestialPoint, MccEqtHrzCoords*)> _transformCoordinatesEqtHrzCoords{};
|
||||||
|
|
||||||
error_t getCoord(mcc_celestial_point_c auto const& from_pt, MccCelestialPoint* to_pt)
|
error_t getCoord(mcc_celestial_point_c auto const& from_pt, MccCelestialPoint* to_pt)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -152,18 +152,41 @@ public:
|
|||||||
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC));
|
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_TIMEFROM_FUNC));
|
||||||
});
|
});
|
||||||
|
|
||||||
_intersectZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) {
|
// _intersectZoneFuncCPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) {
|
||||||
|
// auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
|
// return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
|
// });
|
||||||
|
|
||||||
|
// _intersectZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) {
|
||||||
|
// auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
|
// return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
|
// });
|
||||||
|
|
||||||
|
_intersectZoneFuncCPT2CPT.emplace_back([sptr](const MccCelestialPoint& pt, MccCelestialPoint* res_pt) {
|
||||||
auto ret = sptr->intersectPZone(pt, res_pt);
|
auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
});
|
});
|
||||||
|
|
||||||
_intersectZoneFuncEHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) {
|
_intersectZoneFuncEHC2CPT.emplace_back([sptr](const MccEqtHrzCoords& pt, MccCelestialPoint* res_pt) {
|
||||||
auto ret = sptr->intersectPZone(pt, res_pt);
|
auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_intersectZoneFuncCPT2EHC.emplace_back([sptr](const MccCelestialPoint& pt, MccEqtHrzCoords* res_pt) {
|
||||||
|
auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
|
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
|
});
|
||||||
|
|
||||||
|
_intersectZoneFuncEHC2EHC.emplace_back([sptr](const MccEqtHrzCoords& pt, MccEqtHrzCoords* res_pt) {
|
||||||
|
auto ret = sptr->intersectPZone(pt, res_pt);
|
||||||
|
|
||||||
|
return mcc_deduce_error(ret, mcc::make_error_code(MccPZoneContainerErrorCode::ERROR_INTERSECT_FUNC));
|
||||||
|
});
|
||||||
return _inZoneFuncCPT.size();
|
return _inZoneFuncCPT.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,8 +202,12 @@ public:
|
|||||||
_timeFromZoneFuncCPT.clear();
|
_timeFromZoneFuncCPT.clear();
|
||||||
_timeFromZoneFuncEHC.clear();
|
_timeFromZoneFuncEHC.clear();
|
||||||
|
|
||||||
_intersectZoneFuncCPT.clear();
|
// _intersectZoneFuncCPT.clear();
|
||||||
_intersectZoneFuncEHC.clear();
|
// _intersectZoneFuncEHC.clear();
|
||||||
|
_intersectZoneFuncCPT2CPT.clear();
|
||||||
|
_intersectZoneFuncEHC2CPT.clear();
|
||||||
|
_intersectZoneFuncCPT2EHC.clear();
|
||||||
|
_intersectZoneFuncEHC2EHC.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -298,14 +325,51 @@ public:
|
|||||||
return forEach(coords, apply_func, _timeFromZoneFuncCPT, _timeFromZoneFuncEHC);
|
return forEach(coords, apply_func, _timeFromZoneFuncCPT, _timeFromZoneFuncEHC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template <typename InputT, mcc_celestial_point_c CPT>
|
// template <typename InputT, typename R>
|
||||||
// error_t intersectPZone(InputT coords, std::ranges::output_range<CPT> auto* result)
|
// error_t intersectPZone(InputT coords, R* result)
|
||||||
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>)
|
// requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
template <typename InputT, typename R>
|
// std::ranges::output_range<R, std::ranges::range_value_t<R>> &&
|
||||||
error_t intersectPZone(InputT coords, R* result)
|
// mcc_celestial_point_c<std::ranges::range_value_t<R>>
|
||||||
requires(mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
// {
|
||||||
std::ranges::output_range<R, std::ranges::range_value_t<R>> &&
|
// if (result == nullptr) {
|
||||||
mcc_celestial_point_c<std::ranges::range_value_t<R>>
|
// return MccPZoneContainerErrorCode::ERROR_NULLPTR;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (traits::mcc_range_size(*result) < sizePZones()) {
|
||||||
|
// return MccPZoneContainerErrorCode::ERROR_INVALID_SIZE;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // using CPT = std::ranges::range_value_t<R>;
|
||||||
|
|
||||||
|
// MccCelestialPoint pt;
|
||||||
|
|
||||||
|
// auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
|
||||||
|
// auto ptr = result->begin();
|
||||||
|
// std::ranges::advance(ptr, i);
|
||||||
|
|
||||||
|
// pt.pair_kind = ptr->pair_kind;
|
||||||
|
// pt.time_point = ptr->time_point;
|
||||||
|
|
||||||
|
// error_t ret = func(pt_arg, &pt);
|
||||||
|
// if (!ret) {
|
||||||
|
// // if (traits::mcc_range_size(*result) == i) {
|
||||||
|
// // std::back_inserter(*result) = CPT();
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// mcc_copy_celestial_point(pt, &(*ptr));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ret;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return forEach(coords, apply_func, _intersectZoneFuncCPT, _intersectZoneFuncEHC);
|
||||||
|
// }
|
||||||
|
template <typename InputT, typename ResultT>
|
||||||
|
error_t intersectPZone(InputT coords, ResultT* result)
|
||||||
|
requires((mcc_eqt_hrz_coord_c<InputT> || mcc_celestial_point_c<InputT>) &&
|
||||||
|
std::ranges::output_range<ResultT, std::ranges::range_value_t<ResultT>> &&
|
||||||
|
(mcc_eqt_hrz_coord_c<std::ranges::range_value_t<ResultT>> ||
|
||||||
|
mcc_celestial_point_c<std::ranges::range_value_t<ResultT>>))
|
||||||
{
|
{
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
|
return MccPZoneContainerErrorCode::ERROR_NULLPTR;
|
||||||
@ -315,30 +379,40 @@ public:
|
|||||||
return MccPZoneContainerErrorCode::ERROR_INVALID_SIZE;
|
return MccPZoneContainerErrorCode::ERROR_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// using CPT = std::ranges::range_value_t<R>;
|
|
||||||
|
|
||||||
MccCelestialPoint pt;
|
|
||||||
|
|
||||||
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
|
auto apply_func = [&](auto& func, auto& pt_arg, size_t i) {
|
||||||
auto ptr = result->begin();
|
auto ptr = result->begin();
|
||||||
std::ranges::advance(ptr, i);
|
std::ranges::advance(ptr, i);
|
||||||
|
|
||||||
pt.pair_kind = ptr->pair_kind;
|
error_t ret;
|
||||||
pt.time_point = ptr->time_point;
|
if constexpr (mcc_eqt_hrz_coord_c<ResultT>) {
|
||||||
|
MccEqtHrzCoords pt;
|
||||||
|
|
||||||
error_t ret = func(pt_arg, &pt);
|
mcc_tp2tp(ptr->time_point, pt.time_point);
|
||||||
|
|
||||||
|
ret = func(pt_arg, &pt);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
// if (traits::mcc_range_size(*result) == i) {
|
mcc_copy_eqt_hrz_coord(pt, &(*ptr));
|
||||||
// std::back_inserter(*result) = CPT();
|
}
|
||||||
// }
|
} else {
|
||||||
|
MccCelestialPoint pt;
|
||||||
|
|
||||||
|
pt.pair_kind = ptr->pair_kind;
|
||||||
|
mcc_tp2tp(ptr->time_point, pt.time_point);
|
||||||
|
|
||||||
|
ret = func(pt_arg, &pt);
|
||||||
|
if (!ret) {
|
||||||
mcc_copy_celestial_point(pt, &(*ptr));
|
mcc_copy_celestial_point(pt, &(*ptr));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
return forEach(coords, apply_func, _intersectZoneFuncCPT, _intersectZoneFuncEHC);
|
if constexpr (mcc_eqt_hrz_coord_c<ResultT>) {
|
||||||
|
return forEach(coords, apply_func, _intersectZoneFuncCPT2EHC, _intersectZoneFuncEHC2EHC);
|
||||||
|
} else {
|
||||||
|
return forEach(coords, apply_func, _intersectZoneFuncCPT2CPT, _intersectZoneFuncEHC2CPT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -352,8 +426,13 @@ protected:
|
|||||||
std::vector<std::function<error_t(MccCelestialPoint const&, duration_t*)>> _timeFromZoneFuncCPT;
|
std::vector<std::function<error_t(MccCelestialPoint const&, duration_t*)>> _timeFromZoneFuncCPT;
|
||||||
std::vector<std::function<error_t(MccEqtHrzCoords const&, duration_t*)>> _timeFromZoneFuncEHC;
|
std::vector<std::function<error_t(MccEqtHrzCoords const&, duration_t*)>> _timeFromZoneFuncEHC;
|
||||||
|
|
||||||
std::vector<std::function<error_t(MccCelestialPoint const&, MccCelestialPoint*)>> _intersectZoneFuncCPT;
|
// std::vector<std::function<error_t(MccCelestialPoint const&, MccCelestialPoint*)>> _intersectZoneFuncCPT;
|
||||||
std::vector<std::function<error_t(MccEqtHrzCoords const&, MccCelestialPoint*)>> _intersectZoneFuncEHC;
|
// std::vector<std::function<error_t(MccEqtHrzCoords const&, MccCelestialPoint*)>> _intersectZoneFuncEHC;
|
||||||
|
|
||||||
|
std::vector<std::function<error_t(MccCelestialPoint const&, MccCelestialPoint*)>> _intersectZoneFuncCPT2CPT;
|
||||||
|
std::vector<std::function<error_t(MccEqtHrzCoords const&, MccCelestialPoint*)>> _intersectZoneFuncEHC2CPT;
|
||||||
|
std::vector<std::function<error_t(MccCelestialPoint const&, MccEqtHrzCoords*)>> _intersectZoneFuncCPT2EHC;
|
||||||
|
std::vector<std::function<error_t(MccEqtHrzCoords const&, MccEqtHrzCoords*)>> _intersectZoneFuncEHC2EHC;
|
||||||
|
|
||||||
error_t forEach(auto const& coords, auto& apply_func, auto& containerCPT, auto& containerEHC)
|
error_t forEach(auto const& coords, auto& apply_func, auto& containerCPT, auto& containerEHC)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -255,7 +255,8 @@ public:
|
|||||||
if (adjust_mode && !_currentParams.slewAndStop) {
|
if (adjust_mode && !_currentParams.slewAndStop) {
|
||||||
// do not allow mount speed fall below sideral
|
// do not allow mount speed fall below sideral
|
||||||
if constexpr (mccIsEquatorialMount(HardwareT::mountType)) {
|
if constexpr (mccIsEquatorialMount(HardwareT::mountType)) {
|
||||||
if (tdata.speedX < slewing_params_t::sideralRate) {
|
// turn on sideral rate only if the current position point catches up with the target
|
||||||
|
if ((tdata.target.HA - tdata.HA) <= 0.0 && tdata.speedX < slewing_params_t::sideralRate) {
|
||||||
hw_state.X = (double)tdata.target.X;
|
hw_state.X = (double)tdata.target.X;
|
||||||
hw_state.Y = (double)tdata.target.Y;
|
hw_state.Y = (double)tdata.target.Y;
|
||||||
|
|
||||||
|
|||||||
@ -115,7 +115,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
if constexpr (mccIsEquatorialMount(PcmT::mountType)) {
|
if constexpr (mccIsEquatorialMount(PcmT::mountType)) {
|
||||||
double dha_min = 0.0, dha;
|
double dha_min = std::numbers::pi * 2.0, dha;
|
||||||
|
|
||||||
// find the closest pzone
|
// find the closest pzone
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils::isEqual(dha_min, 0.0)) { // no intersections
|
if (utils::isEqual(dha_min, std::numbers::pi * 2.0)) { // no intersections
|
||||||
no_intersects = true;
|
no_intersects = true;
|
||||||
cpt.X = tdata.HA + 710.0_mins; // 12h - 10min
|
cpt.X = tdata.HA + 710.0_mins; // 12h - 10min
|
||||||
cpt.Y = tdata.DEC_APP;
|
cpt.Y = tdata.DEC_APP;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user