Fixposition SDK 0.0.0-heads/main-0-g7b59b93
Collection of c++ libraries and apps for use with Fixposition products
Loading...
Searching...
No Matches
trafo.hpp
Go to the documentation of this file.
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 * \endverbatim
9 *
10 * @file
11 * @brief Fixposition SDK: Transformation utilities
12 *
13 * @page FPSDK_COMMON_TRAFO Transformation utilities
14 *
15 * **API**: fpsdk_common/trafo.hpp and fpsdk::common::trafo
16 *
17 */
18#ifndef __FPSDK_COMMON_TRAFO_HPP__
19#define __FPSDK_COMMON_TRAFO_HPP__
20
21/* LIBC/STL */
22#include <memory>
23#include <string>
24
25/* EXTERNAL */
26#include "fpsdk_common/ext/eigen_core.hpp"
27#include "fpsdk_common/ext/eigen_geometry.hpp"
28
29/* PACKAGE */
30
31namespace fpsdk {
32namespace common {
33/**
34 * @brief Transformation utilities
35 */
36namespace trafo {
37/* ****************************************************************************************************************** */
38
39/**
40 * @name WGS-84 constants
41 *
42 * https://en.wikipedia.org/wiki/World_Geodetic_System#Defining_Parameters
43 *
44 * @{
45 */
46static constexpr double WGS84_A = 6378137.0; //!< WGS-84 Earth radius major axis [m]
47static constexpr double WGS84_B = 6356752.314245; //!< WGS-84 Earth radius minor axis [m]
48static constexpr double WGS84_1F = 298.257223563; //!< WGS-84 1/f inverse of flattening parameter
49static constexpr double WGS84_E2 = 6.69437999014e-3; //!< WGS-84 first eccentricity squared
50static constexpr double WGS84_A2 = WGS84_A * WGS84_A; //!< WGS-84 a_^2
51static constexpr double WGS84_B2 = WGS84_B * WGS84_B; //!< WGS-84 b_^2
52static constexpr double WGS84_EE2 = WGS84_A2 / WGS84_B2 - 1; //!< WGS-84 e'^2 second eccentricity squared
53///@}
54
55/**
56 * @brief Calculate the rotation matrix from ECEF to ENU for a given reference latitude/longitude
57 *
58 * @param[in] lat Reference latitude [rad]
59 * @param[in] lon Reference longitude [rad]
60 *
61 * @returns the rotation matrix from ECEF to ENU
62 */
63Eigen::Matrix3d RotEnuEcef(const double lat, const double lon);
64
65/**
66 * @brief Calculate the rotation matrix from ECEF to ENU for a given reference position
67 *
68 * @param[in] ecef Reference position in ECEF [m]
69 *
70 * @returns the rotation matrix from ECEF to ENU
71 */
72Eigen::Matrix3d RotEnuEcef(const Eigen::Vector3d& ecef);
73
74/**
75 * @brief Returns rotation matrix between NED and ENU
76 *
77 * @details | 0, 1, 0 |
78 * | 1, 0, 0 |
79 * | 0, 0,-1 |
80 *
81 * @returns the rotation matrix between NED and ENU
82 */
83Eigen::Matrix3d RotNedEnu();
84
85/**
86 * @brief Calculate the rotation matrix from ECEF to NED for a given reference latitude/longitude
87 *
88 * @param[in] lat Reference latitude [rad]
89 * @param[in] lon Reference longitude [rad]
90 *
91 * @returns the rotation matrix from ECEF to NED
92 */
93Eigen::Matrix3d RotNedEcef(const double lat, const double lon);
94
95/**
96 * @brief Calculate the rotation matrix from ECEF to
97 * NED for a given reference origin.
98 *
99 * @param[in] ecef Reference position in ECEF [m]
100 * @returns the rRotation matrix from ECEF to NED
101 */
102Eigen::Matrix3d RotNedEcef(const Eigen::Vector3d& ecef);
103
104/**
105 * @brief Transform ECEF coordinate to ENU with specified ENU-origin
106 *
107 * @param[in] ecef ECEF position to be transformed [m]
108 *
109 * @param[in] wgs84llh_ref ENU-origin in geodetic coordinates (lat [rad], lon [rad], height [m])
110 *
111 * @returns the position in ENU coordinates
112 */
113Eigen::Vector3d TfEnuEcef(const Eigen::Vector3d& ecef, const Eigen::Vector3d& wgs84llh_ref);
114
115/**
116 * @brief Transform ENU coordinate to ECEF with specified ENU-origin
117 *
118 * @param[in] enu ENU position to be transformed [m]
119 * @param[in] wgs84llh_ref ENU-origin in geodetic coordinates (lat [rad], lon [rad], height [m])
120 *
121 * @returns @todo documentation
122 */
123Eigen::Vector3d TfEcefEnu(const Eigen::Vector3d& enu, const Eigen::Vector3d& wgs84llh_ref);
124
125/**
126 * @brief Convert ECEF coordinates to ENU with specified ENU origin
127 *
128 * @param[in] ecef ECEF position to be converted
129 * @param[in] wgs84llh_ref ENU-origin input given in geodetic coordinates
130 *
131 * @returns the position in ENU coordinates
132 */
133Eigen::Vector3d TfNedEcef(const Eigen::Vector3d& ecef, const Eigen::Vector3d& wgs84llh_ref);
134
135/**
136 * @todo documentation
137 */
138Eigen::Vector3d TfEcefNed(const Eigen::Vector3d& ned, const Eigen::Vector3d& wgs84llh_ref);
139
140/**
141 * @brief Convert geodetic coordinates (latitude, longitude, height) to ECEF (x, y, z).
142 *
143 * @param[in] wgs84llh Geodetic coordinates (Lat[rad], Lon[rad], Height[m])
144 *
145 * @return Eigen::Vector3d ECEF coordinates [m]
146 */
147Eigen::Vector3d TfEcefWgs84Llh(const Eigen::Vector3d& wgs84llh);
148
149/**
150 * @brief Convert ECEF (x, y, z) coordinates to geodetic coordinates (latitude, longitude, height)
151 * (latitude, longitude, altitude).
152 *
153 * @param[in] ecef ECEF coordinates [m]
154 *
155 * @returns the geodetic coordinates (lat [rad], lon [rad], height [m])
156 */
157Eigen::Vector3d TfWgs84LlhEcef(const Eigen::Vector3d& ecef);
158
159/**
160 * @brief Calculate yaw, pitch and roll in ENU from a given pose in ECEF
161 *
162 * @details Yaw will be -Pi/2 when X is pointing North, because ENU starts with East
163 *
164 * @param[in] ecef_p 3D position vector in ECEF
165 * @param[in] ecef_r 3x3 rotation matrix representing rotation from body to ECEF
166 *
167 * @returns yaw, pitch and roll in ENU
168 */
169Eigen::Vector3d EcefPoseToEnuEul(const Eigen::Vector3d& ecef_p, const Eigen::Matrix3d& ecef_r);
170
171/**
172 * @brief Vector4 quaternion to intrinsic Euler Angles in ZYX (yaw,pitch,roll)
173 *
174 * @param[in] quat Quaternion (w, i, j, k)
175 *
176 * @returns the intrinsic Euler angles in ZYX (yaw, pitch, roll) order
177 */
178Eigen::Vector3d QuatToEul(const Eigen::Quaterniond& quat);
179
180/**
181 * @brief Rotation Matrix to intrinsic Euler Angles in ZYX (Yaw-Pitch-Roll) order in radian
182 *
183 * @param rot Eigen::Matrix3d
184 * @return Eigen::Vector3d intrinsic euler angle in ZYX (Yaw-Pitch-Roll) order in radian
185 */
186Eigen::Vector3d RotToEul(const Eigen::Matrix3d& rot);
187
188/**
189 * @brief Convert llh from deg to rad, height component unchanged
190 *
191 * @param[in] llh_deg llh in degrees
192 * @return Eigen::Vector3d llh in radian
193 */
194Eigen::Vector3d LlhDegToRad(const Eigen::Vector3d& llh_deg);
195
196/**
197 * @brief Convert llh from rad to deg, height component unchanged
198 *
199 * @param[in] llh_rad llh in radian
200 * @return Eigen::Vector3d llh in degrees
201 */
202Eigen::Vector3d LlhRadToDeg(const Eigen::Vector3d& llh_rad);
203
204#if FP_USE_PROJ
205/**
206 * @brief "Universal" coordinate transformer, backed by PROJ
207 */
209{
210 public:
211 /**
212 * @brief Constructor
213 *
214 * @param[in] name Optional name, for debugging
215 */
216 Transformer(const std::string& name = "");
217
218 ~Transformer();
219
220 /**
221 * @brief Initialise transformer
222 *
223 * The source and target CRS specification can be anything that proj_create_crs_to_crs() understands (see
224 * https://proj.org/en/9.4/development/reference/functions.html#c.proj_create_crs_to_crs). You may have to change
225 * the PROJ configuration (proj.ini) and/or update some PROJ data yourself to support some CRS. See the PROJ
226 * documentation for details (see https://proj.org/en/9.4/resource_files.html).
227 *
228 * @param[in] source_crs Source coordinate reference system, e.g. "EPSG:4326"
229 * @param[in] target_crs Target coordinate reference system, e.g. "EPSG:2056"
230 *
231 * @returns true on success, false otherwise (bad params, missing data, ...)
232 */
233 bool Init(const std::string& source_crs, const std::string& target_crs);
234
235 /**
236 * @brief Transform coordinates
237 *
238 * @param[in,out] inout Coordinates to transform, will be replaced with result
239 * @param[in] inv Do the inverse transformation (true), default is forward (false)
240 *
241 * @returns true on success, false otherwise
242 */
243 bool Transform(Eigen::Vector3d& inout, const bool inv = false);
244
245 /**
246 * @brief Transform coordinates
247 *
248 * @param[in] in Coordinates to transform
249 * @param[out] out Transformed coordinates
250 * @param[in] inv Do the inverse transformation (true), default is forward (false)
251 *
252 * @returns true on success, false otherwise
253 */
254 bool Transform(const Eigen::Vector3d& in, Eigen::Vector3d& out, const bool inv = false);
255
256 /**
257 * @brief Transform coordinates (with time)
258 *
259 * @param[in] in Coordinates to transform (with time)
260 * @param[out] out Transformed coordinates (with time)
261 * @param[in] inv Do the inverse transformation (true), default is forward (false)
262 *
263 * @returns true on success, false otherwise
264 */
265 bool Transform(const Eigen::Vector4d& in, Eigen::Vector4d& out, const bool inv = false);
266
267 // No copy, no move
268 Transformer& operator=(const Transformer&) = delete;
269 Transformer(const Transformer&) = delete;
270 Transformer(Transformer&&) = delete;
271 Transformer& operator=(Transformer&&) = delete;
272
273 private:
274 const std::string name_; //!< Name, for debugging
275 bool pj_init_; //!< Proj is initialised
276 void* pj_ctx_; //!< Proj context
277 void* pj_tf_; //!< Proj transformation object
278};
279#endif // FP_USE_PROJ
280
281/* ****************************************************************************************************************** */
282} // namespace trafo
283} // namespace common
284} // namespace fpsdk
285#endif // __FPSDK_COMMON_TRAFO_HPP__
"Universal" coordinate transformer, backed by PROJ
Definition trafo.hpp:209
Transformer(const std::string &name="")
Constructor.
bool Transform(Eigen::Vector3d &inout, const bool inv=false)
Transform coordinates.
bool Transform(const Eigen::Vector3d &in, Eigen::Vector3d &out, const bool inv=false)
Transform coordinates.
bool Transform(const Eigen::Vector4d &in, Eigen::Vector4d &out, const bool inv=false)
Transform coordinates (with time)
bool Init(const std::string &source_crs, const std::string &target_crs)
Initialise transformer.
Eigen::Matrix3d RotEnuEcef(const double lat, const double lon)
Calculate the rotation matrix from ECEF to ENU for a given reference latitude/longitude.
Eigen::Matrix3d RotNedEcef(const double lat, const double lon)
Calculate the rotation matrix from ECEF to NED for a given reference latitude/longitude.
Eigen::Vector3d LlhDegToRad(const Eigen::Vector3d &llh_deg)
Convert llh from deg to rad, height component unchanged.
Eigen::Vector3d LlhRadToDeg(const Eigen::Vector3d &llh_rad)
Convert llh from rad to deg, height component unchanged.
static constexpr double WGS84_1F
WGS-84 1/f inverse of flattening parameter.
Definition trafo.hpp:48
Eigen::Vector3d TfEcefNed(const Eigen::Vector3d &ned, const Eigen::Vector3d &wgs84llh_ref)
static constexpr double WGS84_B2
WGS-84 b_^2.
Definition trafo.hpp:51
Eigen::Vector3d TfNedEcef(const Eigen::Vector3d &ecef, const Eigen::Vector3d &wgs84llh_ref)
Convert ECEF coordinates to ENU with specified ENU origin.
static constexpr double WGS84_E2
WGS-84 first eccentricity squared.
Definition trafo.hpp:49
Eigen::Vector3d QuatToEul(const Eigen::Quaterniond &quat)
Vector4 quaternion to intrinsic Euler Angles in ZYX (yaw,pitch,roll)
Eigen::Vector3d RotToEul(const Eigen::Matrix3d &rot)
Rotation Matrix to intrinsic Euler Angles in ZYX (Yaw-Pitch-Roll) order in radian.
static constexpr double WGS84_B
WGS-84 Earth radius minor axis [m].
Definition trafo.hpp:47
Eigen::Matrix3d RotNedEnu()
Returns rotation matrix between NED and ENU.
Eigen::Vector3d TfWgs84LlhEcef(const Eigen::Vector3d &ecef)
Convert ECEF (x, y, z) coordinates to geodetic coordinates (latitude, longitude, height) (latitude,...
Eigen::Vector3d TfEcefEnu(const Eigen::Vector3d &enu, const Eigen::Vector3d &wgs84llh_ref)
Transform ENU coordinate to ECEF with specified ENU-origin.
static constexpr double WGS84_A
WGS-84 Earth radius major axis [m].
Definition trafo.hpp:46
Eigen::Vector3d EcefPoseToEnuEul(const Eigen::Vector3d &ecef_p, const Eigen::Matrix3d &ecef_r)
Calculate yaw, pitch and roll in ENU from a given pose in ECEF.
Eigen::Vector3d TfEnuEcef(const Eigen::Vector3d &ecef, const Eigen::Vector3d &wgs84llh_ref)
Transform ECEF coordinate to ENU with specified ENU-origin.
Eigen::Vector3d TfEcefWgs84Llh(const Eigen::Vector3d &wgs84llh)
Convert geodetic coordinates (latitude, longitude, height) to ECEF (x, y, z).
static constexpr double WGS84_A2
WGS-84 a_^2.
Definition trafo.hpp:50
static constexpr double WGS84_EE2
WGS-84 e'^2 second eccentricity squared.
Definition trafo.hpp:52
Fixposition SDK.
Definition fpsdk_doc.hpp:20