AlmOrbit.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk 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
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
44 #include "GNSSconstants.hpp"
45 #include "GPSEllipsoid.hpp"
46 #include "AlmOrbit.hpp"
47 #include "GPSWeekSecond.hpp"
48 #include <cmath>
49 
50 namespace gnsstk
51 {
53  {
54  ecc = i_offset = OMEGAdot = Ahalf = OMEGA0 = w = M0 = AF0 = AF1 = 0.0;
55 
56  Toa = xmit_time = 0;
57 
58  week = SV_health = 0;
59  PRN = 0;
60  }
61 
62  AlmOrbit :: AlmOrbit(short prn, double aEcc, double ai_offset,
63  double aOMEGAdot, double aAhalf, double aOMEGA0,
64  double aw, double aM0, double aAF0, double aAF1,
65  long aToa, long axmit_time, short aweek,
66  short aSV_health)
67  : PRN(prn), ecc(aEcc), i_offset(ai_offset), OMEGAdot(aOMEGAdot), Ahalf(aAhalf),
68  OMEGA0(aOMEGA0), w(aw), M0(aM0), AF0(aAF0), AF1(aAF1), Toa(aToa),
69  xmit_time(axmit_time), week(aweek), SV_health(aSV_health)
70  {
71  }
72 
74  {
75  Xvt sv;
76  GPSEllipsoid ell;
77 
78  double elapt; /* elapsed time since Toa */
79  double A; /* semi-major axis */
80  double n; /* mean motion */
81  double meana; /* mean anomoly */
82  double ea; /* eccentric anomoly */
83  short loop; /* counter */
84  double f,g,delea,q,gsta,gcta; /* temp. variables */
85  double dtc; /* corrected time */
86  double ta; /* true anomoly */
87  double sinea,cosea,sinu,cosu;
88  double alat; /* arguement of latitude */
89  double ualat; /* corrected arguement of latitude */
90  double r; /* radius */
91  double i; /* inclination */
92  double anlon; /* corrected longitue of ascending node */
93  double xip,yip,can,san,cinc,sinc,xef,yef,zef,dek,dlk,div,domk,duv,
94  drv,dxp,dyp,vxef,vyef,vzef;
95  double sqrtgm = ::sqrt(ell.gm());
96 
97 /* Compute time since Almanac epoch (Toa) including week change */
98  elapt = t - getToaTime();
99 
100  /* compute mean motion from semi-major axis */
101  A = Ahalf * Ahalf;
102  n = sqrtgm / (Ahalf * A);
103 
104  /* compute the mean anomaly */
105  meana = M0 + elapt * n;
106  meana = ::fmod(meana, 2.0 * PI);
107 
108  /* compute eccentric anomaly by iteration */
109 
110  ea = meana + ecc * ::sin(meana);
111  loop = 1;
112 
113  do {
114  f = meana - (ea - ecc * ::sin(ea));
115  g = 1.0 - ecc * ::cos(ea);
116  delea = f / g;
117  ea += delea;
118  loop++;
119  } while ( ::fabs(delea) > 1.0e-11 && (loop <= 20));
120 
121  /* compute clock corrections (no relativistic correction computed) */
122  dtc = AF0 + elapt * AF1;
123  sv.clkbias = dtc;
124 
125  /* compute the true anomaly */
126  q = ::sqrt (1.0e0 - ecc * ecc);
127  sinea = ::sin(ea);
128  cosea = ::cos(ea);
129  gsta = q * sinea;
130  gcta = cosea - ecc;
131  ta = ::atan2(gsta,gcta);
132  g = 1.0 - ecc * cosea;
133 
134  /* compute argument of latitude for orbit */
135  alat = ta + w;
136 
137  /* compute correction terms ( no pertubation ) */
138  ualat = alat;
139  r = A * (1.0 - ecc * cosea);
140  i = i_offset + 0.3e0 * PI;
141 
142  /* compute corrected longitude of ascending node */
143  anlon = OMEGA0 +
144  (OMEGAdot - ell.angVelocity()) * elapt -
145  ell.angVelocity() * (double)Toa;
146 
147  /* compute positions in orbital plane */
148  cosu = ::cos(ualat);
149  sinu = ::sin(ualat);
150  xip = r * cosu;
151  yip = r * sinu;
152 
153  /* compute earch fixed coordinates (in meters) */
154  can = ::cos (anlon);
155  san = ::sin (anlon);
156  cinc = ::cos(i);
157  sinc = ::sin(i);
158 
159  xef = xip * can - yip * cinc * san;
160  yef = xip * san + yip * cinc * can;
161  zef = yip * sinc;
162 
163  sv.x[0] = xef;
164  sv.x[1] = yef;
165  sv.x[2] = zef;
166 
167  /* compute velocity of rotation coordinates & velocity of sat. */
168  dek = n / g;
169  dlk = n * q / (g*g);
170  div = 0.0e0;
171  domk = OMEGAdot - ell.angVelocity();
172  duv = dlk;
173  drv = A * ecc * dek * sinea;
174 
175  dxp = drv * cosu - r * sinu * duv;
176  dyp = drv * sinu + r * cosu * duv;
177 
178  vxef = dxp * can - xip * san * domk - dyp * cinc * san
179  + yip * (sinc * san * div - cinc * can * domk);
180  vyef = dxp * san + xip * can * domk + dyp * cinc * can
181  - yip * (sinc * can * div + cinc * san * domk);
182  vzef = dyp * sinc + yip * cinc * div;
183 
184  sv.v[0] = vxef;
185  sv.v[1] = vyef;
186  sv.v[2] = vzef;
188 
189  return sv;
190  }
191 
193  {
195  }
196 
197  short AlmOrbit::getFullWeek() const noexcept
198  {
199  // return value of the transmit week for the given PRN
200  short xmit_week = week;
201  double sow_diff = (double)(Toa - xmit_time);
202  if (sow_diff < -HALFWEEK)
203  xmit_week--;
204  else if (sow_diff > HALFWEEK)
205  xmit_week++;
206 
207  return xmit_week;
208  }
209 
211  {
212  return GPSWeekSecond(week, Toa);
213  }
214 
215  void AlmOrbit::dump(std::ostream& s, int verbosity) const
216  {
217  using std::endl;
218  using std::setw;
219 
220  s << std::setprecision(4);
221  s.setf(std::ios::scientific);
222  switch (verbosity)
223  {
224  case 0:
225  s << PRN << ", "
226  << Toa << ", "
227  << week << ", "
228  << std::hex
229  << SV_health << ", "
230  << std::dec
231  << AF0 << ", "
232  << AF1 << ", "
233  << ecc << ", "
234  << w << ", "
235  << Ahalf << ", "
236  << M0 << ", "
237  << OMEGA0 << ", "
238  << OMEGAdot << ", "
239  << i_offset
240  << endl;
241  break;
242 
243  case 1:
244  s << "PRN:" << PRN
245  << " Toa:" << Toa
246  << " H:" << SV_health
247  << " AFO:" << AF0
248  << " AF1:" << AF1
249  << " Ecc:" << ecc
250  << endl
251  << " w:" << w
252  << " Ahalf:" << Ahalf
253  << " M0:" << M0
254  << endl
255  << " OMEGA0:" << OMEGA0
256  << " OMEGAdot:" << OMEGAdot
257  << " Ioff:" << i_offset
258  << endl;
259  break;
260 
261  default:
262  s << "PRN: " << PRN << endl
263  << "Toa: " << Toa << endl
264  << "xmit_time: " << xmit_time << endl
265  << "week: " << week << endl
266  << "SV_health: " << SV_health << endl
267  << "AFO: " << setw(12) << AF0 << " sec" << endl
268  << "AF1: " << setw(12) << AF1 << " sec/sec" << endl
269  << "Sqrt A: " << setw(12) << Ahalf << " sqrt meters" << endl
270  << "Eccentricity: " << setw(12) << ecc << endl
271  << "Arg of perigee: " << setw(12) << w << " rad" << endl
272  << "Mean anomaly at epoch: " << setw(12) << M0 << " rad" << endl
273  << "Right ascension: " << setw(12) << OMEGA0 << " rad " << setw(16) << OMEGAdot << " rad/sec" << endl
274  << "Inclination offset: " << setw(12) << i_offset << " rad " << endl;
275  }
276  }
277 
278  std::ostream& operator<<(std::ostream& s, const AlmOrbit& ao)
279  {
280  ao.dump(s);
281  return s;
282  }
283 
284 } // namespace
gnsstk::AlmOrbit::OMEGAdot
double OMEGAdot
Definition: AlmOrbit.hpp:106
gnsstk::AlmOrbit::svXvt
Xvt svXvt(const CommonTime &t) const
Definition: AlmOrbit.cpp:73
gnsstk::HALFWEEK
const long HALFWEEK
Seconds per half week.
Definition: TimeConstants.hpp:58
const
#define const
Definition: getopt.c:43
gnsstk::AlmOrbit::ecc
double ecc
Definition: AlmOrbit.hpp:104
gnsstk::GPSEllipsoid::angVelocity
virtual double angVelocity() const noexcept
Definition: GPSEllipsoid.hpp:72
gnsstk::AlmOrbit::Toa
long Toa
Definition: AlmOrbit.hpp:113
gnsstk::Xvt::Healthy
@ Healthy
Satellite is healthy, PVT valid.
Definition: Xvt.hpp:96
gnsstk::AlmOrbit::SV_health
short SV_health
Definition: AlmOrbit.hpp:116
gnsstk::AlmOrbit::OMEGA0
double OMEGA0
Definition: AlmOrbit.hpp:108
gnsstk::AlmOrbit::week
short week
Definition: AlmOrbit.hpp:115
gnsstk::GPSEllipsoid
Definition: GPSEllipsoid.hpp:67
gnsstk::PI
const double PI
GPS value of PI; also specified by GAL.
Definition: GNSSconstants.hpp:62
gnsstk::Xvt::v
Triple v
satellite velocity in ECEF Cartesian, meters/second
Definition: Xvt.hpp:152
GNSSconstants.hpp
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::AlmOrbit::getFullWeek
short getFullWeek() const noexcept
returns full week of TRANSMIT TIME
Definition: AlmOrbit.cpp:197
std::sin
double sin(gnsstk::Angle x)
Definition: Angle.hpp:144
gnsstk::GPSWeekSecond
Definition: GPSWeekSecond.hpp:56
gnsstk::AlmOrbit::getTransmitTime
CommonTime getTransmitTime() const noexcept
Definition: AlmOrbit.cpp:192
gnsstk::Xvt::x
Triple x
Sat position ECEF Cartesian (X,Y,Z) meters.
Definition: Xvt.hpp:151
gnsstk::AlmOrbit::AlmOrbit
AlmOrbit() noexcept
Default constructor, initialize to 0.
Definition: AlmOrbit.cpp:52
gnsstk::AlmOrbit::M0
double M0
Definition: AlmOrbit.hpp:110
gnsstk::operator<<
std::ostream & operator<<(std::ostream &s, const ObsEpoch &oe) noexcept
Definition: ObsEpochMap.cpp:54
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::AlmOrbit::AF0
double AF0
Definition: AlmOrbit.hpp:111
gnsstk::AlmOrbit::PRN
short PRN
Definition: AlmOrbit.hpp:103
gnsstk::AlmOrbit::getToaTime
CommonTime getToaTime() const noexcept
Definition: AlmOrbit.cpp:210
gnsstk::Xvt
Definition: Xvt.hpp:60
std::cos
double cos(gnsstk::Angle x)
Definition: Angle.hpp:146
GPSEllipsoid.hpp
gnsstk::Xvt::health
HealthStatus health
Health status of satellite at ref time.
Definition: Xvt.hpp:157
GPSWeekSecond.hpp
gnsstk::AlmOrbit::dump
void dump(std::ostream &s=std::cout, int verbosity=1) const
Definition: AlmOrbit.cpp:215
gnsstk::AlmOrbit::Ahalf
double Ahalf
Definition: AlmOrbit.hpp:107
gnsstk::AlmOrbit::AF1
double AF1
Definition: AlmOrbit.hpp:112
AlmOrbit.hpp
gnsstk::Xvt::clkbias
double clkbias
Sat clock correction in seconds.
Definition: Xvt.hpp:153
gnsstk::AlmOrbit::w
double w
Definition: AlmOrbit.hpp:109
gnsstk::GPSEllipsoid::gm
virtual double gm() const noexcept
Definition: GPSEllipsoid.hpp:77
gnsstk::AlmOrbit::i_offset
double i_offset
Definition: AlmOrbit.hpp:105
gnsstk::Xvt::Unhealthy
@ Unhealthy
Sat is marked unhealthy, do not use PVT.
Definition: Xvt.hpp:94
gnsstk::AlmOrbit::xmit_time
long xmit_time
Definition: AlmOrbit.hpp:114
gnsstk::AlmOrbit
Definition: AlmOrbit.hpp:59


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:38