Jpp 19.3.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JCompass.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JCOMPASS__
2#define __JDETECTOR__JCOMPASS__
3
4#include <istream>
5#include <ostream>
6#include <cmath>
7#include <limits>
8
9#include "JLang/JEquals.hh"
10#include "JDB/JAHRS.hh"
12#include "JIO/JSerialisable.hh"
15
16
17/**
18 * \author mdejong
19 */
20
21namespace JDETECTOR {}
22namespace JPP { using namespace JDETECTOR; }
23
24namespace JDETECTOR {
25
26 using JLANG::JEquals;
27 using JDATABASE::JAHRS;
31 using JIO::JReader;
32 using JIO::JWriter;
33
34
35 /**
36 * Data structure for compass in three dimensions.
37 *
38 * \image html compass.png "Definitions of yaw, pitch and roll."
39 *
40 * Note that the z-axis of the %KM3NeT reference system points up.\n
41 * So, the yaw angle, measured by the compass is measured from North to East
42 * (since in the compass system z-axis points down).\n
43 * Note also that the sign of the angle JCompass::pitch is maintained and
44 * the signs of the angles JCompass::yaw and JCompass::roll inverted
45 * when converting to/from a rotation matrix or quaternion.
46 *
47 * This class implements the JMATH::JMath and JLANG::JEquals interfaces.
48 */
49 class JCompass :
50 public JEquals<JCompass>
51 {
52 public:
53 /**
54 * Default constructor.
55 */
57 yaw (0.0),
58 pitch(0.0),
59 roll (0.0)
60 {}
61
62
63 /**
64 * Constructor.
65 *
66 * \param yaw yaw angle [rad]
67 * \param pitch pitch angle [rad]
68 * \param roll roll angle [rad]
69 */
70 JCompass(const double yaw,
71 const double pitch,
72 const double roll) :
73 yaw (yaw),
74 pitch(pitch),
75 roll (roll)
76 {}
77
78
79 /**
80 * Constructor.
81 *
82 * \param data AHRS data
83 * \param calibration AHRS calibration
84 */
85 JCompass(const JAHRS& data, const JAHRSCalibration& calibration)
86 {
87 using namespace std;
88 using namespace JPP;
89
90 double A0 = data.AHRS_A0;
91 double A1 = data.AHRS_A1;
92 double A2 = data.AHRS_A2;
93
94 double H0 = data.AHRS_H0;
95 double H1 = data.AHRS_H1;
96 double H2 = data.AHRS_H2;
97
98 A0 -= calibration.ACC_OFFSET_X;
99 A1 -= calibration.ACC_OFFSET_Y;
100 A2 -= calibration.ACC_OFFSET_Z;
101
102 JMatrix3D(calibration.ACC_ROT_XX, calibration.ACC_ROT_XY, calibration.ACC_ROT_XZ,
103 calibration.ACC_ROT_YX, calibration.ACC_ROT_YY, calibration.ACC_ROT_YZ,
104 calibration.ACC_ROT_ZX, calibration.ACC_ROT_ZY, calibration.ACC_ROT_ZZ).transform(A0, A1, A2);
105
106 H0 -= 0.5 * (calibration.MAG_XMIN + calibration.MAG_XMAX);
107 H1 -= 0.5 * (calibration.MAG_YMIN + calibration.MAG_YMAX);
108 H2 -= 0.5 * (calibration.MAG_ZMIN + calibration.MAG_ZMAX);
109
110 JMatrix3D(calibration.MAG_ROT_XX, calibration.MAG_ROT_XY, calibration.MAG_ROT_XZ,
111 calibration.MAG_ROT_YX, calibration.MAG_ROT_YY, calibration.MAG_ROT_YZ,
112 calibration.MAG_ROT_ZX, calibration.MAG_ROT_ZY, calibration.MAG_ROT_ZZ).transform(H0, H1, H2);
113
114 // invert axis for central-logic board being upside down in optical module
115
116 A0 = A0;
117 A1 = -A1;
118 A2 = -A2;
119
120 H0 = H0;
121 H1 = -H1;
122 H2 = -H2;
123
124 this->roll = atan2(-A1, -A2);
125 this->pitch = atan2(A0, sqrt(A1*A1 + A2*A2));
126 this->yaw = atan2(H2 * sin(roll) - H1 * cos(roll), H0 * cos(pitch) + H1 * sin(pitch) * sin(roll) + H2 * sin(pitch) * cos(roll));
127 }
128
129
130 /**
131 * Constructor.
132 *
133 * \param Q quaternion
134 */
136 yaw (0.0),
137 pitch(0.0),
138 roll (0.0)
139 {
140 using namespace std;
141
142 this->yaw = -atan2(2.0*(Q.getA()*Q.getD() + Q.getB()*Q.getC()), 1.0 - 2.0*(Q.getC()*Q.getC() + Q.getD()*Q.getD()));
143
144 const double sp = 2.0*(Q.getA()*Q.getC() - Q.getD()*Q.getB());
145
146 if (sp >= +1.0)
147 this->pitch = asin(+1.0);
148 else if (sp <= -1.0)
149 this->pitch = asin(-1.0);
150 else
151 this->pitch = asin(sp);
152
153 this->roll = -atan2(2.0*(Q.getA()*Q.getB() + Q.getC()*Q.getD()), 1.0 - 2.0*(Q.getB()*Q.getB() + Q.getC()*Q.getC()));
154 }
155
156
157 /**
158 * Get compass.
159 *
160 * \return this compass
161 */
162 const JCompass& getCompass() const
163 {
164 return static_cast<const JCompass&>(*this);
165 }
166
167
168 /**
169 * Set compass.
170 *
171 * \param compass compass
172 */
173 void setCompass(const JCompass& compass)
174 {
175 static_cast<JCompass&>(*this) = compass;
176 }
177
178
179 /**
180 * Get rotation matrix.
181 *
182 * \return rotation matrix
183 */
185 {
186 using namespace JPP;
187
188 const JRotation3D Rx = JRotation3X(-this->getRoll());
189 const JRotation3D Ry = JRotation3Y(+this->getPitch());
190 const JRotation3D Rz = JRotation3Z(-this->getYaw());
191
192 return (Rz * Ry * Rx);
193 }
194
195
196 /**
197 * Get quaternion.
198 *
199 * \return quaternion
200 */
202 {
203 using namespace JPP;
204
205 const double cy = cos(-0.5 * yaw);
206 const double sy = sin(-0.5 * yaw);
207 const double cp = cos(+0.5 * pitch);
208 const double sp = sin(+0.5 * pitch);
209 const double cr = cos(-0.5 * roll);
210 const double sr = sin(-0.5 * roll);
211
212 return JQuaternion3D(cr * cp * cy + sr * sp * sy,
213 sr * cp * cy - cr * sp * sy,
214 cr * sp * cy + sr * cp * sy,
215 cr * cp * sy - sr * sp * cy);
216 }
217
218
219 /**
220 * Get yaw compass.
221 *
222 * \return yaw compass
223 */
224 double getYaw() const
225 {
226 return yaw;
227 }
228
229
230 /**
231 * Get pitch compass.
232 *
233 * \return pitch compass
234 */
235 double getPitch() const
236 {
237 return pitch;
238 }
239
240
241 /**
242 * Get roll compass.
243 *
244 * \return roll compass
245 */
246 double getRoll() const
247 {
248 return roll;
249 }
250
251
252 /**
253 * Check equality.
254 *
255 * \param compass compass
256 * \param precision numerical precision
257 * \return true if compass's are equal; else false
258 */
259 bool equals(const JCompass& compass,
260 const double precision = std::numeric_limits<double>::min()) const
261 {
262 return (fabs(getYaw() - compass.getYaw()) <= precision &&
263 fabs(getPitch() - compass.getPitch()) <= precision &&
264 fabs(getRoll() - compass.getRoll()) <= precision);
265 }
266
267
268 /**
269 * Correct compass for magnetic declination and meridian convergence angle.
270 *
271 * \param declination magnetic declination [rad]
272 * \param meridian meridian convergence angle [rad]
273 */
274 void correct(const double declination, const double meridian)
275 {
276 this->yaw += declination;
277 this->yaw -= meridian;
278 }
279
280
281 /**
282 * Read compasss from input.
283 *
284 * \param in input stream
285 * \param compass compasss
286 * \return input stream
287 */
288 friend inline std::istream& operator>>(std::istream& in, JCompass& compass)
289 {
290 in >> compass.yaw >> compass.pitch >> compass.roll;
291
292 return in;
293 }
294
295
296 /**
297 * Write compasss to output.
298 *
299 * \param out output stream
300 * \param compass compass
301 * \return output stream
302 */
303 friend inline std::ostream& operator<<(std::ostream& out, const JCompass& compass)
304 {
305 out << compass.getYaw() << ' ' << compass.getPitch() << ' ' << compass.getRoll();
306
307 return out;
308 }
309
310
311 /**
312 * Read compasss from input.
313 *
314 * \param in reader
315 * \param compass compasss
316 * \return reader
317 */
318 friend inline JReader& operator>>(JReader& in, JCompass& compass)
319 {
320 in >> compass.yaw;
321 in >> compass.pitch;
322 in >> compass.roll;
323
324 return in;
325 }
326
327
328 /**
329 * Write compasss to output.
330 *
331 * \param out writer
332 * \param compass compasss
333 * \return writer
334 */
335 friend inline JWriter& operator<<(JWriter& out, const JCompass& compass)
336 {
337 out << compass.yaw;
338 out << compass.pitch;
339 out << compass.roll;
340
341 return out;
342 }
343
344
345 protected:
346 double yaw;
347 double pitch;
348 double roll;
349 };
350}
351
352#endif
Data structure for compass in three dimensions.
Definition JCompass.hh:51
double getYaw() const
Get yaw compass.
Definition JCompass.hh:224
const JCompass & getCompass() const
Get compass.
Definition JCompass.hh:162
friend std::istream & operator>>(std::istream &in, JCompass &compass)
Read compasss from input.
Definition JCompass.hh:288
void setCompass(const JCompass &compass)
Set compass.
Definition JCompass.hh:173
JCompass(const JQuaternion3D &Q)
Constructor.
Definition JCompass.hh:135
friend JWriter & operator<<(JWriter &out, const JCompass &compass)
Write compasss to output.
Definition JCompass.hh:335
bool equals(const JCompass &compass, const double precision=std::numeric_limits< double >::min()) const
Check equality.
Definition JCompass.hh:259
friend JReader & operator>>(JReader &in, JCompass &compass)
Read compasss from input.
Definition JCompass.hh:318
JCompass(const JAHRS &data, const JAHRSCalibration &calibration)
Constructor.
Definition JCompass.hh:85
JRotation3D getRotation() const
Get rotation matrix.
Definition JCompass.hh:184
friend std::ostream & operator<<(std::ostream &out, const JCompass &compass)
Write compasss to output.
Definition JCompass.hh:303
void correct(const double declination, const double meridian)
Correct compass for magnetic declination and meridian convergence angle.
Definition JCompass.hh:274
double getRoll() const
Get roll compass.
Definition JCompass.hh:246
JCompass(const double yaw, const double pitch, const double roll)
Constructor.
Definition JCompass.hh:70
JQuaternion3D getQuaternion() const
Get quaternion.
Definition JCompass.hh:201
JCompass()
Default constructor.
Definition JCompass.hh:56
double getPitch() const
Get pitch compass.
Definition JCompass.hh:235
Data structure for unit quaternion in three dimensions.
double getB() const
Get b value.
double getD() const
Get d value.
double getC() const
Get c value.
double getA() const
Get a value.
Rotation around X-axis.
Rotation around Y-axis.
Rotation around Z-axis.
Interface for binary input.
Interface for binary output.
void transform(double &__x, double &__y, double &__z) const
Transform.
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Calibration.
Definition JHead.hh:330
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84