Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
mobilitypath_visualizer::MobilityPathVisualizer Class Reference

#include <mobilitypath_visualizer.hpp>

Inheritance diagram for mobilitypath_visualizer::MobilityPathVisualizer:
Inheritance graph
Collaboration diagram for mobilitypath_visualizer::MobilityPathVisualizer:
Collaboration graph

Public Member Functions

 MobilityPathVisualizer (const rclcpp::NodeOptions &)
 Constructor. More...
 
visualization_msgs::msg::MarkerArray composeVisualizationMarker (const carma_v2x_msgs::msg::MobilityPath &msg, const MarkerColor &color)
 Compose a visualization marker for mobilitypath messages. More...
 
geometry_msgs::msg::Point ECEFToMapPoint (const carma_v2x_msgs::msg::LocationECEF &ecef_point) const
 Accepts ECEF point in cm to convert to a point in map in meters. More...
 
visualization_msgs::msg::MarkerArray composeLabelMarker (const visualization_msgs::msg::MarkerArray &host_marker, const std::vector< visualization_msgs::msg::MarkerArray > &cav_markers) const
 Compose a label marker that displays whether if any of the cav's path cross with that of host (respective points are within 1 meter) More...
 
std::vector< visualization_msgs::msg::MarkerArray > matchTrajectoryTimestamps (const visualization_msgs::msg::MarkerArray &host_marker, const std::vector< visualization_msgs::msg::MarkerArray > &cav_markers) const
 Matches timestamps of CAV's individual points of cav_markers to that of host_marker and interpolates their points using the speed between points. More...
 
void georeferenceCallback (std_msgs::msg::String::UniquePtr msg)
 Callback for map projection string to define lat/lon -> map conversion. More...
 
carma_ros2_utils::CallbackReturn handle_on_configure (const rclcpp_lifecycle::State &)
 
carma_ros2_utils::CallbackReturn handle_on_activate (const rclcpp_lifecycle::State &)
 

Private Member Functions

void initialize ()
 
void callbackMobilityPath (carma_v2x_msgs::msg::MobilityPath::UniquePtr msg)
 
void timer_callback ()
 

Private Attributes

carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > host_marker_pub_
 
carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > cav_marker_pub_
 
carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > label_marker_pub_
 
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityPath > host_mob_path_sub_
 
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityPath > cav_mob_path_sub_
 
carma_ros2_utils::SubPtr< std_msgs::msg::String > georeference_sub_
 
std::string georeference_ {""}
 
std::shared_ptr< lanelet::projection::LocalFrameProjector > map_projector_
 
Config config_
 
rclcpp::TimerBase::SharedPtr timer_
 
std::unordered_map< std::string, carma_v2x_msgs::msg::MobilityPath > latest_cav_mob_path_msg_
 
visualization_msgs::msg::MarkerArray host_marker_
 
std::vector< visualization_msgs::msg::MarkerArray > cav_markers_
 
visualization_msgs::msg::MarkerArray label_marker_
 
std::unordered_map< std::string, size_t > prev_marker_list_size_
 
bool host_marker_received_ = false
 

Detailed Description

Definition at line 47 of file mobilitypath_visualizer.hpp.

Constructor & Destructor Documentation

◆ MobilityPathVisualizer()

mobilitypath_visualizer::MobilityPathVisualizer::MobilityPathVisualizer ( const rclcpp::NodeOptions &  options)

Constructor.

Definition at line 36 of file mobilitypath_visualizer.cpp.

37 : carma_ros2_utils::CarmaLifecycleNode(options)
38 {
39 // Create initial config
40 config_ = Config();
41
42 // Declare parameters
43 config_.timer_cb_rate = declare_parameter<int>("timer_cb_rate", config_.timer_cb_rate);
44 config_.x = declare_parameter<double>("x", config_.x);
45 config_.y = declare_parameter<double>("y", config_.y);
46 config_.z = declare_parameter<double>("z", config_.z);
47 config_.t = declare_parameter<double>("t", config_.t);
48 config_.host_id = declare_parameter<std::string>("vehicle_id", config_.host_id);
49 }

References config_, mobilitypath_visualizer::Config::host_id, mobilitypath_visualizer::Config::t, mobilitypath_visualizer::Config::timer_cb_rate, mobilitypath_visualizer::Config::x, mobilitypath_visualizer::Config::y, and mobilitypath_visualizer::Config::z.

