...
This commit is contained in:
parent
ec27cd981a
commit
bdfc5dbc1c
@ -501,6 +501,7 @@ struct MccPositionControls : CCTE_T, HARDWARE_T, PCM_T {
|
||||
|
||||
static_assert(mcc_julday_c<MccJulianDay>, "");
|
||||
static_assert(mcc_celestial_point_c<MccCelestialPoint>, "");
|
||||
static_assert(mcc_pointing_target_coord_c<MccGenericPointingTarget<double>>, "");
|
||||
static_assert(mcc_telemetry_data_c<MccTelemetryData>, "");
|
||||
|
||||
|
||||
@ -569,6 +570,30 @@ protected:
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <traits::mcc_input_char_range IR>
|
||||
std::error_code parseHourRepr(const IR& bytes, double& ang_value)
|
||||
{
|
||||
std::optional<double> ang;
|
||||
ang = mcc::utils::parsAngleString(bytes, true);
|
||||
if (ang) {
|
||||
ang_value = MccAngle(ang.value(), MccDegreeTag{});
|
||||
} else {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
}
|
||||
|
||||
template <traits::mcc_input_char_range IR>
|
||||
std::error_code parseDegreeRepr(const IR& bytes, double& ang_value)
|
||||
{
|
||||
std::optional<double> ang;
|
||||
ang = mcc::utils::parsAngleString(bytes);
|
||||
if (ang) {
|
||||
ang_value = MccAngle(ang.value(), MccDegreeTag{});
|
||||
} else {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// base class
|
||||
@ -774,12 +799,15 @@ public:
|
||||
pt.Y = MccAngle(ang2.value(), mcc::MccDegreeTag{});
|
||||
|
||||
mcc_copy_celestial_point(pt, &value);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class MccEqtHrzCoordsSerializer : public MccCoordinateSerializer
|
||||
{
|
||||
public:
|
||||
template <mcc_eqt_hrz_coord_c T, traits::mcc_output_char_range OR>
|
||||
void operator()(const T& value, OR& bytes)
|
||||
{
|
||||
@ -826,85 +854,221 @@ class MccEqtHrzCoordsSerializer : public MccCoordinateSerializer
|
||||
|
||||
class MccEqtHrzCoordsDeserializer : public MccCoordinateDeserializer
|
||||
{
|
||||
public:
|
||||
template <traits::mcc_input_char_range IR, mcc_eqt_hrz_coord_c T>
|
||||
std::error_code operator()(IR&& bytes, T& value)
|
||||
{
|
||||
// valid format: RA, DEC, HA, AZ, ZD, ALT, X, Y, pair-kind, time-point
|
||||
// in the case of sexagesimal input the X,Y coordinates will be interpretated
|
||||
// according to value.pair_kind field
|
||||
|
||||
auto els = splitToElements(std::forward<IR>(bytes));
|
||||
if (els.size() < 10) {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
|
||||
MccEqtHrzCoords pt;
|
||||
pt.pair_kind = MccCoordStrToPairKind(els[8]);
|
||||
if (pt.pair_kind == MccCoordPairKind::COORDS_KIND_UNKNOWN) {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
|
||||
auto err = parseTimePoint(els[9], pt);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseHourRepr(els[0], pt.RA_APP);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[1], pt.DEC_APP);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseHourRepr(els[2], pt.HA);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[4], pt.AZ);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], pt.ZD);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[6], pt.ALT);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
switch (value.pair_kind) {
|
||||
case MccCoordPairKind::COORDS_KIND_RADEC_ICRS:
|
||||
case MccCoordPairKind::COORDS_KIND_RADEC_APP:
|
||||
case MccCoordPairKind::COORDS_KIND_HADEC_APP:
|
||||
err = parseHourRepr(els[7], pt.X);
|
||||
break;
|
||||
default:
|
||||
err = parseDegreeRepr(els[7], pt.X);
|
||||
}
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[8], pt.Y);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mcc_copy_eqt_hrz_coord(pt, &value);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**/
|
||||
class MccPointingTargetSerializer : public MccCoordinateSerializer
|
||||
{
|
||||
public:
|
||||
template <mcc_pointing_target_coord_c T, traits::mcc_output_char_range OR>
|
||||
void operator()(const T& value, OR& bytes)
|
||||
{
|
||||
// output format: RA_ICRS, DEC_ICRS, RA_APP, DEC_APP, HA, AZ, ZD, ALT, X, Y, pair-kind, time-point
|
||||
// in the case of sexagesimal output X,Y coordinates will be interpretated
|
||||
// according to value.pair_kind field
|
||||
|
||||
static constexpr char MccCoordinateXFmt = 'x';
|
||||
static constexpr char MccCoordinateYFmt = 'y';
|
||||
static constexpr char MccCoordinateRA_ICRSFmt = 'R';
|
||||
static constexpr char MccCoordinateDEC_ICRSFmt = 'D';
|
||||
static constexpr char MccCoordinateRA_APPFmt = 'r';
|
||||
static constexpr char MccCoordinateDEC_APPFmt = 'd';
|
||||
static constexpr char MccCoordinateHAFmt = 'h';
|
||||
static constexpr char MccCoordinateAZFmt = 'a';
|
||||
static constexpr char MccCoordinateZDFmt = 'z';
|
||||
static constexpr char MccCoordinateALTFmt = 'A';
|
||||
static constexpr char MccCoordinateTMFmt = 't'; // time point
|
||||
static constexpr char MccCoordinatePKFmt = 'p'; // pair kind
|
||||
if (_currentFormat == SerializedCoordFormat::CFMT_DEGREES) {
|
||||
toDegrees(bytes, value.RA_ICRS, value.DEC_ICRS);
|
||||
} else if (_currentFormat == SerializedCoordFormat::CFMT_SGM) {
|
||||
toSexagesimalHour(bytes, value.RA_ICRS);
|
||||
std::format_to(std::back_inserter(bytes), "{}", _delimiter);
|
||||
|
||||
toSexagesimalDeg(bytes, value.DEC_APP);
|
||||
}
|
||||
|
||||
std::format_to(std::back_inserter(bytes), "{}", _delimiter);
|
||||
|
||||
MccEqtHrzCoordsSerializer{}(value, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
class MccPointingTargetDeserializer : public MccCoordinateDeserializer
|
||||
{
|
||||
public:
|
||||
template <traits::mcc_input_char_range IR, mcc_pointing_target_coord_c T>
|
||||
std::error_code operator()(IR&& bytes, T& value)
|
||||
{
|
||||
// valid format: RA_ICRS, DEC_ICRS, RA_APP, DEC_APP, HA, AZ, ZD, ALT, X, Y, pair-kind, time-point
|
||||
// in the case of sexagesimal input the X,Y coordinates will be interpretated
|
||||
// according to value.pair_kind field
|
||||
|
||||
auto els = splitToElements(std::forward<IR>(bytes));
|
||||
if (els.size() < 12) {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
|
||||
MccPointingTarget pt;
|
||||
auto err = parseHourRepr(els[0], pt.RA_ICRS);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[1], pt.DEC_ICRS);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = MccEqtHrzCoordsDeserializer{}(std::string_view{els[2].begin(), els[11].end()}, pt);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mcc_copy_pointing_target_coord(pt, &value);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class MccTelemetryDataSerializer : public MccCoordinateSerializer
|
||||
{
|
||||
public:
|
||||
template <mcc_telemetry_data_c T, traits::mcc_output_char_range OR>
|
||||
void operator()(const T& value, OR& bytes)
|
||||
{
|
||||
// output format: <mount data>, speedX, speedY, pcmX, pcmY, refCorr, <target data>
|
||||
|
||||
MccEqtHrzCoordsSerializer{}(value, bytes);
|
||||
std::format_to(std::back_inserter(bytes), "{}", _delimiter);
|
||||
|
||||
toDegrees(bytes, value.speedX, value.speedY, value.pcmX, value.pcmY, value.refCorr);
|
||||
std::format_to(std::back_inserter(bytes), "{}", _delimiter);
|
||||
|
||||
MccPointingTargetSerializer{}(value.target, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class MccTelemetryDataDeserializer : public MccCoordinateDeserializer
|
||||
{
|
||||
public:
|
||||
template <traits::mcc_input_char_range IR, mcc_telemetry_data_c T>
|
||||
std::error_code operator()(IR&& bytes, T& value)
|
||||
{
|
||||
// valid format: <mount data>, speedX, speedY, pcmX, pcmY, refCorr, <target data>
|
||||
|
||||
auto els = splitToElements(std::forward<IR>(bytes));
|
||||
if (els.size() < 12) {
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
}
|
||||
|
||||
MccTelemetryData tdata;
|
||||
auto err = MccEqtHrzCoordsDeserializer{}(std::string_view{els[0].begin(), els[11].end()}, tdata);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], tdata.speedX);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], tdata.speedY);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], tdata.pcmX);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], tdata.pcmY);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parseDegreeRepr(els[5], tdata.refCorr);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = MccPointingTargetDeserializer{}(std::string_view{els[0].begin(), els[11].end()}, tdata.target);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mcc_copy_telemetry_data(tdata, &value);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mcc
|
||||
|
||||
|
||||
template <mcc::mcc_celestial_point_c T>
|
||||
struct std::formatter<T, char> {
|
||||
std::vector<char> fmt_order;
|
||||
|
||||
template <typename ParseContext>
|
||||
constexpr ParseContext::iterator parse(ParseContext& ctx)
|
||||
{
|
||||
bool do_fmt = false;
|
||||
|
||||
for (auto it = ctx.begin(); it != ctx.end(); ++it) {
|
||||
if (*it == '%' && !do_fmt) {
|
||||
do_fmt = true;
|
||||
continue;
|
||||
} else {
|
||||
throw std::format_error("Invalid format argument for celestial point");
|
||||
}
|
||||
|
||||
switch (*it) {
|
||||
case mcc::MccCoordinateXFmt:
|
||||
case mcc::MccCoordinateYFmt:
|
||||
case mcc::MccCoordinateRA_ICRSFmt:
|
||||
case mcc::MccCoordinateDEC_ICRSFmt:
|
||||
case mcc::MccCoordinateRA_APPFmt:
|
||||
case mcc::MccCoordinateDEC_APPFmt:
|
||||
case mcc::MccCoordinateHAFmt:
|
||||
case mcc::MccCoordinateAZFmt:
|
||||
case mcc::MccCoordinateZDFmt:
|
||||
case mcc::MccCoordinateALTFmt:
|
||||
case mcc::MccCoordinateTMFmt:
|
||||
case mcc::MccCoordinatePKFmt:
|
||||
fmt_order.push_back(*it);
|
||||
do_fmt = false;
|
||||
break;
|
||||
default:
|
||||
throw std::format_error("Invalid format argument for celestial point");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FmtContext>
|
||||
FmtContext::iterator format(mcc::mcc_celestial_point_c auto cp, FmtContext& ctx) const
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
if (fmt_order.empty()) {
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
for (auto& el : fmt_order) {
|
||||
}
|
||||
|
||||
return std::ranges::copy(std::move(out).str(), ctx.out()).out;
|
||||
}
|
||||
};
|
||||
|
||||
@ -70,6 +70,23 @@ int main()
|
||||
|
||||
std::cout << "\n\n\n";
|
||||
|
||||
mcc::MccCelestialPointSerializer cpser;
|
||||
mcc::MccCelestialPointDeserializer cpdser;
|
||||
|
||||
std::string s;
|
||||
cpser(cpt, s);
|
||||
std::cout << "Serialized: " << s << "\n";
|
||||
|
||||
auto err = cpdser(s, cpt);
|
||||
if (err) {
|
||||
std::cout << "deserialization error: " << err.message() << "\n";
|
||||
} else {
|
||||
std::cout << "Deserialized: tp = " << cpt.time_point << "; kind = " << mcc::MccCoordPairKindToStr(cpt.pair_kind)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
std::cout << "\n\n\n";
|
||||
|
||||
mcc::MccCelestialCoordEpoch cep;
|
||||
|
||||
std::cout << "UTC: " << cep.UTC() << "\n";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user