cpm_display.cpp
Go to the documentation of this file.
1 
26 
27 #include <OgreBillboardSet.h>
28 #include <OgreManualObject.h>
29 #include <OgreMaterialManager.h>
30 #include <OgreSceneManager.h>
31 #include <OgreSceneNode.h>
32 #include <OgreTechnique.h>
33 
34 #include "rviz_common/display_context.hpp"
35 #include "rviz_common/frame_manager_iface.hpp"
36 #include "rviz_common/logging.hpp"
37 #include "rviz_common/properties/bool_property.hpp"
38 #include "rviz_common/properties/color_property.hpp"
39 #include "rviz_common/properties/float_property.hpp"
40 #include "rviz_common/transformation/transformation_manager.hpp"
41 
42 #include "rviz_common/properties/parse_color.hpp"
43 
44 namespace etsi_its_msgs {
45 namespace displays {
46 
48  // General Properties
50  new rviz_common::properties::FloatProperty("Timeout", 1.0f, "Time period (in s) in which CPM are valid and should be displayed (now - reference_time of CPM)", this);
51  buffer_timeout_->setMin(0);
52  bb_scale_ = new rviz_common::properties::FloatProperty("Scale", 1.0f, "Scale of objects", this);
53  bb_scale_->setMin(0.01);
54  color_property_ = new rviz_common::properties::ColorProperty("Color", QColor(25, 0, 255), "Object color", this);
55  show_meta_ =
56  new rviz_common::properties::BoolProperty("Metadata", true, "Show metadata as text next to objects", this);
58  new rviz_common::properties::ColorProperty("Color", QColor(25, 0, 255), "Text color", show_meta_);
59  char_height_ = new rviz_common::properties::FloatProperty("Scale", 0.5, "Scale of text", show_meta_);
60  show_station_id_ = new rviz_common::properties::BoolProperty("StationID", true, "Show StationID", show_meta_);
61  show_speed_ = new rviz_common::properties::BoolProperty("Speed", true, "Show speed", show_meta_);
62 }
63 
65  if (initialized()) {
66  scene_manager_->destroyManualObject(manual_object_);
67  }
68 }
69 
71  RTDClass::onInitialize();
72 
73  auto nodeAbstraction = context_->getRosNodeAbstraction().lock();
74  rviz_node_ = nodeAbstraction->get_raw_node();
75 
76  manual_object_ = scene_manager_->createManualObject();
77  manual_object_->setDynamic(true);
78  scene_node_->attachObject(manual_object_);
79 }
80 
82  RTDClass::reset();
83  manual_object_->clear();
84 }
85 
86 void CPMDisplay::processMessage(etsi_its_cpm_ts_msgs::msg::CollectivePerceptionMessage::ConstSharedPtr msg) {
87  rclcpp::Time now = rviz_node_->now();
88  uint64_t nanosecs = now.nanoseconds();
89  if (nanosecs == 0) {
90  setStatus(rviz_common::properties::StatusProperty::Warn, "Topic", "Message received before clock got a valid time");
91  return;
92  }
93 
94  CPMRenderObject cpm(*msg);
95 
96  if (!cpm.validateFloats()) {
97  setStatus(rviz_common::properties::StatusProperty::Error, "Topic",
98  "Message contained invalid floating point values (nans or infs)");
99  return;
100  }
101 
102  // Check if Station ID is already present in list
103  auto it = cpms_.find(cpm.getStationID());
104  if (it != cpms_.end()) {
105  it->second = cpm; // Key exists, update the value
106  } else {
107  cpms_.insert(std::make_pair(cpm.getStationID(), cpm));
108  }
109 
110  return;
111 }
112 
113 void CPMDisplay::update(float, float) {
114  // Check for outdated CPMs
115  for (auto it = cpms_.begin(); it != cpms_.end();) {
116  if (it->second.getAge(rviz_node_->now()) > buffer_timeout_->getFloat()) {
117  it = cpms_.erase(it);
118  } else {
119  ++it;
120  }
121  }
122  bboxs_.clear();
123  texts_.clear();
124  for (auto it = cpms_.begin(); it != cpms_.end(); ++it) {
125  CPMRenderObject cpm = it->second;
126  for (int i = 0; i < cpm.getNumberOfObjects(); i++) {
127  Ogre::Vector3 sn_position;
128  Ogre::Quaternion sn_orientation;
129  if (!context_->getFrameManager()->getTransform(cpm.getHeader(), sn_position, sn_orientation)) {
130  // Check if transform exists
131  setMissingTransformToFixedFrame(cpm.getHeader().frame_id);
132  return;
133  }
134  // We don't want to use the transform in sn_position and sn_orientation though, because they are only in float precision.
135  // So we get the transfrom manually from tf2:
136  std::string fixed_frame = fixed_frame_.toStdString();
137  geometry_msgs::msg::PoseStamped pose_origin;
138  pose_origin.header = cpm.getHeader();
139  pose_origin.pose.position.x = 0;
140  pose_origin.pose.position.y = 0;
141  pose_origin.pose.position.z = 0;
142  pose_origin.pose.orientation.w = 1;
143  pose_origin.pose.orientation.x = 0;
144  pose_origin.pose.orientation.y = 0;
145  pose_origin.pose.orientation.z = 0;
146  geometry_msgs::msg::PoseStamped pose_fixed_frame =
147  context_->getTransformationManager()->getCurrentTransformer()->transform(pose_origin, fixed_frame);
148  geometry_msgs::msg::TransformStamped transform_to_fixed_frame;
149  transform_to_fixed_frame.header = pose_fixed_frame.header;
150  transform_to_fixed_frame.transform.translation.x = pose_fixed_frame.pose.position.x;
151  transform_to_fixed_frame.transform.translation.y = pose_fixed_frame.pose.position.y;
152  transform_to_fixed_frame.transform.translation.z = pose_fixed_frame.pose.position.z;
153  transform_to_fixed_frame.transform.rotation = pose_fixed_frame.pose.orientation;
154 
155  setTransformOk();
156 
157  // set pose of scene node to origin (=fixed frame)!
158  scene_node_->setPosition(Ogre::Vector3{0.0f, 0.0f, 0.0f});
159  scene_node_->setOrientation(Ogre::Quaternion{1.0f, 0.0f, 0.0f, 0.0f});
160 
161  auto child_scene_node = scene_node_->createChildSceneNode();
162  // Set position of scene node to the position relative to the fixed frame
163  geometry_msgs::msg::Pose pose = cpm.getPoseOfObject(i);
164 
165  geometry_msgs::msg::Vector3 dimensions = cpm.getDimensionsOfObject(i);
166  tf2::doTransform(pose, pose, transform_to_fixed_frame);
167  Ogre::Vector3 position(pose.position.x, pose.position.y, pose.position.z);
168  Ogre::Quaternion orientation(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z);
169 
170  // set pose of child scene node of bounding-box
171  child_scene_node->setPosition(position);
172  child_scene_node->setOrientation(orientation);
173 
174  // create bounding-box object
175  std::shared_ptr<rviz_rendering::Shape> bbox =
176  std::make_shared<rviz_rendering::Shape>(rviz_rendering::Shape::Cube, scene_manager_, child_scene_node);
177 
178  // set the dimensions of bounding box
179  Ogre::Vector3 dims;
180  double scale = bb_scale_->getFloat();
181  dims.x = dimensions.x * scale;
182  dims.y = dimensions.y * scale;
183  dims.z = dimensions.z * scale;
184  bbox->setScale(dims);
185  // set the color of bounding box
186  Ogre::ColourValue bb_color = rviz_common::properties::qtToOgre(color_property_->getColor());
187  bbox->setColor(bb_color);
188  bboxs_.push_back(bbox);
189 
190  // Visualize meta-information as text
191  if (show_meta_->getBool()) {
192  std::string text;
193  if (show_station_id_->getBool()) {
194  text += "StationID: " + std::to_string(cpm.getStationID());
195  text += "\n";
196  }
197  if (show_speed_->getBool()) {
198  geometry_msgs::msg::Vector3 velocity = cpm.getVelocityOfObject(i);
199  //get magnitude of velocity
200  double speed = sqrt(pow(velocity.x, 2) + pow(velocity.y, 2) + pow(velocity.z, 2));
201  text += "Speed: " + std::to_string((int)(speed * 3.6)) + " km/h";
202  }
203  if (!text.size()) return;
204  std::shared_ptr<rviz_rendering::MovableText> text_render =
205  std::make_shared<rviz_rendering::MovableText>(text, "Liberation Sans", char_height_->getFloat());
206  double height = dims.z;
207  height += text_render->getBoundingRadius();
208  Ogre::Vector3 offs(0.0, 0.0, height);
209  // There is a bug in rviz_rendering::MovableText::setGlobalTranslation https://github.com/ros2/rviz/issues/974
210  text_render->setGlobalTranslation(offs);
211  Ogre::ColourValue text_color = rviz_common::properties::qtToOgre(text_color_property_->getColor());
212  text_render->setColor(text_color);
213  child_scene_node->attachObject(text_render.get());
214  texts_.push_back(text_render);
215  }
216  }
217  }
218 }
219 
220 } // namespace displays
221 } // namespace etsi_its_msgs
222 
223 #include <pluginlib/class_list_macros.hpp> // NOLINT
224 PLUGINLIB_EXPORT_CLASS(etsi_its_msgs::displays::CPMDisplay, rviz_common::Display)
etsi_its_msgs::displays::CPMDisplay::show_meta_
rviz_common::properties::BoolProperty * show_meta_
Definition: cpm_display.hpp:76
etsi_its_msgs::displays::CPMDisplay::bb_scale_
rviz_common::properties::FloatProperty * bb_scale_
Definition: cpm_display.hpp:77
etsi_its_msgs::displays::CPMRenderObject::getHeader
std_msgs::msg::Header getHeader()
Definition: cpm_render_object.cpp:68
cpm_display.hpp
etsi_its_msgs::displays::CPMRenderObject::getVelocityOfObject
geometry_msgs::msg::Vector3 getVelocityOfObject(const uint8_t idx)
Definition: cpm_render_object.cpp:78
etsi_its_msgs::displays::CPMDisplay::buffer_timeout_
rviz_common::properties::FloatProperty * buffer_timeout_
Definition: cpm_display.hpp:77
etsi_its_msgs::displays::CPMDisplay::texts_
std::vector< std::shared_ptr< rviz_rendering::MovableText > > texts_
Definition: cpm_display.hpp:83
etsi_its_msgs::displays::CPMDisplay::cpms_
std::unordered_map< int, CPMRenderObject > cpms_
Definition: cpm_display.hpp:80
etsi_its_msgs::displays::CPMDisplay::char_height_
rviz_common::properties::FloatProperty * char_height_
Definition: cpm_display.hpp:77
etsi_its_msgs::displays::CPMDisplay
Displays an etsi_its_cpm_msgs::CollectivePerceptionMessage.
Definition: cpm_display.hpp:56
etsi_its_msgs::displays::CPMDisplay::processMessage
void processMessage(etsi_its_cpm_ts_msgs::msg::CollectivePerceptionMessage::ConstSharedPtr msg) override
Definition: cpm_display.cpp:86
etsi_its_msgs::displays::CPMRenderObject::getNumberOfObjects
uint8_t getNumberOfObjects()
Definition: cpm_render_object.cpp:80
etsi_its_msgs::displays::CPMDisplay::color_property_
rviz_common::properties::ColorProperty * color_property_
Definition: cpm_display.hpp:78
etsi_its_msgs::displays::CPMRenderObject::getStationID
uint32_t getStationID()
Definition: cpm_render_object.cpp:70
etsi_its_msgs::displays::CPMDisplay::show_speed_
rviz_common::properties::BoolProperty * show_speed_
Definition: cpm_display.hpp:76
etsi_its_msgs::displays::CPMRenderObject::validateFloats
bool validateFloats()
This function validates all float variables that are part of a CPMRenderObject.
Definition: cpm_render_object.cpp:56
etsi_its_msgs::displays::CPMDisplay::bboxs_
std::vector< std::shared_ptr< rviz_rendering::Shape > > bboxs_
Definition: cpm_display.hpp:82
etsi_its_msgs::displays::CPMDisplay::show_station_id_
rviz_common::properties::BoolProperty * show_station_id_
Definition: cpm_display.hpp:76
etsi_its_msgs::displays::CPMDisplay::update
void update(float wall_dt, float ros_dt) override
Definition: cpm_display.cpp:113
etsi_its_msgs::displays::CPMDisplay::CPMDisplay
CPMDisplay()
Definition: cpm_display.cpp:47
etsi_its_msgs::displays::CPMDisplay::manual_object_
Ogre::ManualObject * manual_object_
Definition: cpm_display.hpp:71
etsi_its_msgs::displays::CPMDisplay::text_color_property_
rviz_common::properties::ColorProperty * text_color_property_
Definition: cpm_display.hpp:78
etsi_its_msgs::displays::CPMRenderObject
This class is used to render a CPM object in RViz.
Definition: cpm_render_object.hpp:46
etsi_its_msgs::displays::CPMDisplay::rviz_node_
rclcpp::Node::SharedPtr rviz_node_
Definition: cpm_display.hpp:73
etsi_its_msgs::displays::CPMDisplay::onInitialize
void onInitialize() override
Definition: cpm_display.cpp:70
etsi_its_msgs::displays::CPMDisplay::reset
void reset() override
Definition: cpm_display.cpp:81
etsi_its_msgs::displays::CPMRenderObject::getDimensionsOfObject
geometry_msgs::msg::Vector3 getDimensionsOfObject(const uint8_t idx)
Definition: cpm_render_object.cpp:76
etsi_its_msgs
Definition: cam_display.hpp:51
etsi_its_msgs::displays::CPMDisplay::~CPMDisplay
~CPMDisplay() override
Definition: cpm_display.cpp:64
etsi_its_msgs::displays::CPMRenderObject::getPoseOfObject
geometry_msgs::msg::Pose getPoseOfObject(const uint8_t idx)
Definition: cpm_render_object.cpp:74


etsi_its_rviz_plugins
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:29:25