Instrument Neutral Distributed Interface INDI  1.9.5
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 
76 bool NearestMathPlugin::Initialise(InMemoryDatabase *pInMemoryDatabase)
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  {
170  AltitudeAzimuthFromTelescopeDirectionVector(nearest.TelescopeDirection, CelestialAltAz);
171  HorizontalToEquatorial(&CelestialAltAz, &Position, nearest.ObservationJulianDate + JulianOffset, &TelescopeRADE);
172  }
173  // Equatorial?
174  else
175  {
176  EquatorialCoordinatesFromTelescopeDirectionVector(nearest.TelescopeDirection, TelescopeRADE);
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 
205 bool NearestMathPlugin::TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector,
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  {
266  EquatorialCoordinatesFromTelescopeDirectionVector(nearest.TelescopeDirection, NearestTelescopeRADE);
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 {
288  ExtendedAlignmentDatabaseEntry nearest;
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
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::GetDisplayName
const char * GetDisplayName()
Definition: DummyMathPlugin.cpp:23
INDI::AlignmentSubsystem::InMemoryDatabase::GetDatabaseReferencePosition
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
Definition: InMemoryDatabase.cpp:43
INDI::AlignmentSubsystem::ExtendedAlignmentDatabaseEntry::CelestialAltitude
double CelestialAltitude
Celestial Altitude of the Sync point at the time it was added to the list.
Definition: NearestMathPlugin.h:120
INDI::IHorizontalCoordinates::azimuth
double azimuth
Definition: libastro.h:58
INDI::IEquatorialCoordinates::declination
double declination
Definition: libastro.h:51
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::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
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::NearestMathPlugin::NearestMathPlugin
NearestMathPlugin()
Definition: NearestMathPlugin.cpp:96
INDI::IEquatorialCoordinates::rightascension
double rightascension
Definition: libastro.h:50
INDI::AlignmentSubsystem::Destroy
void Destroy(DummyMathPlugin *pPlugin)
Definition: DummyMathPlugin.cpp:18
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::ExtendedAlignmentDatabaseEntry
Definition: NearestMathPlugin.h:72
INDI::IHorizontalCoordinates::altitude
double altitude
Definition: libastro.h:59
INDI::AlignmentSubsystem::ExtendedAlignmentDatabaseEntry::TelescopeAzimuth
double TelescopeAzimuth
Telescope Azimuth of Sync Point at the time it was added to the list.
Definition: NearestMathPlugin.h:124
INDI::AlignmentSubsystem::MathPlugin::pInMemoryDatabase
InMemoryDatabase * pInMemoryDatabase
Definition: MathPlugin.h:80
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::NearestMathPlugin::TransformTelescopeToCelestial
virtual bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination)
Get the true celestial coordinates for the supplied telescope pointing direction.
Definition: NearestMathPlugin.cpp:241
INDI::AlignmentSubsystem::ExtendedAlignmentDatabaseEntry::TelescopeAltitude
double TelescopeAltitude
Telescope Altitude of the Sync point at the time it was added to the list.
Definition: NearestMathPlugin.h:128
INDI::AlignmentSubsystem::ExtendedAlignmentDatabaseEntry::CelestialAzimuth
double CelestialAzimuth
Celestial Azimuth of Sync Point at the time it was added to the list.
Definition: NearestMathPlugin.h:116
INDI::AlignmentSubsystem::Create
DummyMathPlugin * Create()
Definition: DummyMathPlugin.cpp:13
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::NearestMathPlugin::~NearestMathPlugin
virtual ~NearestMathPlugin()
Definition: NearestMathPlugin.cpp:104
INDI::AlignmentSubsystem::NearestMathPlugin::TransformCelestialToTelescope
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.
Definition: NearestMathPlugin.cpp:169
INDI::AlignmentSubsystem::NearestMathPlugin::Initialise
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
Definition: NearestMathPlugin.cpp:112
INDI::IHorizontalCoordinates
Definition: libastro.h:56
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
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::TelescopeDirectionVectorSupportFunctions::TelescopeDirectionVectorFromAltitudeAzimuth
const TelescopeDirectionVector TelescopeDirectionVectorFromAltitudeAzimuth(INDI::IHorizontalCoordinates HorizontalCoordinates)
Calculates a normalised direction vector from the supplied altitude and azimuth.
Definition: TelescopeDirectionVectorSupportFunctions.h:132
NearestMathPlugin.h