Member Function Documentation

◆ callbackMobilityPath()

void mobilitypath_visualizer::MobilityPathVisualizer::callbackMobilityPath ( carma_v2x_msgs::msg::MobilityPath::UniquePtr  msg)
private

Definition at line 128 of file mobilitypath_visualizer.cpp.

129 {
130
131 RCLCPP_DEBUG_STREAM(get_logger(), "Received a msg from sender: " << msg->m_header.sender_id << ", and plan id:" << msg->m_header.plan_id << ", for receiver:"
132 << msg->m_header.recipient_id << ", time:" << msg->m_header.timestamp << ", at now: " << std::to_string(this->now().seconds()));
133
134 if (latest_cav_mob_path_msg_.find(msg->m_header.sender_id) != latest_cav_mob_path_msg_.end() &&
135 msg->m_header.plan_id.compare(latest_cav_mob_path_msg_[msg->m_header.sender_id].m_header.plan_id) == 0 &&
136 msg->m_header.timestamp == latest_cav_mob_path_msg_[msg->m_header.sender_id].m_header.timestamp)
137 {
138 RCLCPP_DEBUG_STREAM(get_logger(), "Already received this plan id:" << msg->m_header.plan_id << "from sender_id: " << msg->m_header.sender_id);
139 return;
140 }
141 latest_cav_mob_path_msg_[msg->m_header.sender_id] = *msg;
142
143 if (!map_projector_) {
144 RCLCPP_ERROR(get_logger(), "Cannot visualize mobility path as map projection not yet available");
145 return;
146 }
147
148 if (msg->m_header.timestamp == 0) //if empty
149 {
150 host_marker_received_ = false;
151 return;
152 }
153
154 MarkerColor cav_color;
155 if (msg->m_header.sender_id.compare(config_.host_id) == 0)
156 {
157 cav_color.green = 1.0;
158
161
162 RCLCPP_DEBUG_STREAM(get_logger(), "Composed host marker successfuly!");
163 }
164 else
165 {
166
167 cav_color.blue = 1.0;
168 cav_markers_.push_back(composeVisualizationMarker(*msg,cav_color));
169
170 RCLCPP_DEBUG_STREAM(get_logger(), "Composed cav marker successfuly! with sender_id: " << msg->m_header.sender_id);
171 }
172
173 }
std::unordered_map< std::string, carma_v2x_msgs::msg::MobilityPath > latest_cav_mob_path_msg_
std::vector< visualization_msgs::msg::MarkerArray > cav_markers_
visualization_msgs::msg::MarkerArray composeVisualizationMarker(const carma_v2x_msgs::msg::MobilityPath &msg, const MarkerColor &color)
Compose a visualization marker for mobilitypath messages.
std::shared_ptr< lanelet::projection::LocalFrameProjector > map_projector_
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21

References mobilitypath_visualizer::MarkerColor::blue, cav_markers_, composeVisualizationMarker(), config_, mobilitypath_visualizer::MarkerColor::green, mobilitypath_visualizer::Config::host_id, host_marker_, host_marker_received_, latest_cav_mob_path_msg_, map_projector_, and carma_cooperative_perception::to_string().

Referenced by handle_on_configure().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ composeLabelMarker()

visualization_msgs::msg::MarkerArray mobilitypath_visualizer::MobilityPathVisualizer::composeLabelMarker ( const visualization_msgs::msg::MarkerArray &  host_marker,
const std::vector< visualization_msgs::msg::MarkerArray > &  cav_markers 
) const

Compose a label marker that displays whether if any of the cav's path cross with that of host (respective points are within 1 meter)

Parameters
host_markerHost marker's visualization marker as arrow type
cav_markersOther CAV marker's visualization markers as arrow type
Note
This function assumes that every point's timestamp in marker is matched
Returns
Visualization Marker in text type

Definition at line 280 of file mobilitypath_visualizer.cpp.

