gps_pvt 0.5.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,7 @@
51
51
  #endif
52
52
 
53
53
  #include "param/vector3.h"
54
+ #include "param/quaternion.h"
54
55
  #include "param/matrix.h"
55
56
 
56
57
  #include "WGS84.h"
@@ -130,6 +131,73 @@ class System_3D {
130
131
  in >> self[2];
131
132
  return in;
132
133
  }
134
+
135
+
136
+ ///< Coordinate rotation
137
+ struct Rotation {
138
+ Quaternion<FloatT> q;
139
+ Rotation() : q(1, 0, 0, 0) {}
140
+ Rotation &then(const Quaternion<FloatT> &q_) {
141
+ q *= q_;
142
+ return *this;
143
+ }
144
+ Rotation &then(const Rotation &rot) {
145
+ return then(rot.q);
146
+ }
147
+ Rotation &then_x(const FloatT &rad) {
148
+ return then(Quaternion<FloatT>(
149
+ std::cos(rad / 2), std::sin(rad / 2), 0, 0));
150
+ }
151
+ Rotation &then_y(const FloatT &rad) {
152
+ return then(Quaternion<FloatT>(
153
+ std::cos(rad / 2), 0, std::sin(rad / 2), 0));
154
+ }
155
+ Rotation &then_z(const FloatT &rad) {
156
+ return then(Quaternion<FloatT>(
157
+ std::cos(rad / 2), 0, 0, std::sin(rad / 2)));
158
+ }
159
+ operator Matrix<FloatT>() const {
160
+ return q.getDCM();
161
+ }
162
+ /**
163
+ * Perform coordinate rotation
164
+ * For example; application of clockwise 90 degree coordinate rotation along to z axis
165
+ * to vector(1,0,0) yields to vector(0,-1,0).
166
+ * This is not identical to vector rotation along with some axis,
167
+ * which corresponds to vector(0,1,0) of example, i.e.,
168
+ * z-axis 90 degree rotation of vector(1,0,0).
169
+ *
170
+ * @param vec target vector to which rotation is applied.
171
+ */
172
+ void apply(FloatT (&vec)[3]) const {
173
+ #if 0
174
+ // as definition: (~q * vec * q).vector();
175
+ Vector3<FloatT> v(((q.conj() *= Vector3<FloatT>(vec.v)) *= q).vector());
176
+ vec[0] = v[0];
177
+ vec[1] = v[1];
178
+ vec[2] = v[2];
179
+ #else // optimized version
180
+ FloatT q0(q[0]), qv[3] = {q[1], q[2], q[3]};
181
+ FloatT q0_(qv[0] * vec[0] + qv[1] * vec[1] + qv[2] * vec[2]), // -q~.vec (i*) vec
182
+ qv_[3] = { // q~[0] * vec + q~.vec (e*) vec
183
+ q0 * vec[0] - qv[1] * vec[2] + qv[2] * vec[1], // polarity checked; q~.vec = -qv
184
+ q0 * vec[1] - qv[2] * vec[0] + qv[0] * vec[2],
185
+ q0 * vec[2] - qv[0] * vec[1] + qv[1] * vec[0]};
186
+ vec[0] = q0_ * qv[0] + q0 * qv_[0] + qv_[1] * qv[2] - qv_[2] * qv[1];
187
+ vec[1] = q0_ * qv[1] + q0 * qv_[1] + qv_[2] * qv[0] - qv_[0] * qv[2];
188
+ vec[2] = q0_ * qv[2] + q0 * qv_[2] + qv_[0] * qv[1] - qv_[1] * qv[0];
189
+ #endif
190
+ }
191
+
192
+ /**
193
+ * Perform coordinate rotation by invoking apply(vec.v)
194
+ *
195
+ * @see apply(FloatT (&vec)[3])
196
+ */
197
+ void apply(System_3D &vec) const {
198
+ apply(vec.v);
199
+ }
200
+ };
133
201
  };
134
202
 
135
203
  template <class FloatT, class Earth> class System_XYZ;
@@ -186,7 +254,6 @@ class System_XYZ : public System_3D<FloatT> {
186
254
  }
187
255
 
188
256
  FloatT dist() const {
189
-
190
257
  return FloatT(std::sqrt(
191
258
  pow2(x()) + pow2(y()) + pow2(z())));
192
259
  }
@@ -220,6 +287,19 @@ class System_XYZ : public System_3D<FloatT> {
220
287
  std::atan2(y(), x()),
221
288
  (p / std::cos(_lat) - n));
222
289
  }
