gps_pvt 0.5.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);