Carma-platform v4.10.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.
traffic_incident_parser::TrafficIncidentParserWorker Class Reference

#include <traffic_incident_parser_worker.hpp>

Collaboration diagram for traffic_incident_parser::TrafficIncidentParserWorker:
Collaboration graph

Public Types

using PublishTrafficControlCallback = std::function< void(const carma_v2x_msgs::msg::TrafficControlMessage &)>
 

Public Member Functions

 TrafficIncidentParserWorker (carma_wm::WorldModelConstPtr wm, const PublishTrafficControlCallback &traffic_control_pub, rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger, rclcpp::Clock::SharedPtr clock)
 TrafficIncidentParserWorker constructor. More...
 
void georeferenceCallback (std_msgs::msg::String::UniquePtr projection_msg)
 Callback for the georeference subscriber used to set the map projection. More...
 
void mobilityOperationCallback (carma_v2x_msgs::msg::MobilityOperation::UniquePtr mobility_msg)
 Function to receive the incoming mobility operation message from the message node and publish the geofence message upon processing the mobility msg. Only incoming mobility operation messages with strategy "carma3/Incident_Use_Case" are processed. More...
 
bool mobilityMessageParser (std::string mobility_strategy_params)
 Function to help parse incoming mobility operation messages to required format. More...
 
std::string stringParserHelper (std::string str, unsigned long str_index) const
 Function to help convert string to double data type. More...
 
std::vector< carma_v2x_msgs::msg::TrafficControlMessageV01 > composeTrafficControlMesssages ()
 Algorithm for extracting the closed lanelet from internally saved mobility message (or geofence) params and assigning it to a traffic contol message. Closed lanelets are represent by vector of points, where each point represents the geometric middle point of a closed lanelet. More...
 
lanelet::BasicPoint2d getIncidentOriginPoint () const
 Function to convert internally saved incident origin point from lat/lon to local map frame. More...
 
void getAdjacentForwardCenterlines (const lanelet::ConstLanelets &adjacentSet, const lanelet::BasicPoint2d &start_point, double downtrack, std::vector< std::vector< lanelet::BasicPoint2d > > *forward_lanes) const
 Helper method to compute the concatenated centerlines of the lanes in front of the emergency vehicle point. More...
 
void getAdjacentReverseCenterlines (const lanelet::ConstLanelets &adjacentSet, const lanelet::BasicPoint2d &start_point, double uptrack, std::vector< std::vector< lanelet::BasicPoint2d > > *reverse_lanes) const
 Helper method that is identical to getAdjacentForwardCenterlines except it works in reverse using uptrack distance. More...
 

Public Attributes

const double MphToMetersPerSec = 0.44704
 
double latitude = 0.0
 
double longitude = 0.0
 
double down_track = 0.0
 
double up_track = 0.0
 
double min_gap = 0.0
 
double speed_advisory = 0.0
 
std::string event_reason
 
std::string event_type
 
std::string previous_strategy_params =""
 

Private Attributes

lanelet::BasicPoint2d local_point_
 
std::string projection_msg_
 
PublishTrafficControlCallback traffic_control_pub_
 
carma_wm::WorldModelConstPtr wm_
 
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger_
 
rclcpp::Clock::SharedPtr clock_
 

Detailed Description

Definition at line 43 of file traffic_incident_parser_worker.hpp.

Member Typedef Documentation

◆ PublishTrafficControlCallback

using traffic_incident_parser::TrafficIncidentParserWorker::PublishTrafficControlCallback = std::function<void(const carma_v2x_msgs::msg::TrafficControlMessage&)>

Definition at line 48 of file traffic_incident_parser_worker.hpp.

Constructor & Destructor Documentation

◆ TrafficIncidentParserWorker()

traffic_incident_parser::TrafficIncidentParserWorker::TrafficIncidentParserWorker ( carma_wm::WorldModelConstPtr  wm,
const PublishTrafficControlCallback traffic_control_pub,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr  logger,
rclcpp::Clock::SharedPtr  clock 
)

Member Function Documentation

◆ composeTrafficControlMesssages()

std::vector< carma_v2x_msgs::msg::TrafficControlMessageV01 > traffic_incident_parser::TrafficIncidentParserWorker::composeTrafficControlMesssages ( )

