Instrument Neutral Distributed Interface INDI  2.0.2
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
80  const auto &SyncPoints = pInMemoryDatabase->GetAlignmentDatabase();
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  // Get Position
137  IGeographicCoordinates Position;
139  return false;
140 
141  // Get Julian date from system and apply Julian Offset if any.
142  double JDD = ln_get_julian_from_sys() + JulianOffset;
143 
144  // Compute CURRENT horizontal coords.
145  INDI::IEquatorialCoordinates CelestialRADE {RightAscension, Declination};
146  INDI::IHorizontalCoordinates CelestialAltAz;
147  EquatorialToHorizontal(&CelestialRADE, &Position, JDD, &CelestialAltAz);
148 
149  // Return Telescope Direction Vector directly from Celestial coordinates if we
150  // do not have any sync points.
151  if (ExtendedAlignmentPoints.empty())
152  {
154  {
155  // Return Alt-Az Telescope Direction Vector For Alt-Az mounts.
156  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(CelestialAltAz);
157  }
158  // Equatorial?
159  else
160  {
161  // Return RA-DE Telescope Direction Vector for Equatorial mounts.
162  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(CelestialRADE);
163  }
164 
165  return true;
166  }
167 
168  // If we have sync points, then get the Nearest Point
169  ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(CelestialAltAz.azimuth, CelestialAltAz.altitude, true);
170 
171  INDI::IEquatorialCoordinates TelescopeRADE;
172 
173  // Get the nearest point in the telescope reference frame
174 
175  // Alt-Az? Transform the nearest telescope direction vector to telescope Alt-Az and then to telescope RA/DE
177  {
178  INDI::IHorizontalCoordinates TelescopeAltAz;
180  HorizontalToEquatorial(&TelescopeAltAz, &Position, nearest.ObservationJulianDate, &TelescopeRADE);
181  }
182  // Equatorial? Transform nearest directly to telescope RA/DE
183  else
184  {
186  }
187 
188  // Adjust the Celestial coordinates to account for the offset between the nearest point and the telescope
189  // e.g. Celestial RA = 5. Nearest Point (Sky: 4, Telescope: 3)
190  // Means Final Telescope RA = 5 - (4-3) = 4
191  // So we can issue GOTO to RA ~4, and it should up near Celestial RA ~5
192  INDI::IEquatorialCoordinates TransformedTelescopeRADE = CelestialRADE;
193  TransformedTelescopeRADE.rightascension -= (nearest.RightAscension - TelescopeRADE.rightascension);
194  TransformedTelescopeRADE.declination -= (nearest.Declination - TelescopeRADE.declination);
195 
196  // Final step is to convert transformed telescope coordinates to a direction vector
198  {
199  INDI::IHorizontalCoordinates TransformedTelescopeAltAz;
200  EquatorialToHorizontal(&TransformedTelescopeRADE, &Position, JDD, &TransformedTelescopeAltAz);
201  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(TransformedTelescopeAltAz);
202  }
203  // Equatorial?
204  else
205  {
206  ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(TransformedTelescopeRADE);
207  }
208 
209  return true;
210 }
211 
216  double &RightAscension, double &Declination)
217 {
218  IGeographicCoordinates Position;
220  return false;
221 
222  double JDD = ln_get_julian_from_sys();
223 
224  // Telescope Equatorial Coordinates
225  INDI::IEquatorialCoordinates TelescopeRADE;
226 
227  // Do nothing if we don't have sync points.
228  if (ExtendedAlignmentPoints.empty())
229  {
230  // Alt/Az Mount?
232  {
233  INDI::IHorizontalCoordinates TelescopeAltAz;
234  AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
235  HorizontalToEquatorial(&TelescopeAltAz, &Position, JDD, &TelescopeRADE);
236  }
237  // Equatorial?
238  else
239  {
240  EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
241  }
242 
243  RightAscension = TelescopeRADE.rightascension;
244  Declination = TelescopeRADE.declination;
245  return true;
246  }
247 
248  // Need to get CURRENT Telescope horizontal coords
249  INDI::IHorizontalCoordinates TelescopeAltAz;
250  // Alt/Az Mount?
252  {
253  AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
254  HorizontalToEquatorial(&TelescopeAltAz, &Position, JDD, &TelescopeRADE);
255  }
256  // Equatorial?
257  else
258  {
259  EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
260  EquatorialToHorizontal(&TelescopeRADE, &Position, JDD, &TelescopeAltAz);
261  }
262 
263  // Find the nearest point to our telescope now
264  ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(TelescopeAltAz.azimuth, TelescopeAltAz.altitude, false);
265 
266  // Now get the nearest telescope in equatorial coordinates.
267  INDI::IEquatorialCoordinates NearestTelescopeRADE;
269  {
270  INDI::IHorizontalCoordinates NearestTelescopeAltAz {nearest.TelescopeAzimuth, nearest.TelescopeAltitude};
271  HorizontalToEquatorial(&NearestTelescopeAltAz, &Position, nearest.ObservationJulianDate, &NearestTelescopeRADE);
272  }
273  // Equatorial?
274  else
275  {
277  }
278 
279  // Adjust the Telescope coordinates to account for the offset between the nearest point and the telescope
280  // e.g. Telescope RA = 5. Nearest Point (Target: 4, Telescope: 3)
281  // Means Final Telescope RA = 5 + (4-3) = 6
282  // So a telescope reporting ~5 hours should actually be pointing to ~6 hours in the sky.
283  INDI::IEquatorialCoordinates TransformedCelestialRADE = TelescopeRADE;
284  TransformedCelestialRADE.rightascension += (nearest.RightAscension - NearestTelescopeRADE.rightascension);
285  TransformedCelestialRADE.declination += (nearest.Declination - NearestTelescopeRADE.declination);
286 
287  RightAscension = TransformedCelestialRADE.rightascension;
288  Declination = TransformedCelestialRADE.declination;
289  return true;
290 }
291 
295 ExtendedAlignmentDatabaseEntry NearestMathPlugin::GetNearestPoint(const double Azimuth, const double Altitude,
296  bool isCelestial)
297 {
299  double distance = 1e6;
300 
301  for (auto &oneEntry : ExtendedAlignmentPoints)
302  {
303  double oneDistance = 0;
304 
305  if (isCelestial)
306  oneDistance = SphereUnitDistance(Azimuth, oneEntry.CelestialAzimuth, Altitude, oneEntry.CelestialAltitude);
307  else
308  oneDistance = SphereUnitDistance(Azimuth, oneEntry.TelescopeAzimuth, Altitude, oneEntry.TelescopeAltitude);
309 
310  if (oneDistance < distance)
311  {
312  nearest = oneEntry;
313  distance = oneDistance;
314  }
315  }
316 
317  return nearest;
318 }
319 
323 double NearestMathPlugin::SphereUnitDistance(double theta1, double theta2, double phi1, double phi2)
324 {
325  double sqrt_haversin_lat = sin(((phi2 - phi1) / 2) * (M_PI / 180));
326  double sqrt_haversin_long = sin(((theta2 - theta1) / 2) * (M_PI / 180));
327  return (2 *
328  asin(sqrt((sqrt_haversin_lat * sqrt_haversin_lat) + cos(phi1 * (M_PI / 180)) * cos(phi2 * (M_PI / 180)) *
329  (sqrt_haversin_long * sqrt_haversin_long))));
330 }
331 } // namespace AlignmentSubsystem
332 } // 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.
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