Instrument Neutral Distributed Interface INDI  2.0.0
NearestMathPlugin.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2021 Jasem Mutlaq. All rights reserved.
3 
4  AstroTrac Mount Driver.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
9  .
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14  .
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 *******************************************************************************/
20 
21 #include "NearestMathPlugin.h"
22 
23 #include <libnova/julian_day.h>
24 
25 namespace INDI
26 {
27 namespace AlignmentSubsystem
28 {
29 // Standard functions required for all plugins
30 extern "C" {
31 
35  NearestMathPlugin *Create()
36  {
37  return new NearestMathPlugin;
38  }
39 
43  void Destroy(NearestMathPlugin *pPlugin)
44  {
45  delete pPlugin;
46  }
47 
51  const char *GetDisplayName()
52  {
53  return "Nearest Math Plugin";
54  }
55 }
56 
61 {
62 
63 }
64 
69 {
70 
71 }
72 
77 {
78  // Call the base class to initialise to in in memory database pointer
81  // Clear all extended alignment points so we can re-create them.
82  ExtendedAlignmentPoints.clear();
83 
84  IGeographicCoordinates Position;
86  return false;
87 
88  // JM: We iterate over all the sync point and compute the celestial and telescope horizontal coordinates
89  // Since these are used to sort the nearest alignment points to the current target. The offsets of the
90  // nearest point celestial coordintes are then applied to the current target to correct for its position.
91  // No complex transformations used.
92  for (auto &oneSyncPoint : SyncPoints)
93  {
95  oneEntry.RightAscension = oneSyncPoint.RightAscension;
96  oneEntry.Declination = oneSyncPoint.Declination;
97  oneEntry.ObservationJulianDate = oneSyncPoint.ObservationJulianDate;
98  oneEntry.TelescopeDirection = oneSyncPoint.TelescopeDirection;
99 
100  INDI::IEquatorialCoordinates CelestialRADE {oneEntry.RightAscension, oneEntry.Declination};
101  INDI::IHorizontalCoordinates CelestialAltAz;
102  EquatorialToHorizontal(&CelestialRADE, &Position, oneEntry.ObservationJulianDate, &CelestialAltAz);
103 
104  oneEntry.CelestialAzimuth = CelestialAltAz.azimuth;
105  oneEntry.CelestialAltitude = CelestialAltAz.altitude;
106 
107  INDI::IHorizontalCoordinates TelescopeAltAz;
108  // Alt-Az Mounts?
110  {
112  }
113  // Equatorial?
114  else
115  {
116  INDI::IEquatorialCoordinates TelescopeRADE;
118  EquatorialToHorizontal(&TelescopeRADE, &Position, oneEntry.ObservationJulianDate, &TelescopeAltAz);
119  }
120 
121  oneEntry.TelescopeAzimuth = TelescopeAltAz.azimuth;
122  oneEntry.TelescopeAltitude = TelescopeAltAz.altitude;
123 
124  ExtendedAlignmentPoints.push_back(oneEntry);
125  }
126 
127  return true;
128 }
129 
133 bool NearestMathPlugin::TransformCelestialToTelescope(const double RightAscension, const double Declination,
134  double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
135 {
136  IGeographicCoordinates Position;
138  return false;
139 
140  double JDD = ln_get_julian_from_sys() + JulianOffset;
141 
142  // Compute CURRENT horizontal coords.
143  INDI::IEquatorialCoordinates CelestialRADE {RightAscension, Declination};
144  INDI::IHorizontalCoordinates CelestialAltAz;
145  EquatorialToHorizontal(&CelestialRADE, &Position, JDD, &CelestialAltAz);
146 
147  // Do nothing if we don't have sync points.
148  if (ExtendedAlignmentPoints.empty())
149  {
151  {
152  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(CelestialAltAz);
153  }
154  // Equatorial?
155  else
156  {
157  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(CelestialRADE);
158  }
159 
160  return true;
161  }
162 
163  // Get Nearest Point
164  ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(CelestialAltAz.azimuth, CelestialAltAz.altitude, true);
165 
166  INDI::IEquatorialCoordinates TelescopeRADE;
168  {
169  INDI::IHorizontalCoordinates CelestialAltAz;
171  HorizontalToEquatorial(&CelestialAltAz, &Position, nearest.ObservationJulianDate + JulianOffset, &TelescopeRADE);
172  }
173  // Equatorial?
174  else
175  {
177  }
178 
179  // Adjust the Celestial coordinates to account for the offset between the nearest point and the telescope
180  // e.g. Celestial RA = 5. Nearest Point (Target: 4, Telescope: 3)
181  // Means Final Telescope RA = 5 - (4-3) = 4
182  // So we can issue GOTO to ~4, and it should up near Celestial RA ~5
183  INDI::IEquatorialCoordinates TransformedTelescopeRADE = CelestialRADE;
184  TransformedTelescopeRADE.rightascension -= (nearest.RightAscension - TelescopeRADE.rightascension);
185  TransformedTelescopeRADE.declination -= (nearest.Declination - TelescopeRADE.declination);
186 
188  {
189  INDI::IHorizontalCoordinates TransformedTelescopeAltAz;
190  EquatorialToHorizontal(&TransformedTelescopeRADE, &Position, JDD, &TransformedTelescopeAltAz);
191  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(TransformedTelescopeAltAz);
192  }
193  // Equatorial?
194  else
195  {
196  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(TransformedTelescopeRADE);
197  }
198 
199  return true;
200 }
201 
206  double &RightAscension, double &Declination)
207 {
208  IGeographicCoordinates Position;
210  return false;
211 
212  double JDD = ln_get_julian_from_sys();
213 
214  // Telescope Equatorial Coordinates
215  INDI::IEquatorialCoordinates TelescopeRADE;
216 
217  // Do nothing if we don't have sync points.
218  if (ExtendedAlignmentPoints.empty())
219  {
220  // Alt/Az Mount?
222  {
223  INDI::IHorizontalCoordinates TelescopeAltAz;
224  AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
225  HorizontalToEquatorial(&TelescopeAltAz, &Position, JDD, &TelescopeRADE);
226  }
227  // Equatorial?
228  else
229  {
230  EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
231  }
232 
233  RightAscension = TelescopeRADE.rightascension;
234  Declination = TelescopeRADE.declination;
235  return true;
236  }
237 
238  // Need to get CURRENT Telescope horizontal coords
239  INDI::IHorizontalCoordinates TelescopeAltAz;
240  // Alt/Az Mount?
242  {
243  AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
244  HorizontalToEquatorial(&TelescopeAltAz, &Position, JDD, &TelescopeRADE);
245  }
246  // Equatorial?
247  else
248  {
249  EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
250  EquatorialToHorizontal(&TelescopeRADE, &Position, JDD, &TelescopeAltAz);
251  }
252 
253  // Find the nearest point to our telescope now
254  ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(TelescopeAltAz.azimuth, TelescopeAltAz.altitude, false);
255 
256  // Now get the nearest telescope in equatorial coordinates.
257  INDI::IEquatorialCoordinates NearestTelescopeRADE;
259  {
260  INDI::IHorizontalCoordinates NearestTelescopeAltAz {nearest.TelescopeAzimuth, nearest.TelescopeAltitude};
261  HorizontalToEquatorial(&NearestTelescopeAltAz, &Position, nearest.ObservationJulianDate, &NearestTelescopeRADE);
262  }
263  // Equatorial?
264  else
265  {
267  }
268 
269  // Adjust the Telescope coordinates to account for the offset between the nearest point and the telescope
270  // e.g. Telescope RA = 5. Nearest Point (Target: 4, Telescope: 3)
271  // Means Final Telescope RA = 5 + (4-3) = 6
272  // So a telescope reporting ~5 hours should actually be pointing to ~6 hours in the sky.
273  INDI::IEquatorialCoordinates TransformedCelestialRADE = TelescopeRADE;
274  TransformedCelestialRADE.rightascension += (nearest.RightAscension - NearestTelescopeRADE.rightascension);
275  TransformedCelestialRADE.declination += (nearest.Declination - NearestTelescopeRADE.declination);
276 
277  RightAscension = TransformedCelestialRADE.rightascension;
278  Declination = TransformedCelestialRADE.declination;
279  return true;
280 }
281 
285 ExtendedAlignmentDatabaseEntry NearestMathPlugin::GetNearestPoint(const double Azimuth, const double Altitude,
286  bool isCelestial)
287 {
289  double distance = 1e6;
290 
291  for (auto &oneEntry : ExtendedAlignmentPoints)
292  {
293  double oneDistance = 0;
294 
295  if (isCelestial)
296  oneDistance = SphereUnitDistance(Azimuth, oneEntry.CelestialAzimuth, Altitude, oneEntry.CelestialAltitude);
297  else
298  oneDistance = SphereUnitDistance(Azimuth, oneEntry.TelescopeAzimuth, Altitude, oneEntry.TelescopeAltitude);
299 
300  if (oneDistance < distance)
301  {
302  nearest = oneEntry;
303  distance = oneDistance;
304  }
305  }
306 
307  return nearest;
308 }
309 
313 double NearestMathPlugin::SphereUnitDistance(double theta1, double theta2, double phi1, double phi2)
314 {
315  double sqrt_haversin_lat = sin(((phi2 - phi1) / 2) * (M_PI / 180));
316  double sqrt_haversin_long = sin(((theta2 - theta1) / 2) * (M_PI / 180));
317  return (2 *
318  asin(sqrt((sqrt_haversin_lat * sqrt_haversin_lat) + cos(phi1 * (M_PI / 180)) * cos(phi2 * (M_PI / 180)) *
319  (sqrt_haversin_long * sqrt_haversin_long))));
320 }
321 } // namespace AlignmentSubsystem
322 } // namespace INDI
This class provides the driver side API to the in memory alignment database.
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
std::vector< AlignmentDatabaseEntry > AlignmentDatabaseType
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
InMemoryDatabase * pInMemoryDatabase
Definition: MathPlugin.h:83
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
Definition: MathPlugin.cpp:15
MountAlignment_t ApproximateMountAlignment
Describe the approximate alignment of the mount. This information is normally used in a one star alig...
Definition: MathPlugin.h:82
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
virtual bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination)
Get the true celestial coordinates for the supplied telescope pointing direction.
virtual bool TransformCelestialToTelescope(const double RightAscension, const double Declination, double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
Get the alignment corrected telescope pointing direction for the supplied celestial coordinates.
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.
void Destroy(DummyMathPlugin *pPlugin)
DummyMathPlugin * Create()
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.
Definition: libastro.cpp:140
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
Definition: libastro.cpp:156
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
Definition: Common.h:190
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
Definition: Common.h:197
double Declination
Declination in decimal degrees.
Definition: Common.h:193
double CelestialAzimuth
Celestial Azimuth of Sync Point at the time it was added to the list.
double TelescopeAzimuth
Telescope Azimuth of Sync Point at the time it was added to the list.
double TelescopeAltitude
Telescope Altitude of the Sync point at the time it was added to the list.
double CelestialAltitude
Celestial Altitude of the Sync point at the time it was added to the list.
Holds a nomalised direction vector (direction cosines)
Definition: Common.h:69