Algorithm for extracting the closed lanelet from internally saved mobility message (or geofence) params and assigning it to a traffic contol message. Closed lanelets are represent by vector of points, where each point represents the geometric middle point of a closed lanelet.

Returns
A vector of traffic control messages; one for each closed lane.

Definition at line 292 of file traffic_incident_parser_worker.cpp.

293 {
294 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "In composeTrafficControlMesssages");
295
297 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Responder point in map frame: " << local_point_.x() << ", " << local_point_.y());
298 auto current_lanelets = lanelet::geometry::findNearest(wm_->getMap()->laneletLayer, local_point_, 1);
299 if (current_lanelets.empty()) {
300 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "No nearest lanelet to responder vehicle in map point: " << local_point_.x() << ", " << local_point_.y());
301 return {};
302 }
303
304 lanelet::ConstLanelet current_lanelet = current_lanelets[0].second;
305
306 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Nearest Lanelet: " << current_lanelet.id());
307
308 lanelet::ConstLanelets lefts = { current_lanelet };
309 for (const auto& l : wm_->getMapRoutingGraph()->lefts(current_lanelet)) {
310 lefts.emplace_back(l);
311 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Left lanelet: " << l.id());
312 }
313
314 lanelet::ConstLanelets rights = wm_->getMapRoutingGraph()->rights(current_lanelet);
315 for (const auto& l : rights) {
316 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Right lanelet: " << l.id());
317 }
318
319 // Assume that if there are more lanelets to the left than the right then the tahoe is on the left
320 std::vector<std::vector<lanelet::BasicPoint2d>> forward_lanes;
321 std::vector<std::vector<lanelet::BasicPoint2d>> reverse_lanes;
322
323 if (lefts.size() >= rights.size()) {
324 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Emergency vehicle on the right ");
326 getAdjacentReverseCenterlines(lefts, local_point_, up_track, &reverse_lanes);
327 } else {
328 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Emergency vehicle on the left ");
329 getAdjacentForwardCenterlines(rights, local_point_, down_track, &forward_lanes);
330 getAdjacentReverseCenterlines(rights, local_point_, up_track, &reverse_lanes);
331 }
332
333 for (auto& lane : reverse_lanes) {
334 std::reverse(lane.begin(), lane.end()); // Reverse the backward points
335 }
336
337 // Compine results
338 for (size_t i = 0; i < reverse_lanes.size(); i++) {
339 if (forward_lanes[i].size() > 1) {
340 reverse_lanes[i].insert(reverse_lanes[i].end(), forward_lanes[i].begin() + 1, forward_lanes[i].end()); // Concat linestirngs but drop the shared point
341 }
342 }
343
344 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Constructing message for lanes: " << reverse_lanes.size());
345 std::vector<carma_v2x_msgs::msg::TrafficControlMessageV01> output_msg;
346
347 carma_v2x_msgs::msg::TrafficControlMessageV01 traffic_mobility_msg;
348
349 traffic_mobility_msg.geometry_exists=true;
350 traffic_mobility_msg.params_exists=true;
351 traffic_mobility_msg.package_exists=true;
352 j2735_v2x_msgs::msg::TrafficControlVehClass veh_type;
353 veh_type.vehicle_class = j2735_v2x_msgs::msg::TrafficControlVehClass::ANY; // TODO decide what vehicle is affected
354 traffic_mobility_msg.params.vclasses.push_back(veh_type);
355 traffic_mobility_msg.params.schedule.start=clock_->now();
356 traffic_mobility_msg.params.schedule.end_exists=false;
357 traffic_mobility_msg.params.schedule.dow_exists=false;
358 traffic_mobility_msg.params.schedule.between_exists=false;
359 traffic_mobility_msg.params.schedule.repeat_exists = false;
360
362 // Begin handling of projection definition
363 // This logic works by enforcing the ROS2 message specifications for TrafficControlMessage on the output data
364 // First the latlon point in the provided data is identified, then a projection with a north east oriented tmerc frame is created to compute node locations
366 std::string common_frame = "WGS84"; // Common frame to use for lat/lon definition. This will populate the datum field of the message. A more complex CRS should not be used here
367
368 PJ* common_to_map_proj = proj_create_crs_to_crs(PJ_DEFAULT_CTX, common_frame.c_str(), projection_msg_.c_str() , nullptr); // Create transformation between map frame and common frame. Reverse here takes map->latlon. Froward is latlon->map
369
370 if (common_to_map_proj == nullptr) { // proj_create_crs_to_crs returns 0 when there is an error in the projection
371
372 RCLCPP_ERROR_STREAM(logger_->get_logger(), "Failed to generate projection between map georeference and common frame with error number: " << proj_context_errno(PJ_DEFAULT_CTX)
373 << " projection_msg_: " << projection_msg_ << " common_frame: " << common_frame);
374
375 return {}; // Ignore geofence if it could not be projected into the map frame
376 }
377
378 PJ_COORD map_origin_map_frame{{0.0, 0.0, 0.0, 0.0}}; // Map origin to use as ref lat/lon
379 PJ_COORD map_origin_in_common_frame;
380
381 map_origin_in_common_frame = proj_trans(common_to_map_proj, PJ_INV, map_origin_map_frame);
382
383 traffic_mobility_msg.geometry.datum = "WGS84";
384 traffic_mobility_msg.geometry.reflat = map_origin_in_common_frame.lpz.lam;
385 traffic_mobility_msg.geometry.reflon = map_origin_in_common_frame.lpz.phi;
386
387 std::ostringstream lat_string;
388 std::ostringstream lon_string;
389
390 lat_string.precision(14);
391 lat_string << std::fixed << traffic_mobility_msg.geometry.reflat;
392
393 lon_string.precision(14);
394 lon_string << std::fixed << traffic_mobility_msg.geometry.reflon;
395
396 // Create a local transverse mercator frame at the reference point to allow us to get east,north oriented data reguardless of map projection orientation
397 // This is needed to match the TrafficControlMessage specification
398 std::string local_tmerc_enu_proj = "+proj=tmerc +datum=WGS84 +h_0=0 +lat_0=" + lat_string.str() + " +lon_0=" + lon_string.str() + " +k=1 +x_0=0 +y_0=0 +units=m +vunits=m +no_defs";
399
400 PJ* map_to_tmerc_proj = proj_create_crs_to_crs(PJ_DEFAULT_CTX, projection_msg_.c_str(), local_tmerc_enu_proj.c_str() , nullptr); // Create transformation between the common frame and the local ENU oriented frame
401
402 if (map_to_tmerc_proj == nullptr) { // proj_create_crs_to_crs returns 0 when there is an error in the projection
403
404 RCLCPP_ERROR_STREAM(logger_->get_logger(), "Failed to generate projection between map georeference and tmerc frame with error number: " << proj_context_errno(PJ_DEFAULT_CTX)
405 << " projection_msg_: " << projection_msg_ << " local_tmerc_enu_proj: " << local_tmerc_enu_proj);
406
407 return {}; // Ignore geofence if it could not be projected into the map frame
408 }
409
410 traffic_mobility_msg.geometry.proj = local_tmerc_enu_proj;
411
412 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Projection in message: " << traffic_mobility_msg.geometry.proj);
413
415 // Projections setup. Next projections will be used for node computation
417
418 for (size_t i = 0; i < reverse_lanes.size(); i++) {
419
420 traffic_mobility_msg.geometry.nodes.clear();
421 if (reverse_lanes[i].size() == 0) {
422 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Skipping empty lane");
423 continue;
424 }
425
426
427 PJ_COORD map_pt{{reverse_lanes[i].front().x(), reverse_lanes[i].front().y(), 0.0, 0.0}}; // Map point to convert to tmerc frame
428
429 PJ_COORD tmerc_pt = proj_trans(map_to_tmerc_proj, PJ_FWD, map_pt);
430
431 carma_v2x_msgs::msg::PathNode prev_point;
432 prev_point.x = tmerc_pt.xyz.x;
433 prev_point.y = tmerc_pt.xyz.y;
434 bool first = true;
435 for(const auto& p : carma_ros2_utils::containers::downsample_vector(reverse_lanes[i], 8))
436 {
437 carma_v2x_msgs::msg::PathNode delta;
438
439 map_pt = PJ_COORD({p.x(), p.y(), 0.0, 0.0}); // Map point to convert to tmerc frame
440 tmerc_pt = proj_trans(map_to_tmerc_proj, PJ_FWD, map_pt); // Convert point to tmerc frame
441
442 delta.x=tmerc_pt.xyz.x - prev_point.x;
443 delta.y=tmerc_pt.xyz.y - prev_point.y;
444
445 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "prev_point x" << prev_point.x << ", prev_point y " << prev_point.y);
446 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "tmerc_pt.xyz.x" << tmerc_pt.xyz.x << ", tmerc_pt.xyz.y " << tmerc_pt.xyz.y);
447 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "map_pt x" << p.x() << ", map_pt y " << p.y());
448
449 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "calculated diff x" << delta.x << ", diff y" << delta.y);
450 if (first)
451 {
452 traffic_mobility_msg.geometry.nodes.push_back(prev_point);
453 first = false;
454 }
455 else
456 {
457 traffic_mobility_msg.geometry.nodes.push_back(delta);
458 }
459
460 prev_point.x = p.x();
461 prev_point.y = p.y();
462 }
463
464 if (i == 0) {
465 boost::uuids::uuid closure_id = boost::uuids::random_generator()();
466 std::copy(closure_id.begin(), closure_id.end(), traffic_mobility_msg.id.id.begin());
467 traffic_mobility_msg.params.detail.choice=carma_v2x_msgs::msg::TrafficControlDetail::CLOSED_CHOICE;
468 traffic_mobility_msg.params.detail.closed=carma_v2x_msgs::msg::TrafficControlDetail::CLOSED;
469 traffic_mobility_msg.package.label=event_reason;
470 output_msg.push_back(traffic_mobility_msg);
471 }
472
473 boost::uuids::uuid headway_id = boost::uuids::random_generator()();
474 std::copy(headway_id.begin(), headway_id.end(), traffic_mobility_msg.id.id.begin());
475 traffic_mobility_msg.params.detail.choice=carma_v2x_msgs::msg::TrafficControlDetail::MINHDWY_CHOICE;
476 traffic_mobility_msg.params.detail.minhdwy=min_gap;
477 output_msg.push_back(traffic_mobility_msg);
478
479 boost::uuids::uuid speed_id = boost::uuids::random_generator()();
480 std::copy(speed_id.begin(), speed_id.end(), traffic_mobility_msg.id.id.begin());
481 traffic_mobility_msg.params.detail.choice=carma_v2x_msgs::msg::TrafficControlDetail::MAXSPEED_CHOICE;
482 traffic_mobility_msg.params.detail.maxspeed=speed_advisory;
483 output_msg.push_back(traffic_mobility_msg);
484
485 }
486
487
488 return output_msg;
489
490 }
lanelet::BasicPoint2d getIncidentOriginPoint() const
Function to convert internally saved incident origin point from lat/lon to local map frame.
void getAdjacentForwardCenterlines(const lanelet::ConstLanelets &adjacentSet, const lanelet::BasicPoint2d &start_point, double downtrack, std::vector< std::vector< lanelet::BasicPoint2d > > *forward_lanes) const
Helper method to compute the concatenated centerlines of the lanes in front of the emergency vehicle ...
void getAdjacentReverseCenterlines(const lanelet::ConstLanelets &adjacentSet, const lanelet::BasicPoint2d &start_point, double uptrack, std::vector< std::vector< lanelet::BasicPoint2d > > *reverse_lanes) const
Helper method that is identical to getAdjacentForwardCenterlines except it works in reverse using upt...