281 {
282 visualization_msgs::msg::MarkerArray output;
283 visualization_msgs::msg::Marker marker;
284 marker.header.frame_id = "map";
285 marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
286 marker.action = visualization_msgs::msg::Marker::ADD;
287 marker.ns = "mobilitypath_visualizer";
288
289 marker.scale.x = config_.x;
290 marker.scale.y = config_.y;
291 marker.scale.z = config_.z;
292 marker.color.r = 1.0;
293 marker.color.g = 1.0;
294 marker.color.b = 1.0;
295 marker.color.a = 1.0;
296 marker.frame_locked = true;
297 marker.lifetime = builtin_interfaces::msg::Duration((rclcpp::Duration(config_.t * 1e9)));
298
299 for (auto const& cav_marker: cav_markers)
300 {
301 size_t idx = 0;
302 while(idx < host_marker.markers.size() && idx < cav_marker.markers.size())
303 {
304 if (compute_2d_distance(cav_marker.markers[idx].points[0], host_marker.markers[idx].points[0]) <= 1.0) // within 1 meter
305 {
306 marker.id = (int32_t)idx;
307 marker.header.stamp = host_marker.markers[idx].header.stamp;
308 marker.pose.position.x = cav_marker.markers[idx].points[0].x;
309 marker.pose.position.y = cav_marker.markers[idx].points[0].y;
310 marker.pose.position.z = cav_marker.markers[idx].points[0].z;
311 marker.pose.orientation.w = 1.0f;
312
313 std::string collision_time = std::to_string((rclcpp::Time(cav_marker.markers[idx].header.stamp) - rclcpp::Time(host_marker.markers[0].header.stamp)).seconds());
314 collision_time = collision_time.substr(0,collision_time.size() - 4); //reduce precision to 2 decimals
315 marker.text = "Collision in " + collision_time + "s!";
316
317 output.markers.push_back(marker);
318 }
319 idx++;
320 }
321
322 if (compute_2d_distance(cav_marker.markers[idx-1].points[1], host_marker.markers[idx-1].points[1]) <= 1.0) // within 1 meter
323 {
324 // last point
325 marker.id = (int32_t)idx;
326 marker.header.stamp = host_marker.markers[idx-1].header.stamp;
327 marker.pose.position.x = cav_marker.markers[idx-1].points[1].x;
328 marker.pose.position.y = cav_marker.markers[idx-1].points[1].y;
329 marker.pose.position.z = cav_marker.markers[idx-1].points[1].z;
330
331 rclcpp::Time cav_marker_stamp(cav_marker.markers[idx-1].header.stamp);
332 rclcpp::Time host_marker_stamp(host_marker.markers[0].header.stamp);
333 rclcpp::Duration duration = cav_marker_stamp - host_marker_stamp;
334 std::string collision_time = std::to_string(duration.seconds());
335 collision_time = collision_time.substr(0,collision_time.size() - 4); //reduce precision to 2 decimals
336 marker.text = "Collision in " + collision_time + "s!";
337 output.markers.push_back(marker);
338 }
339 }
340
341 return output;
342 }
double compute_2d_distance(const geometry_msgs::msg::Point &pt1, const geometry_msgs::msg::Point &pt2)

References mobilitypath_visualizer::anonymous_namespace{mobilitypath_visualizer.cpp}::compute_2d_distance(), config_, mobilitypath_visualizer::Config::t, carma_cooperative_perception::to_string(), mobilitypath_visualizer::Config::x, mobilitypath_visualizer::Config::y, and mobilitypath_visualizer::Config::z.

Referenced by timer_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ composeVisualizationMarker()

visualization_msgs::msg::MarkerArray mobilitypath_visualizer::MobilityPathVisualizer::composeVisualizationMarker ( const carma_v2x_msgs::msg::MobilityPath &  msg,
const MarkerColor color 
)

Compose a visualization marker for mobilitypath messages.

Parameters
msgMobiliy path message
colorcolor to visualize the marker, for example host car should have different color than other car
Returns
Visualization Marker in arrow type

Definition at line 175 of file mobilitypath_visualizer.cpp.

