1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
******************************************************************************
*
* @file worldmagmodel.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WORLDMAGMODEL_H
#define WORLDMAGMODEL_H
#include "utils_global.h"
// ******************************
// internal structure definitions
#define WMM_MAX_MODEL_DEGREES 12
#define WMM_MAX_SECULAR_VARIATION_MODEL_DEGREES 12
#define WMM_NUMTERMS 91 // ((WMM_MAX_MODEL_DEGREES + 1) * (WMM_MAX_MODEL_DEGREES + 2) / 2);
#define WMM_NUMPCUP 92 // NUMTERMS + 1
#define WMM_NUMPCUPS 13 // WMM_MAX_MODEL_DEGREES + 1
typedef struct
{
double EditionDate;
double epoch; //Base time of Geomagnetic model epoch (yrs)
char ModelName[20];
// double Main_Field_Coeff_G[WMM_NUMTERMS]; // C - Gauss coefficients of main geomagnetic model (nT)
// double Main_Field_Coeff_H[WMM_NUMTERMS]; // C - Gauss coefficients of main geomagnetic model (nT)
// double Secular_Var_Coeff_G[WMM_NUMTERMS]; // CD - Gauss coefficients of secular geomagnetic model (nT/yr)
// double Secular_Var_Coeff_H[WMM_NUMTERMS]; // CD - Gauss coefficients of secular geomagnetic model (nT/yr)
int nMax; // Maximum degree of spherical harmonic model
int nMaxSecVar; // Maxumum degree of spherical harmonic secular model
int SecularVariationUsed; // Whether or not the magnetic secular variation vector will be needed by program
} WMMtype_MagneticModel;
typedef struct
{
double a; // semi-major axis of the ellipsoid
double b; // semi-minor axis of the ellipsoid
double fla; // flattening
double epssq; // first eccentricity squared
double eps; // first eccentricity
double re; // mean radius of ellipsoid
} WMMtype_Ellipsoid;
typedef struct
{
double lambda; // longitude
double phi; // geodetic latitude
double HeightAboveEllipsoid; // height above the ellipsoid (HaE)
} WMMtype_CoordGeodetic;
typedef struct
{
double lambda; // longitude
double phig; // geocentric latitude
double r; // distance from the center of the ellipsoid
} WMMtype_CoordSpherical;
typedef struct
{
int Year;
int Month;
int Day;
double DecimalYear;
} WMMtype_Date;
typedef struct
{
double Pcup[WMM_NUMPCUP]; // Legendre Function
double dPcup[WMM_NUMPCUP]; // Derivative of Lagendre fn
} WMMtype_LegendreFunction;
typedef struct
{
double Bx; // North
double By; // East
double Bz; // Down
} WMMtype_MagneticResults;
typedef struct
{
double RelativeRadiusPower[WMM_MAX_MODEL_DEGREES + 1]; // [earth_reference_radius_km / sph. radius ]^n
double cos_mlambda[WMM_MAX_MODEL_DEGREES + 1]; // cp(m) - cosine of (m*spherical coord. longitude
double sin_mlambda[WMM_MAX_MODEL_DEGREES + 1]; // sp(m) - sine of (m*spherical coord. longitude)
} WMMtype_SphericalHarmonicVariables;
typedef struct
{
double Decl; /*1. Angle between the magnetic field vector and true north, positive east */
double Incl; /*2. Angle between the magnetic field vector and the horizontal plane, positive down */
double F; /*3. Magnetic Field Strength */
double H; /*4. Horizontal Magnetic Field Strength */
double X; /*5. Northern component of the magnetic field vector */
double Y; /*6. Eastern component of the magnetic field vector */
double Z; /*7. Downward component of the magnetic field vector */
double GV; /*8. The Grid Variation */
double Decldot; /*9. Yearly Rate of change in declination */
double Incldot; /*10. Yearly Rate of change in inclination */
double Fdot; /*11. Yearly rate of change in Magnetic field strength */
double Hdot; /*12. Yearly rate of change in horizontal field strength */
double Xdot; /*13. Yearly rate of change in the northern component */
double Ydot; /*14. Yearly rate of change in the eastern component */
double Zdot; /*15. Yearly rate of change in the downward component */
double GVdot; /*16. Yearly rate of chnage in grid variation */
} WMMtype_GeoMagneticElements;
// ******************************
namespace Utils {
class QTCREATOR_UTILS_EXPORT WorldMagModel
{
public:
WorldMagModel();
int GetMagVector(double LLA[3], int Month, int Day, int Year, double Be[3]);
private:
WMMtype_Ellipsoid Ellip;
WMMtype_MagneticModel MagneticModel;
double decimal_date;
void Initialize();
int Geomag(WMMtype_CoordSpherical *CoordSpherical, WMMtype_CoordGeodetic *CoordGeodetic, WMMtype_GeoMagneticElements *GeoMagneticElements);
void ComputeSphericalHarmonicVariables(WMMtype_CoordSpherical *CoordSpherical, int nMax, WMMtype_SphericalHarmonicVariables *SphVariables);
int AssociatedLegendreFunction(WMMtype_CoordSpherical *CoordSpherical, int nMax, WMMtype_LegendreFunction *LegendreFunction);
void Summation( WMMtype_LegendreFunction *LegendreFunction,
WMMtype_SphericalHarmonicVariables *SphVariables,
WMMtype_CoordSpherical *CoordSpherical,
WMMtype_MagneticResults *MagneticResults);
void SecVarSummation( WMMtype_LegendreFunction *LegendreFunction,
WMMtype_SphericalHarmonicVariables *SphVariables,
WMMtype_CoordSpherical *CoordSpherical,
WMMtype_MagneticResults *MagneticResults);
void RotateMagneticVector( WMMtype_CoordSpherical *CoordSpherical,
WMMtype_CoordGeodetic *CoordGeodetic,
WMMtype_MagneticResults *MagneticResultsSph,
WMMtype_MagneticResults *MagneticResultsGeo);
void CalculateGeoMagneticElements(WMMtype_MagneticResults *MagneticResultsGeo, WMMtype_GeoMagneticElements *GeoMagneticElements);
void CalculateSecularVariation(WMMtype_MagneticResults *MagneticVariation, WMMtype_GeoMagneticElements *MagneticElements);
int PcupHigh(double *Pcup, double *dPcup, double x, int nMax);
void PcupLow(double *Pcup, double *dPcup, double x, int nMax);
void SummationSpecial(WMMtype_SphericalHarmonicVariables *SphVariables, WMMtype_CoordSpherical *CoordSpherical, WMMtype_MagneticResults *MagneticResults);
void SecVarSummationSpecial(WMMtype_SphericalHarmonicVariables *SphVariables, WMMtype_CoordSpherical *CoordSpherical, WMMtype_MagneticResults *MagneticResults);
double get_main_field_coeff_g(int index);
double get_main_field_coeff_h(int index);
double get_secular_var_coeff_g(int index);
double get_secular_var_coeff_h(int index);
int DateToYear(int month, int day, int year);
void GeodeticToSpherical(WMMtype_CoordGeodetic *CoordGeodetic, WMMtype_CoordSpherical *CoordSpherical);
};
}
// ******************************
#endif