9#include <libnova/julian_day.h>
11#include <gsl/gsl_blas.h>
12#include <gsl/gsl_permutation.h>
13#include <gsl/gsl_linalg.h>
23namespace AlignmentSubsystem
55 switch (SyncPoints.size())
91 DummyActualDirectionCosine2.
x = 0.0;
92 DummyActualDirectionCosine2.
y = 0.0;
93 DummyActualDirectionCosine2.
z = 1.0;
94 DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
103 DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
112 DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
116 DummyActualDirectionCosine3 = ActualDirectionCosine1 * DummyActualDirectionCosine2;
118 DummyApparentDirectionCosine3 = Entry1.
TelescopeDirection * DummyApparentDirectionCosine2;
119 DummyApparentDirectionCosine3.
Normalise();
160 DummyActualDirectionCosine3 = ActualDirectionCosine1 * ActualDirectionCosine2;
163 DummyApparentDirectionCosine3.
Normalise();
232 int VertexNumber = 1;
234 for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
235 Itr != SyncPoints.end(); Itr++)
254 ActualDirectionCosine.
z, VertexNumber);
256 (*Itr).TelescopeDirection.z, VertexNumber);
273#ifdef CONVEX_HULL_DEBUGGING
276 if (
nullptr != CurrentFace)
280#ifdef CONVEX_HULL_DEBUGGING
286#ifdef CONVEX_HULL_DEBUGGING
287 ASSDEBUGF(
"Initialise - Ignoring actual face %d", ActualFaces);
292#ifdef CONVEX_HULL_DEBUGGING
293 ASSDEBUGF(
"Initialise - Processing actual face %d v1 %d v2 %d v3 %d", ActualFaces,
300 SyncPoints[CurrentFace->
vertex[0]->
vnum - 1].TelescopeDirection,
301 SyncPoints[CurrentFace->
vertex[1]->
vnum - 1].TelescopeDirection,
302 SyncPoints[CurrentFace->
vertex[2]->
vnum - 1].TelescopeDirection,
303 CurrentFace->
pMatrix,
nullptr);
305 CurrentFace = CurrentFace->
next;
312#ifdef CONVEX_HULL_DEBUGGING
313 int ApparentFaces = 0;
315 if (
nullptr != CurrentFace)
319#ifdef CONVEX_HULL_DEBUGGING
325#ifdef CONVEX_HULL_DEBUGGING
326 ASSDEBUGF(
"Initialise - Ignoring apparent face %d", ApparentFaces);
331#ifdef CONVEX_HULL_DEBUGGING
332 ASSDEBUGF(
"Initialise - Processing apparent face %d v1 %d v2 %d v3 %d", ApparentFaces,
337 SyncPoints[CurrentFace->
vertex[1]->
vnum - 1].TelescopeDirection,
338 SyncPoints[CurrentFace->
vertex[2]->
vnum - 1].TelescopeDirection,
342 CurrentFace->
pMatrix,
nullptr);
344 CurrentFace = CurrentFace->
next;
349#ifdef CONVEX_HULL_DEBUGGING
350 ASSDEBUGF(
"Initialise - ActualFaces %d ApparentFaces %d", ActualFaces, ApparentFaces);
366 ln_get_julian_from_sys() + JulianOffset,
367 ApparentTelescopeDirectionVector);
384 switch (SyncPoints.size())
426 gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
427 gsl_vector_set(pGSLActualVector, 0, ActualVector.
x);
428 gsl_vector_set(pGSLActualVector, 1, ActualVector.
y);
429 gsl_vector_set(pGSLActualVector, 2, ActualVector.
z);
430 gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
432 ApparentTelescopeDirectionVector.
x = gsl_vector_get(pGSLApparentVector, 0);
433 ApparentTelescopeDirectionVector.
y = gsl_vector_get(pGSLApparentVector, 1);
434 ApparentTelescopeDirectionVector.
z = gsl_vector_get(pGSLApparentVector, 2);
435 ApparentTelescopeDirectionVector.
Normalise();
436 gsl_vector_free(pGSLActualVector);
437 gsl_vector_free(pGSLApparentVector);
455 gsl_matrix *pTransform;
456 gsl_matrix *pComputedTransform =
nullptr;
462#ifdef CONVEX_HULL_DEBUGGING
465 if (
nullptr != CurrentFace)
469#ifdef CONVEX_HULL_DEBUGGING
476#ifdef CONVEX_HULL_DEBUGGING
477 ASSDEBUGF(
"Celestial to telescope - Ignoring actual face %d", ActualFaces);
482#ifdef CONVEX_HULL_DEBUGGING
483 ASSDEBUGF(
"Celestial to telescope - Processing actual face %d v1 %d v2 %d v3 %d", ActualFaces,
493 CurrentFace = CurrentFace->
next;
499 std::map<double, const AlignmentDatabaseEntry *> NearestMap;
500 for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
501 Itr != SyncPoints.end(); Itr++)
517 NearestMap[(ActualDirectionCosine - ActualVector).Length()] = &(*Itr);
520 std::map<double, const AlignmentDatabaseEntry *>::const_iterator Nearest = NearestMap.begin();
560 pComputedTransform = gsl_matrix_alloc(3, 3);
564 pTransform = pComputedTransform;
567 pTransform = CurrentFace->
pMatrix;
573 gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
574 gsl_vector_set(pGSLActualVector, 0, ActualVector.
x);
575 gsl_vector_set(pGSLActualVector, 1, ActualVector.
y);
576 gsl_vector_set(pGSLActualVector, 2, ActualVector.
z);
577 gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
579 ApparentTelescopeDirectionVector.
x = gsl_vector_get(pGSLApparentVector, 0);
580 ApparentTelescopeDirectionVector.
y = gsl_vector_get(pGSLApparentVector, 1);
581 ApparentTelescopeDirectionVector.
z = gsl_vector_get(pGSLApparentVector, 2);
582 ApparentTelescopeDirectionVector.
Normalise();
583 gsl_vector_free(pGSLActualVector);
584 gsl_vector_free(pGSLApparentVector);
585 if (
nullptr != pComputedTransform)
586 gsl_matrix_free(pComputedTransform);
599 double &RightAscension,
double &Declination,
double JulianOffset)
602 ln_get_julian_from_sys() + JulianOffset);
606 double &RightAscension,
double &Declination,
double JulianDate)
620 ASSDEBUG(
"No database or no position in database");
624 switch (SyncPoints.size())
636 ASSDEBUGF(
"ApparentVector x %lf y %lf z %lf", ApparentTelescopeDirectionVector.
x,
637 ApparentTelescopeDirectionVector.
y, ApparentTelescopeDirectionVector.
z);
660 gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
661 gsl_vector_set(pGSLApparentVector, 0, ApparentTelescopeDirectionVector.
x);
662 gsl_vector_set(pGSLApparentVector, 1, ApparentTelescopeDirectionVector.
y);
663 gsl_vector_set(pGSLApparentVector, 2, ApparentTelescopeDirectionVector.
z);
664 gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
667 Dump3(
"ApparentVector", pGSLApparentVector);
668 Dump3(
"ActualVector", pGSLActualVector);
671 ActualTelescopeDirectionVector.
x = gsl_vector_get(pGSLActualVector, 0);
672 ActualTelescopeDirectionVector.
y = gsl_vector_get(pGSLActualVector, 1);
673 ActualTelescopeDirectionVector.
z = gsl_vector_get(pGSLActualVector, 2);
674 ActualTelescopeDirectionVector.
Normalise();
686 gsl_vector_free(pGSLActualVector);
687 gsl_vector_free(pGSLApparentVector);
693 gsl_matrix *pTransform;
694 gsl_matrix *pComputedTransform =
nullptr;
700#ifdef CONVEX_HULL_DEBUGGING
701 int ApparentFaces = 0;
703 if (
nullptr != CurrentFace)
707#ifdef CONVEX_HULL_DEBUGGING
714#ifdef CONVEX_HULL_DEBUGGING
715 ASSDEBUGF(
"Celestial to telescope - Ignoring apparent face %d", ApparentFaces);
720#ifdef CONVEX_HULL_DEBUGGING
721 ASSDEBUGF(
"TelescopeToCelestial - Processing apparent face %d v1 %d v2 %d v3 %d", ApparentFaces,
726 SyncPoints[CurrentFace->
vertex[0]->
vnum - 1].TelescopeDirection,
727 SyncPoints[CurrentFace->
vertex[1]->
vnum - 1].TelescopeDirection,
728 SyncPoints[CurrentFace->
vertex[2]->
vnum - 1].TelescopeDirection))
731 CurrentFace = CurrentFace->
next;
737 std::map<double, const AlignmentDatabaseEntry *> NearestMap;
738 for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
739 Itr != SyncPoints.end(); Itr++)
741 NearestMap[((*Itr).TelescopeDirection - ApparentTelescopeDirectionVector).Length()] = &(*Itr);
744 std::map<double, const AlignmentDatabaseEntry *>::const_iterator Nearest = NearestMap.begin();
783 pComputedTransform = gsl_matrix_alloc(3, 3);
786 ActualDirectionCosine2, ActualDirectionCosine3, pComputedTransform,
788 pTransform = pComputedTransform;
791 pTransform = CurrentFace->
pMatrix;
797 gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
798 gsl_vector_set(pGSLApparentVector, 0, ApparentTelescopeDirectionVector.
x);
799 gsl_vector_set(pGSLApparentVector, 1, ApparentTelescopeDirectionVector.
y);
800 gsl_vector_set(pGSLApparentVector, 2, ApparentTelescopeDirectionVector.
z);
801 gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
804 ActualTelescopeDirectionVector.
x = gsl_vector_get(pGSLActualVector, 0);
805 ActualTelescopeDirectionVector.
y = gsl_vector_get(pGSLActualVector, 1);
806 ActualTelescopeDirectionVector.
z = gsl_vector_get(pGSLActualVector, 2);
807 ActualTelescopeDirectionVector.
Normalise();
820 gsl_vector_free(pGSLActualVector);
821 gsl_vector_free(pGSLApparentVector);
822 if (
nullptr != pComputedTransform)
823 gsl_matrix_free(pComputedTransform);
836 ASSDEBUGF(
"%lf %lf %lf", gsl_vector_get(pVector, 0), gsl_vector_get(pVector, 1), gsl_vector_get(pVector, 2));
842 ASSDEBUGF(
"Row 0 %lf %lf %lf", gsl_matrix_get(pMatrix, 0, 0), gsl_matrix_get(pMatrix, 0, 1),
843 gsl_matrix_get(pMatrix, 0, 2));
844 ASSDEBUGF(
"Row 1 %lf %lf %lf", gsl_matrix_get(pMatrix, 1, 0), gsl_matrix_get(pMatrix, 1, 1),
845 gsl_matrix_get(pMatrix, 1, 2));
846 ASSDEBUGF(
"Row 2 %lf %lf %lf", gsl_matrix_get(pMatrix, 2, 0), gsl_matrix_get(pMatrix, 2, 1),
847 gsl_matrix_get(pMatrix, 2, 2));
853 gsl_permutation *pPermutation = gsl_permutation_alloc(3);
854 gsl_matrix *pDecomp = gsl_matrix_alloc(3, 3);
858 gsl_matrix_memcpy(pDecomp, pMatrix);
860 gsl_linalg_LU_decomp(pDecomp, pPermutation, &Signum);
862 Determinant = gsl_linalg_LU_det(pDecomp, Signum);
864 gsl_matrix_free(pDecomp);
865 gsl_permutation_free(pPermutation);
874 gsl_permutation *pPermutation = gsl_permutation_alloc(3);
875 gsl_matrix *pDecomp = gsl_matrix_alloc(3, 3);
878 gsl_matrix_memcpy(pDecomp, pInput);
880 gsl_linalg_LU_decomp(pDecomp, pPermutation, &Signum);
883 if (0 == gsl_linalg_LU_det(pDecomp, Signum))
888 gsl_linalg_LU_invert(pDecomp, pPermutation, pInversion);
890 gsl_matrix_free(pDecomp);
891 gsl_permutation_free(pPermutation);
901 gsl_matrix_set_zero(pC);
903 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, pA, pB, 0.0, pC);
911 gsl_vector_set_zero(pC);
913 gsl_blas_dgemv(CblasNoTrans, 1.0, pA, pB, 0.0, pC);
927 double Determinant = Edge1 ^ P;
928 double InverseDeterminant = 1.0 / Determinant;
932 if ((Determinant > -std::numeric_limits<double>::epsilon()) &&
933 (Determinant < std::numeric_limits<double>::epsilon()))
940 double u = (T ^ P) * InverseDeterminant;
942 if (u < 0.0 || u > 1.0)
950 double v = (Ray ^ Q) * InverseDeterminant;
952 if (v < 0.0 || u + v > 1.0)
956 double t = (Edge2 ^ Q) * InverseDeterminant;
958 if (t > std::numeric_limits<double>::epsilon())
#define ASSDEBUGF(msg,...)
bool MatrixInvert3x3(gsl_matrix *pInput, gsl_matrix *pInversion)
Calculate the inverse of the supplied matrix.
gsl_matrix * pApparentToActualTransform
gsl_matrix * pActualToApparentTransform
double Matrix3x3Determinant(gsl_matrix *pMatrix)
Calculate the determinant of the supplied matrix.
void MatrixMatrixMultiply(gsl_matrix *pA, gsl_matrix *pB, gsl_matrix *pC)
Multiply matrix A by matrix B and put the result in C.
virtual bool TransformTelescopeToCelestialJD(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination, double JulianDate) override
Override for the base class virtual function.
void Dump3(const char *Label, gsl_vector *pVector)
Print out a 3 vector to debug.
virtual bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination, double JulianOffset=0) override
Compat shim - resolves JD and delegates to TransformTelescopeToCelestialJD.
virtual void CalculateTransformMatrices(const TelescopeDirectionVector &Alpha1, const TelescopeDirectionVector &Alpha2, const TelescopeDirectionVector &Alpha3, const TelescopeDirectionVector &Beta1, const TelescopeDirectionVector &Beta2, const TelescopeDirectionVector &Beta3, gsl_matrix *pAlphaToBeta, gsl_matrix *pBetaToAlpha)=0
Calculate transformation matrices from the supplied vectors.
std::vector< TelescopeDirectionVector > ActualDirectionCosines
virtual bool TransformCelestialToTelescope(const double RightAscension, const double Declination, double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector) override
Compat shim - resolves JD and delegates to TransformCelestialToTelescopeJD.
ConvexHull ActualConvexHull
virtual bool TransformCelestialToTelescopeJD(double RightAscension, double Declination, double JulianDate, TelescopeDirectionVector &ApparentTelescopeDirectionVector) override
Override for the base class virtual function.
void MatrixVectorMultiply(gsl_matrix *pA, gsl_vector *pB, gsl_vector *pC)
Multiply matrix A by vector B and put the result in vector C.
BasicMathPlugin()
Default constructor.
virtual ~BasicMathPlugin()
Virtual destructor.
bool RayTriangleIntersection(TelescopeDirectionVector &Ray, TelescopeDirectionVector &TriangleVertex1, TelescopeDirectionVector &TriangleVertex2, TelescopeDirectionVector &TriangleVertex3)
Test if a ray intersects a triangle in 3d space.
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase) override
Override for the base class virtual function.
ConvexHull ApparentConvexHull
void Dump3x3(const char *Label, gsl_matrix *pMatrix)
Print out a 3x3 matrix to debug.
void EdgeOrderOnFaces()
EdgeOrderOnFaces: puts e0 between v0 and v1, e1 between v1 and v2, e2 between v2 and v0 on each face....
void Reset()
Frees the vertices edges and faces lists and resets the debug and check flags.
void MakeNewVertex(double x, double y, double z, int VertexId)
Makes a vertex from the supplied information and adds it to the vertices list.
void PrintOut(const char *FileName, tVertex v)
Prints vertices, edges and faces to the standard error output.
bool DoubleTriangle()
DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two...
void ConstructHull()
ConstructHull adds the vertices to the hull one at a time. The hull vertices are those in the list ma...
void PrintObj(const char *FileName="chull.obj")
Outputs the faces in Lightwave obj format for 3d viewing. The files chull.obj and chull....
This class provides the driver side API to the in memory alignment database.
std::vector< AlignmentDatabaseEntry > AlignmentDatabaseType
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
InMemoryDatabase * pInMemoryDatabase
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
MountAlignment_t ApproximateMountAlignment
Describe the approximate alignment of the mount. This information is normally used in a one star alig...
const TelescopeDirectionVector TelescopeDirectionVectorFromAltitudeAzimuth(INDI::IHorizontalCoordinates HorizontalCoordinates)
Calculates a normalised direction vector from the supplied altitude and azimuth.
void EquatorialCoordinatesFromTelescopeDirectionVector(const TelescopeDirectionVector TelescopeDirectionVector, INDI::IEquatorialCoordinates &EquatorialCoordinates)
Calculates equatorial coordinates from the supplied telescope direction vector and declination.
const TelescopeDirectionVector TelescopeDirectionVectorFromEquatorialCoordinates(INDI::IEquatorialCoordinates EquatorialCoordinates)
Calculates a telescope direction vector from the supplied equatorial coordinates.
void AltitudeAzimuthFromTelescopeDirectionVector(const TelescopeDirectionVector TelescopeDirectionVector, INDI::IHorizontalCoordinates &HorizontalCoordinates)
Calculates an altitude and azimuth from the supplied normalised direction vector and declination.
Implementations for common driver routines.
Namespace to encapsulate INDI client, drivers, and mediator classes.
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
Entry in the in memory alignment database.
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
double ObservationJulianDate
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
double Declination
Declination in decimal degrees.
Holds a normalised direction vector (direction cosines)
void Normalise()
Normalise the vector.