Instrument Neutral Distributed Interface INDI 2.2.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
25namespace INDI
26{
27namespace AlignmentSubsystem
28{
29#ifndef NO_PLUGIN_HOOKS
30// Standard functions required for all plugins
31extern "C" {
32
36 NearestMathPlugin *Create()
37 {
38 return new NearestMathPlugin;
39 }
40
45 {
46 delete pPlugin;
47 }
48
52 const char *GetDisplayName()
53 {
54 return "Nearest Math Plugin";
55 }
56}
57#endif
58
66
74
79{
80 // Call the base class to initialise to in in memory database pointer
82 const auto &SyncPoints = pInMemoryDatabase->GetAlignmentDatabase();
83 // Clear all extended alignment points so we can re-create them.
84 ExtendedAlignmentPoints.clear();
85
88 return false;
89
90 // JM: We iterate over all the sync point and compute the celestial and telescope horizontal coordinates
91 // Since these are used to sort the nearest alignment points to the current target. The offsets of the
92 // nearest point celestial coordinates are then applied to the current target to correct for its position.
93 // No complex transformations used.
94 for (auto &oneSyncPoint : SyncPoints)
95 {
97 oneEntry.RightAscension = oneSyncPoint.RightAscension;
98 oneEntry.Declination = oneSyncPoint.Declination;
99 oneEntry.ObservationJulianDate = oneSyncPoint.ObservationJulianDate;
100 oneEntry.TelescopeDirection = oneSyncPoint.TelescopeDirection;
101
102 INDI::IEquatorialCoordinates CelestialRADE {oneEntry.RightAscension, oneEntry.Declination};
103 INDI::IHorizontalCoordinates CelestialAltAz;
104 EquatorialToHorizontal(&CelestialRADE, &Position, oneEntry.ObservationJulianDate, &CelestialAltAz);
105
106 oneEntry.CelestialAzimuth = CelestialAltAz.azimuth;
107 oneEntry.CelestialAltitude = CelestialAltAz.altitude;
108
109 INDI::IHorizontalCoordinates TelescopeAltAz;
110 // Alt-Az Mounts?
112 {
114 }
115 // Equatorial?
116 else
117 {
118 INDI::IEquatorialCoordinates TelescopeRADE;
120 EquatorialToHorizontal(&TelescopeRADE, &Position, oneEntry.ObservationJulianDate, &TelescopeAltAz);
121 }
122
123 oneEntry.TelescopeAzimuth = TelescopeAltAz.azimuth;
124 oneEntry.TelescopeAltitude = TelescopeAltAz.altitude;
125
126 ExtendedAlignmentPoints.push_back(oneEntry);
127 }
128
129 return true;
130}
131
135bool NearestMathPlugin::TransformCelestialToTelescope(const double RightAscension, const double Declination,
136 double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
137{
138 return TransformCelestialToTelescopeJD(RightAscension, Declination,
139 ln_get_julian_from_sys() + JulianOffset,
140 ApparentTelescopeDirectionVector);
141}
142
143bool NearestMathPlugin::TransformCelestialToTelescopeJD(double RightAscension, double Declination,
144 double JulianDate, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
145{
146 // Get Position
147 IGeographicCoordinates Position;
149 return false;
150
151 // Compute CURRENT horizontal coords.
152 INDI::IEquatorialCoordinates CelestialRADE {RightAscension, Declination};
153 INDI::IHorizontalCoordinates CelestialAltAz;
154 EquatorialToHorizontal(&CelestialRADE, &Position, JulianDate, &CelestialAltAz);
155
156 // Return Telescope Direction Vector directly from Celestial coordinates if we
157 // do not have any sync points.
158 if (ExtendedAlignmentPoints.empty())
159 {
161 {
162 // Return Alt-Az Telescope Direction Vector For Alt-Az mounts.
163 ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(CelestialAltAz);
164 }
165 // Equatorial?
166 else
167 {
168 // Return RA-DE Telescope Direction Vector for Equatorial mounts.
169 ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(CelestialRADE);
170 }
171
172 return true;
173 }
174
175 // If we have sync points, then get the Nearest Point
176 ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(CelestialAltAz.azimuth, CelestialAltAz.altitude, true);
177
178 INDI::IEquatorialCoordinates TelescopeRADE;
179
180 // Get the nearest point in the telescope reference frame
181
182 // Alt-Az? Transform the nearest telescope direction vector to telescope Alt-Az and then to telescope RA/DE
184 {
185 INDI::IHorizontalCoordinates TelescopeAltAz;
187 HorizontalToEquatorial(&TelescopeAltAz, &Position, nearest.ObservationJulianDate, &TelescopeRADE);
188 }
189 // Equatorial? Transform nearest directly to telescope RA/DE
190 else
191 {
193 }
194
195 // Adjust the Celestial coordinates to account for the offset between the nearest point and the telescope
196 // e.g. Celestial RA = 5. Nearest Point (Sky: 4, Telescope: 3)
197 // Means Final Telescope RA = 5 - (4-3) = 4
198 // So we can issue GOTO to RA ~4, and it should up near Celestial RA ~5
199 INDI::IEquatorialCoordinates TransformedTelescopeRADE = CelestialRADE;
200 TransformedTelescopeRADE.rightascension -= (nearest.RightAscension - TelescopeRADE.rightascension);
201 TransformedTelescopeRADE.declination -= (nearest.Declination - TelescopeRADE.declination);
202
203 // Final step is to convert transformed telescope coordinates to a direction vector
205 {
206 INDI::IHorizontalCoordinates TransformedTelescopeAltAz;
207 EquatorialToHorizontal(&TransformedTelescopeRADE, &Position, JulianDate, &TransformedTelescopeAltAz);
208 ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromAltitudeAzimuth(TransformedTelescopeAltAz);
209 }
210 // Equatorial?
211 else
212 {
213 ApparentTelescopeDirectionVector = TelescopeDirectionVectorFromEquatorialCoordinates(TransformedTelescopeRADE);
214 }
215
216 return true;
217}
218
223 double &RightAscension, double &Declination, double JulianOffset)
224{
225 return TransformTelescopeToCelestialJD(ApparentTelescopeDirectionVector, RightAscension, Declination,
226 ln_get_julian_from_sys() + JulianOffset);
227}
228
230 double &RightAscension, double &Declination, double JulianDate)
231{
232 IGeographicCoordinates Position;
234 return false;
235
236 // Telescope Equatorial Coordinates
237 INDI::IEquatorialCoordinates TelescopeRADE;
238
239 // Do nothing if we don't have sync points.
240 if (ExtendedAlignmentPoints.empty())
241 {
242 // Alt/Az Mount?
244 {
245 INDI::IHorizontalCoordinates TelescopeAltAz;
246 AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
247 HorizontalToEquatorial(&TelescopeAltAz, &Position, JulianDate, &TelescopeRADE);
248 }
249 // Equatorial?
250 else
251 {
252 EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
253 }
254
255 RightAscension = TelescopeRADE.rightascension;
256 Declination = TelescopeRADE.declination;
257 return true;
258 }
259
260 // Need to get CURRENT Telescope horizontal coords
261 INDI::IHorizontalCoordinates TelescopeAltAz;
262 // Alt/Az Mount?
264 {
265 AltitudeAzimuthFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeAltAz);
266 HorizontalToEquatorial(&TelescopeAltAz, &Position, JulianDate, &TelescopeRADE);
267 }
268 // Equatorial?
269 else
270 {
271 EquatorialCoordinatesFromTelescopeDirectionVector(ApparentTelescopeDirectionVector, TelescopeRADE);
272 EquatorialToHorizontal(&TelescopeRADE, &Position, JulianDate, &TelescopeAltAz);
273 }
274
275 // Find the nearest point to our telescope now
276 ExtendedAlignmentDatabaseEntry nearest = GetNearestPoint(TelescopeAltAz.azimuth, TelescopeAltAz.altitude, false);
277
278 // Now get the nearest telescope in equatorial coordinates.
279 INDI::IEquatorialCoordinates NearestTelescopeRADE;
281 {
282 INDI::IHorizontalCoordinates NearestTelescopeAltAz {nearest.TelescopeAzimuth, nearest.TelescopeAltitude};
283 HorizontalToEquatorial(&NearestTelescopeAltAz, &Position, nearest.ObservationJulianDate, &NearestTelescopeRADE);
284 }
285 // Equatorial?
286 else
287 {
289 }
290
291 // Adjust the Telescope coordinates to account for the offset between the nearest point and the telescope
292 // e.g. Telescope RA = 5. Nearest Point (Target: 4, Telescope: 3)
293 // Means Final Telescope RA = 5 + (4-3) = 6
294 // So a telescope reporting ~5 hours should actually be pointing to ~6 hours in the sky.
295 INDI::IEquatorialCoordinates TransformedCelestialRADE = TelescopeRADE;
296 TransformedCelestialRADE.rightascension += (nearest.RightAscension - NearestTelescopeRADE.rightascension);
297 TransformedCelestialRADE.declination += (nearest.Declination - NearestTelescopeRADE.declination);
298
299 RightAscension = TransformedCelestialRADE.rightascension;
300 Declination = TransformedCelestialRADE.declination;
301 return true;
302}
303
307ExtendedAlignmentDatabaseEntry NearestMathPlugin::GetNearestPoint(const double Azimuth, const double Altitude,
308 bool isCelestial)
309{
311 double distance = 1e6;
312
313 for (auto &oneEntry : ExtendedAlignmentPoints)
314 {
315 double oneDistance = 0;
316
317 if (isCelestial)
318 oneDistance = SphereUnitDistance(Azimuth, oneEntry.CelestialAzimuth, Altitude, oneEntry.CelestialAltitude);
319 else
320 oneDistance = SphereUnitDistance(Azimuth, oneEntry.TelescopeAzimuth, Altitude, oneEntry.TelescopeAltitude);
321
322 if (oneDistance < distance)
323 {
324 nearest = oneEntry;
325 distance = oneDistance;
326 }
327 }
328
329 return nearest;
330}
331
335double NearestMathPlugin::SphereUnitDistance(double theta1, double theta2, double phi1, double phi2)
336{
337 double sqrt_haversin_lat = sin(((phi2 - phi1) / 2) * (M_PI / 180));
338 double sqrt_haversin_long = sin(((theta2 - theta1) / 2) * (M_PI / 180));
339 return (2 *
340 asin(sqrt((sqrt_haversin_lat * sqrt_haversin_lat) + cos(phi1 * (M_PI / 180)) * cos(phi2 * (M_PI / 180)) *
341 (sqrt_haversin_long * sqrt_haversin_long))));
342}
343} // namespace AlignmentSubsystem
344} // 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.
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
MountAlignment_t ApproximateMountAlignment
Describe the approximate alignment of the mount. This information is normally used in a one star alig...
Definition MathPlugin.h:128
virtual bool TransformTelescopeToCelestial(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination, double JulianOffset=0) override
Get the true celestial coordinates for the supplied telescope pointing direction.
virtual bool TransformCelestialToTelescopeJD(double RightAscension, double Declination, double JulianDate, TelescopeDirectionVector &ApparentTelescopeDirectionVector) override
Get the alignment corrected telescope pointing direction for the supplied celestial coordinates.
virtual bool TransformCelestialToTelescope(const double RightAscension, const double Declination, double JulianOffset, TelescopeDirectionVector &ApparentTelescopeDirectionVector) override
Get the alignment corrected telescope pointing direction for the supplied celestial coordinates.
virtual bool TransformTelescopeToCelestialJD(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination, double JulianDate) override
Get the true celestial coordinates for the supplied telescope pointing direction.
virtual bool Initialise(InMemoryDatabase *pInMemoryDatabase) override
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
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.
#define M_PI
Definition dsp.h:52
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:141
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
Definition libastro.cpp:161
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 normalised direction vector (direction cosines)
Definition Common.h:69