176 {
177 visualization_msgs::msg::MarkerArray output;
178
179 visualization_msgs::msg::Marker marker;
180 marker.header.frame_id = "map";
181
182 rclcpp::Time marker_header_stamp = rclcpp::Time((msg.m_header.timestamp/1000.0) * 1e9);
183 marker.header.stamp = builtin_interfaces::msg::Time(marker_header_stamp);
184 marker.type = visualization_msgs::msg::Marker::ARROW;
185 marker.action = visualization_msgs::msg::Marker::ADD;
186 marker.ns = "mobilitypath_visualizer";
187
188 marker.scale.x = config_.x;
189 marker.scale.y = config_.y;
190 marker.scale.z = config_.z;
191 marker.frame_locked = true;
192
193 marker.color.r = (float)color.red;
194 marker.color.g = (float)color.green;
195 marker.color.b = (float)color.blue;
196 marker.color.a = 1.0f;
197
198 size_t count = std::max(prev_marker_list_size_[msg.m_header.sender_id], msg.trajectory.offsets.size());
199
200 auto curr_location_msg = msg; //variable to update on each iteration as offsets are measured since last traj point
201
202 marker.id = 0;
203 geometry_msgs::msg::Point arrow_start;
204 geometry_msgs::msg::Point arrow_end;
205
206 if (msg.trajectory.offsets.empty())
207 {
208 marker.action = visualization_msgs::msg::Marker::DELETE;
209 }
210 else
211 {
212 RCLCPP_DEBUG_STREAM(get_logger(), "ECEF point x: " << curr_location_msg.trajectory.location.ecef_x << ", y:" << curr_location_msg.trajectory.location.ecef_y);
213 arrow_start = ECEFToMapPoint(curr_location_msg.trajectory.location); //also convert from cm to m
214 RCLCPP_DEBUG_STREAM(get_logger(), "Map point x: " << arrow_start.x << ", y:" << arrow_start.y);
215
216 curr_location_msg.trajectory.location.ecef_x += + msg.trajectory.offsets[0].offset_x;
217 curr_location_msg.trajectory.location.ecef_y += + msg.trajectory.offsets[0].offset_y;
218 curr_location_msg.trajectory.location.ecef_z += + msg.trajectory.offsets[0].offset_z;
219 arrow_end = ECEFToMapPoint(curr_location_msg.trajectory.location); //also convert from cm to m
220
221 marker.points.push_back(arrow_start);
222 marker.points.push_back(arrow_end);
223 }
224
225 output.markers.push_back(marker);
226
227 for (size_t i = 1; i < count; i++) // start id = 1 to comply with arrow marker type
228 {
229 marker.id = i;
230 rclcpp::Time marker_cur_time(marker.header.stamp);
231 //Update time by 0.1s
232 rclcpp::Time updated_time = marker_cur_time + rclcpp::Duration(0.1 * 1e9);
233 marker.header.stamp = builtin_interfaces::msg::Time(updated_time);
234
235 if (i >= msg.trajectory.offsets.size()) { // If we need to delete previous points
236 marker.action = visualization_msgs::msg::Marker::DELETE;
237 output.markers.push_back(marker);
238 continue;
239 }
240
241 marker.points = {};
242 RCLCPP_DEBUG_STREAM(get_logger(), "ECEF Point- DEBUG x: " << curr_location_msg.trajectory.location.ecef_x << ", y:" << curr_location_msg.trajectory.location.ecef_y);
243 arrow_start = ECEFToMapPoint(curr_location_msg.trajectory.location); //convert from cm to m
244 RCLCPP_DEBUG_STREAM(get_logger(), "Map Point- DEBUG x: " << arrow_start.x << ", y:" << arrow_start.y);
245
246 curr_location_msg.trajectory.location.ecef_x += msg.trajectory.offsets[i].offset_x;
247 curr_location_msg.trajectory.location.ecef_y += msg.trajectory.offsets[i].offset_y;
248 curr_location_msg.trajectory.location.ecef_z += msg.trajectory.offsets[i].offset_z;
249 arrow_end = ECEFToMapPoint(curr_location_msg.trajectory.location);
250
251 marker.points.push_back(arrow_start);
252 marker.points.push_back(arrow_end);
253
254 output.markers.push_back(marker);
255 }
256 RCLCPP_DEBUG_STREAM(get_logger(), "Last ECEF Point- DEBUG x: " << curr_location_msg.trajectory.location.ecef_x << ", y:" << curr_location_msg.trajectory.location.ecef_y);
257 RCLCPP_DEBUG_STREAM(get_logger(), "Last Map Point- DEBUG x: " << arrow_end.x << ", y:" << arrow_end.y);
258 prev_marker_list_size_[msg.m_header.sender_id] = msg.trajectory.offsets.size();
259
260 return output;
261 }
std::unordered_map< std::string, size_t > prev_marker_list_size_
geometry_msgs::msg::Point ECEFToMapPoint(const carma_v2x_msgs::msg::LocationECEF &ecef_point) const
Accepts ECEF point in cm to convert to a point in map in meters.