References clock_, down_track, event_reason, getAdjacentForwardCenterlines(), getAdjacentReverseCenterlines(), getIncidentOriginPoint(), process_bag::i, local_point_, logger_, min_gap, projection_msg_, speed_advisory, up_track, and wm_.

Referenced by mobilityOperationCallback().

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

◆ georeferenceCallback()

void traffic_incident_parser::TrafficIncidentParserWorker::georeferenceCallback ( std_msgs::msg::String::UniquePtr  projection_msg)

Callback for the georeference subscriber used to set the map projection.

Parameters
msgThe latest georeference.

Definition at line 73 of file traffic_incident_parser_worker.cpp.

74 {
75 projection_msg_=projection_msg->data;
76 }

References projection_msg_.

Referenced by traffic_incident_parser::TrafficIncidentParserNode::handle_on_configure().

Here is the caller graph for this function:

◆ getAdjacentForwardCenterlines()

void traffic_incident_parser::TrafficIncidentParserWorker::getAdjacentForwardCenterlines ( const lanelet::ConstLanelets &  adjacentSet,
const lanelet::BasicPoint2d &  start_point,
double  downtrack,
std::vector< std::vector< lanelet::BasicPoint2d > > *  forward_lanes 
) const

Helper method to compute the concatenated centerlines of the lanes in front of the emergency vehicle point.

