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


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