References mobilitypath_visualizer::MarkerColor::blue, config_, ECEFToMapPoint(), mobilitypath_visualizer::MarkerColor::green, process_bag::i, prev_marker_list_size_, mobilitypath_visualizer::MarkerColor::red, mobilitypath_visualizer::Config::x, mobilitypath_visualizer::Config::y, and mobilitypath_visualizer::Config::z.

Referenced by callbackMobilityPath().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ECEFToMapPoint()

geometry_msgs::msg::Point mobilitypath_visualizer::MobilityPathVisualizer::ECEFToMapPoint ( const carma_v2x_msgs::msg::LocationECEF &  ecef_point) const

Accepts ECEF point in cm to convert to a point in map in meters.

Parameters
ecef_pointECEF point to convert in cm
Returns
Point in map

Definition at line 263 of file mobilitypath_visualizer.cpp.

264 {
265
266 if (!map_projector_) {
267 throw std::invalid_argument("No map projector available for ecef conversion");
268 }
269 geometry_msgs::msg::Point output;
270
271 lanelet::BasicPoint3d map_point = map_projector_->projectECEF( { (double)ecef_point.ecef_x/100.0, (double)ecef_point.ecef_y/100.0, (double)ecef_point.ecef_z/100.0 } , -1);
272 output.x = map_point.x();
273 output.y = map_point.y();
274 output.z = map_point.z();
275
276 return output;
277 }

References map_projector_.

Referenced by composeVisualizationMarker().

Here is the caller graph for this function:

◆ georeferenceCallback()

void mobilitypath_visualizer::MobilityPathVisualizer::georeferenceCallback ( std_msgs::msg::String::UniquePtr  msg)

Callback for map projection string to define lat/lon -> map conversion.

msg The proj string defining the projection.

Definition at line 119 of file mobilitypath_visualizer.cpp.

120 {
121 if (georeference_ != msg->data)
122 {
123 georeference_ = msg->data;
124 map_projector_ = std::make_shared<lanelet::projection::LocalFrameProjector>(msg->data.c_str()); // Build projector from proj string
125 }
126 }

References georeference_, and map_projector_.

Referenced by handle_on_configure().

Here is the caller graph for this function:

◆ handle_on_activate()

carma_ros2_utils::CallbackReturn mobilitypath_visualizer::MobilityPathVisualizer::handle_on_activate ( const rclcpp_lifecycle::State &  )

Definition at line 87 of file mobilitypath_visualizer.cpp.

