ros2_parsers/quaternion_msg.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <geometry_msgs/msg/quaternion.hpp>
4 #include "ros2_parser.h"
5 
6 class QuaternionMsgParser : public BuiltinMessageParser<geometry_msgs::msg::Quaternion>
7 {
8 public:
9  QuaternionMsgParser(const std::string& topic_name, PJ::PlotDataMapRef& plot_data)
10  : BuiltinMessageParser<geometry_msgs::msg::Quaternion>(topic_name, plot_data)
11  {
12  }
13 
14  void parseMessageImpl(const geometry_msgs::msg::Quaternion& msg, double& timestamp) override
15  {
16  if( !_initialized )
17  {
18  _initialized = true;
19  _data.push_back(&getSeries(_topic_name + "/x"));
20  _data.push_back(&getSeries(_topic_name + "/y"));
21  _data.push_back(&getSeries(_topic_name + "/z"));
22  _data.push_back(&getSeries(_topic_name + "/w"));
23 
24  _data.push_back(&getSeries(_topic_name + "/roll_deg"));
25  _data.push_back(&getSeries(_topic_name + "/pitch_deg"));
26  _data.push_back(&getSeries(_topic_name + "/yaw_deg"));
27  }
28  _data[0]->pushBack({ timestamp, msg.x });
29  _data[1]->pushBack({ timestamp, msg.y });
30  _data[2]->pushBack({ timestamp, msg.z });
31  _data[3]->pushBack({ timestamp, msg.w });
32 
33  //-----------------------------
34  auto q = msg;
35  double quat_norm2 = (q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z);
36  if (std::abs(quat_norm2 - 1.0) > std::numeric_limits<double>::epsilon())
37  {
38  double mult = 1.0 / std::sqrt(quat_norm2);
39  q.x *= mult;
40  q.y *= mult;
41  q.z *= mult;
42  q.w *= mult;
43  }
44 
45  double roll, pitch, yaw;
46  // roll (x-axis rotation)
47  double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
48  double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
49  roll = std::atan2(sinr_cosp, cosr_cosp);
50 
51  // pitch (y-axis rotation)
52  double sinp = 2 * (q.w * q.y - q.z * q.x);
53  if (std::abs(sinp) >= 1)
54  {
55  pitch = std::copysign(M_PI_2, sinp); // use 90 degrees if out of range
56  }
57  else
58  {
59  pitch = std::asin(sinp);
60  }
61 
62  // yaw (z-axis rotation)
63  double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
64  double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
65  yaw = std::atan2(siny_cosp, cosy_cosp);
66 
67  const double RAD_TO_DEG = 180.0 / M_PI;
68 
69  _data[4]->pushBack({ timestamp, RAD_TO_DEG * roll });
70  _data[5]->pushBack({ timestamp, RAD_TO_DEG * pitch });
71  _data[6]->pushBack({ timestamp, RAD_TO_DEG * yaw });
72  }
73 
74 private:
75  std::vector<PJ::PlotData*> _data;
76  bool _initialized = false;
77 };
QuaternionMsgParser(const std::string &topic_name, PJ::PlotDataMapRef &plot_data)
#define M_PI_2
PJ::PlotData & getSeries(const std::string &key)
void parseMessageImpl(const geometry_msgs::msg::Quaternion &msg, double &timestamp) override
constexpr double RAD_TO_DEG
#define M_PI
std::string _topic_name
std::vector< PJ::PlotData * > _data
msg


plotjuggler_ros
Author(s): Davide Faconti
autogenerated on Fri Jun 23 2023 02:28:03