Parameters
adjacentSetThe set of adjacent lanes to start from
start_pointPoint to start the downtrack calculation from. Should be the emergency vehicle points
downtrackdowntrack distance to grab centerline points from
forward_lanesOuput parameter which will be populated with the centerlines for each lane up to the downtrack distance

Definition at line 198 of file traffic_incident_parser_worker.cpp.

200 {
201 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "getAdjacentForwardCenterlines");
202 for (const auto& ll : adjacentSet) {
203 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Processing adjacent lanelet: " << ll.id());
204 std::vector<lanelet::BasicPoint2d> following_lane;
205 auto cur_ll = ll;
206 double dist = 0;
207
208
209 // Identify the point to start the accumulation from
210 size_t p_idx = getNearestPointIndex(cur_ll.centerline(), start_point); // Get the index of the nearest point
211
212 lanelet::BasicPoint2d prev_point = cur_ll.centerline()[p_idx].basicPoint2d();
213
214 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "nearest point" << cur_ll.centerline()[p_idx].id() << " : " << prev_point.x() << ", " << prev_point.y());
215
216 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "p_idx: " << p_idx);
217
218 // Accumulate distance
219 while (dist < downtrack) {
220 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Accumulating lanelet: " << cur_ll.id());
221 if (p_idx == cur_ll.centerline().size()) {
222 auto next_lls = wm_->getMapRoutingGraph()->following(cur_ll, false);
223 if (next_lls.empty()) {
224 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "No followers");
225 break;
226 }
227 const auto& next = next_lls[0];
228 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Getting next lanelet: " << next.id());
229 cur_ll = next;
230 p_idx = 0;
231 }
232 if (p_idx != 0 || dist == 0) {
233 following_lane.push_back(lanelet::traits::to2D(cur_ll.centerline()[p_idx]));
234 dist += lanelet::geometry::distance2d(prev_point, following_lane.back());
235 }
236 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "distance " << dist);
237 prev_point = lanelet::traits::to2D(cur_ll.centerline()[p_idx]);
238 p_idx++;
239 }
240 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Adding lane with size: " << following_lane.size());
241 forward_lanes->emplace_back(following_lane);
242 }
243 }
size_t getNearestPointIndex(const lanelet::ConstLineString3d &points, const lanelet::BasicPoint2d &point)
Helper method to get the nearest point index of a point and a linestring.