87 {
88
89 //Setup timer
90 timer_ = create_timer(get_clock(), std::chrono::milliseconds(config_.timer_cb_rate),
92
93 return CallbackReturn::SUCCESS;
94 }

References config_, timer_, timer_callback(), and mobilitypath_visualizer::Config::timer_cb_rate.

Here is the call graph for this function:

◆ handle_on_configure()

carma_ros2_utils::CallbackReturn mobilitypath_visualizer::MobilityPathVisualizer::handle_on_configure ( const rclcpp_lifecycle::State &  )

Definition at line 52 of file mobilitypath_visualizer.cpp.

53 {
54 //Reset Config
55 config_ = Config();
56
57 //Load parameters
58 get_parameter<int>("timer_cb_rate", config_.timer_cb_rate);
59 get_parameter<double>("x", config_.x);
60 get_parameter<double>("y", config_.y);
61 get_parameter<double>("z", config_.z);
62 get_parameter<double>("t", config_.t);
63
64 get_parameter("vehicle_id", config_.host_id);
65
66 RCLCPP_INFO_STREAM(get_logger(), "Loaded params "<< config_);
67
68 // init publishers
69 host_marker_pub_ = create_publisher<visualization_msgs::msg::MarkerArray>("host_marker", 1);
70 cav_marker_pub_ = create_publisher<visualization_msgs::msg::MarkerArray>("cav_marker", 1);
71 label_marker_pub_ = create_publisher<visualization_msgs::msg::MarkerArray>("label_marker", 1);
72
73 // init subscribers
74 host_mob_path_sub_ = create_subscription<carma_v2x_msgs::msg::MobilityPath>("mobility_path_msg", 10,
75 std::bind(&MobilityPathVisualizer::callbackMobilityPath, this, std_ph::_1));
76
77 cav_mob_path_sub_ = create_subscription<carma_v2x_msgs::msg::MobilityPath>("incoming_mobility_path", 10,
78 std::bind(&MobilityPathVisualizer::callbackMobilityPath, this, std_ph::_1));
79
80 georeference_sub_ = create_subscription<std_msgs::msg::String>("georeference", 10,
81 std::bind(&MobilityPathVisualizer::georeferenceCallback, this, std_ph::_1));
82
83 // Return success if everthing initialized successfully
84 return CallbackReturn::SUCCESS;
85 }
carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > label_marker_pub_
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityPath > cav_mob_path_sub_
carma_ros2_utils::SubPtr< std_msgs::msg::String > georeference_sub_
carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > cav_marker_pub_
void callbackMobilityPath(carma_v2x_msgs::msg::MobilityPath::UniquePtr msg)
void georeferenceCallback(std_msgs::msg::String::UniquePtr msg)
Callback for map projection string to define lat/lon -> map conversion.
carma_ros2_utils::PubPtr< visualization_msgs::msg::MarkerArray > host_marker_pub_
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityPath > host_mob_path_sub_

References callbackMobilityPath(), cav_marker_pub_, cav_mob_path_sub_, config_, georeference_sub_, georeferenceCallback(), mobilitypath_visualizer::Config::host_id, host_marker_pub_, host_mob_path_sub_, label_marker_pub_, mobilitypath_visualizer::Config::t, mobilitypath_visualizer::Config::timer_cb_rate, mobilitypath_visualizer::Config::x, mobilitypath_visualizer::Config::y, and mobilitypath_visualizer::Config::z.

Here is the call graph for this function:

◆ initialize()

void mobilitypath_visualizer::MobilityPathVisualizer::initialize ( )
private

◆ matchTrajectoryTimestamps()

std::vector< visualization_msgs::msg::MarkerArray > mobilitypath_visualizer::MobilityPathVisualizer::matchTrajectoryTimestamps ( const visualization_msgs::msg::MarkerArray &  host_marker,
const std::vector< visualization_msgs::msg::MarkerArray > &  cav_markers 
) const

Matches timestamps of CAV's individual points of cav_markers to that of host_marker and interpolates their points using the speed between points.

Parameters
host_markerHost marker's visualization marker as arrow type
cav_markersOther CAV marker's visualization markers as arrow type
Note
This function assumes 0.1s between any of the points. It also drops CAV markers that start later than the first point in host_marker does. This is acceptable as the host is publishing in 0.1s and we don't need to visualize points in the future. It extrapolates the last point CAV's just to conform with
Returns
Synchronized CAV markers

Definition at line 344 of file mobilitypath_visualizer.cpp.

346 {
347 if (host_marker.markers.empty() || host_marker.markers[0].action == visualization_msgs::msg::Marker::DELETE)
348 return cav_markers;
349
350 std::vector<visualization_msgs::msg::MarkerArray> synchronized_output;
351 for (auto const& curr_cav: cav_markers)
352 {
353 visualization_msgs::msg::MarkerArray synchronized_marker_array;
354 signed int curr_idx = 0;
355 double time_step = 0.1;
356 // although it is very rare to reach here
357 // we do not need to visualize other car that starts "in the future", so skip
358
359 if (rclcpp::Time(curr_cav.markers[0].header.stamp) > rclcpp::Time(host_marker.markers[0].header.stamp) ||
360 curr_cav.markers[0].action == visualization_msgs::msg::Marker::DELETE)
361 {
362 continue;
363 }
364 // this marker is outdated, drop
365
366 rclcpp::Time curr_cav_marker_stamp(curr_cav.markers.back().header.stamp);
367 rclcpp::Time host_marker_stamp(host_marker.markers[0].header.stamp);
368
369
370 if (curr_cav_marker_stamp + rclcpp::Duration(time_step * 1e9) < host_marker_stamp){
371 continue;
372 }
373
374 // skip points until the idx to start interpolating
375 while (curr_idx < curr_cav.markers.size() && rclcpp::Time(curr_cav.markers[curr_idx].header.stamp) <= rclcpp::Time(host_marker.markers[0].header.stamp))
376 {
377 curr_idx++;
378 }
379
380 curr_idx -= 1; // carma_v2x_msg stamp is before that of host now
381 // interpolate position to match the starting time (dt < time_step)
382
383 if (curr_idx < 0 )
384 curr_idx = 0;
385
386 double dt = (rclcpp::Time(host_marker.markers[0].header.stamp) - rclcpp::Time(curr_cav.markers[curr_idx].header.stamp)).seconds();
387
388 rclcpp::Time curr_time(host_marker.markers[0].header.stamp);
389
390 // only update start_point of each arrow type marker for now
391
392 while (curr_idx < curr_cav.markers.size())
393 {
394 if (curr_cav.markers[curr_idx].action == visualization_msgs::msg::Marker::DELETE)
395 break;
396
397 visualization_msgs::msg::Marker curr_marker = curr_cav.markers[curr_idx]; //copy static info
398 if (dt != 0.0 && !curr_cav.markers[curr_idx].points.empty()) // if not already synchronized
399 {
400 double dx = (curr_cav.markers[curr_idx].points[1].x - curr_cav.markers[curr_idx].points[0].x)/time_step * dt;
401 double dy = (curr_cav.markers[curr_idx].points[1].y - curr_cav.markers[curr_idx].points[0].y)/time_step * dt;
402 double dz = (curr_cav.markers[curr_idx].points[1].z - curr_cav.markers[curr_idx].points[0].z)/time_step * dt;
403
404 curr_marker.points[0].x += dx;
405 curr_marker.points[0].y += dy;
406 curr_marker.points[0].z += dz;
407
408 } //else just loop and copy
409 curr_marker.header.stamp = curr_time;
410 synchronized_marker_array.markers.push_back(curr_marker);
411 curr_idx ++;
412 curr_time += rclcpp::Duration(time_step, 0.0);
413 }
414
415 curr_idx = 0; // resetting idx to work on new, synchronized list
416
417
418 // update end_point of each arrow type marker, except that of last point
419 while (curr_idx < synchronized_marker_array.markers.size()-1)
420 {
421 if (curr_cav.markers[curr_idx].action == visualization_msgs::msg::Marker::DELETE)
422 break;
423
424 if (!synchronized_marker_array.markers[curr_idx].points.empty())
425 synchronized_marker_array.markers[curr_idx].points[1] = synchronized_marker_array.markers[curr_idx + 1].points[0];
426 curr_idx ++;
427 }
428
429 if (!synchronized_marker_array.markers[curr_idx].points.empty())
430 {
431 // extrapolate the last point just to conform with 0.1s interval between points
432 double dx = (synchronized_marker_array.markers[curr_idx].points[1].x - synchronized_marker_array.markers[curr_idx].points[0].x)/(time_step - dt) * time_step;
433 double dy = (synchronized_marker_array.markers[curr_idx].points[1].y - synchronized_marker_array.markers[curr_idx].points[0].y)/(time_step - dt) * time_step;
434 double dz = (synchronized_marker_array.markers[curr_idx].points[1].z - synchronized_marker_array.markers[curr_idx].points[0].z)/(time_step - dt) * time_step;
435
436 synchronized_marker_array.markers[curr_idx].points[1].x = synchronized_marker_array.markers[curr_idx].points[0].x + dx;
437 synchronized_marker_array.markers[curr_idx].points[1].y = synchronized_marker_array.markers[curr_idx].points[0].y + dy;
438 synchronized_marker_array.markers[curr_idx].points[1].z = synchronized_marker_array.markers[curr_idx].points[0].z + dz;
439
440 }
441
442 synchronized_output.push_back(synchronized_marker_array);
443
444 }
445
446 return synchronized_output;
447 }

Referenced by timer_callback().

Here is the caller graph for this function:

◆ timer_callback()

void mobilitypath_visualizer::MobilityPathVisualizer::timer_callback ( )
private

Definition at line 96 of file mobilitypath_visualizer.cpp.

97 {
98 // match cav_markers' timestamps to that of host
100 return;
101 }
102
103 // publish host marker
105
107
108 for (auto const &marker: cav_markers_)
109 {
110 cav_marker_pub_->publish(marker);
111 }
112
113 // publish label
116
117 }
visualization_msgs::msg::MarkerArray composeLabelMarker(const visualization_msgs::msg::MarkerArray &host_marker, const std::vector< visualization_msgs::msg::MarkerArray > &cav_markers) const
Compose a label marker that displays whether if any of the cav's path cross with that of host (respec...
std::vector< visualization_msgs::msg::MarkerArray > matchTrajectoryTimestamps(const visualization_msgs::msg::MarkerArray &host_marker, const std::vector< visualization_msgs::msg::MarkerArray > &cav_markers) const
Matches timestamps of CAV's individual points of cav_markers to that of host_marker and interpolates ...
visualization_msgs::msg::MarkerArray label_marker_

