Telescope Control Library
Diff: CelestialMath.h
- Revision:
- 0:6cb2eaf8b133
- Child:
- 18:3ea58b079adc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CelestialMath.h Sun Aug 19 05:21:20 2018 +0000 @@ -0,0 +1,310 @@ +/* + * CelestialMath.h + * + * Created on: Feb 21, 2018 + * Author: Yuan + */ + +#ifndef CELESTIALMATH_H_ +#define CELESTIALMATH_H_ + +#include <time.h> +#include <math.h> + +static const double sidereal_speed = 0.00417807462; /* deg / s */ + +struct EquatorialCoordinates +{ + double dec; // Declination + double ra; // Right ascension + EquatorialCoordinates(double d = 0, double r = 0) : + dec(d), ra(r) + { + } +}; + +struct LocalEquatorialCoordinates +{ + double dec; // Declination + double ha; // Hour angle + LocalEquatorialCoordinates(double d = 0, double h = 0) : + dec(d), ha(h) + { + } + LocalEquatorialCoordinates operator+( + const LocalEquatorialCoordinates &b) const + { + return LocalEquatorialCoordinates(remainder(dec + b.dec, 360), + remainder(ha + b.ha, 360)); + } + LocalEquatorialCoordinates operator-( + const LocalEquatorialCoordinates &b) const + { + return LocalEquatorialCoordinates(remainder(dec - b.dec, 360), + remainder(ha - b.ha, 360)); + } +}; + +struct AzimuthalCoordinates +{ + double alt; // Altitude + double azi; // Azimuth + AzimuthalCoordinates(double a1 = 0, double a2 = 0) : + alt(a1), azi(a2) + { + } +}; + +struct LocationCoordinates +{ + double lat; // Latitude + double lon; // Longtitude + LocationCoordinates(double l1 = 0, double l2 = 0) : + lat(l1), lon(l2) + { + } +}; + +struct Transformation; + +struct CartesianVector +{ + double x, y, z; + CartesianVector(double x = 0, double y = 0, double z = 0) : + x(x), y(y), z(z) + { + } + CartesianVector operator*(const Transformation &t); +}; + +struct Transformation +{ + double a11, a12, a13; + double a21, a22, a23; + double a31, a32, a33; + CartesianVector operator*(const CartesianVector &vec); + void transpose() + { + double temp = a12; + a12 = a21; + a21 = temp; + temp = a13; + a13 = a31; + a31 = temp; + temp = a32; + a32 = a23; + a23 = temp; + } +}; + +typedef enum +{ + PIER_SIDE_EAST, PIER_SIDE_WEST, PIER_SIDE_AUTO = 0 +} pierside_t; + +struct IndexOffset +{ + double dec_off; // Offset of the index position in DEC + double ra_off; // Offset of the index position in RA/HA axis + IndexOffset(double d = 0, double r = 0) : + dec_off(d), ra_off(r) + { + } +}; + +struct MountCoordinates +{ + double dec_delta; // Displacement from index position in DEC axis + double ra_delta; // Displacement from index position in RA/HA axis + pierside_t side; + MountCoordinates(double dec = 0, double ra = 0, pierside_t s = + PIER_SIDE_AUTO) : + dec_delta(dec), ra_delta(ra), side(s) + { + } + MountCoordinates operator+(const IndexOffset &offset) const + { + return MountCoordinates(remainder(dec_delta + offset.dec_off, 360), + remainder(ra_delta + offset.ra_off, 360), side); + } + MountCoordinates operator-(const IndexOffset &offset) const + { + return MountCoordinates(remainder(dec_delta - offset.dec_off, 360), + remainder(ra_delta - offset.ra_off, 360), side); + } +}; +/** + * Alignment star object + */ +struct AlignmentStar +{ + EquatorialCoordinates star_ref; /// Reference position of the star in the sky (in current epoch) + MountCoordinates star_meas; /// Measured position of the star in mount coordinates + time_t timestamp; /// UTC timestamp of the measurement + AlignmentStar() + { + timestamp = 0; + } + AlignmentStar(const EquatorialCoordinates & ref, MountCoordinates meas, + time_t t) : + star_ref(ref), star_meas(meas), timestamp(t) + { + } + LocalEquatorialCoordinates star_ref_local( + const LocationCoordinates &loc) const; +}; + +struct EqCalibration +{ + IndexOffset offset; + AzimuthalCoordinates pa; + double cone; + double error; + EqCalibration() : + cone(0), error(0) + { + } + EqCalibration(const IndexOffset &off, const AzimuthalCoordinates p, + double c, double e) : + offset(off), pa(p), cone(c), error(e) + { + } +}; +/** + * Utility functions for doing math on coordinates of the celestial sphere + */ +class CelestialMath +{ +public: + CelestialMath() + { + } + ~CelestialMath() + { + } + + /*Basic conversion between reference frames*/ + static AzimuthalCoordinates localEquatorialToAzimuthal( + const LocalEquatorialCoordinates &a, + const LocationCoordinates &loc); + static LocalEquatorialCoordinates azimuthalToLocalEquatorial( + const AzimuthalCoordinates &b, const LocationCoordinates &loc); + static double getGreenwichMeanSiderealTime(time_t timestamp); + static double getLocalSiderealTime(time_t timestamp, + const LocationCoordinates &loc); + static LocalEquatorialCoordinates equatorialToLocalEquatorial( + const EquatorialCoordinates &e, time_t timestamp, + const LocationCoordinates &loc); + static EquatorialCoordinates localEquatorialToEquatorial( + const LocalEquatorialCoordinates &a, time_t timestamp, + const LocationCoordinates &loc); + + /*Misalignment correction functions*/ + static Transformation &getMisalignedPolarAxisTransformation( + Transformation &t, const AzimuthalCoordinates &mpa, + const LocationCoordinates &loc); + static LocalEquatorialCoordinates applyMisalignment(const Transformation &t, + const LocalEquatorialCoordinates &a); + static LocalEquatorialCoordinates applyMisalignment( + const LocalEquatorialCoordinates &a, + const AzimuthalCoordinates &mpa, const LocationCoordinates &loc); + static LocalEquatorialCoordinates applyConeError( + const LocalEquatorialCoordinates &a, double cone); + static LocalEquatorialCoordinates deapplyMisalignment( + const Transformation &t, const LocalEquatorialCoordinates &a); + static LocalEquatorialCoordinates deapplyMisalignment( + const LocalEquatorialCoordinates &a, + const AzimuthalCoordinates &mpa, const LocationCoordinates &loc); + static LocalEquatorialCoordinates deapplyConeError( + const LocalEquatorialCoordinates &a, double cone); + + /*Convert to and from Mount coordinates*/ + static MountCoordinates localEquatorialToMount( + const LocalEquatorialCoordinates &a, pierside_t side = + PIER_SIDE_AUTO); + static LocalEquatorialCoordinates mountToLocalEquatorial( + const MountCoordinates &m); + + /*Alignment procedures*/ + + /** + * One-star alignment (only for testing), to find the PA misalignment + */ + static AzimuthalCoordinates alignOneStar( + const LocalEquatorialCoordinates &star_ref, + const LocalEquatorialCoordinates &star_meas, + const LocationCoordinates &loc, + const AzimuthalCoordinates &pa_start); + + static IndexOffset alignOneStarForOffset( + const LocalEquatorialCoordinates &star_ref, + const MountCoordinates &star_meas); + + /*static AzimuthalCoordinates alignOneStar(const LocalEquatorialCoordinates &star_ref, const LocalEquatorialCoordinates &star_meas, + const LocationCoordinates &loc, const AzimuthalCoordinates &pa_start);*/ + /** + * Two-star alignment for finding PA misalignment as well as offset in both axis + * @param star_ref Reference stars (array of 2) + * @param star_meas Measured stars (array of 2) + * @param loc Location + * @param pa Initial PA alt-az coordinates. This parameter will be updated with new values + * @param offset Initial offset values. This parameter will be updated with new values + */ + static void alignTwoStars(const LocalEquatorialCoordinates star_ref[], + const LocalEquatorialCoordinates star_meas[], + const LocationCoordinates &loc, AzimuthalCoordinates &pa, + LocalEquatorialCoordinates &offset); + static void alignTwoStars(const LocalEquatorialCoordinates star_ref[], + const MountCoordinates star_meas[], const LocationCoordinates &loc, + AzimuthalCoordinates &pa, IndexOffset &offset, bool &diverge); + + /** + * N-star alignment for finding PA misalignment, offset, and cone error + * This function will first call alignTwoStars with the first two stars assuming no cone error, then run an optimization algorithm to minimize the residual error by tweaking all 5 parameters. + * @param N number of alignment stars + * @param star_ref Reference stars + * @param star_meas Measured stars + * @param loc Location + * @param pa Initial PA alt-az coordinates. This parameter will be updated with new values + * @param offset Initial offset values. This parameter will be updated with new values + * @param cone Initial cone error. This parameter will be updated with new values + */ + static void alignNStars(const int N, + const LocalEquatorialCoordinates star_ref[], + const LocalEquatorialCoordinates star_meas[], + const LocationCoordinates &loc, AzimuthalCoordinates &pa, + LocalEquatorialCoordinates &offset, double &cone); + static void alignNStars(const int N, + const LocalEquatorialCoordinates star_ref[], + const MountCoordinates star_meas[], const LocationCoordinates &loc, + AzimuthalCoordinates &pa, IndexOffset &offset, double &cone, + bool &diverge); + + /** + * Adaptor for EqMount + */ + static EqCalibration align(const int N, const AlignmentStar stars[], + const LocationCoordinates &loc, bool &diverge); + + static double alignmentError(const int N, const AlignmentStar stars[], + const EqCalibration &calib, const LocationCoordinates &loc); + + /*Utility functions*/ + + /* + * Convert HMS notation such as 21h54m31.6s to degrees (counting from 0h0m0s = 0degree, from -180 ~ 180 degrees) + */ + static double parseHMSAngle(char *hms); + + static double parseDMSAngle(char *dms); + + /** + * Calculate King tracking rate based on the star position and location + */ + static double kingRate(EquatorialCoordinates eq, LocationCoordinates loc, + time_t time); + +}; + +#endif /* CELESTIALMATH_H_ */ +