quaternion_to_rpy.cpp
Go to the documentation of this file.
1 #include "quaternion_to_rpy.h"
2 #include <array>
3 #include <math.h>
4 
6 {
7  reset();
8 }
9 
11 {
12  _prev_roll = 0;
13  _prev_yaw = 0;
14  _prev_pitch = 0;
15  _roll_offset = 0;
16  _pitch_offset = 0;
17  _yaw_offset = 0;
18  _last_timestamp = std::numeric_limits<double>::lowest();
19 }
20 
22 {
23  auto& data_x = *_src_vector[0];
24  auto& data_y = *_src_vector[1];
25  auto& data_z = *_src_vector[2];
26  auto& data_w = *_src_vector[3];
27 
28  auto& data_roll = *_dst_vector[0];
29  auto& data_pitch = *_dst_vector[1];
30  auto& data_yaw = *_dst_vector[2];
31 
32  data_roll.setMaximumRangeX(data_x.maximumRangeX());
33  data_pitch.setMaximumRangeX(data_x.maximumRangeX());
34  data_yaw.setMaximumRangeX(data_x.maximumRangeX());
35 
36  data_roll.clear();
37  data_pitch.clear();
38  data_yaw.clear();
39 
40  if (data_x.size() == 0 || data_x.size() != data_y.size() ||
41  data_y.size() != data_z.size() || data_z.size() != data_w.size())
42  {
43  return;
44  }
45 
46  int pos = data_x.getIndexFromX(_last_timestamp);
47  size_t index = pos < 0 ? 0 : static_cast<size_t>(pos);
48 
49  while (index < data_x.size())
50  {
51  auto& point_x = data_x.at(index);
52  double timestamp = point_x.x;
53  double q_x = point_x.y;
54  double q_y = data_y.at(index).y;
55  double q_z = data_z.at(index).y;
56  double q_w = data_w.at(index).y;
57 
58  if (timestamp >= _last_timestamp)
59  {
60  std::array<double, 3> RPY;
61  calculateNextPoint(index, { q_x, q_y, q_z, q_w }, RPY);
62 
63  data_roll.pushBack({ timestamp, _scale * (RPY[0] + _roll_offset) });
64  data_pitch.pushBack({ timestamp, _scale * (RPY[1] + _pitch_offset) });
65  data_yaw.pushBack({ timestamp, _scale * (RPY[2] + _yaw_offset) });
66 
67  _last_timestamp = timestamp;
68  }
69  index++;
70  }
71 }
72 
74  const std::array<double, 4>& quat,
75  std::array<double, 3>& rpy)
76 {
77  double q_x = quat[0];
78  double q_y = quat[1];
79  double q_z = quat[2];
80  double q_w = quat[3];
81 
82  double quat_norm2 = (q_w * q_w) + (q_x * q_x) + (q_y * q_y) + (q_z * q_z);
83  if (std::abs(quat_norm2 - 1.0) > std::numeric_limits<double>::epsilon())
84  {
85  double mult = 1.0 / std::sqrt(quat_norm2);
86  q_x *= mult;
87  q_y *= mult;
88  q_z *= mult;
89  q_w *= mult;
90  }
91  double roll, pitch, yaw;
92  // roll (x-axis rotation)
93  double sinr_cosp = 2 * (q_w * q_x + q_y * q_z);
94  double cosr_cosp = 1 - 2 * (q_x * q_x + q_y * q_y);
95  roll = std::atan2(sinr_cosp, cosr_cosp);
96 
97  // pitch (y-axis rotation)
98  double sinp = 2 * (q_w * q_y - q_z * q_x);
99  if (std::abs(sinp) >= 1)
100  {
101  pitch = std::copysign(M_PI_2, sinp); // use 90 degrees if out of range
102  }
103  else
104  {
105  pitch = std::asin(sinp);
106  }
107  // yaw (z-axis rotation)
108  double siny_cosp = 2 * (q_w * q_z + q_x * q_y);
109  double cosy_cosp = 1 - 2 * (q_y * q_y + q_z * q_z);
110  yaw = std::atan2(siny_cosp, cosy_cosp);
111 
112  const double WRAP_ANGLE = M_PI * 2.0;
113  const double WRAP_THRESHOLD = M_PI * 1.95;
114 
115  //--------- wrap ------
116  if (index != 0 && _wrap)
117  {
118  if ((roll - _prev_roll) > WRAP_THRESHOLD)
119  {
120  _roll_offset -= WRAP_ANGLE;
121  }
122  else if ((_prev_roll - roll) > WRAP_THRESHOLD)
123  {
124  _roll_offset += WRAP_ANGLE;
125  }
126 
127  if ((pitch - _prev_pitch) > WRAP_THRESHOLD)
128  {
129  _pitch_offset -= WRAP_ANGLE;
130  }
131  else if ((_prev_pitch - pitch) > WRAP_THRESHOLD)
132  {
133  _pitch_offset += WRAP_ANGLE;
134  }
135 
136  if ((yaw - _prev_yaw) > WRAP_THRESHOLD)
137  {
138  _yaw_offset -= WRAP_ANGLE;
139  }
140  else if ((_prev_yaw - yaw) > WRAP_THRESHOLD)
141  {
142  _yaw_offset += WRAP_ANGLE;
143  }
144  }
145 
146  _prev_pitch = pitch;
147  _prev_roll = roll;
148  _prev_yaw = yaw;
149 
150  rpy = { roll, pitch, yaw };
151 }
QuaternionToRollPitchYaw::calculateNextPoint
void calculateNextPoint(size_t index, const std::array< double, 4 > &quat, std::array< double, 3 > &rpy)
Definition: quaternion_to_rpy.cpp:73
QuaternionToRollPitchYaw::_yaw_offset
double _yaw_offset
Definition: quaternion_to_rpy.h:49
QuaternionToRollPitchYaw::reset
void reset() override
Definition: quaternion_to_rpy.cpp:10
quaternion_to_rpy.h
PJ::TransformFunction::_src_vector
std::vector< const PlotData * > _src_vector
Definition: transform_function.h:78
M_PI
#define M_PI
Definition: qwt_math.h:56
QuaternionToRollPitchYaw::_prev_yaw
double _prev_yaw
Definition: quaternion_to_rpy.h:45
M_PI_2
#define M_PI_2
Definition: qwt_math.h:60
QuaternionToRollPitchYaw::_wrap
bool _wrap
Definition: quaternion_to_rpy.h:51
QuaternionToRollPitchYaw::_prev_pitch
double _prev_pitch
Definition: quaternion_to_rpy.h:46
QuaternionToRollPitchYaw::QuaternionToRollPitchYaw
QuaternionToRollPitchYaw()
Definition: quaternion_to_rpy.cpp:5
QuaternionToRollPitchYaw::_prev_roll
double _prev_roll
Definition: quaternion_to_rpy.h:44
QuaternionToRollPitchYaw::calculate
void calculate() override
Definition: quaternion_to_rpy.cpp:21
QuaternionToRollPitchYaw::_pitch_offset
double _pitch_offset
Definition: quaternion_to_rpy.h:48
QuaternionToRollPitchYaw::_last_timestamp
double _last_timestamp
Definition: quaternion_to_rpy.h:52
QuaternionToRollPitchYaw::_roll_offset
double _roll_offset
Definition: quaternion_to_rpy.h:47
QuaternionToRollPitchYaw::_scale
double _scale
Definition: quaternion_to_rpy.h:50
PJ::TransformFunction::_dst_vector
std::vector< PlotData * > _dst_vector
Definition: transform_function.h:79


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:45