290
+
291
+ /**
292
+ * Get coordinates in a delayed (i.e., rotated) ECEF frame.
293
+ *
294
+ * @param (delay_sec) delayed seconds (both positive (delayed) and negative (hasten) values
295
+ * are acceptable)
296
+ * @return (self_t) coordinates
297
+ */
298
+ self_t after(const FloatT &delay_sec) const {
299
+ FloatT rad(delay_sec * -Earth::Omega_Earth_IAU); // Earth rotation is negative direction (y->x)
300
+ FloatT crad(std::cos(rad)), srad(std::sin(rad));
301
+ return self_t(x() * crad - y() * srad, x() * srad + y() * crad, z());
302
+ }
223
303
  };
224
304
 
225
305
  template <class FloatT, class Earth>
@@ -22,6 +22,8 @@
22
22
  #include "navigation/QZSS.h"
23
23
  #include "navigation/GLONASS.h"
24
24
  #include "navigation/RINEX.h"
25
+ #include "navigation/SP3.h"
26
+ #include "navigation/ANTEX.h"
25
27
 
26
28
  #include "navigation/GPS_Solver_Base.h"
27
29
  #include "navigation/GPS_Solver.h"
@@ -300,6 +302,10 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
300
302
  GPS_Ephemeris(const typename GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris &eph)
301
303
  : GPS_SpaceNode<FloatT>::SatelliteProperties::Ephemeris(eph),
302
304
  iode_subframe3(eph.iode) {}
305
+ struct constellation_res_t {
306
+ System_XYZ<FloatT, WGS84> position, velocity;
307
+ FloatT clock_error, clock_error_dot;
308
+ };
303
309
  };
304
310
  %}
305
311
  %extend GPS_Ephemeris {
@@ -387,20 +393,21 @@ struct GPS_Ephemeris : public GPS_SpaceNode<FloatT>::SatelliteProperties::Epheme
387
393
  break;
388
394
  }
389
395
  }
390
- %typemap(in,numinputs=0) System_XYZ<FloatT, WGS84> & (System_XYZ<FloatT, WGS84> temp) %{
391
- $1 = &temp;
392
- %}
393
- %typemap(argout) System_XYZ<FloatT, WGS84> & {
394
- %append_output(SWIG_NewPointerObj((new $*1_ltype(*$1)), $1_descriptor, SWIG_POINTER_OWN));
395
- }
396
- void constellation(
397
- System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
398
- const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
399
- const bool &with_velocity = true) const {
400
- typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
401
- self->constellation(t, pseudo_range, with_velocity));
402
- position = res.position;
403
- velocity = res.velocity;
396
+ %typemap(out) constellation_res_t {
397
+ %append_output(SWIG_NewPointerObj((new System_XYZ<FloatT, WGS84>($1.position)),
398
+ $descriptor(System_XYZ<FloatT, WGS84> *), SWIG_POINTER_OWN));
399
+ %append_output(SWIG_NewPointerObj((new System_XYZ<FloatT, WGS84>($1.velocity)),
400
+ $descriptor(System_XYZ<FloatT, WGS84> *), SWIG_POINTER_OWN));
401
+ %append_output(swig::from($1.clock_error));
402
+ %append_output(swig::from($1.clock_error_dot));
403
+ }
404
+ typename GPS_Ephemeris<FloatT>::constellation_res_t constellation(
405
+ const GPS_Time<FloatT> &t_tx, const FloatT &dt_transit = 0) const {
406
+ typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t pv(
407
+ self->constellation(t_tx, dt_transit, true));
408
+ typename GPS_Ephemeris<FloatT>::constellation_res_t res = {
409
+ pv.position, pv.velocity, self->clock_error(t_tx), self->clock_error_dot(t_tx)};
410
+ return res;
404
411
  }
405
412
  #if defined(SWIGRUBY)
406
413
  %rename("consistent?") is_consistent;
@@ -459,15 +466,14 @@ struct SBAS_Ephemeris : public SBAS_SpaceNode<FloatT>::SatelliteProperties::Ephe
459
466
  MAKE_ACCESSOR(ddx, FloatT); MAKE_ACCESSOR(ddy, FloatT); MAKE_ACCESSOR(ddz, FloatT);
460
467
  MAKE_ACCESSOR(a_Gf0, FloatT);
461
468
  MAKE_ACCESSOR(a_Gf1, FloatT);
462
- %apply GPS_Ephemeris::System_XYZ<FloatT, WGS84> & { System_XYZ<FloatT, WGS84> & }; // TODO ineffective?
463
- void constellation(
464
- System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
465
- const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0,
469
+ typename GPS_Ephemeris<FloatT>::constellation_res_t constellation(
470
+ const GPS_Time<FloatT> &t_tx, const FloatT &dt_transit = 0,
466
471
  const bool &with_velocity = true) const {
467
- typename SBAS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
468
- self->constellation(t, pseudo_range, with_velocity));
469
- position = res.position;
470
- velocity = res.velocity;
472
+ typename SBAS_SpaceNode<FloatT>::SatelliteProperties::constellation_t pv(
473
+ self->constellation(t_tx, dt_transit, with_velocity));
474
+ typename GPS_Ephemeris<FloatT>::constellation_res_t res = {
475
+ pv.position, pv.velocity, self->clock_error(t_tx), self->clock_error_dot(t_tx)};
476
+ return res;
471
477
  }