References traffic_incident_parser::getNearestPointIndex(), logger_, and wm_.

Referenced by composeTrafficControlMesssages().

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

◆ getAdjacentReverseCenterlines()

void traffic_incident_parser::TrafficIncidentParserWorker::getAdjacentReverseCenterlines ( const lanelet::ConstLanelets &  adjacentSet,
const lanelet::BasicPoint2d &  start_point,
double  uptrack,
std::vector< std::vector< lanelet::BasicPoint2d > > *  reverse_lanes 
) const

Helper method that is identical to getAdjacentForwardCenterlines except it works in reverse using uptrack distance.

Parameters
adjacentSetThe set of adjacent lanes to start from
start_pointPoint to start the downtrack calculation from. Should be the emergency vehicle points
downtrackdowntrack distance to grab centerline points from
forward_lanesOuput parameter which will be populated with the centerlines for each lane up to the downtrack distance

Definition at line 245 of file traffic_incident_parser_worker.cpp.

247 {
248 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "getAdjacentReverseCenterlines");
249 for (const auto& ll : adjacentSet) {
250 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Processing adjacent lanelet: " << ll.id());
251 std::vector<lanelet::BasicPoint2d> previous_lane;
252 auto cur_ll = ll;
253 double dist = 0;
254
255 // Identify the point to start the accumulation from
256 size_t p_idx = getNearestPointIndex(cur_ll.centerline(), start_point); // Get the index of the nearest point
257
258 lanelet::BasicPoint2d prev_point = cur_ll.centerline()[p_idx].basicPoint2d();
259
260 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "nearest point" << cur_ll.centerline()[p_idx].id() << " : " << prev_point.x() << ", " << prev_point.y());
261
262 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "p_idx: " << p_idx);
263
264 // Accumulate distance
265 while (dist < uptrack) {
266 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Accumulating lanelet: " << cur_ll.id());
267 if (p_idx == 0) {
268 auto next_lls = wm_->getMapRoutingGraph()->previous(cur_ll, false);
269 if (next_lls.empty()) {
270 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "No previous lanelets");
271 break;
272 }
273 const auto& next = next_lls[0];
274 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Getting next lanelet: " << next.id());
275 cur_ll = next;
276 p_idx = cur_ll.centerline().size() - 1;
277 }
278 if (p_idx != cur_ll.centerline().size() - 1 || dist == 0) {
279
280 previous_lane.push_back(lanelet::traits::to2D(cur_ll.centerline()[p_idx]));
281 dist += lanelet::geometry::distance2d(prev_point, previous_lane.back());
282 }
283 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "distance " << dist);
284 prev_point = lanelet::traits::to2D(cur_ll.centerline()[p_idx]);
285 p_idx--;
286 }
287 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Adding lane with size: " << previous_lane.size());
288 reverse_lanes->emplace_back(previous_lane);
289 }
290 }

