Instrument Neutral Distributed Interface INDI  2.0.2
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 
43 namespace INDI
44 {
45 
47 // converts the Observed (JNow) position to a J2000 catalogue position by removing
48 // aberration, nutation and precession using the libnova library
50 void ObservedToJ2000(IEquatorialCoordinates * observed, double jd, IEquatorialCoordinates * J2000pos)
51 {
52  ln_equ_posn tempPos;
53  // RA Hours --> Degrees
54  struct ln_equ_posn libnova_observed = {observed->rightascension * 15.0, observed->declination};
55  // remove the aberration
56  ln_get_equ_aber(&libnova_observed, jd, &tempPos);
57  // this conversion has added the aberration, we want to subtract it
58  tempPos.ra = libnova_observed.ra - (tempPos.ra - libnova_observed.ra);
59  tempPos.dec = libnova_observed.dec * 2 - tempPos.dec;
60 
61  // remove the nutation
62  ln_get_equ_nut(&tempPos, jd, true);
63 
64  struct ln_equ_posn libnova_J2000Pos;
65  // precess from now to J2000
66  ln_get_equ_prec2(&tempPos, jd, JD2000, &libnova_J2000Pos);
67 
68  J2000pos->rightascension = libnova_J2000Pos.ra / 15.0;
69  J2000pos->declination = libnova_J2000Pos.dec;
70 
71 
72 }
73 
80 void J2000toObserved(IEquatorialCoordinates *J2000pos, double jd, IEquatorialCoordinates *observed)
81 {
82  ln_equ_posn tempPosn;
83  struct ln_equ_posn libnova_J2000Pos = {J2000pos->rightascension * 15.0, J2000pos->declination };
84 
85  // apply precession from J2000 to jd
86  ln_get_equ_prec2(&libnova_J2000Pos, JD2000, jd, &tempPosn);
87 
88  // apply nutation
89  ln_get_equ_nut(&tempPosn, jd, false);
90 
91  struct ln_equ_posn libnova_observed;
92  // apply aberration
93  ln_get_equ_aber(&tempPosn, jd, &libnova_observed);
94 
95  observed->rightascension = libnova_observed.ra / 15.0;
96  observed->declination = libnova_observed.dec;
97 }
98 
102 void ln_get_equ_nut(ln_equ_posn *posn, double jd, bool reverse)
103 {
104  // code lifted from libnova ln_get_equ_nut
105  // with the option to add or remove nutation
106  struct ln_nutation nut;
107  ln_get_nutation (jd, &nut);
108 
109  double mean_ra, mean_dec, delta_ra, delta_dec;
110 
111  mean_ra = DEG_TO_RAD(posn->ra);
112  mean_dec = DEG_TO_RAD(posn->dec);
113 
114  // Equ 22.1
115 
116  double nut_ecliptic = DEG_TO_RAD(nut.ecliptic + nut.obliquity);
117  double sin_ecliptic = sin(nut_ecliptic);
118 
119  double sin_ra = sin(mean_ra);
120  double cos_ra = cos(mean_ra);
121 
122  double tan_dec = tan(mean_dec);
123 
124  delta_ra = (cos (nut_ecliptic) + sin_ecliptic * sin_ra * tan_dec) * nut.longitude - cos_ra * tan_dec * nut.obliquity;
125  delta_dec = (sin_ecliptic * cos_ra) * nut.longitude + sin_ra * nut.obliquity;
126 
127  // the sign changed to remove nutation
128  if (reverse)
129  {
130  delta_ra = -delta_ra;
131  delta_dec = -delta_dec;
132  }
133  posn->ra += delta_ra;
134  posn->dec += delta_dec;
135 }
136 
141  IHorizontalCoordinates *position)
142 {
143  // Convert from INDI standard location to libnova standard location
144  struct ln_lnlat_posn libnova_location = {observer->longitude > 180 ? observer->longitude - 360 : observer->longitude, observer->latitude};
145  // RA Hours --> Degrees
146  struct ln_equ_posn libnova_object = {object->rightascension * 15.0, object->declination};
147  struct ln_hrz_posn horizontalPos;
148  ln_get_hrz_from_equ(&libnova_object, &libnova_location, JD, &horizontalPos);
149  position->azimuth = range360(180 + horizontalPos.az);
150  position->altitude = horizontalPos.alt;
151 }
152 
157  IEquatorialCoordinates *position)
158 {
159  // Convert from INDI standard location to libnova standard location
160  struct ln_lnlat_posn libnova_location = {observer->longitude > 180 ? observer->longitude - 360 : observer->longitude, observer->latitude};
161  // Convert from INDI standard location to libnova standard location
162  struct ln_hrz_posn libnova_object = {range360(object->azimuth + 180), object->altitude};
163  struct ln_equ_posn equatorialPos;
164  ln_get_equ_from_hrz(&libnova_object, &libnova_location, JD, &equatorialPos);
165  // Degrees --> Hours
166  position->rightascension = equatorialPos.ra / 15.0;
167  position->declination = equatorialPos.dec;
168 
169 }
170 
171 
172 }
double range360(double r)
range360 Limits an angle to be between 0-360 degrees.
Definition: indicom.c:1245
Implementations for common driver routines.
#define DEG_TO_RAD(deg)
Definition: libastro.h:37
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:102
void J2000toObserved(IEquatorialCoordinates *J2000pos, double jd, IEquatorialCoordinates *observed)
*J2000toObserved converts catalogue to observed
Definition: libastro.cpp:80
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
void ObservedToJ2000(IEquatorialCoordinates *observed, double jd, IEquatorialCoordinates *J2000pos)
ObservedToJ2000 converts an observed position to a J2000 catalogue position removes aberration,...
Definition: libastro.cpp:50