Instrument Neutral Distributed Interface INDI  1.9.5
BasicMathPlugin.cpp
Go to the documentation of this file.
1 
5 #include "BasicMathPlugin.h"
6 
7 #include "DriverCommon.h"
8 #include "libastro.h"
9 #include <libnova/julian_day.h>
10 
11 #include <gsl/gsl_blas.h>
12 #include <gsl/gsl_permutation.h>
13 #include <gsl/gsl_linalg.h>
14 
15 #include "indicom.h"
16 
17 #include <limits>
18 #include <iostream>
19 #include <map>
20 
21 namespace INDI
22 {
23 namespace AlignmentSubsystem
24 {
26 {
27  pActualToApparentTransform = gsl_matrix_alloc(3, 3);
28  pApparentToActualTransform = gsl_matrix_alloc(3, 3);
29 }
30 
31 // Destructor
32 
34 {
35  gsl_matrix_free(pActualToApparentTransform);
36  gsl_matrix_free(pApparentToActualTransform);
37 }
38 
39 // Public methods
40 
42 {
45 
55  switch (SyncPoints.size())
56  {
57  // JM 2021-07-04: No Transformation required.
58  case 0:
59  return true;
60 
61  // JM 2021-07-04: For 1 point, it should be direct reciporical transformation.
62  case 1:
63  {
64  AlignmentDatabaseEntry &Entry1 = SyncPoints[0];
66  INDI::IHorizontalCoordinates ActualSyncPoint1;
67  TelescopeDirectionVector ActualDirectionCosine1;
68  IGeographicCoordinates Position;
70  return false;
71  RaDec.declination = Entry1.Declination;
72  RaDec.rightascension = Entry1.RightAscension;
74  {
75  EquatorialToHorizontal(&RaDec, &Position, Entry1.ObservationJulianDate, &ActualSyncPoint1);
76  // Now express this coordinate as a normalised direction vector (a.k.a direction cosines)
77  ActualDirectionCosine1 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint1);
78  }
79  else
80  {
81  ActualDirectionCosine1 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec);
82  }
83  TelescopeDirectionVector DummyActualDirectionCosine2;
84  TelescopeDirectionVector DummyApparentDirectionCosine2;
85  TelescopeDirectionVector DummyActualDirectionCosine3;
86  TelescopeDirectionVector DummyApparentDirectionCosine3;
87 
89  {
90  case ZENITH:
91  DummyActualDirectionCosine2.x = 0.0;
92  DummyActualDirectionCosine2.y = 0.0;
93  DummyActualDirectionCosine2.z = 1.0;
94  DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
95  break;
96 
98  {
100  //INDI::IHorizontalCoordinates DummyAltAz;
101  DummyRaDec.rightascension = 0.0;
102  DummyRaDec.declination = 90.0;
103  //EquatorialToHorizontal(&DummyRaDec, &Position, ln_get_julian_from_sys(), &DummyAltAz);
104  DummyActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(DummyRaDec);
105  DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
106  break;
107  }
109  {
110  INDI::IEquatorialCoordinates DummyRaDec;
111  //INDI::IHorizontalCoordinates DummyAltAz;
112  DummyRaDec.rightascension = 0.0;
113  DummyRaDec.declination = -90.0;
114  //EquatorialToHorizontal(&DummyRaDec, &Position, ln_get_julian_from_sys(), &DummyAltAz);
115  DummyActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(DummyRaDec);
116  DummyApparentDirectionCosine2 = DummyActualDirectionCosine2;
117  break;
118  }
119  }
120  DummyActualDirectionCosine3 = ActualDirectionCosine1 * DummyActualDirectionCosine2;
121  DummyActualDirectionCosine3.Normalise();
122  DummyApparentDirectionCosine3 = Entry1.TelescopeDirection * DummyApparentDirectionCosine2;
123  DummyApparentDirectionCosine3.Normalise();
124  CalculateTransformMatrices(ActualDirectionCosine1, DummyActualDirectionCosine2, DummyActualDirectionCosine3,
125  Entry1.TelescopeDirection, DummyApparentDirectionCosine2,
126  DummyApparentDirectionCosine3, pActualToApparentTransform,
128  return true;
129  }
130  case 2:
131  {
132  // First compute local horizontal coordinates for the two sync points
133  AlignmentDatabaseEntry &Entry1 = SyncPoints[0];
134  AlignmentDatabaseEntry &Entry2 = SyncPoints[1];
137  TelescopeDirectionVector ActualDirectionCosine1;
138  TelescopeDirectionVector ActualDirectionCosine2;
139  RaDec1.declination = Entry1.Declination;
140  RaDec1.rightascension = Entry1.RightAscension;
141  RaDec2.declination = Entry2.Declination;
142  RaDec2.rightascension = Entry2.RightAscension;
143  IGeographicCoordinates Position { 0, 0, 0 };
145  return false;
147  {
148  INDI::IHorizontalCoordinates ActualSyncPoint1;
149  INDI::IHorizontalCoordinates ActualSyncPoint2;
150  EquatorialToHorizontal(&RaDec1, &Position, Entry1.ObservationJulianDate, &ActualSyncPoint1);
151  EquatorialToHorizontal(&RaDec2, &Position, Entry2.ObservationJulianDate, &ActualSyncPoint2);
152  ActualDirectionCosine1 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint1);
153  ActualDirectionCosine2 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint2);
154  }
155  else
156  {
157  ActualDirectionCosine1 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec1);
158  ActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec2);
159  }
160 
161  // Now express these coordinates as normalised direction vectors (a.k.a direction cosines)
162  TelescopeDirectionVector DummyActualDirectionCosine3;
163  TelescopeDirectionVector DummyApparentDirectionCosine3;
164  DummyActualDirectionCosine3 = ActualDirectionCosine1 * ActualDirectionCosine2;
165  DummyActualDirectionCosine3.Normalise();
166  DummyApparentDirectionCosine3 = Entry1.TelescopeDirection * Entry2.TelescopeDirection;
167  DummyApparentDirectionCosine3.Normalise();
168 
169  // The third direction vectors is generated by taking the cross product of the first two
170  CalculateTransformMatrices(ActualDirectionCosine1, ActualDirectionCosine2, DummyActualDirectionCosine3,
171  Entry1.TelescopeDirection, Entry2.TelescopeDirection,
172  DummyApparentDirectionCosine3, pActualToApparentTransform,
174  return true;
175  }
176 
177  case 3:
178  {
179  // First compute local horizontal coordinates for the three sync points
180  AlignmentDatabaseEntry &Entry1 = SyncPoints[0];
181  AlignmentDatabaseEntry &Entry2 = SyncPoints[1];
182  AlignmentDatabaseEntry &Entry3 = SyncPoints[2];
183  INDI::IEquatorialCoordinates RaDec1, RaDec2, RaDec3;
184  TelescopeDirectionVector ActualDirectionCosine1, ActualDirectionCosine2, ActualDirectionCosine3;
185  RaDec1.declination = Entry1.Declination;
186  RaDec1.rightascension = Entry1.RightAscension;
187  RaDec2.declination = Entry2.Declination;
188  RaDec2.rightascension = Entry2.RightAscension;
189  RaDec3.declination = Entry3.Declination;
190  RaDec3.rightascension = Entry3.RightAscension;
191  IGeographicCoordinates Position { 0, 0, 0 };
193  return false;
195  {
196  INDI::IHorizontalCoordinates ActualSyncPoint1;
197  INDI::IHorizontalCoordinates ActualSyncPoint2;
198  INDI::IHorizontalCoordinates ActualSyncPoint3;
199  EquatorialToHorizontal(&RaDec1, &Position, Entry1.ObservationJulianDate, &ActualSyncPoint1);
200  EquatorialToHorizontal(&RaDec2, &Position, Entry2.ObservationJulianDate, &ActualSyncPoint2);
201  EquatorialToHorizontal(&RaDec3, &Position, Entry3.ObservationJulianDate, &ActualSyncPoint3);
202 
203  // Now express these coordinates as normalised direction vectors (a.k.a direction cosines)
204  ActualDirectionCosine1 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint1);
205  ActualDirectionCosine2 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint2);
206  ActualDirectionCosine3 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint3);
207  }
208  else
209  {
210  ActualDirectionCosine1 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec1);
211  ActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec2);
212  ActualDirectionCosine3 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec3);
213  }
214 
215  CalculateTransformMatrices(ActualDirectionCosine1, ActualDirectionCosine2, ActualDirectionCosine3,
218  return true;
219  }
220 
221  default:
222  {
223  IGeographicCoordinates Position { 0, 0, 0 };
225  return false;
226 
227  // Compute Hulls etc.
230  ActualDirectionCosines.clear();
231 
232  // Add a dummy point at the nadir
233  ActualConvexHull.MakeNewVertex(0.0, 0.0, -1.0, 0);
234  ApparentConvexHull.MakeNewVertex(0.0, 0.0, -1.0, 0);
235 
236  int VertexNumber = 1;
237  // Add the rest of the vertices
238  for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
239  Itr != SyncPoints.end(); Itr++)
240  {
242  TelescopeDirectionVector ActualDirectionCosine;
243  RaDec.declination = (*Itr).Declination;
244  RaDec.rightascension = (*Itr).RightAscension;
246  {
247  INDI::IHorizontalCoordinates ActualSyncPoint;
248  EquatorialToHorizontal(&RaDec, &Position, (*Itr).ObservationJulianDate, &ActualSyncPoint);
249  // Now express this coordinate as normalised direction vectors (a.k.a direction cosines)
250  ActualDirectionCosine = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint);
251  }
252  else
253  {
254  ActualDirectionCosine = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec);
255  }
256  ActualDirectionCosines.push_back(ActualDirectionCosine);
257  ActualConvexHull.MakeNewVertex(ActualDirectionCosine.x, ActualDirectionCosine.y,
258  ActualDirectionCosine.z, VertexNumber);
259  ApparentConvexHull.MakeNewVertex((*Itr).TelescopeDirection.x, (*Itr).TelescopeDirection.y,
260  (*Itr).TelescopeDirection.z, VertexNumber);
261  VertexNumber++;
262  }
263  // I should only need to do this once but it is easier to do it twice
270 
271  // Make the matrices
273 #ifdef CONVEX_HULL_DEBUGGING
274  int ActualFaces = 0;
275 #endif
276  if (nullptr != CurrentFace)
277  {
278  do
279  {
280 #ifdef CONVEX_HULL_DEBUGGING
281  ActualFaces++;
282 #endif
283  if ((0 == CurrentFace->vertex[0]->vnum) || (0 == CurrentFace->vertex[1]->vnum) ||
284  (0 == CurrentFace->vertex[2]->vnum))
285  {
286 #ifdef CONVEX_HULL_DEBUGGING
287  ASSDEBUGF("Initialise - Ignoring actual face %d", ActualFaces);
288 #endif
289  }
290  else
291  {
292 #ifdef CONVEX_HULL_DEBUGGING
293  ASSDEBUGF("Initialise - Processing actual face %d v1 %d v2 %d v3 %d", ActualFaces,
294  CurrentFace->vertex[0]->vnum, CurrentFace->vertex[1]->vnum,
295  CurrentFace->vertex[2]->vnum);
296 #endif
298  ActualDirectionCosines[CurrentFace->vertex[1]->vnum - 1],
299  ActualDirectionCosines[CurrentFace->vertex[2]->vnum - 1],
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);
304  }
305  CurrentFace = CurrentFace->next;
306  }
307  while (CurrentFace != ActualConvexHull.faces);
308  }
309 
310  // One of these days I will optimise this
311  CurrentFace = ApparentConvexHull.faces;
312 #ifdef CONVEX_HULL_DEBUGGING
313  int ApparentFaces = 0;
314 #endif
315  if (nullptr != CurrentFace)
316  {
317  do
318  {
319 #ifdef CONVEX_HULL_DEBUGGING
320  ApparentFaces++;
321 #endif
322  if ((0 == CurrentFace->vertex[0]->vnum) || (0 == CurrentFace->vertex[1]->vnum) ||
323  (0 == CurrentFace->vertex[2]->vnum))
324  {
325 #ifdef CONVEX_HULL_DEBUGGING
326  ASSDEBUGF("Initialise - Ignoring apparent face %d", ApparentFaces);
327 #endif
328  }
329  else
330  {
331 #ifdef CONVEX_HULL_DEBUGGING
332  ASSDEBUGF("Initialise - Processing apparent face %d v1 %d v2 %d v3 %d", ApparentFaces,
333  CurrentFace->vertex[0]->vnum, CurrentFace->vertex[1]->vnum,
334  CurrentFace->vertex[2]->vnum);
335 #endif
336  CalculateTransformMatrices(SyncPoints[CurrentFace->vertex[0]->vnum - 1].TelescopeDirection,
337  SyncPoints[CurrentFace->vertex[1]->vnum - 1].TelescopeDirection,
338  SyncPoints[CurrentFace->vertex[2]->vnum - 1].TelescopeDirection,
339  ActualDirectionCosines[CurrentFace->vertex[0]->vnum - 1],
340  ActualDirectionCosines[CurrentFace->vertex[1]->vnum - 1],
341  ActualDirectionCosines[CurrentFace->vertex[2]->vnum - 1],
342  CurrentFace->pMatrix, nullptr);
343  }
344  CurrentFace = CurrentFace->next;
345  }
346  while (CurrentFace != ApparentConvexHull.faces);
347  }
348 
349 #ifdef CONVEX_HULL_DEBUGGING
350  ASSDEBUGF("Initialise - ActualFaces %d ApparentFaces %d", ActualFaces, ApparentFaces);
351  ActualConvexHull.PrintObj("ActualHull.obj");
353  ApparentConvexHull.PrintObj("ApparentHull.obj");
355 #endif
356  return true;
357  }
358  }
359 }
360 
361 bool BasicMathPlugin::TransformCelestialToTelescope(const double RightAscension, const double Declination,
362  double JulianOffset,
363  TelescopeDirectionVector &ApparentTelescopeDirectionVector)
364 {
365  INDI::IEquatorialCoordinates ActualRaDec;
366  ActualRaDec.rightascension = RightAscension;
367  ActualRaDec.declination = Declination;
368  IGeographicCoordinates Position { 0, 0, 0 };
369 
370  // Should check that this the same as the current observing position
371  if ((nullptr == pInMemoryDatabase) || !pInMemoryDatabase->GetDatabaseReferencePosition(Position))
372  return false;
373 
375  switch (SyncPoints.size())
376  {
377  case 0:
378  {
379  // 0 sync points
381  {
382  case ZENITH:
383  INDI::IHorizontalCoordinates ActualAltAz;
384  EquatorialToHorizontal(&ActualRaDec, &Position, ln_get_julian_from_sys() + JulianOffset, &ActualAltAz);
385  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(ActualAltAz);
386  ASSDEBUGF("Celestial to telescope - Actual Az %lf Alt %lf", ActualAltAz.azimuth, ActualAltAz.altitude);
387  break;
388 
390  // Rotate the TDV coordinate system clockwise (negative) around the y axis by 90 minus
391  // the (positive)observatory latitude. The vector itself is rotated anticlockwise
392  //ApparentTelescopeDirectionVector.RotateAroundY(Position.latitude - 90.0);
394  // Rotate the TDV coordinate system anticlockwise (positive) around the y axis by 90 plus
395  // the (negative)observatory latitude. The vector itself is rotated clockwise
396  //ApparentTelescopeDirectionVector.RotateAroundY(Position.latitude + 90.0);
397  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(ActualRaDec);
398  break;
399  }
400  break;
401  }
402  case 1:
403  case 2:
404  case 3:
405  {
406  TelescopeDirectionVector ActualVector;
408  {
409  INDI::IHorizontalCoordinates ActualAltAz;
410  EquatorialToHorizontal(&ActualRaDec, &Position, ln_get_julian_from_sys() + JulianOffset, &ActualAltAz);
411  ActualVector = TelescopeDirectionVectorFromAltitudeAzimuth(ActualAltAz);
412  }
413  else
414  {
415  ActualVector = TelescopeDirectionVectorFromEquatorialCoordinates(ActualRaDec);
416  }
417  gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
418  gsl_vector_set(pGSLActualVector, 0, ActualVector.x);
419  gsl_vector_set(pGSLActualVector, 1, ActualVector.y);
420  gsl_vector_set(pGSLActualVector, 2, ActualVector.z);
421  gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
422  MatrixVectorMultiply(pActualToApparentTransform, pGSLActualVector, pGSLApparentVector);
423  ApparentTelescopeDirectionVector.x = gsl_vector_get(pGSLApparentVector, 0);
424  ApparentTelescopeDirectionVector.y = gsl_vector_get(pGSLApparentVector, 1);
425  ApparentTelescopeDirectionVector.z = gsl_vector_get(pGSLApparentVector, 2);
426  ApparentTelescopeDirectionVector.Normalise();
427  gsl_vector_free(pGSLActualVector);
428  gsl_vector_free(pGSLApparentVector);
429  break;
430  }
431 
432  default:
433  {
434  TelescopeDirectionVector ActualVector;
436  {
437  INDI::IHorizontalCoordinates ActualAltAz;
438  EquatorialToHorizontal(&ActualRaDec, &Position, ln_get_julian_from_sys() + JulianOffset, &ActualAltAz);
439  ActualVector = TelescopeDirectionVectorFromAltitudeAzimuth(ActualAltAz);
440  }
441  else
442  {
443  ActualVector = TelescopeDirectionVectorFromEquatorialCoordinates(ActualRaDec);
444  }
445 
446  gsl_matrix *pTransform;
447  gsl_matrix *pComputedTransform = nullptr;
448  // Scale the actual telescope direction vector to make sure it traverses the unit sphere.
449  TelescopeDirectionVector ScaledActualVector = ActualVector * 2.0;
450  // Shoot the scaled vector in the into the list of actual facets
451  // and use the conversuion matrix from the one it intersects
453 #ifdef CONVEX_HULL_DEBUGGING
454  int ActualFaces = 0;
455 #endif
456  if (nullptr != CurrentFace)
457  {
458  do
459  {
460 #ifdef CONVEX_HULL_DEBUGGING
461  ActualFaces++;
462 #endif
463  // Ignore faces containg vertex 0 (nadir).
464  if ((0 == CurrentFace->vertex[0]->vnum) || (0 == CurrentFace->vertex[1]->vnum) ||
465  (0 == CurrentFace->vertex[2]->vnum))
466  {
467 #ifdef CONVEX_HULL_DEBUGGING
468  ASSDEBUGF("Celestial to telescope - Ignoring actual face %d", ActualFaces);
469 #endif
470  }
471  else
472  {
473 #ifdef CONVEX_HULL_DEBUGGING
474  ASSDEBUGF("Celestial to telescope - Processing actual face %d v1 %d v2 %d v3 %d", ActualFaces,
475  CurrentFace->vertex[0]->vnum, CurrentFace->vertex[1]->vnum,
476  CurrentFace->vertex[2]->vnum);
477 #endif
478  if (RayTriangleIntersection(ScaledActualVector,
479  ActualDirectionCosines[CurrentFace->vertex[0]->vnum - 1],
480  ActualDirectionCosines[CurrentFace->vertex[1]->vnum - 1],
481  ActualDirectionCosines[CurrentFace->vertex[2]->vnum - 1]))
482  break;
483  }
484  CurrentFace = CurrentFace->next;
485  }
486  while (CurrentFace != ActualConvexHull.faces);
487  if (CurrentFace == ActualConvexHull.faces)
488  {
489  // Find the three nearest points and build a transform
490  std::map<double, const AlignmentDatabaseEntry *> NearestMap;
491  for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
492  Itr != SyncPoints.end(); Itr++)
493  {
495  TelescopeDirectionVector ActualDirectionCosine;
496  RaDec.rightascension = (*Itr).RightAscension;
497  RaDec.declination = (*Itr).Declination;
499  {
500  INDI::IHorizontalCoordinates ActualPoint;
501  EquatorialToHorizontal(&RaDec, &Position, (*Itr).ObservationJulianDate, &ActualPoint);
502  ActualDirectionCosine = TelescopeDirectionVectorFromAltitudeAzimuth(ActualPoint);
503  }
504  else
505  {
506  ActualDirectionCosine = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec);
507  }
508  NearestMap[(ActualDirectionCosine - ActualVector).Length()] = &(*Itr);
509  }
510  // First compute local horizontal coordinates for the three sync points
511  std::map<double, const AlignmentDatabaseEntry *>::const_iterator Nearest = NearestMap.begin();
512  const AlignmentDatabaseEntry *pEntry1 = (*Nearest).second;
513  Nearest++;
514  const AlignmentDatabaseEntry *pEntry2 = (*Nearest).second;
515  Nearest++;
516  const AlignmentDatabaseEntry *pEntry3 = (*Nearest).second;
520  TelescopeDirectionVector ActualDirectionCosine1;
521  TelescopeDirectionVector ActualDirectionCosine2;
522  TelescopeDirectionVector ActualDirectionCosine3;
523  RaDec1.declination = pEntry1->Declination;
524  RaDec1.rightascension = pEntry1->RightAscension;
525  RaDec2.declination = pEntry2->Declination;
526  RaDec2.rightascension = pEntry2->RightAscension;
527  RaDec3.declination = pEntry3->Declination;
528  RaDec3.rightascension = pEntry3->RightAscension;
529 
531  {
532  INDI::IHorizontalCoordinates ActualSyncPoint1;
533  INDI::IHorizontalCoordinates ActualSyncPoint2;
534  INDI::IHorizontalCoordinates ActualSyncPoint3;
535  EquatorialToHorizontal(&RaDec1, &Position, pEntry1->ObservationJulianDate, &ActualSyncPoint1);
536  EquatorialToHorizontal(&RaDec2, &Position, pEntry2->ObservationJulianDate, &ActualSyncPoint2);
537  EquatorialToHorizontal(&RaDec3, &Position, pEntry3->ObservationJulianDate, &ActualSyncPoint3);
538 
539  // Now express these coordinates as normalised direction vectors (a.k.a direction cosines)
540  ActualDirectionCosine1 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint1);
541  ActualDirectionCosine2 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint2);
542  ActualDirectionCosine3 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint3);
543  }
544  else
545  {
546  ActualDirectionCosine1 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec1);
547  ActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec2);
548  ActualDirectionCosine3 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec3);
549  }
550 
551  pComputedTransform = gsl_matrix_alloc(3, 3);
552  CalculateTransformMatrices(ActualDirectionCosine1, ActualDirectionCosine2, ActualDirectionCosine3,
553  pEntry1->TelescopeDirection, pEntry2->TelescopeDirection,
554  pEntry3->TelescopeDirection, pComputedTransform, nullptr);
555  pTransform = pComputedTransform;
556  }
557  else
558  pTransform = CurrentFace->pMatrix;
559  }
560  else
561  return false;
562 
563  // OK - got an intersection - CurrentFace is pointing at the face
564  gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
565  gsl_vector_set(pGSLActualVector, 0, ActualVector.x);
566  gsl_vector_set(pGSLActualVector, 1, ActualVector.y);
567  gsl_vector_set(pGSLActualVector, 2, ActualVector.z);
568  gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
569  MatrixVectorMultiply(pTransform, pGSLActualVector, pGSLApparentVector);
570  ApparentTelescopeDirectionVector.x = gsl_vector_get(pGSLApparentVector, 0);
571  ApparentTelescopeDirectionVector.y = gsl_vector_get(pGSLApparentVector, 1);
572  ApparentTelescopeDirectionVector.z = gsl_vector_get(pGSLApparentVector, 2);
573  ApparentTelescopeDirectionVector.Normalise();
574  gsl_vector_free(pGSLActualVector);
575  gsl_vector_free(pGSLApparentVector);
576  if (nullptr != pComputedTransform)
577  gsl_matrix_free(pComputedTransform);
578  break;
579  }
580  }
581 
582  // INDI::IHorizontalCoordinates ApparentAltAz;
583  // AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, ApparentAltAz);
584  // ASSDEBUGF("Celestial to telescope - Apparent Az %lf Alt %lf", ApparentAltAz.azimuth, ApparentAltAz.altitude);
585 
586  return true;
587 }
588 
590  double &RightAscension, double &Declination)
591 {
592  IGeographicCoordinates Position;
593 
594  //INDI::IHorizontalCoordinates ApparentAltAz;
595  INDI::IHorizontalCoordinates ActualAltAz;
596  INDI::IEquatorialCoordinates ActualRaDec;
597 
598  // AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, ApparentAltAz);
599  // ASSDEBUGF("Telescope to celestial - Apparent Az %lf Alt %lf", ApparentAltAz.azimuth, ApparentAltAz.altitude);
600 
601  if ((nullptr == pInMemoryDatabase) || !pInMemoryDatabase->GetDatabaseReferencePosition(Position))
602  {
603  // Should check that this the same as the current observing position
604  ASSDEBUG("No database or no position in database");
605  return false;
606  }
608  switch (SyncPoints.size())
609  {
610  case 0:
611  {
612  // 0 sync points
613 
615  {
616  // For Alt-Az mounts, get Alt-Az from the telescope direction vector first
617  // Then transform to actual RA/DE
618  case ZENITH:
619  {
620  ASSDEBUGF("ApparentVector x %lf y %lf z %lf", ApparentTelescopeDirectionVector.x,
621  ApparentTelescopeDirectionVector.y, ApparentTelescopeDirectionVector.z);
622  //ASSDEBUGF("ActualVector x %lf y %lf z %lf", RotatedTDV.x, RotatedTDV.y, RotatedTDV.z);
623  AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, ActualAltAz);
624  HorizontalToEquatorial(&ActualAltAz, &Position, ln_get_julian_from_sys(), &ActualRaDec);
625  }
626  break;
627 
628  // For equatorial mount with zero sync points, just convert back from telescope
629  // direction vector to equatorial coordinates.
632  EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, ActualRaDec);
633  break;
634  }
635 
636  RightAscension = ActualRaDec.rightascension;
637  Declination = ActualRaDec.declination;
638  break;
639  }
640  case 1:
641  case 2:
642  case 3:
643  {
644  gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
645  gsl_vector_set(pGSLApparentVector, 0, ApparentTelescopeDirectionVector.x);
646  gsl_vector_set(pGSLApparentVector, 1, ApparentTelescopeDirectionVector.y);
647  gsl_vector_set(pGSLApparentVector, 2, ApparentTelescopeDirectionVector.z);
648  gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
649  MatrixVectorMultiply(pApparentToActualTransform, pGSLApparentVector, pGSLActualVector);
650 
651  Dump3("ApparentVector", pGSLApparentVector);
652  Dump3("ActualVector", pGSLActualVector);
653 
654  TelescopeDirectionVector ActualTelescopeDirectionVector;
655  ActualTelescopeDirectionVector.x = gsl_vector_get(pGSLActualVector, 0);
656  ActualTelescopeDirectionVector.y = gsl_vector_get(pGSLActualVector, 1);
657  ActualTelescopeDirectionVector.z = gsl_vector_get(pGSLActualVector, 2);
658  ActualTelescopeDirectionVector.Normalise();
660  {
661  AltitudeAzimuthFromTelescopeDirectionVector(ActualTelescopeDirectionVector, ActualAltAz);
662  HorizontalToEquatorial(&ActualAltAz, &Position, ln_get_julian_from_sys(), &ActualRaDec);
663  }
664  else
665  {
666  EquatorialCoordinatesFromTelescopeDirectionVector(ActualTelescopeDirectionVector, ActualRaDec);
667  }
668  RightAscension = ActualRaDec.rightascension;
669  Declination = ActualRaDec.declination;
670  gsl_vector_free(pGSLActualVector);
671  gsl_vector_free(pGSLApparentVector);
672  break;
673  }
674 
675  default:
676  {
677  gsl_matrix *pTransform;
678  gsl_matrix *pComputedTransform = nullptr;
679  // Scale the apparent telescope direction vector to make sure it traverses the unit sphere.
680  TelescopeDirectionVector ScaledApparentVector = ApparentTelescopeDirectionVector * 2.0;
681  // Shoot the scaled vector in the into the list of apparent facets
682  // and use the conversuion matrix from the one it intersects
684 #ifdef CONVEX_HULL_DEBUGGING
685  int ApparentFaces = 0;
686 #endif
687  if (nullptr != CurrentFace)
688  {
689  do
690  {
691 #ifdef CONVEX_HULL_DEBUGGING
692  ApparentFaces++;
693 #endif
694  // Ignore faces containg vertex 0 (nadir).
695  if ((0 == CurrentFace->vertex[0]->vnum) || (0 == CurrentFace->vertex[1]->vnum) ||
696  (0 == CurrentFace->vertex[2]->vnum))
697  {
698 #ifdef CONVEX_HULL_DEBUGGING
699  ASSDEBUGF("Celestial to telescope - Ignoring apparent face %d", ApparentFaces);
700 #endif
701  }
702  else
703  {
704 #ifdef CONVEX_HULL_DEBUGGING
705  ASSDEBUGF("TelescopeToCelestial - Processing apparent face %d v1 %d v2 %d v3 %d", ApparentFaces,
706  CurrentFace->vertex[0]->vnum, CurrentFace->vertex[1]->vnum,
707  CurrentFace->vertex[2]->vnum);
708 #endif
709  if (RayTriangleIntersection(ScaledApparentVector,
710  SyncPoints[CurrentFace->vertex[0]->vnum - 1].TelescopeDirection,
711  SyncPoints[CurrentFace->vertex[1]->vnum - 1].TelescopeDirection,
712  SyncPoints[CurrentFace->vertex[2]->vnum - 1].TelescopeDirection))
713  break;
714  }
715  CurrentFace = CurrentFace->next;
716  }
717  while (CurrentFace != ApparentConvexHull.faces);
718  if (CurrentFace == ApparentConvexHull.faces)
719  {
720  // Find the three nearest points and build a transform
721  std::map<double, const AlignmentDatabaseEntry *> NearestMap;
722  for (InMemoryDatabase::AlignmentDatabaseType::const_iterator Itr = SyncPoints.begin();
723  Itr != SyncPoints.end(); Itr++)
724  {
725  NearestMap[((*Itr).TelescopeDirection - ApparentTelescopeDirectionVector).Length()] = &(*Itr);
726  }
727  // First compute local horizontal coordinates for the three sync points
728  std::map<double, const AlignmentDatabaseEntry *>::const_iterator Nearest = NearestMap.begin();
729  const AlignmentDatabaseEntry *pEntry1 = (*Nearest).second;
730  Nearest++;
731  const AlignmentDatabaseEntry *pEntry2 = (*Nearest).second;
732  Nearest++;
733  const AlignmentDatabaseEntry *pEntry3 = (*Nearest).second;
737  TelescopeDirectionVector ActualDirectionCosine1;
738  TelescopeDirectionVector ActualDirectionCosine2;
739  TelescopeDirectionVector ActualDirectionCosine3;
740  RaDec1.declination = pEntry1->Declination;
741  RaDec1.rightascension = pEntry1->RightAscension;
742  RaDec2.declination = pEntry2->Declination;
743  RaDec2.rightascension = pEntry2->RightAscension;
744  RaDec3.declination = pEntry3->Declination;
745  RaDec3.rightascension = pEntry3->RightAscension;
746 
748  {
749  INDI::IHorizontalCoordinates ActualSyncPoint1;
750  INDI::IHorizontalCoordinates ActualSyncPoint2;
751  INDI::IHorizontalCoordinates ActualSyncPoint3;
752  EquatorialToHorizontal(&RaDec1, &Position, pEntry1->ObservationJulianDate, &ActualSyncPoint1);
753  EquatorialToHorizontal(&RaDec2, &Position, pEntry2->ObservationJulianDate, &ActualSyncPoint2);
754  EquatorialToHorizontal(&RaDec3, &Position, pEntry3->ObservationJulianDate, &ActualSyncPoint3);
755 
756  // Now express these coordinates as normalised direction vectors (a.k.a direction cosines)
757  ActualDirectionCosine1 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint1);
758  ActualDirectionCosine2 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint2);
759  ActualDirectionCosine3 = TelescopeDirectionVectorFromAltitudeAzimuth(ActualSyncPoint3);
760  }
761  else
762  {
763  ActualDirectionCosine1 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec1);
764  ActualDirectionCosine2 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec2);
765  ActualDirectionCosine3 = TelescopeDirectionVectorFromEquatorialCoordinates(RaDec3);
766  }
767  pComputedTransform = gsl_matrix_alloc(3, 3);
769  pEntry3->TelescopeDirection, ActualDirectionCosine1,
770  ActualDirectionCosine2, ActualDirectionCosine3, pComputedTransform,
771  nullptr);
772  pTransform = pComputedTransform;
773  }
774  else
775  pTransform = CurrentFace->pMatrix;
776  }
777  else
778  return false;
779 
780  // OK - got an intersection - CurrentFace is pointing at the face
781  gsl_vector *pGSLApparentVector = gsl_vector_alloc(3);
782  gsl_vector_set(pGSLApparentVector, 0, ApparentTelescopeDirectionVector.x);
783  gsl_vector_set(pGSLApparentVector, 1, ApparentTelescopeDirectionVector.y);
784  gsl_vector_set(pGSLApparentVector, 2, ApparentTelescopeDirectionVector.z);
785  gsl_vector *pGSLActualVector = gsl_vector_alloc(3);
786  MatrixVectorMultiply(pTransform, pGSLApparentVector, pGSLActualVector);
787  TelescopeDirectionVector ActualTelescopeDirectionVector;
788  ActualTelescopeDirectionVector.x = gsl_vector_get(pGSLActualVector, 0);
789  ActualTelescopeDirectionVector.y = gsl_vector_get(pGSLActualVector, 1);
790  ActualTelescopeDirectionVector.z = gsl_vector_get(pGSLActualVector, 2);
791  ActualTelescopeDirectionVector.Normalise();
793  {
794  AltitudeAzimuthFromTelescopeDirectionVector(ActualTelescopeDirectionVector, ActualAltAz);
795  HorizontalToEquatorial(&ActualAltAz, &Position, ln_get_julian_from_sys(), &ActualRaDec);
796  }
797  else
798  {
799  EquatorialCoordinatesFromTelescopeDirectionVector(ActualTelescopeDirectionVector, ActualRaDec);
800  }
801  // libnova works in decimal degrees so conversion is needed here
802  RightAscension = ActualRaDec.rightascension;
803  Declination = ActualRaDec.declination;
804  gsl_vector_free(pGSLActualVector);
805  gsl_vector_free(pGSLApparentVector);
806  if (nullptr != pComputedTransform)
807  gsl_matrix_free(pComputedTransform);
808  break;
809  }
810  }
811  //ASSDEBUGF("Telescope to Celestial - Actual Az %lf Alt %lf", ActualAltAz.azimuth, ActualAltAz.altitude);
812  return true;
813 }
814 
815 // Private methods
816 
817 void BasicMathPlugin::Dump3(const char *Label, gsl_vector *pVector)
818 {
819  ASSDEBUGF("Vector dump - %s", Label);
820  ASSDEBUGF("%lf %lf %lf", gsl_vector_get(pVector, 0), gsl_vector_get(pVector, 1), gsl_vector_get(pVector, 2));
821 }
822 
823 void BasicMathPlugin::Dump3x3(const char *Label, gsl_matrix *pMatrix)
824 {
825  ASSDEBUGF("Matrix dump - %s", Label);
826  ASSDEBUGF("Row 0 %lf %lf %lf", gsl_matrix_get(pMatrix, 0, 0), gsl_matrix_get(pMatrix, 0, 1),
827  gsl_matrix_get(pMatrix, 0, 2));
828  ASSDEBUGF("Row 1 %lf %lf %lf", gsl_matrix_get(pMatrix, 1, 0), gsl_matrix_get(pMatrix, 1, 1),
829  gsl_matrix_get(pMatrix, 1, 2));
830  ASSDEBUGF("Row 2 %lf %lf %lf", gsl_matrix_get(pMatrix, 2, 0), gsl_matrix_get(pMatrix, 2, 1),
831  gsl_matrix_get(pMatrix, 2, 2));
832 }
833 
835 double BasicMathPlugin::Matrix3x3Determinant(gsl_matrix *pMatrix)
836 {
837  gsl_permutation *pPermutation = gsl_permutation_alloc(3);
838  gsl_matrix *pDecomp = gsl_matrix_alloc(3, 3);
839  int Signum;
840  double Determinant;
841 
842  gsl_matrix_memcpy(pDecomp, pMatrix);
843 
844  gsl_linalg_LU_decomp(pDecomp, pPermutation, &Signum);
845 
846  Determinant = gsl_linalg_LU_det(pDecomp, Signum);
847 
848  gsl_matrix_free(pDecomp);
849  gsl_permutation_free(pPermutation);
850 
851  return Determinant;
852 }
853 
855 bool BasicMathPlugin::MatrixInvert3x3(gsl_matrix *pInput, gsl_matrix *pInversion)
856 {
857  bool Retcode = true;
858  gsl_permutation *pPermutation = gsl_permutation_alloc(3);
859  gsl_matrix *pDecomp = gsl_matrix_alloc(3, 3);
860  int Signum;
861 
862  gsl_matrix_memcpy(pDecomp, pInput);
863 
864  gsl_linalg_LU_decomp(pDecomp, pPermutation, &Signum);
865 
866  // Test for singularity
867  if (0 == gsl_linalg_LU_det(pDecomp, Signum))
868  {
869  Retcode = false;
870  }
871  else
872  gsl_linalg_LU_invert(pDecomp, pPermutation, pInversion);
873 
874  gsl_matrix_free(pDecomp);
875  gsl_permutation_free(pPermutation);
876 
877  return Retcode;
878 }
879 
882 void BasicMathPlugin::MatrixMatrixMultiply(gsl_matrix *pA, gsl_matrix *pB, gsl_matrix *pC)
883 {
884  // Zeroise the output matrix
885  gsl_matrix_set_zero(pC);
886 
887  gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, pA, pB, 0.0, pC);
888 }
889 
892 void BasicMathPlugin::MatrixVectorMultiply(gsl_matrix *pA, gsl_vector *pB, gsl_vector *pC)
893 {
894  // Zeroise the output vector
895  gsl_vector_set_zero(pC);
896 
897  gsl_blas_dgemv(CblasNoTrans, 1.0, pA, pB, 0.0, pC);
898 }
899 
901  TelescopeDirectionVector &TriangleVertex2,
902  TelescopeDirectionVector &TriangleVertex3)
903 {
904  // Use Möller-Trumbore
905 
906  //Find vectors for two edges sharing V1
907  TelescopeDirectionVector Edge1 = TriangleVertex2 - TriangleVertex1;
908  TelescopeDirectionVector Edge2 = TriangleVertex3 - TriangleVertex1;
909 
910  TelescopeDirectionVector P = Ray * Edge2; // cross product
911  double Determinant = Edge1 ^ P; // dot product
912  double InverseDeterminant = 1.0 / Determinant;
913 
914  // If the determinant is negative the triangle is backfacing
915  // If the determinant is close to 0, the ray misses the triangle
916  if ((Determinant > -std::numeric_limits<double>::epsilon()) &&
917  (Determinant < std::numeric_limits<double>::epsilon()))
918  return false;
919 
920  // I use zero as ray origin so
921  TelescopeDirectionVector T(-TriangleVertex1.x, -TriangleVertex1.y, -TriangleVertex1.z);
922 
923  // Calculate the u parameter
924  double u = (T ^ P) * InverseDeterminant;
925 
926  if (u < 0.0 || u > 1.0)
927  //The intersection lies outside of the triangle
928  return false;
929 
930  //Prepare to test v parameter
931  TelescopeDirectionVector Q = T * Edge1;
932 
933  //Calculate v parameter and test bound
934  double v = (Ray ^ Q) * InverseDeterminant;
935 
936  if (v < 0.0 || u + v > 1.0)
937  //The intersection lies outside of the triangle
938  return false;
939 
940  double t = (Edge2 ^ Q) * InverseDeterminant;
941 
942  if (t > std::numeric_limits<double>::epsilon())
943  {
944  //ray intersection
945  return true;
946  }
947 
948  // No hit, no win
949  return false;
950 }
951 
952 } // namespace AlignmentSubsystem
953 } // namespace INDI
INDI::AlignmentSubsystem::ZENITH
@ ZENITH
Definition: Common.h:30
INDI::AlignmentSubsystem::AlignmentDatabaseEntry::TelescopeDirection
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
Definition: Common.h:191
INDI::AlignmentSubsystem::TelescopeDirectionVectorSupportFunctions::EquatorialCoordinatesFromTelescopeDirectionVector
void EquatorialCoordinatesFromTelescopeDirectionVector(const TelescopeDirectionVector TelescopeDirectionVector, INDI::IEquatorialCoordinates &EquatorialCoordinates)
Calculates equatorial coordinates from the supplied telescope direction vector and declination.
Definition: TelescopeDirectionVectorSupportFunctions.h:85
INDI::AlignmentSubsystem::ConvexHull::tFaceStructure
Definition: ConvexHull.h:146
INDI::AlignmentSubsystem::ConvexHull::ConstructHull
void ConstructHull()
ConstructHull adds the vertices to the hull one at a time. The hull vertices are those in the list ma...
Definition: ConvexHull.cpp:347
INDI::AlignmentSubsystem::ConvexHull::PrintObj
void PrintObj(const char *FileName="chull.obj")
Outputs the faces in Lightwave obj format for 3d viewing. The files chull.obj and chull....
Definition: ConvexHull.cpp:824
INDI::AlignmentSubsystem::InMemoryDatabase::GetDatabaseReferencePosition
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
Definition: InMemoryDatabase.cpp:43
INDI::AlignmentSubsystem::BasicMathPlugin::Dump3
void Dump3(const char *Label, gsl_vector *pVector)
Print out a 3 vector to debug.
Definition: BasicMathPlugin.cpp:817
INDI::IHorizontalCoordinates::azimuth
double azimuth
Definition: libastro.h:58
INDI::IEquatorialCoordinates::declination
double declination
Definition: libastro.h:51
INDI::AlignmentSubsystem::AlignmentDatabaseEntry
Entry in the in memory alignment database.
Definition: Common.h:145
INDI::AlignmentSubsystem::ConvexHull::MakeNewVertex
void MakeNewVertex(double x, double y, double z, int VertexId)
Makes a vertex from the supplied information and adds it to the vertices list.
Definition: ConvexHull.cpp:610
INDI::AlignmentSubsystem::MathPlugin::ApproximateMountAlignment
MountAlignment_t ApproximateMountAlignment
Describe the approximate alignment of the mount. This information is normally used in a one star alig...
Definition: MathPlugin.h:79
INDI::AlignmentSubsystem::BasicMathPlugin::RayTriangleIntersection
bool RayTriangleIntersection(TelescopeDirectionVector &Ray, TelescopeDirectionVector &TriangleVertex1, TelescopeDirectionVector &TriangleVertex2, TelescopeDirectionVector &TriangleVertex3)
Test if a ray intersects a triangle in 3d space.
Definition: BasicMathPlugin.cpp:900
indicom.h
Implementations for common driver routines.
INDI::AlignmentSubsystem::SOUTH_CELESTIAL_POLE
@ SOUTH_CELESTIAL_POLE
Definition: Common.h:30
INDI::AlignmentSubsystem::BasicMathPlugin::ActualConvexHull
ConvexHull ActualConvexHull
Definition: BasicMathPlugin.h:102
INDI::AlignmentSubsystem::TelescopeDirectionVectorSupportFunctions::AltitudeAzimuthFromTelescopeDirectionVector
void AltitudeAzimuthFromTelescopeDirectionVector(const TelescopeDirectionVector TelescopeDirectionVector, INDI::IHorizontalCoordinates &HorizontalCoordinates)
Calculates an altitude and azimuth from the supplied normalised direction vector and declination.
Definition: TelescopeDirectionVectorSupportFunctions.h:68
ASSDEBUG
#define ASSDEBUG(msg)
Definition: DriverCommon.h:17
INDI::AlignmentSubsystem::ConvexHull::tFaceStructure::pMatrix
gsl_matrix * pMatrix
Definition: ConvexHull.h:154
INDI::AlignmentSubsystem::BasicMathPlugin::BasicMathPlugin
BasicMathPlugin()
Default constructor.
Definition: BasicMathPlugin.cpp:25
INDI::AlignmentSubsystem::NORTH_CELESTIAL_POLE
@ NORTH_CELESTIAL_POLE
Definition: Common.h:30
INDI::AlignmentSubsystem::MathPlugin::Initialise
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
Definition: MathPlugin.cpp:15
INDI::AlignmentSubsystem::BasicMathPlugin::pApparentToActualTransform
gsl_matrix * pApparentToActualTransform
Definition: BasicMathPlugin.h:99
INDI::AlignmentSubsystem::BasicMathPlugin::TransformCelestialToTelescope
virtual bool TransformCelestialToTelescope(const double RightAscension, const double Declination, double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
Override for the base class virtual function.
Definition: BasicMathPlugin.cpp:361
INDI::AlignmentSubsystem::BasicMathPlugin::TransformTelescopeToCelestial
virtual bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination)
Override for the base class virtual function.
Definition: BasicMathPlugin.cpp:589
DriverCommon.h
INDI::AlignmentSubsystem::ConvexHull::vertices
tVertex vertices
Definition: ConvexHull.h:164
INDI::AlignmentSubsystem::BasicMathPlugin::CalculateTransformMatrices
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 tranformation matrices from the supplied vectors.
INDI::IEquatorialCoordinates::rightascension
double rightascension
Definition: libastro.h:50
INDI::AlignmentSubsystem::ConvexHull::Reset
void Reset()
Frees the vertices edges and faces lists and resets the debug and check flags.
Definition: ConvexHull.cpp:961
INDI::AlignmentSubsystem::BasicMathPlugin::~BasicMathPlugin
virtual ~BasicMathPlugin()
Virtual destructor.
Definition: BasicMathPlugin.cpp:33
INDI::AlignmentSubsystem::BasicMathPlugin::Matrix3x3Determinant
double Matrix3x3Determinant(gsl_matrix *pMatrix)
Caluclate the determinant of the supplied matrix.
Definition: BasicMathPlugin.cpp:835
INDI::AlignmentSubsystem::BasicMathPlugin::ApparentConvexHull
ConvexHull ApparentConvexHull
Definition: BasicMathPlugin.h:103
INDI::EquatorialToHorizontal
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
Definition: libastro.cpp:140
INDI::AlignmentSubsystem::ConvexHull::tVertexStructure::vnum
int vnum
Definition: ConvexHull.h:130
INDI::AlignmentSubsystem::BasicMathPlugin::Initialise
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Override for the base class virtual function.
Definition: BasicMathPlugin.cpp:41
INDI::AlignmentSubsystem::TelescopeDirectionVector::z
double z
Definition: Common.h:78
INDI::IHorizontalCoordinates::altitude
double altitude
Definition: libastro.h:59
INDI::AlignmentSubsystem::ConvexHull::EdgeOrderOnFaces
void EdgeOrderOnFaces()
EdgeOrderOnFaces: puts e0 between v0 and v1, e1 between v1 and v2, e2 between v2 and v0 on each face....
Definition: ConvexHull.cpp:461
INDI::AlignmentSubsystem::InMemoryDatabase
This class provides the driver side API to the in memory alignment database.
Definition: InMemoryDatabase.h:23
INDI::AlignmentSubsystem::MathPlugin::pInMemoryDatabase
InMemoryDatabase * pInMemoryDatabase
Definition: MathPlugin.h:80
INDI::AlignmentSubsystem::BasicMathPlugin::Dump3x3
void Dump3x3(const char *Label, gsl_matrix *pMatrix)
Print out a 3x3 matrix to debug.
Definition: BasicMathPlugin.cpp:823
INDI::AlignmentSubsystem::InMemoryDatabase::AlignmentDatabaseType
std::vector< AlignmentDatabaseEntry > AlignmentDatabaseType
Definition: InMemoryDatabase.h:32
INDI::IGeographicCoordinates
Definition: libastro.h:64
INDI::HorizontalToEquatorial
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
Definition: libastro.cpp:156
INDI::AlignmentSubsystem::TelescopeDirectionVector::y
double y
Definition: Common.h:77
INDI::AlignmentSubsystem::ConvexHull::DoubleTriangle
void DoubleTriangle()
DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two...
Definition: ConvexHull.cpp:405
INDI::AlignmentSubsystem::BasicMathPlugin::MatrixInvert3x3
bool MatrixInvert3x3(gsl_matrix *pInput, gsl_matrix *pInversion)
Calculate the inverse of the supplied matrix.
Definition: BasicMathPlugin.cpp:855
INDI::AlignmentSubsystem::ConvexHull::faces
tFace faces
Definition: ConvexHull.h:166
INDI::AlignmentSubsystem::BasicMathPlugin::MatrixVectorMultiply
void MatrixVectorMultiply(gsl_matrix *pA, gsl_vector *pB, gsl_vector *pC)
Multiply matrix A by vector B and put the result in vector C.
Definition: BasicMathPlugin.cpp:892
INDI::AlignmentSubsystem::BasicMathPlugin::pActualToApparentTransform
gsl_matrix * pActualToApparentTransform
Definition: BasicMathPlugin.h:98
INDI::AlignmentSubsystem::ConvexHull::tFaceStructure::next
tFace next
Definition: ConvexHull.h:153
INDI
Namespace to encapsulate INDI client, drivers, and mediator classes.
Definition: AlignmentSubsystemForClients.cpp:11
INDI::AlignmentSubsystem::InMemoryDatabase::GetAlignmentDatabase
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
Definition: InMemoryDatabase.h:44
INDI::AlignmentSubsystem::AlignmentDatabaseEntry::Declination
double Declination
Declination in decimal degrees.
Definition: Common.h:187
INDI::AlignmentSubsystem::BasicMathPlugin::ActualDirectionCosines
std::vector< TelescopeDirectionVector > ActualDirectionCosines
Definition: BasicMathPlugin.h:105
INDI::AlignmentSubsystem::BasicMathPlugin::MatrixMatrixMultiply
void MatrixMatrixMultiply(gsl_matrix *pA, gsl_matrix *pB, gsl_matrix *pC)
Multiply matrix A by matrix B and put the result in C.
Definition: BasicMathPlugin.cpp:882
ASSDEBUGF
#define ASSDEBUGF(msg,...)
Definition: DriverCommon.h:18
INDI::AlignmentSubsystem::ConvexHull::PrintOut
void PrintOut(const char *FileName, tVertex v)
Prints vertices, edges and faces to the standard error output.
Definition: ConvexHull.cpp:898
INDI::IHorizontalCoordinates
Definition: libastro.h:56
INDI::AlignmentSubsystem::TelescopeDirectionVector::Normalise
void Normalise()
Normalise the vector.
Definition: Common.h:125
INDI::AlignmentSubsystem::AlignmentDatabaseEntry::RightAscension
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
Definition: Common.h:184
INDI::IEquatorialCoordinates
Definition: libastro.h:48
BasicMathPlugin.h
INDI::AlignmentSubsystem::AlignmentDatabaseEntry::ObservationJulianDate
double ObservationJulianDate
Definition: Common.h:180
INDI::AlignmentSubsystem::TelescopeDirectionVectorSupportFunctions::TelescopeDirectionVectorFromEquatorialCoordinates
const TelescopeDirectionVector TelescopeDirectionVectorFromEquatorialCoordinates(INDI::IEquatorialCoordinates EquatorialCoordinates)
Calculates a telescope direction vector from the supplied equatorial coordinates.
Definition: TelescopeDirectionVectorSupportFunctions.h:146
INDI::AlignmentSubsystem::TelescopeDirectionVector::x
double x
Definition: Common.h:76
INDI::AlignmentSubsystem::ConvexHull::tFaceStructure::vertex
tVertex vertex[3]
Definition: ConvexHull.h:151
INDI::AlignmentSubsystem::TelescopeDirectionVector
Holds a nomalised direction vector (direction cosines)
Definition: Common.h:68
libastro.h
INDI::AlignmentSubsystem::TelescopeDirectionVectorSupportFunctions::TelescopeDirectionVectorFromAltitudeAzimuth
const TelescopeDirectionVector TelescopeDirectionVectorFromAltitudeAzimuth(INDI::IHorizontalCoordinates HorizontalCoordinates)
Calculates a normalised direction vector from the supplied altitude and azimuth.
Definition: TelescopeDirectionVectorSupportFunctions.h:132