References traffic_incident_parser::getNearestPointIndex(), logger_, and wm_.

Referenced by composeTrafficControlMesssages().

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

◆ getIncidentOriginPoint()

lanelet::BasicPoint2d traffic_incident_parser::TrafficIncidentParserWorker::getIncidentOriginPoint ( ) const

Function to convert internally saved incident origin point from lat/lon to local map frame.

Returns
The internally saved incident origin point within the local map frame.

Definition at line 164 of file traffic_incident_parser_worker.cpp.

165 {
166 lanelet::projection::LocalFrameProjector projector(projection_msg_.c_str());
167 lanelet::GPSPoint gps_point;
168 gps_point.lat = latitude;
169 gps_point.lon = longitude;
170 gps_point.ele = 0;
171 auto local_point3d = projector.forward(gps_point);
172 return {local_point3d.x(), local_point3d.y()};
173 }

References latitude, longitude, and projection_msg_.

Referenced by composeTrafficControlMesssages().

Here is the caller graph for this function:

◆ mobilityMessageParser()

bool traffic_incident_parser::TrafficIncidentParserWorker::mobilityMessageParser ( std::string  mobility_strategy_params)

Function to help parse incoming mobility operation messages to required format.

Parameters
mobility_strategy_paramsThe strategy params associated with an incoming mobility operation message.
Returns
True if the new message is valid and can be used. False if not new or not valid.

Definition at line 79 of file traffic_incident_parser_worker.cpp.