472
478
  }
473
479
 
@@ -610,23 +616,13 @@ struct GLONASS_Ephemeris
610
616
  self->has_string = has_string;
611
617
  return updated;
612
618
  }
613
- FloatT clock_error(
614
- const GPS_Time<FloatT> &t_arrival, const FloatT &pseudo_range = 0) const {
615
- return self->clock_error(t_arrival, pseudo_range);
616
- }
617
- %typemap(in,numinputs=0) System_XYZ<FloatT, WGS84> & (System_XYZ<FloatT, WGS84> temp) %{
618
- $1 = &temp;
619
- %}
620
- %typemap(argout) System_XYZ<FloatT, WGS84> & {
621
- %append_output(SWIG_NewPointerObj((new $*1_ltype(*$1)), $1_descriptor, SWIG_POINTER_OWN));
622
- }
623
- void constellation(
624
- System_XYZ<FloatT, WGS84> &position, System_XYZ<FloatT, WGS84> &velocity,
625
- const GPS_Time<FloatT> &t, const FloatT &pseudo_range = 0) const {
626
- typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t res(
627
- self->constellation(t, pseudo_range));
628
- position = res.position;
629
- velocity = res.velocity;
619
+ typename GPS_Ephemeris<FloatT>::constellation_res_t constellation(
620
+ const GPS_Time<FloatT> &t_tx, const FloatT &dt_transit = 0) const {
621
+ typename GPS_SpaceNode<FloatT>::SatelliteProperties::constellation_t pv(
622
+ self->constellation(t_tx, dt_transit));
623
+ typename GPS_Ephemeris<FloatT>::constellation_res_t res = {
624
+ pv.position, pv.velocity, self->clock_error(t_tx), self->clock_error_dot()};
625
+ return res;
630
626
  }
631
627
  #if defined(SWIGRUBY)
632
628
  %rename("consistent?") is_consistent;
@@ -1378,7 +1374,28 @@ struct GPS_Solver
1378
1374
  GPS_SpaceNode<FloatT> space_node;
1379
1375
  GPS_SolverOptions<FloatT> options;
1380
1376
  GPS_SinglePositioning<FloatT> solver;
1381
- gps_t() : space_node(), options(), solver(space_node) {}
1377
+ struct ephemeris_proxy_t {
1378
+ struct item_t {
1379
+ const void *impl;
1380
+ typename base_t::satellite_t (*impl_select)(
1381
+ const void *,
1382
+ const typename base_t::prn_t &, const typename base_t::gps_time_t &);
1383
+ } gps, qzss;
1384
+ static typename base_t::satellite_t forward(
1385
+ const void *ptr,
1386
+ const typename base_t::prn_t &prn, const typename base_t::gps_time_t &t){
1387
+ const ephemeris_proxy_t *proxy(static_cast<const ephemeris_proxy_t *>(ptr));
1388
+ const item_t &target(((prn >= 193) && (prn <= 202)) ? proxy->qzss : proxy->gps);
1389
+ return target.impl_select(target.impl, prn, t);
1390
+ }
1391
+ ephemeris_proxy_t(GPS_SinglePositioning<FloatT> &solver){
1392
+ gps.impl = qzss.impl = solver.satellites.impl;
1393
+ gps.impl_select = qzss.impl_select = solver.satellites.impl_select;
1394
+ solver.satellites.impl = this;
1395
+ solver.satellites.impl_select = forward;
1396
+ }
1397
+ } ephemeris_proxy;
1398
+ gps_t() : space_node(), options(), solver(space_node), ephemeris_proxy(solver) {}
1382
1399
  } gps;
1383
1400
  struct sbas_t {
1384
1401
  SBAS_SpaceNode<FloatT> space_node;
@@ -1636,6 +1653,101 @@ template <class FloatT>
1636
1653
  struct RINEX_Observation {};
1637
1654
  }
1638
1655
 