References cav_marker_pub_, cav_markers_, composeLabelMarker(), host_marker_, host_marker_pub_, host_marker_received_, label_marker_, label_marker_pub_, and matchTrajectoryTimestamps().

Referenced by handle_on_activate().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ cav_marker_pub_

carma_ros2_utils::PubPtr<visualization_msgs::msg::MarkerArray> mobilitypath_visualizer::MobilityPathVisualizer::cav_marker_pub_
private

Definition at line 112 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure(), and timer_callback().

◆ cav_markers_

std::vector<visualization_msgs::msg::MarkerArray> mobilitypath_visualizer::MobilityPathVisualizer::cav_markers_
private

Definition at line 140 of file mobilitypath_visualizer.hpp.

Referenced by callbackMobilityPath(), and timer_callback().

◆ cav_mob_path_sub_

carma_ros2_utils::SubPtr<carma_v2x_msgs::msg::MobilityPath> mobilitypath_visualizer::MobilityPathVisualizer::cav_mob_path_sub_
private

Definition at line 117 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure().

◆ config_

Config mobilitypath_visualizer::MobilityPathVisualizer::config_
private

◆ georeference_

std::string mobilitypath_visualizer::MobilityPathVisualizer::georeference_ {""}
private

Definition at line 123 of file mobilitypath_visualizer.hpp.