80 {
81
82 std::vector<std::string> vec={};
83 std::string delimiter = ",";
84 size_t pos = 0;
85 std::string token;
86 while ((pos = mobility_strategy_params.find(delimiter)) != std::string::npos)
87 {
88 token = mobility_strategy_params.substr(0, pos);
89 vec.push_back(token);
90 mobility_strategy_params.erase(0, pos + delimiter.length());
91 }
92 vec.push_back(mobility_strategy_params);
93
94 if (vec.size() != 8)
95 {
96 RCLCPP_ERROR_STREAM(logger_->get_logger(),"Given mobility strategy params are not correctly formatted.");
97 return false;
98 }
99
100 std::string lat_str=vec[0];
101 std::string lon_str=vec[1];
102 std::string downtrack_str=vec[2];
103 std::string uptrack_str=vec[3];
104 std::string min_gap_str=vec[4];
105 std::string speed_advisory_str=vec[5];
106 std::string event_reason_str=vec[6];
107 std::string event_type_str=vec[7];
108
109 // Evaluate if this message should be forwarded based on the gps point
110 double temp_lat = stod(stringParserHelper(lat_str,lat_str.find_last_of("lat:")));
111 double temp_lon = stod(stringParserHelper(lon_str,lon_str.find_last_of("lon:")));
112
113 double constexpr APPROXIMATE_DEG_PER_5M = 0.00005;
114 double delta_lat = temp_lat - latitude;
115 double delta_lon = temp_lon - longitude;
116 double approximate_degree_delta = sqrt(delta_lat*delta_lat + delta_lon*delta_lon);
117
118 double temp_down_track=stod(stringParserHelper(downtrack_str,downtrack_str.find_last_of("down_track:")));
119 double temp_up_track=stod(stringParserHelper(uptrack_str,uptrack_str.find_last_of("up_track:")));
120 double temp_min_gap=stod(stringParserHelper(min_gap_str,min_gap_str.find_last_of("min_gap:")));
121 double temp_speed_advisory=stod(stringParserHelper(speed_advisory_str,speed_advisory_str.find_last_of("advisory_speed:"))) * MphToMetersPerSec;
122 std::string temp_event_reason=stringParserHelper(event_reason_str,event_reason_str.find_last_of("event_reason:"));
123 std::string temp_event_type=stringParserHelper(event_type_str,event_type_str.find_last_of("event_type:"));
124
125 if ( approximate_degree_delta < APPROXIMATE_DEG_PER_5M // If the vehicle has not moved more than 5m and the parameters remain unchanged
126 && temp_down_track == down_track
127 && temp_up_track == up_track
128 && temp_min_gap == min_gap
129 && temp_speed_advisory == speed_advisory
130 && temp_event_reason == event_reason
131 && temp_event_type == event_type) {
132
133 RCLCPP_DEBUG_STREAM(logger_->get_logger(), "Strategy params are unchanged so ignoring new message: " << mobility_strategy_params
134 << " degree_delta: " << approximate_degree_delta
135 << " prev_lat: " << latitude << " prev_lon: " << longitude);
136
137 return false;
138
139 }
140
141 // Valid message contents so populate member variables
142 latitude = temp_lat;
143 longitude = temp_lon;
144 down_track = temp_down_track;
145 up_track = temp_up_track;
146 min_gap = temp_min_gap;
147 speed_advisory = temp_speed_advisory;
148 event_reason = temp_event_reason;
149 event_type = temp_event_type;
150
151 return true;
152 }
std::string stringParserHelper(std::string str, unsigned long str_index) const
Function to help convert string to double data type.

References down_track, event_reason, event_type, latitude, logger_, longitude, min_gap, MphToMetersPerSec, speed_advisory, stringParserHelper(), and up_track.

Referenced by mobilityOperationCallback().

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

◆ mobilityOperationCallback()

void traffic_incident_parser::TrafficIncidentParserWorker::mobilityOperationCallback ( carma_v2x_msgs::msg::MobilityOperation::UniquePtr  mobility_msg)

Function to receive the incoming mobility operation message from the message node and publish the geofence message upon processing the mobility msg. Only incoming mobility operation messages with strategy "carma3/Incident_Use_Case" are processed.

Parameters
mobility_msgIncoming mobility operation message

Definition at line 32 of file traffic_incident_parser_worker.cpp.

33 {
34 if(!wm_->getMap())
35 {
36 RCLCPP_WARN_STREAM(logger_->get_logger(), "The map is not loaded yet, ignoring the Traffic Incident Mobility Message");
37 return;
38 }
39 if (projection_msg_ == "")
40 {
41 RCLCPP_WARN_STREAM(logger_->get_logger(), "The georeference is not loaded yet, ignoring the Traffic Incident Mobility Message");
42 return;
43 }
44 if(!wm_->getRoute())
45 {
46 RCLCPP_WARN_STREAM(logger_->get_logger(), "The route is not loaded yet, ignoring the Traffic Incident Mobility Message");
47 return;
48 }
49
50 if(mobility_msg->strategy=="carma3/Incident_Use_Case")
51 {
52
53 bool valid_msg = mobilityMessageParser(mobility_msg->strategy_params);
54
55 if(valid_msg && event_type=="CLOSED")
56 {
57 previous_strategy_params=mobility_msg->strategy_params;
58 carma_v2x_msgs::msg::TrafficControlMessage traffic_control_msg;
59 traffic_control_msg.choice = carma_v2x_msgs::msg::TrafficControlMessage::TCMV01;
60 for(const auto &traffic_msg : composeTrafficControlMesssages())
61 {
62 traffic_control_msg.tcm_v01=traffic_msg;
63 traffic_control_pub_(traffic_control_msg); // Publish the message to existing subscribers
64 }
65 }
66 else
67 {
68 return;
69 }
70 }
71 }
std::vector< carma_v2x_msgs::msg::TrafficControlMessageV01 > composeTrafficControlMesssages()
Algorithm for extracting the closed lanelet from internally saved mobility message (or geofence) para...
bool mobilityMessageParser(std::string mobility_strategy_params)
Function to help parse incoming mobility operation messages to required format.

