Instrument Neutral Distributed Interface INDI 2.2.5
libastro.cpp
Go to the documentation of this file.
1/*
2 libastro
3
4 functions used for coordinate conversions, based on libnova
5
6 Copyright (C) 2020 Chris Rowland
7 Copyright (C) 2021 Jasem Mutlaq
8
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library; if not, write to the Free Software Foundation,
21 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
23*/
24
25// file libastro.c
26//
27// holds extensions to the libnova library to provide useful functions for INDI
28//
29// Chris Rowland April 2020
30//
31
32
33#include "libastro.h"
34#include "indicom.h"
35
36#include <math.h>
37
38#include <libnova/precession.h>
39#include <libnova/aberration.h>
40#include <libnova/transform.h>
41#include <libnova/nutation.h>
42#include <libnova/sidereal_time.h>
43
44namespace INDI
45{
46
48// converts the Observed (JNow) position to a J2000 catalogue position by removing
49// aberration, nutation and precession using the libnova library
51void ObservedToJ2000(IEquatorialCoordinates * observed, double jd, IEquatorialCoordinates * J2000pos)
52{
53 ln_equ_posn tempPos;
54 // RA Hours --> Degrees
55 struct ln_equ_posn libnova_observed = {observed->rightascension * 15.0, observed->declination};
56 // remove the aberration
57 ln_get_equ_aber(&libnova_observed, jd, &tempPos);
58 // this conversion has added the aberration, we want to subtract it
59 tempPos.ra = libnova_observed.ra - (tempPos.ra - libnova_observed.ra);
60 tempPos.dec = libnova_observed.dec * 2 - tempPos.dec;
61
62 // remove the nutation
63 ln_get_equ_nut(&tempPos, jd, true);
64
65 struct ln_equ_posn libnova_J2000Pos;
66 // precess from now to J2000
67 ln_get_equ_prec2(&tempPos, jd, JD2000, &libnova_J2000Pos);
68
69 J2000pos->rightascension = libnova_J2000Pos.ra / 15.0;
70 J2000pos->declination = libnova_J2000Pos.dec;
71
72
73}
74
82{
83 ln_equ_posn tempPosn;
84 struct ln_equ_posn libnova_J2000Pos = {J2000pos->rightascension * 15.0, J2000pos->declination };
85
86 // apply precession from J2000 to jd
87 ln_get_equ_prec2(&libnova_J2000Pos, JD2000, jd, &tempPosn);
88
89 // apply nutation
90 ln_get_equ_nut(&tempPosn, jd, false);
91
92 struct ln_equ_posn libnova_observed;
93 // apply aberration
94 ln_get_equ_aber(&tempPosn, jd, &libnova_observed);
95
96 observed->rightascension = libnova_observed.ra / 15.0;
97 observed->declination = libnova_observed.dec;
98}
99
103void ln_get_equ_nut(ln_equ_posn *posn, double jd, bool reverse)
104{
105 // code lifted from libnova ln_get_equ_nut
106 // with the option to add or remove nutation
107 struct ln_nutation nut;
108 ln_get_nutation (jd, &nut);
109
110 double mean_ra, mean_dec, delta_ra, delta_dec;
111
112 mean_ra = DEG_TO_RAD(posn->ra);
113 mean_dec = DEG_TO_RAD(posn->dec);
114
115 // Equ 22.1
116
117 double nut_ecliptic = DEG_TO_RAD(nut.ecliptic + nut.obliquity);
118 double sin_ecliptic = sin(nut_ecliptic);
119
120 double sin_ra = sin(mean_ra);
121 double cos_ra = cos(mean_ra);
122
123 double tan_dec = tan(mean_dec);
124
125 delta_ra = (cos (nut_ecliptic) + sin_ecliptic * sin_ra * tan_dec) * nut.longitude - cos_ra * tan_dec * nut.obliquity;
126 delta_dec = (sin_ecliptic * cos_ra) * nut.longitude + sin_ra * nut.obliquity;
127
128 // the sign changed to remove nutation
129 if (reverse)
130 {
131 delta_ra = -delta_ra;
132 delta_dec = -delta_dec;
133 }
134 posn->ra += delta_ra;
135 posn->dec += delta_dec;
136}
137
142 IHorizontalCoordinates *position)
143{
144 // Convert from INDI standard location to libnova standard location
145 struct ln_lnlat_posn libnova_location = {observer->longitude > 180 ? observer->longitude - 360 : observer->longitude, observer->latitude};
146 // RA Hours --> Degrees
147 struct ln_equ_posn libnova_object = {object->rightascension * 15.0, object->declination};
148 struct ln_hrz_posn horizontalPos;
149 // Use apparent sidereal time to match ln_get_equ_from_hrz (which already uses apparent).
150 // ln_get_hrz_from_equ uses mean sidereal time — a libnova bug that introduces a ~17" RA
151 // offset (equation of the equinoxes) in the round-trip.
152 double apparentSidereal = ln_get_apparent_sidereal_time(JD);
153 ln_get_hrz_from_equ_sidereal_time(&libnova_object, &libnova_location, apparentSidereal, &horizontalPos);
154 position->azimuth = range360(180 + horizontalPos.az);
155 position->altitude = horizontalPos.alt;
156}
157
162 IEquatorialCoordinates *position)
163{
164 // Convert from INDI standard location to libnova standard location
165 struct ln_lnlat_posn libnova_location = {observer->longitude > 180 ? observer->longitude - 360 : observer->longitude, observer->latitude};
166 // Convert from INDI standard location to libnova standard location
167 struct ln_hrz_posn libnova_object = {range360(object->azimuth + 180), object->altitude};
168 struct ln_equ_posn equatorialPos;
169 // ln_get_equ_from_hrz uses apparent sidereal time, matching EquatorialToHorizontal above.
170 ln_get_equ_from_hrz(&libnova_object, &libnova_location, JD, &equatorialPos);
171 // Degrees --> Hours
172 position->rightascension = equatorialPos.ra / 15.0;
173 position->declination = equatorialPos.dec;
174
175}
176
177
178}
double range360(double r)
range360 Limits an angle to be between 0-360 degrees.
Definition indicom.c:1321
Implementations for common driver routines.
#define DEG_TO_RAD(d)
Definition indimacros.h:128
Namespace to encapsulate INDI client, drivers, and mediator classes.
void ln_get_equ_nut(ln_equ_posn *posn, double jd, bool reverse)
apply or remove nutation
Definition libastro.cpp:103
void J2000toObserved(IEquatorialCoordinates *J2000pos, double jd, IEquatorialCoordinates *observed)
*J2000toObserved converts catalogue to observed
Definition libastro.cpp:81
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
void ObservedToJ2000(IEquatorialCoordinates *observed, double jd, IEquatorialCoordinates *J2000pos)
ObservedToJ2000 converts an observed position to a J2000 catalogue position removes aberration,...
Definition libastro.cpp:51