1656
+ %extend SP3 {
1657
+ %typemap(in,numinputs=0) int count[ANY] (int temp[$1_dim0]) "$1 = temp;"
1658
+ %typemap(argout) int count[ANY] {
1659
+ for(int i(0); i < $1_dim0; ++i){
1660
+ %append_output(SWIG_From(int)($1[i]));
1661
+ }
1662
+ }
1663
+ void satellites(int count[SP3::SYS_SYSTEMS]) const {
1664
+ typename SP3_Product<FloatT>::satellite_count_t x(self->satellite_count());
1665
+ count[SP3<FloatT>::SYS_GPS] = x.gps;
1666
+ count[SP3<FloatT>::SYS_SBAS] = x.sbas;
1667
+ count[SP3<FloatT>::SYS_QZSS] = x.qzss;
1668
+ count[SP3<FloatT>::SYS_GLONASS] = x.glonass;
1669
+ count[SP3<FloatT>::SYS_GALILEO] = x.galileo;
1670
+ count[SP3<FloatT>::SYS_BEIDOU] = x.beidou;
1671
+ }
1672
+
1673
+ }
1674
+ %inline {
1675
+ template <class FloatT>
1676
+ struct SP3 : public SP3_Product<FloatT> {
1677
+ int read(const char *fname) {
1678
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
1679
+ return SP3_Reader<FloatT>::read_all(fin, *this);
1680
+ }
1681
+ enum system_t {
1682
+ SYS_GPS,
1683
+ SYS_SBAS,
1684
+ SYS_QZSS,
1685
+ SYS_GLONASS,
1686
+ SYS_GALILEO,
1687
+ SYS_BEIDOU,
1688
+ SYS_SYSTEMS,
1689
+ };
1690
+ bool push(GPS_Solver<FloatT> &solver, const system_t &sys) const {
1691
+ switch(sys){
1692
+ case SYS_GPS:
1693
+ return SP3_Product<FloatT>::push(
1694
+ solver.gps.ephemeris_proxy.gps, SP3_Product<FloatT>::SYSTEM_GPS);
1695
+ case SYS_SBAS:
1696
+ return SP3_Product<FloatT>::push(
1697
+ solver.sbas.solver.satellites, SP3_Product<FloatT>::SYSTEM_SBAS);
1698
+ case SYS_QZSS:
1699
+ return SP3_Product<FloatT>::push(
1700
+ solver.gps.ephemeris_proxy.qzss, SP3_Product<FloatT>::SYSTEM_QZSS);
1701
+ case SYS_GLONASS:
1702
+ return SP3_Product<FloatT>::push(
1703
+ solver.glonass.solver.satellites, SP3_Product<FloatT>::SYSTEM_GLONASS);
1704
+ case SYS_GALILEO:
1705
+ case SYS_BEIDOU:
1706
+ default:
1707
+ break;
1708
+ }
1709
+ return false;
1710
+ }
1711
+ bool push(GPS_Solver<FloatT> &solver) const {
1712
+ system_t target[] = {
1713
+ SYS_GPS,
1714
+ SYS_SBAS,
1715
+ SYS_QZSS,
1716
+ SYS_GLONASS,
1717
+ //SYS_GALILEO,
1718
+ //SYS_BEIDOU,
1719
+ };
1720
+ for(std::size_t i(0); i < sizeof(target) / sizeof(target[0]); ++i){
1721
+ if(!push(solver, target[i])){return false;}
1722
+ }
1723
+ return true;
1724
+ }
1725
+ System_XYZ<FloatT, WGS84> position(
1726
+ const int &sat_id, const GPS_Time<FloatT> &t) const {
1727
+ return SP3_Product<FloatT>::select(sat_id, t).position(t);
1728
+ }
1729
+ System_XYZ<FloatT, WGS84> velocity(
1730
+ const int &sat_id, const GPS_Time<FloatT> &t) const {
1731
+ return SP3_Product<FloatT>::select(sat_id, t).velocity(t);
1732
+ }
1733
+ FloatT clock_error(
1734
+ const int &sat_id, const GPS_Time<FloatT> &t) const {
1735
+ return SP3_Product<FloatT>::select(sat_id, t).clock_error(t);
1736
+ }
1737
+ FloatT clock_error_dot(
1738
+ const int &sat_id, const GPS_Time<FloatT> &t) const {
1739
+ return SP3_Product<FloatT>::select(sat_id, t).clock_error_dot(t);
1740
+ }
1741
+ int apply_antex(const char *fname) {
1742
+ ANTEX_Product<FloatT> antex;
1743
+ std::fstream fin(fname, std::ios::in | std::ios::binary);
1744
+ int read_items(ANTEX_Reader<FloatT>::read_all(fin, antex));
1745
+ if(read_items < 0){return read_items;}
1746
+ return antex.move_to_antenna_position(*this);
1747
+ }
1748
+ };
1749
+ }
1750
+
1639
1751
  #undef MAKE_ACCESSOR
1640
1752
  #undef MAKE_VECTOR2ARRAY
1641
1753
  #undef MAKE_ARRAY_INPUT
@@ -1663,6 +1775,7 @@ struct RINEX_Observation {};
1663
1775
  %template(SolverOptions_GLONASS) GLONASS_SolverOptions<type>;
1664
1776
 
1665
1777
  %template(RINEX_Observation) RINEX_Observation<type>;
1778
+ %template(SP3) SP3<type>;
1666
1779
  %enddef
1667
1780
 
1668
1781
  CONCRETIZE(double);