mcc_pzone.h: add serializer/deserializer of the implemented prohibited
zone clases mcc_pcm.h: add mccGenerateBsplineKnots function mcc_deserializer.h: fixes
This commit is contained in:
@@ -126,7 +126,8 @@ protected:
|
|||||||
return MccDeserializerErrorCode::ERROR_OK;
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r_str = std::views::split(input, params.seq_delim);
|
// auto r_str = std::views::split(input, params.seq_delim);
|
||||||
|
auto r_str = std::views::split(input, params.elem_delim);
|
||||||
VT val;
|
VT val;
|
||||||
|
|
||||||
auto it = r.begin();
|
auto it = r.begin();
|
||||||
|
|||||||
@@ -106,6 +106,24 @@ class is_error_code_enum<mcc::impl::MccDefaultPCMErrorCode> : public true_type
|
|||||||
namespace mcc::impl
|
namespace mcc::impl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// The routine generates a sequence of length 'innerN'+2 elements.
|
||||||
|
// Th e first element is 'start_border' and the last one is 'stop_border'
|
||||||
|
// (i.e. it returns at least 2-elements std::vector)
|
||||||
|
// 'innerN' is a number of inner elements
|
||||||
|
static std::vector<double> mccGenerateBsplineKnots(double start_border, double stop_border, size_t innerN)
|
||||||
|
{
|
||||||
|
std::vector<double> res(innerN + 2);
|
||||||
|
res.front() = start_border;
|
||||||
|
res.back() = stop_border;
|
||||||
|
|
||||||
|
if (innerN) {
|
||||||
|
const double step = (stop_border - start_border) / (innerN + 1);
|
||||||
|
std::ranges::for_each(std::views::iota(1, (int)innerN + 1),
|
||||||
|
[&](auto const& i) { res[i] = start_border + i * step; });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// type of PCM corrections (algorithm used):
|
// type of PCM corrections (algorithm used):
|
||||||
// PCM_TYPE_GEOMETRY - "classic" geometry-based correction coefficients
|
// PCM_TYPE_GEOMETRY - "classic" geometry-based correction coefficients
|
||||||
|
|||||||
@@ -13,12 +13,14 @@
|
|||||||
#include "mcc_concepts.h"
|
#include "mcc_concepts.h"
|
||||||
#include "mcc_constants.h"
|
#include "mcc_constants.h"
|
||||||
#include "mcc_coordinate.h"
|
#include "mcc_coordinate.h"
|
||||||
|
#include "mcc_deserializer.h"
|
||||||
|
#include "mcc_serializer.h"
|
||||||
|
|
||||||
namespace mcc::impl
|
namespace mcc::impl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
enum class MccPZoneErrorCode : int { ERROR_OK, ERROR_NULLPTR, ERROR_COORD_TRANSFROM, ERROR_PCM_COMP };
|
enum class MccPZoneErrorCode : int { ERROR_OK, ERROR_NULLPTR, ERROR_COORD_TRANSFROM, ERROR_NO_PCM, ERROR_PCM_COMP };
|
||||||
|
|
||||||
} // namespace mcc::impl
|
} // namespace mcc::impl
|
||||||
|
|
||||||
@@ -56,6 +58,8 @@ struct MccPZoneCategory : public std::error_category {
|
|||||||
return "input argument os nullptr";
|
return "input argument os nullptr";
|
||||||
case MccPZoneErrorCode::ERROR_COORD_TRANSFROM:
|
case MccPZoneErrorCode::ERROR_COORD_TRANSFROM:
|
||||||
return "coordinate transformation error";
|
return "coordinate transformation error";
|
||||||
|
case MccPZoneErrorCode::ERROR_NO_PCM:
|
||||||
|
return "PCM was not set";
|
||||||
case MccPZoneErrorCode::ERROR_PCM_COMP:
|
case MccPZoneErrorCode::ERROR_PCM_COMP:
|
||||||
return "PCM computation error";
|
return "PCM computation error";
|
||||||
default:
|
default:
|
||||||
@@ -89,6 +93,7 @@ public:
|
|||||||
|
|
||||||
MccAltLimitPZ(mcc_angle_c auto const& alt_limit, mcc_angle_c auto const& latitude)
|
MccAltLimitPZ(mcc_angle_c auto const& alt_limit, mcc_angle_c auto const& latitude)
|
||||||
: _altLimit(MccAngle(alt_limit).normalize<MccAngle::NORM_KIND_90_90>()),
|
: _altLimit(MccAngle(alt_limit).normalize<MccAngle::NORM_KIND_90_90>()),
|
||||||
|
_latitude(MccAngle::normalizeAngle<MccAngle::NORM_KIND_90_90>(latitude)),
|
||||||
_cosALim(cos(_altLimit)),
|
_cosALim(cos(_altLimit)),
|
||||||
_sinAlim(sin(_altLimit)),
|
_sinAlim(sin(_altLimit)),
|
||||||
_cosLat(cos(latitude)),
|
_cosLat(cos(latitude)),
|
||||||
@@ -106,6 +111,29 @@ public:
|
|||||||
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
: KIND == MccAltLimitKind::MAX_ALT_LIMIT ? "MAXALT-ZONE"
|
||||||
: "ALTLIMIT-UNKNOWN";
|
: "ALTLIMIT-UNKNOWN";
|
||||||
|
|
||||||
|
template <mcc_angle_c T>
|
||||||
|
T altLimit() const
|
||||||
|
requires(!std::derived_from<T, MccAngle>)
|
||||||
|
{
|
||||||
|
return _altLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccAngle altLimit() const
|
||||||
|
{
|
||||||
|
return _altLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <mcc_angle_c T>
|
||||||
|
T latitude() const
|
||||||
|
requires(!std::derived_from<T, MccAngle>)
|
||||||
|
{
|
||||||
|
return _latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccAngle latitude() const
|
||||||
|
{
|
||||||
|
return _latitude;
|
||||||
|
}
|
||||||
|
|
||||||
error_t inPZone(mcc_skypoint_c auto const& coords, bool* result)
|
error_t inPZone(mcc_skypoint_c auto const& coords, bool* result)
|
||||||
{
|
{
|
||||||
@@ -230,7 +258,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
double _altLimit, _cosALim, _sinAlim;
|
double _altLimit, _cosALim, _sinAlim;
|
||||||
double _cosLat, _sinLat, _absLat, _latLim;
|
double _latitude, _cosLat, _sinLat, _absLat, _latLim;
|
||||||
|
|
||||||
bool doesObjectReachZone(const double& dec_app)
|
bool doesObjectReachZone(const double& dec_app)
|
||||||
{
|
{
|
||||||
@@ -322,14 +350,83 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
to be serialized in format:
|
||||||
|
ALT-LIMIT<seq-delim>LATITUDE
|
||||||
|
*/
|
||||||
|
template <MccAltLimitKind KIND>
|
||||||
|
struct MccSerializer<MccAltLimitPZ<KIND>> : MccSerializerBase {
|
||||||
|
constexpr static std::string_view serializerName{"MCC-ALTITUDE-PZONE-SERIALIZER"};
|
||||||
|
|
||||||
/* co-longitude axis (HA or AZ) limit switch prohibited zone */
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
|
MccAltLimitPZ<KIND> const& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
MccSerializer<MccAngle> aser;
|
||||||
|
|
||||||
|
auto err = aser(output, value.altLimit(), params);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::format_to(std::back_inserter(output), "{}", params.seq_delim);
|
||||||
|
|
||||||
|
err = aser(output, value.latitude(), params);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccSerializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <MccAltLimitKind KIND>
|
||||||
|
struct MccDeserializer<MccAltLimitPZ<KIND>> : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-ALTITUDE-PZONE-DESERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
MccAltLimitPZ<KIND>& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
std::string_view s;
|
||||||
|
MccDeserializer<MccAngle> ades;
|
||||||
|
|
||||||
|
auto seq = std::views::split(params.seq_delim);
|
||||||
|
if (std::ranges::size(seq) < 2) {
|
||||||
|
s = utils::trimSpaces(seq, utils::TrimType::TRIM_BOTH);
|
||||||
|
MccAngle alt, lat;
|
||||||
|
|
||||||
|
auto err = ades(input, alt, params);
|
||||||
|
if (err) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ades(input, lat, params);
|
||||||
|
if (err) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = MccAltLimitPZ<KIND>{alt, lat};
|
||||||
|
} else {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* co-longitude axis (HA or AZ) and co-latitude (DEC, ZD) limit switch prohibited zone */
|
||||||
|
|
||||||
template <MccCoordKind AXIS_KIND>
|
template <MccCoordKind AXIS_KIND>
|
||||||
class MccAxisLimitSwitchPZ : public mcc_pzone_interface_t<std::error_code>
|
class MccAxisLimitSwitchPZ : public mcc_pzone_interface_t<std::error_code>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static_assert(AXIS_KIND == MccCoordKind::COORDS_KIND_AZ || AXIS_KIND == MccCoordKind::COORDS_KIND_HA_OBS,
|
static_assert(AXIS_KIND == MccCoordKind::COORDS_KIND_AZ || AXIS_KIND == MccCoordKind::COORDS_KIND_HA_OBS ||
|
||||||
|
AXIS_KIND == MccCoordKind::COORDS_KIND_ZD || AXIS_KIND == MccCoordKind::COORDS_KIND_DEC_OBS,
|
||||||
"UNSUPPORTED AXIS TYPE!");
|
"UNSUPPORTED AXIS TYPE!");
|
||||||
|
|
||||||
typedef std::error_code error_t;
|
typedef std::error_code error_t;
|
||||||
@@ -339,13 +436,17 @@ public:
|
|||||||
static constexpr MccProhibitedZonePolicy pzPolicy = MccProhibitedZonePolicy::PZ_POLICY_FLIP;
|
static constexpr MccProhibitedZonePolicy pzPolicy = MccProhibitedZonePolicy::PZ_POLICY_FLIP;
|
||||||
|
|
||||||
//
|
//
|
||||||
// min_limit_val and max_limit_val are hardware encoder angles in radians!
|
// min_limit_val and max_limit_val are hardware encoder angles!
|
||||||
|
// pcm is nullptr or pointer to mcc_pcm_c
|
||||||
//
|
//
|
||||||
MccAxisLimitSwitchPZ(mcc_angle_c auto const& min_limit_val,
|
template <typename PCM_T>
|
||||||
mcc_angle_c auto const& max_limit_val,
|
MccAxisLimitSwitchPZ(mcc_angle_c auto const& min_limit_val, mcc_angle_c auto const& max_limit_val, PCM_T pcm)
|
||||||
mcc_pcm_c auto* pcm)
|
requires(std::is_null_pointer_v<PCM_T> || mcc_pcm_c<std::remove_pointer_t<PCM_T>>)
|
||||||
: _minLimit(min_limit_val), _maxLimit(max_limit_val)
|
: _minLimit(min_limit_val), _maxLimit(max_limit_val)
|
||||||
{
|
{
|
||||||
|
if constexpr (std::is_null_pointer_v<PCM_T>) {
|
||||||
|
_correctForPCM = [](MccSkyPoint const&, MccGenXY*) -> error_t { return MccPZoneErrorCode::ERROR_NO_PCM; };
|
||||||
|
} else {
|
||||||
_correctForPCM = [pcm](MccSkyPoint const& skypt, MccGenXY* hw_coords) {
|
_correctForPCM = [pcm](MccSkyPoint const& skypt, MccGenXY* hw_coords) {
|
||||||
struct pcm_res_t {
|
struct pcm_res_t {
|
||||||
double pcmX, pcmY;
|
double pcmX, pcmY;
|
||||||
@@ -358,14 +459,61 @@ public:
|
|||||||
return mcc_deduced_err(err, MccPZoneErrorCode::ERROR_PCM_COMP);
|
return mcc_deduced_err(err, MccPZoneErrorCode::ERROR_PCM_COMP);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static constexpr std::string_view pzoneName = axisKind == MccCoordKind::COORDS_KIND_AZ ? "AZ_AXIS-LIMITSWITCH_ZONE"
|
static constexpr std::string_view pzoneName =
|
||||||
: axisKind == MccCoordKind::COORDS_KIND_HA_OBS
|
axisKind == MccCoordKind::COORDS_KIND_AZ ? "AZ-AXIS-LIMITSWITCH-ZONE"
|
||||||
? "HA_AXIS-LIMITSWITCH_ZONE"
|
: axisKind == MccCoordKind::COORDS_KIND_HA_OBS ? "HA-AXIS-LIMITSWITCH-ZONE"
|
||||||
|
: axisKind == MccCoordKind::COORDS_KIND_ZD ? "ZD-AXIS-LIMITSWITCH-ZONE"
|
||||||
|
: axisKind == MccCoordKind::COORDS_KIND_DEC_OBS ? "DEC-AXIS-LIMITSWITCH-ZONE"
|
||||||
: "UKNOWN";
|
: "UKNOWN";
|
||||||
|
|
||||||
|
|
||||||
|
template <mcc_angle_c T>
|
||||||
|
T minLimit() const
|
||||||
|
requires(!std::derived_from<T, MccAngle>)
|
||||||
|
{
|
||||||
|
return _minLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccAngle minLimit() const
|
||||||
|
{
|
||||||
|
return _minLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <mcc_angle_c T>
|
||||||
|
T maxLimit() const
|
||||||
|
requires(!std::derived_from<T, MccAngle>)
|
||||||
|
{
|
||||||
|
return _maxLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MccAngle maxLimit() const
|
||||||
|
{
|
||||||
|
return _maxLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PCM_T>
|
||||||
|
void setPCM(PCM_T pcm)
|
||||||
|
requires(std::is_null_pointer_v<PCM_T> || mcc_pcm_c<std::remove_pointer_t<PCM_T>>)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_null_pointer_v<PCM_T>) {
|
||||||
|
_correctForPCM = [](MccSkyPoint const&, MccGenXY*) -> error_t { return MccPZoneErrorCode::ERROR_NO_PCM; };
|
||||||
|
} else {
|
||||||
|
_correctForPCM = [pcm](MccSkyPoint const& skypt, MccGenXY* hw_coords) {
|
||||||
|
struct pcm_res_t {
|
||||||
|
double pcmX, pcmY;
|
||||||
|
};
|
||||||
|
|
||||||
|
pcm_res_t res;
|
||||||
|
|
||||||
|
auto err = pcm->computeInversePCM(skypt, &res, hw_coords);
|
||||||
|
|
||||||
|
return mcc_deduced_err(err, MccPZoneErrorCode::ERROR_PCM_COMP);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error_t inPZone(mcc_skypoint_c auto const& coords, bool* result)
|
error_t inPZone(mcc_skypoint_c auto const& coords, bool* result)
|
||||||
{
|
{
|
||||||
@@ -439,6 +587,9 @@ protected:
|
|||||||
time_ang = (_maxLimit - x) / MCC_SIDERAL_TO_UT1_RATIO; // to UT1 scale
|
time_ang = (_maxLimit - x) / MCC_SIDERAL_TO_UT1_RATIO; // to UT1 scale
|
||||||
}
|
}
|
||||||
} else if constexpr (AXIS_KIND == MccCoordKind::COORDS_KIND_AZ) {
|
} else if constexpr (AXIS_KIND == MccCoordKind::COORDS_KIND_AZ) {
|
||||||
|
static_assert(false, "NOT IMPLEMENTED YET!!!");
|
||||||
|
} else {
|
||||||
|
static_assert(false, "NOT IMPLEMENTED YET!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::nanoseconds ns{
|
std::chrono::nanoseconds ns{
|
||||||
@@ -452,4 +603,74 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
to be serialized in format:
|
||||||
|
MIN_LIMIT<seq-delim>MAX_LIMIT
|
||||||
|
*/
|
||||||
|
template <MccCoordKind AXIS_KIND>
|
||||||
|
struct MccSerializer<MccAxisLimitSwitchPZ<AXIS_KIND>> : MccSerializerBase {
|
||||||
|
constexpr static std::string_view serializerName{"MCC-AXIS-LIMIT-SWITCH-SERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_output_char_range auto& output,
|
||||||
|
MccAxisLimitSwitchPZ<AXIS_KIND> const& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
MccSerializer<MccAngle> aser;
|
||||||
|
|
||||||
|
auto err = aser(output, value.minLimit(), params);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::format_to(std::back_inserter(output), "{}", params.seq_delim);
|
||||||
|
|
||||||
|
err = aser(output, value.maxLimit(), params);
|
||||||
|
if (err) {
|
||||||
|
return mcc_deduced_err(err, MccSerializerErrorCode::ERROR_UNDERLYING_SERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return MccSerializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <MccCoordKind AXIS_KIND>
|
||||||
|
struct MccDeserializer<MccAxisLimitSwitchPZ<AXIS_KIND>> : MccDeserializerBase {
|
||||||
|
static constexpr std::string_view deserializerName{"MCC-AXIS-LIMIT-SWITCH-DESERIALIZER"};
|
||||||
|
|
||||||
|
template <mcc_serialization_params_c ParamsT = mcc_serialization_params_t>
|
||||||
|
error_t operator()(traits::mcc_input_char_range auto const& input,
|
||||||
|
MccAxisLimitSwitchPZ<AXIS_KIND>& value,
|
||||||
|
ParamsT const& params = mcc_serialization_params_t{})
|
||||||
|
{
|
||||||
|
std::string_view s;
|
||||||
|
MccDeserializer<MccAngle> ades;
|
||||||
|
|
||||||
|
auto seq = std::views::split(params.seq_delim);
|
||||||
|
if (std::ranges::size(seq) < 2) {
|
||||||
|
s = utils::trimSpaces(seq, utils::TrimType::TRIM_BOTH);
|
||||||
|
MccAngle minLim, maxLim;
|
||||||
|
|
||||||
|
auto err = ades(input, minLim, params);
|
||||||
|
if (err) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ades(input, maxLim, params);
|
||||||
|
if (err) {
|
||||||
|
return MccDeserializerErrorCode::ERROR_UNDERLYING_DESERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: the class below is created without the PCM-class pointer!!!
|
||||||
|
value = MccAxisLimitSwitchPZ<AXIS_KIND>{minLim, maxLim};
|
||||||
|
} else {
|
||||||
|
return MccDeserializerErrorCode::ERROR_INVALID_SERIALIZED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccDeserializerErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mcc::impl
|
} // namespace mcc::impl
|
||||||
|
|||||||
Reference in New Issue
Block a user