HelmertTransform.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 
39 #include <ostream>
40 #include <iomanip>
41 
42 #include "HelmertTransform.hpp"
43 #include "TimeString.hpp"
44 #include "YDSTime.hpp"
45 #include "GNSSconstants.hpp"
46 
47 using namespace gnsstk;
48 using namespace std;
49 
50 namespace gnsstk
51 {
54  : fromFrame(ReferenceFrame::Unknown),
55  toFrame(ReferenceFrame::Unknown),
56  rx(std::numeric_limits<double>::quiet_NaN()),
57  ry(std::numeric_limits<double>::quiet_NaN()),
58  rz(std::numeric_limits<double>::quiet_NaN()),
59  tx(std::numeric_limits<double>::quiet_NaN()),
60  ty(std::numeric_limits<double>::quiet_NaN()),
61  tz(std::numeric_limits<double>::quiet_NaN()),
62  scale(std::numeric_limits<double>::quiet_NaN()),
63  description("Undefined")
64  {
65  }
66 
67  // Explicit constructor, from the 7 parameters.
70  double irx, double iry, double irz,
71  double itx, double ity, double itz,
72  double sc, const std::string& desc, const CommonTime& refEpoch)
73  : rx(irx*DEG_TO_RAD), ry(iry*DEG_TO_RAD), rz(irz*DEG_TO_RAD),
74  tx(itx), ty(ity), tz(itz), scale(sc), description(desc),
75  epoch(refEpoch), fromFrame(from), toFrame(to)
76  {
77  if ((from == ReferenceFrame::Unknown) || (to == ReferenceFrame::Unknown))
78  {
79  InvalidRequest e("Invalid Helmert transformation with Unknown frame");
80  GNSSTK_THROW(e);
81  }
82 
83  // check that rotation angles are small;
84  // sin x ~ x at 0.244 radians = 13.9 deg
85  if ((::fabs(rx) > 1.e-3) || (::fabs(ry) > 1.e-3) || (::fabs(rz) > 1.e-3))
86  {
87  InvalidRequest e("Invalid Helmert transformation : "
88  "small angle approximation.");
89  GNSSTK_THROW(e);
90  }
91 
92  // rotation matrix.
96  rotation = Matrix<double>(3,3,0.0);
97  rotation(0,0) = 1.0;
98  rotation(0,1) = -rz;
99  rotation(0,2) = ry;
100 
101  rotation(1,0) = rz;
102  rotation(1,1) = 1.0;
103  rotation(1,2) = -rx;
104 
105  rotation(2,0) = -ry;
106  rotation(2,1) = rx;
107  rotation(2,2) = 1.0;
108 
109  // translation vector
111  translation(0) = tx;
112  translation(1) = ty;
113  translation(2) = tz;
114  }
115 
116 
117  // Dump the object to a multi-line string including reference frames, the
118  // 7 parameters and description.
120  {
121  ostringstream oss;
122  oss << "Helmert Transformation"
123  << " from " << fromFrame
124  << " to " << toFrame << ":\n"
125  << scientific << setprecision(4)
126  << " Scale factor : " << scale
127  << fixed << " = " << scale/PPB << " ppb" << endl
128  << " Rotation angles (deg):"
129  << scientific
130  << " X : " << rx*RAD_TO_DEG
131  << ", Y : " << ry*RAD_TO_DEG
132  << ", Z : " << rz*RAD_TO_DEG << endl
133  << " Rotation angles (mas):"
134  << fixed
135  << " X : " << rx*RAD_TO_DEG/DEG_PER_MAS
136  << ", Y : " << ry*RAD_TO_DEG/DEG_PER_MAS
137  << ", Z : " << rz*RAD_TO_DEG/DEG_PER_MAS << endl
138  << " Translation (meters):"
139  << " X : " << tx
140  << ", Y : " << ty
141  << ", Z : " << tz << endl
142  << " Beginning Epoch: "
143  << (epoch == CommonTime::BEGINNING_OF_TIME ? string(" [all times]")
144  : printTime(epoch,"%Y/%02m/%02d %2H:%02M:%06.3f = %F %.3g %P"))
145  << endl
146  << " Description: " << description;
147  return (oss.str());
148  }
149 
150 
152  {
153  if (pos.getReferenceFrame() == fromFrame)
154  {
155  // transform
156  result = pos;
158  Vector<double> vec(3),res(3);
159  vec(0) = result[0];
160  vec(1) = result[1];
161  vec(2) = result[2];
162  res = rotation*vec + scale*vec + translation;
163  result[0] = res(0);
164  result[1] = res(1);
165  result[2] = res(2);
167  }
168  else if (pos.getReferenceFrame() == toFrame)
169  {
170  // inverse transform
171  result = pos;
173  Vector<double> vec(3),res(3);
174  vec(0) = result[0];
175  vec(1) = result[1];
176  vec(2) = result[2];
177  res = transpose(rotation) * (vec - scale*vec - translation);
178  result[0] = res(0);
179  result[1] = res(1);
180  result[2] = res(2);
182  }
183  else
184  {
185  InvalidRequest e(
186  "Helmert tranformation cannot act on frame " +
187  gnsstk::StringUtils::asString(pos.getReferenceFrame()));
188  GNSSTK_THROW(e);
189  }
190  }
191 
192 
195  Vector<double>& result)
196  {
197  if (vec.size() > 3)
198  {
199  InvalidRequest e("Input Vector is not of length 3");
200  GNSSTK_THROW(e);
201  }
202  try
203  {
204  Position pos(vec[0],vec[1],vec[2],Position::Cartesian), res;
205  pos.setReferenceFrame(RefFrame(frame, epoch));
206  transform(pos, res);
207  result = Vector<double>(3);
208  result[0] = res.X();
209  result[1] = res.Y();
210  result[2] = res.Z();
211  }
212  catch(Exception& e)
213  {
214  GNSSTK_RETHROW(e);
215  }
216  }
217 
218 
220  transform(const Triple& vec, ReferenceFrame frame, Triple& result)
221  {
222  try
223  {
224  Position pos(vec, Position::Cartesian), res;
225  pos.setReferenceFrame(RefFrame(frame, epoch));
226  transform(pos, res);
227  result[0] = res[0];
228  result[1] = res[1];
229  result[2] = res[2];
230  }
231  catch(Exception& e)
232  {
233  GNSSTK_RETHROW(e);
234  }
235  }
236 
237 
239  transform(const Xvt& xvt, Xvt& result)
240  {
241  try
242  {
243  Position pos(xvt.x, Position::Cartesian), res;
244  pos.setReferenceFrame(xvt.frame);
245  transform(pos, res);
246  result = xvt;
247  result.x[0] = res[0];
248  result.x[1] = res[1];
249  result.x[2] = res[2];
250  result.frame = res.getReferenceFrame();
251  }
252  catch(Exception& e)
253  {
254  GNSSTK_RETHROW(e);
255  }
256  }
257 
258 
260  transform(double x, double y, double z,
261  ReferenceFrame frame,
262  double& rx, double& ry, double& rz)
263  {
264  try
265  {
266  Position pos(x,y,z,Position::Cartesian), res;
267  pos.setReferenceFrame(RefFrame(frame, epoch));
268  transform(pos, res);
269  rx = res.X();
270  ry = res.Y();
271  rz = res.Z();
272  }
273  catch(Exception& e)
274  {
275  GNSSTK_RETHROW(e);
276  }
277  }
278 
279 
280  // time of PZ90 change
282  YDSTime(2007,263,61200.0,TimeSystem::UTC));
283  //HelmertTransform::PZ90Epoch(2454364L,61200L,0.0,TimeSystem::UTC);
284 
285  // array of pre-defined HelmertTransforms
287  {
290  0, 0, 0, 0.0, 0.0, 0.0, 0,
291  "WGS84 to ITRF identity transform, a default value\n"
292  " (\"...since 1997, the WGS84 GPS broadcast ...\n"
293  " is consistent with the ITRS at better than 5-cm level.\"\n"
294  " Boucher & Altamimi 2001)",
295  YDSTime(1997,1,0.0,TimeSystem::UTC)),
296  //CommonTime(2450450L,0L,0.0,TimeSystem::UTC)),
297 
298  // PZ90 WGS84
301  -19*DEG_PER_MAS, -4*DEG_PER_MAS, 353*DEG_PER_MAS,
302  0.07, 0.0, -0.77,
303  -3*PPB,
304  "PZ90 to WGS84, determined by IGEX-98, reference\n"
305  " \"ITRS, PZ-90 and WGS 84: current realizations\n"
306  " and the related transformation parameters,\"\n"
307  " Journal Geodesy (2001), 75:613, by Boucher and Altamimi.\n"
308  " Use before 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).",
309  YDSTime(-4713,1,0.0,TimeSystem::UTC)),
310 
313  0, 0, 0, -0.36, 0.08, 0.18, 0,
314  "PZ90.02 to ITRF2000, from Sergey Revnivykh, GLONASS PNT\n"
315  " Information Analysis Center, 47th CGSIC Meeting and ION\n"
316  " GNSS 2007, Fort Worth, Texas, implemented by GLONASS\n"
317  " 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).",
318  PZ90Epoch),
319 
320  // PZ90 ITRF
323  -19*DEG_PER_MAS, -4*DEG_PER_MAS, 353*DEG_PER_MAS,
324  0.07, 0.0, -0.77,
325  -3*PPB,
326  "PZ90 to ITRF(WGS84), determined by IGEX-98, reference\n"
327  " \"ITRS, PZ-90 and WGS 84: current realizations\n"
328  " and the related transformation parameters,\"\n"
329  " Journal Geodesy (2001), 75:613, by Boucher and Altamimi.\n"
330  " Use before 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).",
331  YDSTime(-4713,1,0.0,TimeSystem::UTC)),
332 
335  0, 0, 0, -0.36, 0.08, 0.18, 0,
336  "PZ90.02 to ITRF2000, from Sergey Revnivykh, GLONASS PNT\n"
337  " Information Analysis Center, 47th CGSIC Meeting and ION\n"
338  " GNSS 2007, Fort Worth, Texas, implemented by GLONASS\n"
339  " 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).",
340  PZ90Epoch),
341 
342  // add more transforms here, and increase
343  // HelmertTransform::stdCount in .cpp
344  };
345 
346 } // end namespace gnsstk
gnsstk::HelmertTransform::transform
void transform(const Position &pos, Position &result)
Definition: HelmertTransform.cpp:151
gnsstk::HelmertTransform::epoch
CommonTime epoch
epoch at which transform is first applicable
Definition: HelmertTransform.hpp:238
YDSTime.hpp
gnsstk::ReferenceFrame
ReferenceFrame
Definition: ReferenceFrame.hpp:52
gnsstk::Position::Cartesian
@ Cartesian
cartesian (Earth-centered, Earth-fixed)
Definition: Position.hpp:147
gnsstk::HelmertTransform::ty
double ty
Y axis translation in meters.
Definition: HelmertTransform.hpp:229
gnsstk::Position::transformTo
Position & transformTo(CoordinateSystem sys) noexcept
Definition: Position.cpp:247
const
#define const
Definition: getopt.c:43
gnsstk::Position::setReferenceFrame
void setReferenceFrame(const RefFrame &frame) noexcept
Definition: Position.cpp:467
gnsstk::YDSTime
Definition: YDSTime.hpp:58
gnsstk::ReferenceFrame::Unknown
@ Unknown
unknown frame
gnsstk::HelmertTransform::fromFrame
ReferenceFrame fromFrame
Reference frame to which *this is applied.
Definition: HelmertTransform.hpp:221
gnsstk::Xvt::frame
RefFrame frame
reference frame of this data
Definition: Xvt.hpp:156
gnsstk::StringUtils::asString
std::string asString(IonexStoreStrategy e)
Convert a IonexStoreStrategy to a whitespace-free string name.
Definition: IonexStoreStrategy.cpp:46
gnsstk::Position::Y
double Y() const noexcept
return Y coordinate (meters)
Definition: Position.cpp:364
gnsstk::Position::Z
double Z() const noexcept
return Z coordinate (meters)
Definition: Position.cpp:375
gnsstk::CommonTime::BEGINNING_OF_TIME
static const GNSSTK_EXPORT CommonTime BEGINNING_OF_TIME
earliest representable CommonTime
Definition: CommonTime.hpp:102
gnsstk::PPB
static const double PPB
parts per billion
Definition: GNSSconstants.hpp:84
GNSSconstants.hpp
gnsstk::RefFrame
Definition: RefFrame.hpp:53
gnsstk::Triple
Definition: Triple.hpp:68
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::HelmertTransform::ry
double ry
Y axis rotation in radians.
Definition: HelmertTransform.hpp:226
gnsstk::Position::getReferenceFrame
const RefFrame & getReferenceFrame() const noexcept
return coordinate RefFrame
Definition: Position.cpp:346
gnsstk::Xvt::x
Triple x
Sat position ECEF Cartesian (X,Y,Z) meters.
Definition: Xvt.hpp:151
gnsstk::RAD_TO_DEG
static const double RAD_TO_DEG
Conversion Factor from radians to degrees (units: degrees)
Definition: GNSSconstants.hpp:78
y
page HOWTO subpage DoxygenGuide Documenting Your Code page DoxygenGuide Documenting Your Code todo Flesh out this document section doctips Tips for Documenting When defining make sure that the prototype is identical between the cpp and hpp including both the namespaces and the parameter names for you have std::string as the return type in the hpp file and string as the return type in the cpp Doxygen may get confused and autolink to the cpp version with no documentation If you don t use the same parameter names between the cpp and hpp that will also confuse Doxygen Don t put type information in return or param documentation It doesn t really add anything and will often cause Doxygen to complain and not produce the documentation< br > use note Do not put a comma after a param name unless you mean to document multiple parameters< br/> the output stream</code >< br/> y
Definition: DOCUMENTING.dox:15
gnsstk::HelmertTransform::description
std::string description
Definition: HelmertTransform.hpp:242
gnsstk::transpose
SparseMatrix< T > transpose(const SparseMatrix< T > &M)
transpose
Definition: SparseMatrix.hpp:829
gnsstk::Matrix< double >
gnsstk::HelmertTransform::tx
double tx
X axis translation in meters.
Definition: HelmertTransform.hpp:228
gnsstk::HelmertTransform::asString
std::string asString() const noexcept
Definition: HelmertTransform.cpp:119
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::ReferenceFrame::WGS84
@ WGS84
WGS84, assumed to be the latest version.
example5.epoch
epoch
Definition: example5.py:24
gnsstk::ReferenceFrame::ITRF
@ ITRF
ITRF, assumed to be the latest version.
gnsstk::Xvt
Definition: Xvt.hpp:60
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
example4.pos
pos
Definition: example4.py:125
gnsstk::HelmertTransform::scale
double scale
scale factor, dimensionless, 0=no scale
Definition: HelmertTransform.hpp:231
gnsstk::Vector< double >
gnsstk::TimeSystem::UTC
@ UTC
Coordinated Universal Time (e.g., from NTP)
gnsstk::HelmertTransform
Definition: HelmertTransform.hpp:63
gnsstk::HelmertTransform::HelmertTransform
HelmertTransform() noexcept
Default constructor.
Definition: HelmertTransform.cpp:53
gnsstk::Position::X
double X() const noexcept
return X coordinate (meters)
Definition: Position.cpp:353
gnsstk::HelmertTransform::rz
double rz
Z axis rotation in radians.
Definition: HelmertTransform.hpp:227
gnsstk::HelmertTransform::stdTransforms
static const GNSSTK_EXPORT HelmertTransform stdTransforms[stdCount]
array of all pre-defined HelmertTransforms
Definition: HelmertTransform.hpp:215
gnsstk::HelmertTransform::rx
double rx
X axis rotation in radians.
Definition: HelmertTransform.hpp:225
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
gnsstk::Vector::size
size_t size() const
STL size.
Definition: Vector.hpp:207
gnsstk::HelmertTransform::translation
Vector< double > translation
the transform 3-vector in meters
Definition: HelmertTransform.hpp:235
std
Definition: Angle.hpp:142
gnsstk::DEG_PER_MAS
static const double DEG_PER_MAS
degrees per milliarcsecond (1e-3/3600.)
Definition: GNSSconstants.hpp:80
gnsstk::ReferenceFrame::PZ90
@ PZ90
PZ90 (GLONASS)
gnsstk::Position
Definition: Position.hpp:136
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::HelmertTransform::rotation
Matrix< double > rotation
the transform 3x3 rotation matrix (w/o scale)
Definition: HelmertTransform.hpp:234
HelmertTransform.hpp
gnsstk::HelmertTransform::toFrame
ReferenceFrame toFrame
Reference frame resulting from *this transform.
Definition: HelmertTransform.hpp:222
gnsstk::HelmertTransform::PZ90Epoch
static const GNSSTK_EXPORT CommonTime PZ90Epoch
Epoch at which GLONASS transitions from PZ90 to PZ90.02.
Definition: HelmertTransform.hpp:209
gnsstk::HelmertTransform::tz
double tz
Z axis translation in meters.
Definition: HelmertTransform.hpp:230
TimeString.hpp
gnsstk::DEG_TO_RAD
static const double DEG_TO_RAD
Conversion Factor from degrees to radians (units: degrees^-1)
Definition: GNSSconstants.hpp:76


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