References composeTrafficControlMesssages(), event_type, logger_, mobilityMessageParser(), previous_strategy_params, projection_msg_, traffic_control_pub_, and wm_.

Referenced by traffic_incident_parser::TrafficIncidentParserNode::handle_on_configure().

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

◆ stringParserHelper()

std::string traffic_incident_parser::TrafficIncidentParserWorker::stringParserHelper ( std::string  str,
unsigned long  str_index 
) const

Function to help convert string to double data type.

Parameters
strString object from which to extract the numeric value (a double).
str_idxThe String object's index to start looking at.
Returns
A string object containing only the numeric value included in the str object.

Definition at line 154 of file traffic_incident_parser_worker.cpp.

155 {
156 std::string str_temp="";
157 for(size_t i=str_index+1;i<str.length();i++)
158 {
159 str_temp+=str[i];
160 }
161 return str_temp;
162 }

References process_bag::i, and create_two_lane_map::str.

Referenced by mobilityMessageParser().

Here is the caller graph for this function:

Member Data Documentation

◆ clock_

rclcpp::Clock::SharedPtr traffic_incident_parser::TrafficIncidentParserWorker::clock_
private

Definition at line 140 of file traffic_incident_parser_worker.hpp.

Referenced by composeTrafficControlMesssages().

◆ down_track

double traffic_incident_parser::TrafficIncidentParserWorker::down_track = 0.0

◆ event_reason

std::string traffic_incident_parser::TrafficIncidentParserWorker::event_reason

◆ event_type

std::string traffic_incident_parser::TrafficIncidentParserWorker::event_type

◆ latitude

double traffic_incident_parser::TrafficIncidentParserWorker::latitude = 0.0

◆ local_point_

lanelet::BasicPoint2d traffic_incident_parser::TrafficIncidentParserWorker::local_point_
private

Definition at line 133 of file traffic_incident_parser_worker.hpp.

Referenced by composeTrafficControlMesssages().

◆ logger_

rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr traffic_incident_parser::TrafficIncidentParserWorker::logger_
private

◆ longitude

double traffic_incident_parser::TrafficIncidentParserWorker::longitude = 0.0

◆ min_gap

double traffic_incident_parser::TrafficIncidentParserWorker::min_gap = 0.0

◆ MphToMetersPerSec

const double traffic_incident_parser::TrafficIncidentParserWorker::MphToMetersPerSec = 0.44704

Definition at line 49 of file traffic_incident_parser_worker.hpp.

Referenced by mobilityMessageParser().

◆ previous_strategy_params

std::string traffic_incident_parser::TrafficIncidentParserWorker::previous_strategy_params =""

Definition at line 129 of file traffic_incident_parser_worker.hpp.

Referenced by mobilityOperationCallback().

◆ projection_msg_

std::string traffic_incident_parser::TrafficIncidentParserWorker::projection_msg_
private

◆ speed_advisory

double traffic_incident_parser::TrafficIncidentParserWorker::speed_advisory = 0.0

◆ traffic_control_pub_

PublishTrafficControlCallback traffic_incident_parser::TrafficIncidentParserWorker::traffic_control_pub_
private

Definition at line 135 of file traffic_incident_parser_worker.hpp.

Referenced by mobilityOperationCallback().

◆ up_track

double traffic_incident_parser::TrafficIncidentParserWorker::up_track = 0.0

◆ wm_

carma_wm::WorldModelConstPtr traffic_incident_parser::TrafficIncidentParserWorker::wm_
private

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