Referenced by georeferenceCallback().

◆ georeference_sub_

carma_ros2_utils::SubPtr<std_msgs::msg::String> mobilitypath_visualizer::MobilityPathVisualizer::georeference_sub_
private

Definition at line 118 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure().

◆ host_marker_

visualization_msgs::msg::MarkerArray mobilitypath_visualizer::MobilityPathVisualizer::host_marker_
private

Definition at line 139 of file mobilitypath_visualizer.hpp.

Referenced by callbackMobilityPath(), and timer_callback().

◆ host_marker_pub_

carma_ros2_utils::PubPtr<visualization_msgs::msg::MarkerArray> mobilitypath_visualizer::MobilityPathVisualizer::host_marker_pub_
private

Definition at line 111 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure(), and timer_callback().

◆ host_marker_received_

bool mobilitypath_visualizer::MobilityPathVisualizer::host_marker_received_ = false
private

Definition at line 145 of file mobilitypath_visualizer.hpp.

Referenced by callbackMobilityPath(), and timer_callback().

◆ host_mob_path_sub_

carma_ros2_utils::SubPtr<carma_v2x_msgs::msg::MobilityPath> mobilitypath_visualizer::MobilityPathVisualizer::host_mob_path_sub_
private

Definition at line 116 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure().

◆ label_marker_

visualization_msgs::msg::MarkerArray mobilitypath_visualizer::MobilityPathVisualizer::label_marker_
private

Definition at line 141 of file mobilitypath_visualizer.hpp.

Referenced by timer_callback().

◆ label_marker_pub_

carma_ros2_utils::PubPtr<visualization_msgs::msg::MarkerArray> mobilitypath_visualizer::MobilityPathVisualizer::label_marker_pub_
private

Definition at line 113 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_configure(), and timer_callback().

◆ latest_cav_mob_path_msg_

std::unordered_map<std::string, carma_v2x_msgs::msg::MobilityPath> mobilitypath_visualizer::MobilityPathVisualizer::latest_cav_mob_path_msg_
private

Definition at line 136 of file mobilitypath_visualizer.hpp.

Referenced by callbackMobilityPath().

◆ map_projector_

std::shared_ptr<lanelet::projection::LocalFrameProjector> mobilitypath_visualizer::MobilityPathVisualizer::map_projector_
private

◆ prev_marker_list_size_

std::unordered_map<std::string, size_t> mobilitypath_visualizer::MobilityPathVisualizer::prev_marker_list_size_
private

Definition at line 144 of file mobilitypath_visualizer.hpp.

Referenced by composeVisualizationMarker().

◆ timer_

rclcpp::TimerBase::SharedPtr mobilitypath_visualizer::MobilityPathVisualizer::timer_
private

Definition at line 129 of file mobilitypath_visualizer.hpp.

Referenced by handle_on_activate().


The documentation for this class was generated from the following files: