...
This commit is contained in:
parent
4082b28176
commit
56c3131520
@ -333,4 +333,37 @@ int fitpack_eval_spl2d(const TXT& tx,
|
||||
return ier;
|
||||
}
|
||||
|
||||
|
||||
// scalar x,y version
|
||||
template <std::ranges::contiguous_range TXT,
|
||||
std::ranges::contiguous_range TYT,
|
||||
typename XT,
|
||||
typename YT,
|
||||
std::ranges::contiguous_range CoeffT,
|
||||
typename FuncT>
|
||||
int fitpack_eval_spl2d(const TXT& tx,
|
||||
const TYT& ty,
|
||||
const CoeffT& coeffs,
|
||||
const XT& x,
|
||||
const YT& y,
|
||||
FuncT& func,
|
||||
int kx = 3,
|
||||
int ky = 3)
|
||||
{
|
||||
static_assert(std::same_as<std::ranges::range_value_t<TXT>, double> &&
|
||||
std::same_as<std::ranges::range_value_t<TYT>, double> &&
|
||||
std::same_as<std::ranges::range_value_t<CoeffT>, double>,
|
||||
"Input ranges elements type must be double!");
|
||||
|
||||
static_assert(
|
||||
std::convertible_to<XT, double> && std::convertible_to<YT, double> && std::convertible_to<FuncT, double>,
|
||||
"XT, YT and FuncT types must be a scalar convertible to double!");
|
||||
|
||||
auto xv = std::vector<double>(1, x);
|
||||
auto yv = std::vector<double>(1, y);
|
||||
auto fv = std::vector<double>(1, func);
|
||||
|
||||
return fitpack_eval_spl2d(tx, ty, coeffs, xv, yv, fv, kx, ky);
|
||||
}
|
||||
|
||||
} // namespace mcc::fitpack
|
||||
|
||||
@ -1,10 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
||||
|
||||
/* AN REFERENCE "PERIODIC-ERROR-CORRECTION" CLASS IMPLEMENTATION */
|
||||
|
||||
|
||||
|
||||
#include "fitpack/fitpack.h"
|
||||
#include "mcc_mount_coord.h"
|
||||
|
||||
namespace mcc
|
||||
{
|
||||
|
||||
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
concept mcc_mount_pec_c = requires(T t) {
|
||||
typename T::pec_result_t;
|
||||
|
||||
[]<std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>(const XT & x, const YT & y, T inst) ->
|
||||
typename T::pec_result_t { return inst.compute(x, y); }(t);
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
// type of PEC corrections (algorithm used):
|
||||
// PEC_TYPE_GEOMETRY - "classic" geometry-based correction coefficients
|
||||
// PEC_TYPE_GEOMETRY_BSPLINE - previous one and additional 2D B-spline corrections
|
||||
// PEC_TYPE_BSPLINE - pure 2D B-spline corrections
|
||||
enum class MccMountPECType { PEC_TYPE_GEOMETRY, PEC_TYPE_GEOMETRY_BSPLINE, PEC_TYPE_BSPLINE };
|
||||
|
||||
template <MccMountPECType TYPE = MccMountPECType::PEC_TYPE_GEOMETRY>
|
||||
@ -40,20 +66,30 @@ public:
|
||||
typedef double knot_t;
|
||||
typedef double coeff_t;
|
||||
|
||||
std::vector<knot_t> knots;
|
||||
std::vector<coeff_t> coeffs;
|
||||
size_t bsplDegreeX = 3;
|
||||
size_t bsplDegreeY = 3;
|
||||
|
||||
std::vector<knot_t> knotsX{};
|
||||
std::vector<knot_t> knotsY{};
|
||||
|
||||
std::vector<coeff_t> coeffsX{};
|
||||
std::vector<coeff_t> coeffsY{};
|
||||
};
|
||||
|
||||
|
||||
MccMountPEC(pec_geom_coeffs_t geom_coeffs, pec_bspline_coeffs_t bspline_coeffs)
|
||||
// constructors
|
||||
|
||||
template <std::derived_from<MccAngle> PhiT>
|
||||
MccMountPEC(const PhiT& phi, pec_geom_coeffs_t geom_coeffs, pec_bspline_coeffs_t bspline_coeffs)
|
||||
requires(TYPE == MccMountPECType::PEC_TYPE_GEOMETRY_BSPLINE)
|
||||
: _geomCoeffs(std::move(geom_coeffs)), _bspleCoeffs(std::move(bspline_coeffs))
|
||||
: _phi(phi), _geomCoeffs(std::move(geom_coeffs)), _bspleCoeffs(std::move(bspline_coeffs))
|
||||
{
|
||||
}
|
||||
|
||||
MccMountPEC(pec_geom_coeffs_t geom_coeffs)
|
||||
template <std::derived_from<MccAngle> PhiT>
|
||||
MccMountPEC(const PhiT& phi, pec_geom_coeffs_t geom_coeffs)
|
||||
requires(TYPE == MccMountPECType::PEC_TYPE_GEOMETRY)
|
||||
: _geomCoeffs(std::move(geom_coeffs)), _bspleCoeffs()
|
||||
: _phi(phi), _geomCoeffs(std::move(geom_coeffs)), _bspleCoeffs()
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,21 +111,50 @@ public:
|
||||
|
||||
if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
if constexpr (TYPE == MccMountPECType::PEC_TYPE_GEOMETRY) {
|
||||
const auto cosPhi = std::cos(_phi);
|
||||
const auto sinPhi = std::sin(_phi);
|
||||
const auto tanY = std::tan(y);
|
||||
const auto sinX = std::sin(x);
|
||||
const auto cosX = std::cos(x);
|
||||
const auto cosY = std::cos(y);
|
||||
|
||||
res.dx = _geomCoeffs.zeroPointX + _geomCoeffs.collimationErr / std::cos(y) +
|
||||
_geomCoeffs.nonperpendErr * tanY - _geomCoeffs.misalignErr1 * cosX * tanY +
|
||||
_geomCoeffs.misalignErr2 * sinX * tanY;
|
||||
|
||||
res.dy = _geomCoeffs.zeroPointY + _geomCoeffs.misalignErr1 * sinX + _geomCoeffs.misalignErr2 * cosX;
|
||||
res.dx = _geomCoeffs.zeroPointX + _geomCoeffs.collimationErr / cosY + _geomCoeffs.nonperpendErr * tanY -
|
||||
_geomCoeffs.misalignErr1 * cosX * tanY + _geomCoeffs.misalignErr2 * sinX * tanY +
|
||||
_geomCoeffs.tubeFlexure * cosPhi * sinX / cosY -
|
||||
_geomCoeffs.DECaxisFlexure * (cosPhi * cosX + sinPhi * tanY);
|
||||
|
||||
res.dy = _geomCoeffs.zeroPointY + _geomCoeffs.misalignErr1 * sinX + _geomCoeffs.misalignErr2 * cosX +
|
||||
_geomCoeffs.tubeFlexure * (cosPhi * cosX * std::sin(y) - sinPhi * cosY) +
|
||||
_geomCoeffs.forkFlexure / cosX;
|
||||
}
|
||||
|
||||
if constexpr (TYPE == MccMountPECType::PEC_TYPE_BSPLINE ||
|
||||
TYPE == MccMountPECType::PEC_TYPE_GEOMETRY_BSPLINE) {
|
||||
res.dx += 0.0;
|
||||
res.dy += 0.0;
|
||||
double spl_valX, spl_valY;
|
||||
|
||||
int ret = fitpack::fitpack_eval_spl2d(_bspleCoeffs.knotsX, _bspleCoeffs.knotsY, _bspleCoeffs.coeffsX, x,
|
||||
y, spl_valX, _bspleCoeffs.bsplDegreeX, _bspleCoeffs.bsplDegreeY);
|
||||
|
||||
if (ret) {
|
||||
res.dx = std::numeric_limits<double>::quiet_NaN();
|
||||
res.dy = std::numeric_limits<double>::quiet_NaN();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
ret = fitpack::fitpack_eval_spl2d(_bspleCoeffs.knotsX, _bspleCoeffs.knotsY, _bspleCoeffs.coeffsY, x, y,
|
||||
spl_valY, _bspleCoeffs.bsplDegreeX, _bspleCoeffs.bsplDegreeY);
|
||||
|
||||
if (ret) {
|
||||
res.dx = std::numeric_limits<double>::quiet_NaN();
|
||||
res.dy = std::numeric_limits<double>::quiet_NaN();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
res.dx += spl_valX;
|
||||
res.dy += spl_valY;
|
||||
}
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||
} else {
|
||||
@ -99,7 +164,26 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// X and Y apparent equatorial/altazimuthal coordinates (not corrected for refraction)
|
||||
template <std::derived_from<MccAngle> XT, std::derived_from<MccAngle> YT>
|
||||
pec_result_t computeInverse(const XT& x, const YT& y)
|
||||
{
|
||||
static constexpr MccCoordPairKind coord_kind = traits::mcc_type_pair_hash<XT, YT>();
|
||||
|
||||
pec_result_t res{0.0, 0.0};
|
||||
|
||||
if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_HADEC_APP) {
|
||||
} else if constexpr (coord_kind == MccCoordPairKind::COORDS_KIND_AZALT) {
|
||||
} else {
|
||||
static_assert(false, "UNSUPPORTED");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
double _phi;
|
||||
pec_geom_coeffs_t _geomCoeffs;
|
||||
pec_bspline_coeffs_t _bspleCoeffs;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user