MRTKLIB 0.7.14
Modernized GNSS Positioning Library
Loading...
Searching...
No Matches
mrtk_astro.c
Go to the documentation of this file.
1/*------------------------------------------------------------------------------
2 * mrtk_astro.c : astronomical functions for sun/moon position
3 *
4 * Copyright (C) 2026 H.SHIONO (MRTKLIB Project)
5 * Copyright (C) 2023-2025 Cabinet Office, Japan
6 * Copyright (C) 2024-2025 Lighthouse Technology & Consulting Co. Ltd.
7 * Copyright (C) 2023-2025 Japan Aerospace Exploration Agency
8 * Copyright (C) 2023-2025 TOSHIBA ELECTRONIC TECHNOLOGIES CORPORATION
9 * Copyright (C) 2015- Mitsubishi Electric Corp.
10 * Copyright (C) 2014 Geospatial Information Authority of Japan
11 * Copyright (C) 2014 T.SUZUKI
12 * Copyright (C) 2007-2023 T.TAKASU
13 *
14 * SPDX-License-Identifier: BSD-2-Clause
15 *----------------------------------------------------------------------------*/
16/**
17 * @file mrtk_astro.c
18 * @brief MRTKLIB Astronomy Module — Implementation.
19 *
20 * All functions and static data in this file are cut-and-paste extractions
21 * from the legacy rtkcmn.c with zero algorithmic changes.
22 */
23
24#include "mrtklib/mrtk_astro.h"
25
26#include <math.h>
27
28#include "mrtklib/mrtk_coords.h"
29#include "mrtklib/mrtk_mat.h"
30#include "mrtklib/mrtk_trace.h"
31
32/*============================================================================
33 * Forward Declarations (resolved at link time)
34 *===========================================================================*/
35
36/*============================================================================
37 * Private Constants
38 *===========================================================================*/
39
40#define PI 3.1415926535897932 /* pi */
41#define D2R (PI / 180.0) /* deg to rad */
42#define AS2R (D2R / 3600.0) /* arc sec to radian */
43#define AU 149597870691.0 /* 1 AU (m) */
44#define RE_WGS84 6378137.0 /* earth semimajor axis (WGS84) (m) */
45
46/*============================================================================
47 * Private Functions
48 *===========================================================================*/
49
50/* astronomical arguments: f={l,l',F,D,OMG} (rad) ----------------------------*/
51static void ast_args(double t, double* f) {
52 static const double fc[][5] = {/* coefficients for iau 1980 nutation */
53 {134.96340251, 1717915923.2178, 31.8792, 0.051635, -0.00024470},
54 {357.52910918, 129596581.0481, -0.5532, 0.000136, -0.00001149},
55 {93.27209062, 1739527262.8478, -12.7512, -0.001037, 0.00000417},
56 {297.85019547, 1602961601.2090, -6.3706, 0.006593, -0.00003169},
57 {125.04455501, -6962890.2665, 7.4722, 0.007702, -0.00005939}};
58 double tt[4];
59 int i, j;
60
61 for (tt[0] = t, i = 1; i < 4; i++) {
62 tt[i] = tt[i - 1] * t;
63 }
64 for (i = 0; i < 5; i++) {
65 f[i] = fc[i][0] * 3600.0;
66 for (j = 0; j < 4; j++) {
67 f[i] += fc[i][j + 1] * tt[j];
68 }
69 f[i] = fmod(f[i] * AS2R, 2.0 * PI);
70 }
71}
72
73/*============================================================================
74 * Public Functions
75 *===========================================================================*/
76
77/* sun and moon position in eci (ref [4] 5.1.1, 5.2.1) -----------------------*/
78extern void sunmoonpos_eci(gtime_t tut, double* rsun, double* rmoon) {
79 const double ep2000[] = {2000, 1, 1, 12, 0, 0};
80 double t, f[5], eps, Ms, ls, rs, lm, pm, rm, sine, cose, sinp, cosp, sinl, cosl;
81
82 trace(NULL, 4, "sunmoonpos_eci: tut=%s\n", time_str(tut, 3));
83
84 t = timediff(tut, epoch2time(ep2000)) / 86400.0 / 36525.0;
85
86 /* astronomical arguments */
87 ast_args(t, f);
88
89 /* obliquity of the ecliptic */
90 eps = 23.439291 - 0.0130042 * t;
91 sine = sin(eps * D2R);
92 cose = cos(eps * D2R);
93
94 /* sun position in eci */
95 if (rsun) {
96 Ms = 357.5277233 + 35999.05034 * t;
97 ls = 280.460 + 36000.770 * t + 1.914666471 * sin(Ms * D2R) + 0.019994643 * sin(2.0 * Ms * D2R);
98 rs = AU * (1.000140612 - 0.016708617 * cos(Ms * D2R) - 0.000139589 * cos(2.0 * Ms * D2R));
99 sinl = sin(ls * D2R);
100 cosl = cos(ls * D2R);
101 rsun[0] = rs * cosl;
102 rsun[1] = rs * cose * sinl;
103 rsun[2] = rs * sine * sinl;
104
105 trace(NULL, 5, "rsun =%.3f %.3f %.3f\n", rsun[0], rsun[1], rsun[2]);
106 }
107 /* moon position in eci */
108 if (rmoon) {
109 lm = 218.32 + 481267.883 * t + 6.29 * sin(f[0]) - 1.27 * sin(f[0] - 2.0 * f[3]) + 0.66 * sin(2.0 * f[3]) +
110 0.21 * sin(2.0 * f[0]) - 0.19 * sin(f[1]) - 0.11 * sin(2.0 * f[2]);
111 pm = 5.13 * sin(f[2]) + 0.28 * sin(f[0] + f[2]) - 0.28 * sin(f[2] - f[0]) - 0.17 * sin(f[2] - 2.0 * f[3]);
112 rm = RE_WGS84 / sin((0.9508 + 0.0518 * cos(f[0]) + 0.0095 * cos(f[0] - 2.0 * f[3]) + 0.0078 * cos(2.0 * f[3]) +
113 0.0028 * cos(2.0 * f[0])) *
114 D2R);
115 sinl = sin(lm * D2R);
116 cosl = cos(lm * D2R);
117 sinp = sin(pm * D2R);
118 cosp = cos(pm * D2R);
119 rmoon[0] = rm * cosp * cosl;
120 rmoon[1] = rm * (cose * cosp * sinl - sine * sinp);
121 rmoon[2] = rm * (sine * cosp * sinl + cose * sinp);
122
123 trace(NULL, 5, "rmoon=%.3f %.3f %.3f\n", rmoon[0], rmoon[1], rmoon[2]);
124 }
125}
126/* sun and moon position -------------------------------------------------------
127 * get sun and moon position in ecef
128 * args : gtime_t tut I time in ut1
129 * double *erpv I erp value {xp,yp,ut1_utc,lod} (rad,rad,s,s/d)
130 * double *rsun IO sun position in ecef (m) (NULL: not output)
131 * double *rmoon IO moon position in ecef (m) (NULL: not output)
132 * double *gmst O gmst (rad)
133 * return : none
134 *-----------------------------------------------------------------------------*/
135extern void sunmoonpos(gtime_t tutc, const double* erpv, double* rsun, double* rmoon, double* gmst) {
136 gtime_t tut;
137 double rs[3], rm[3], U[9], gmst_;
138
139 trace(NULL, 4, "sunmoonpos: tutc=%s\n", time_str(tutc, 3));
140
141 tut = timeadd(tutc, erpv[2]); /* utc -> ut1 */
142
143 /* sun and moon position in eci */
144 sunmoonpos_eci(tut, rsun ? rs : NULL, rmoon ? rm : NULL);
145
146 /* eci to ecef transformation matrix */
147 eci2ecef(tutc, erpv, U, &gmst_);
148
149 /* sun and moon position in ecef */
150 if (rsun) {
151 matmul("NN", 3, 1, 3, 1.0, U, rs, 0.0, rsun);
152 }
153 if (rmoon) {
154 matmul("NN", 3, 1, 3, 1.0, U, rm, 0.0, rmoon);
155 }
156 if (gmst) {
157 *gmst = gmst_;
158 }
159}
void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun, double *rmoon, double *gmst)
Compute sun and moon position in ECEF.
Definition mrtk_astro.c:135
static void ast_args(double t, double *f)
Definition mrtk_astro.c:51
void sunmoonpos_eci(gtime_t tut, double *rsun, double *rmoon)
Compute sun and moon position in ECI.
Definition mrtk_astro.c:78
#define AU
Definition mrtk_astro.c:43
MRTKLIB Astronomy Module — Sun and moon position computation.
#define D2R
Definition mrtk_coords.c:36
#define PI
Definition mrtk_coords.c:35
void eci2ecef(gtime_t tutc, const double *erpv, double *U, double *gmst)
Compute ECI to ECEF transformation matrix.
#define RE_WGS84
Definition mrtk_coords.c:38
#define AS2R
Definition mrtk_coords.c:37
MRTKLIB Coordinates Module — Coordinate transformations and geometry.
void matmul(const char *tr, int n, int k, int m, double alpha, const double *A, const double *B, double beta, double *C)
Multiply matrix by matrix (C = alpha*A*B + beta*C).
Definition mrtk_mat.c:310
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
gtime_t epoch2time(const double *ep)
Convert calendar day/time to gtime_t struct.
Definition mrtk_time.c:113
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
Definition mrtk_time.c:279
gtime_t timeadd(gtime_t t, double sec)
Add seconds to gtime_t.
Definition mrtk_time.c:265
char * time_str(gtime_t t, int n)
Get time string (not reentrant).
Definition mrtk_time.c:530
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
Definition mrtk_trace.c:78
MRTKLIB Trace Module — debug trace and logging functions.
GNSS time representation.
Definition mrtk_time.h:49