18#define GET_MANEUVER_PROPERTY(mvr, property) \
19 (((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN ? \
20 (mvr).intersection_transit_left_turn_maneuver.property : \
21 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN ? \
22 (mvr).intersection_transit_right_turn_maneuver.property : \
23 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT ? \
24 (mvr).intersection_transit_straight_maneuver.property : \
25 ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE ? (mvr).lane_change_maneuver.property : \
26 ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING ? (mvr).lane_following_maneuver.property : \
27 ((mvr).type == carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT ? (mvr).stop_and_wait_maneuver.property : \
28 throw new std::invalid_argument("GET_MANEUVER_" \
39namespace std_ph = std::placeholders;
51 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
52 return mvr.lane_following_maneuver.end_speed;
53 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
54 return mvr.lane_change_maneuver.end_speed;
55 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
56 return mvr.intersection_transit_straight_maneuver.end_speed;
57 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
58 return mvr.intersection_transit_left_turn_maneuver.end_speed;
59 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
60 return mvr.intersection_transit_right_turn_maneuver.end_speed;
61 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
64 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Requested end speed from unsupported maneuver type");
114 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Done loading parameters: " <<
config_);
117 mob_operation_sub_ = create_subscription<carma_v2x_msgs::msg::MobilityOperation>(
"incoming_mobility_operation", 1,
121 current_pose_sub_ = create_subscription<geometry_msgs::msg::PoseStamped>(
"current_pose", 1,
125 bsm_sub_ = create_subscription<carma_v2x_msgs::msg::BSM>(
"bsm_outbound", 1,
129 guidance_state_sub_ = create_subscription<carma_planning_msgs::msg::GuidanceState>(
"guidance_state", 5,
136 mobility_operation_pub_ = create_publisher<carma_v2x_msgs::msg::MobilityOperation>(
"outgoing_mobility_operation", 1);
139 return CallbackReturn::SUCCESS;
144 auto error_double = update_params<double>({
154 rcl_interfaces::msg::SetParametersResult result;
156 result.successful = !error_double;
164 std::chrono::duration<double>(0.1),
167 return CallbackReturn::SUCCESS;
173 if (!req.prior_plan.maneuvers.empty())
175 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Provided with initial plan...");
183 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"No initial plan provided...");
185 state.
stamp = req.header.stamp;
187 state.
speed = req.veh_logitudinal_velocity;
188 state.
lane_id = stoi(req.veh_lane_id);
191 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"state.stamp: " <<
std::to_string(state.
stamp.seconds()));
192 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"state.downtrack : " << state.
downtrack );
193 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"state.speed: " << state.
speed);
194 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"state.lane_id: " << state.
lane_id);
203 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Received Schedule message with id: " << msg->m_header.plan_id);
210 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"street_msg_timestamp_: " <<
street_msg_timestamp_);
220 std::vector<uint8_t> bsm_id_vec = msg->core_data.id;
221 bsm_id_ = BSMHelper::BSMHelper::bsmIDtoString(bsm_id_vec);
233 geometry_msgs::msg::PoseStamped pose_msg = geometry_msgs::msg::PoseStamped(*msg.get());
236 lanelet::BasicPoint2d current_loc(pose_msg.pose.position.x, pose_msg.pose.position.y);
238 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Downtrack from current pose: " <<
current_downtrack_);
247 std::string params = strategy_params;
248 std::vector<std::string> inputsParams;
251 std::vector<std::string> st_parsed;
254 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"scheduled_stop_time_: " <<
scheduled_stop_time_);
256 std::vector<std::string> et_parsed;
259 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"scheduled_enter_time_: " <<
scheduled_enter_time_);
261 std::vector<std::string> dt_parsed;
264 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"scheduled_depart_time_: " <<
scheduled_depart_time_);
267 std::vector<std::string> dp_parsed;
272 std::vector<std::string> access_parsed;
274 int access = std::stoi(access_parsed[1]);
276 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"is_allowed_int_: " <<
is_allowed_int_);
285 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"estimated_stop_time: " << estimated_stop_time);
286 if (estimated_stop_time < schedule_stop_time)
293 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"speed_before_stop: " << speed_before_stop);
294 if (speed_before_stop < speed_limit)
311 t_stop = 2*stop_dist/current_speed;
317 double speed_before_decel = 0;
322 double sqr_term = sqrt(pow(1 - (desired_acceleration/desired_deceleration), 2) * pow(stop_dist/stop_time, 2)
323 + (1 - (desired_acceleration/desired_deceleration))*(current_speed*current_speed - 2*current_speed*stop_dist/stop_time));
325 speed_before_decel = (stop_dist/stop_time) + sqr_term/(1 - (desired_acceleration/desired_deceleration));
327 return speed_before_decel;
332 double end_downtrack,
333 bool shortest_path_only,
334 bool bounds_inclusive)
const
336 std::vector<lanelet::ConstLanelet> crossed_lanelets =
337 wm_->getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive);
339 if (crossed_lanelets.empty())
341 throw std::invalid_argument(
"getLaneletsBetweenWithException called but inputs do not cross any lanelets going "
346 return crossed_lanelets;
352 std::shared_ptr<rmw_request_id_t> srv_header,
353 carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req,
354 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
356 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"In Maneuver callback...");
359 if (!
wm_->getRoute())
361 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Could not plan maneuvers as route was not available");
367 resp->new_plan.maneuvers = {};
368 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Not approaching stop-controlled intersection so no maneuvers");
373 if (is_empty_schedule_msg)
375 resp->new_plan.maneuvers = {};
376 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Receiving empty schedule message");
380 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Planning for intersection...");
382 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Finding car information");
387 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"\n\nFinding intersection information");
389 auto stop_intersection_list =
wm_->getIntersectionsAlongRoute({ req->veh_x, req->veh_y });
390 bool no_intersections = stop_intersection_list.empty();
391 if (no_intersections)
393 resp->new_plan.maneuvers = {};
394 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"There are no stop controlled intersections in the map");
398 auto nearest_stop_intersection = stop_intersection_list.front();
400 bool no_stop_lines = nearest_stop_intersection->stopLines().empty();
403 resp->new_plan.maneuvers = {};
404 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"There are no stop lines on the closest stop-controlled intersections in the map");
410 std::vector<double> stop_lines;
411 for (
auto l : nearest_stop_intersection->stopLines())
414 double stop_bar_dtd =
wm_->routeTrackPos(l.front().basicPoint2d()).downtrack -
config_.
veh_length;
415 stop_lines.push_back(stop_bar_dtd);
417 std::sort(stop_lines.begin(), stop_lines.end());
419 double stop_intersection_down_track = stop_lines.front();
421 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"stop_intersection_down_track " << stop_intersection_down_track);
425 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"distance_to_stopline " << distance_to_stopline);
429 resp->new_plan.maneuvers = {};
430 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Already passed intersection, sending empty maneuvers");
435 double intersection_end_downtrack = stop_lines.back();
437 std::vector<lanelet::ConstLanelet> intersection_lanelets =
447 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time_to_approach_int " << time_to_approach_int);
449 carma_planning_msgs::msg::Maneuver maneuver_planned;
452 if (time_to_approach_int)
455 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"tmp " << tmp);
456 double time_to_schedule_stop = (tmp)/1000.0;
457 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time_to_schedule_stop " << time_to_schedule_stop);
459 std::vector<lanelet::ConstLanelet> crossed_lanelets =
467 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time_to_schedule_stop " << time_to_schedule_stop);
472 double safe_distance = pow(current_state.
speed, 2)/(2*desired_deceleration);
473 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"safe_distance: " << safe_distance);
478 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"case_num: " << case_num);
483 case_num, current_state.
downtrack, stop_intersection_down_track, current_state.
speed, 0.0,
484 current_state.
stamp, time_to_schedule_stop,
485 lanelet::utils::transform(crossed_lanelets, [](
const auto& ll) { return ll.id(); }));
486 resp->new_plan.maneuvers.push_back(maneuver_planned);
490 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Decelerating to stop at the intersection");
495 std::vector<lanelet::ConstLanelet> crossed_lanelets =
500 stopping_accel = std::max(-stopping_accel, desired_deceleration);
501 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"used deceleration for case three: " << stopping_accel);
504 current_state.
downtrack, stop_intersection_down_track, current_state.
speed, crossed_lanelets[0].id(),
505 crossed_lanelets[0].id(), stopping_accel, current_state.
stamp,
506 current_state.
stamp + rclcpp::Duration(time_to_schedule_stop*1e9));
508 resp->new_plan.maneuvers.push_back(maneuver_planned);
514 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Too close to the intersection, constant deceleration to stop");
517 current_state.
downtrack, stop_intersection_down_track, current_state.
speed, crossed_lanelets[0].id(),
518 crossed_lanelets[0].id(), desired_deceleration, current_state.
stamp,
519 current_state.
stamp + rclcpp::Duration(time_to_schedule_stop*1e9));
524 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time_to_reach_stopline: " << time_to_reach_stopline);
526 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"not_time_to_intersection_traverse: " << not_time_to_intersection_traverse);
527 bool time_to_stop_at_stopline = (time_to_reach_stopline && not_time_to_intersection_traverse);
528 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time_to_stop_at_stopline: " << time_to_stop_at_stopline);
530 if (time_to_stop_at_stopline)
534 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"stop_duration: " << stop_duration);
535 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Planning stop and wait maneuver");
537 auto stop_line_lanelet = nearest_stop_intersection->lanelets().front();
540 current_state.
downtrack, stop_intersection_down_track, current_state.
speed, stop_line_lanelet.id(),
541 stop_line_lanelet.id(), stopping_accel, current_state.
stamp,
542 current_state.
stamp + rclcpp::Duration(stop_duration*1e9));
547 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Vehicle at stop line, waiting for access to intersection");
551 double stop_duration = 999;
553 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"current_downtrack_: " <<
current_downtrack_);
554 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"current state dtd: " << current_state.
downtrack);
555 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"stop_intersection_down_track dtd: " << stop_intersection_down_track);
560 current_state.
stamp + rclcpp::Duration(stop_duration*1e9));
567 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"time for crossing? " << time_for_crossing);
574 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Vehicle is crossing the intersection");
580 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"intersection_transit_time: " << intersection_transit_time);
583 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"used intersection_transit_time: " << intersection_transit_time);
585 std::vector<lanelet::ConstLanelet> crossed_lanelets =
593 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"turn direction at the intersection is: " <<
intersection_turn_direction_);
595 double intersection_speed_limit =
findSpeedLimit(nearest_stop_intersection->lanelets().front());
599 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Actual length of intersection: " << intersection_end_downtrack - stop_intersection_down_track);
600 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Used length of intersection: " << end_of_intersection);
603 current_state.
downtrack, current_state.
downtrack + end_of_intersection, current_state.
speed, intersection_speed_limit,
604 current_state.
stamp, rclcpp::Time(req->header.stamp) + rclcpp::Duration(intersection_transit_time*1e9),
intersection_turn_direction_, crossed_lanelets.front().id(), crossed_lanelets.back().id());
607 if (distance_to_stopline < -end_of_intersection)
609 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Vehicle is out of intersection, stop planning...");
617 resp->new_plan.maneuvers.push_back(maneuver_planned);
625 for (
auto l:lanelets_list)
627 if(l.hasAttribute(
"turn_direction")) {
628 std::string direction_attribute = l.attribute(
"turn_direction").value();
629 if (direction_attribute ==
"right")
634 else if (direction_attribute ==
"left")
640 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"intersection crossed lanelet direction is: " << turn_direction);
649 return turn_direction;
653 std::vector<double>* float_metadata_list)
const
659 double a_acc = ((1 - desired_acceleration/desired_deceleration)*speed_before_decel - current_speed)/stop_time;
660 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case one a_acc: " << a_acc);
661 a_acc = std::min(a_acc, desired_acceleration);
662 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Used Case one a_acc: " << a_acc);
664 double a_dec = ((desired_deceleration - desired_acceleration)*speed_before_decel - desired_deceleration * current_speed)/(desired_acceleration * stop_time);
665 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case one a_dec: " << a_dec);
666 a_dec = std::max(a_dec, desired_deceleration);
667 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Used Case one a_dec: " << a_dec);
669 double t_acc = (speed_before_decel - current_speed)/a_acc;
670 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case one t_acc: " << t_acc);
671 double t_dec = -speed_before_decel/a_dec;
672 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case one t_dec: " << t_dec);
673 float_metadata_list->push_back(a_acc);
674 float_metadata_list->push_back(a_dec);
675 float_metadata_list->push_back(t_acc);
676 float_metadata_list->push_back(t_dec);
677 float_metadata_list->push_back(speed_before_decel);
681 double current_speed,
double stop_time,
double speed_limit,
682 std::vector<double>* float_metadata_list)
const
687 if (speed_before_decel > speed_limit)
689 speed_before_decel = speed_limit;
690 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two speed_before_decel: " << speed_before_decel);
693 double t_c_nom = 2*stop_dist * ((1 - desired_acceleration/desired_deceleration)*speed_limit - current_speed) -
694 stop_time * ((1 - desired_acceleration/desired_deceleration)*pow(speed_limit,2) - pow(current_speed, 2));
695 double t_c_den = pow(speed_limit - current_speed, 2) - (desired_acceleration/desired_deceleration) * pow(speed_limit, 2);
696 double t_cruise = t_c_nom / t_c_den;
697 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two t_cruise: " << t_cruise);
700 double a_acc = ((1 - desired_acceleration/desired_deceleration)*speed_limit - current_speed)/(stop_time - t_cruise);
701 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two a_acc: " << a_acc);
702 a_acc = std::min(desired_acceleration, std::abs(a_acc));
703 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Used Case two a_acc: " << a_acc);
705 double a_dec = ((desired_deceleration - desired_acceleration)*speed_limit - desired_deceleration * current_speed)/(desired_acceleration*(stop_time - t_cruise));
706 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two a_dec: " << a_dec);
707 a_dec = -1*std::min(desired_deceleration, std::abs(a_dec));
708 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Used Case two a_dec: " << a_dec);
710 double t_acc = (speed_limit - current_speed)/a_acc;
711 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two t_acc: " << t_acc);
712 double t_dec = -speed_limit/a_dec;
713 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case two t_dec: " << t_dec);
715 float_metadata_list->push_back(a_acc);
716 float_metadata_list->push_back(a_dec);
717 float_metadata_list->push_back(t_acc);
718 float_metadata_list->push_back(t_dec);
719 float_metadata_list->push_back(t_cruise);
720 float_metadata_list->push_back(speed_before_decel);
727 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Case three a_dec: " << a_dec);
732 double start_speed,
double target_speed,
733 rclcpp::Time start_time,
double time_to_stop,
734 std::vector<lanelet::Id> lane_ids)
736 carma_planning_msgs::msg::Maneuver maneuver_msg;
737 carma_planning_msgs::msg::Maneuver empty_msg;
738 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
740 maneuver_msg.lane_following_maneuver.parameters.presence_vector =
741 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_INT_META_DATA |
742 carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA | carma_planning_msgs::msg::ManeuverParameters::HAS_STRING_META_DATA;
743 maneuver_msg.lane_following_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
745 maneuver_msg.lane_following_maneuver.start_dist = start_dist;
746 maneuver_msg.lane_following_maneuver.end_dist = end_dist;
747 maneuver_msg.lane_following_maneuver.start_speed = start_speed;
748 maneuver_msg.lane_following_maneuver.end_speed = target_speed;
749 maneuver_msg.lane_following_maneuver.start_time = start_time;
750 maneuver_msg.lane_following_maneuver.end_time = start_time + rclcpp::Duration(time_to_stop*1e9);
751 maneuver_msg.lane_following_maneuver.lane_ids =
752 lanelet::utils::transform(lane_ids, [](
auto id) {
return std::to_string(
id); });
754 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Creating lane follow start dist: " << start_dist <<
" end dist: " << end_dist);
756 std::vector<double> float_metadata_list;
773 maneuver_msg.lane_following_maneuver.parameters.int_valued_meta_data.push_back(case_num);
775 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data = float_metadata_list;
783 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules =
wm_->getTrafficRules();
786 return (*traffic_rules)->speedLimit(llt).speedLimit.value();
790 throw std::invalid_argument(
"Valid traffic rules object could not be built");
796 carma_v2x_msgs::msg::MobilityOperation mo_;
797 mo_.m_header.timestamp = now().nanoseconds()/1000000;
799 mo_.m_header.sender_bsm_id =
bsm_id_;
805 std::string intersection_turn_direction =
"straight";
831 const lanelet::Id& starting_lane_id,
832 const lanelet::Id& ending_lane_id,
double stopping_accel,
833 rclcpp::Time start_time, rclcpp::Time end_time)
const
835 carma_planning_msgs::msg::Maneuver maneuver_msg;
836 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
838 maneuver_msg.stop_and_wait_maneuver.parameters.presence_vector =
839 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA;
840 maneuver_msg.stop_and_wait_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
842 maneuver_msg.stop_and_wait_maneuver.start_speed = start_speed;
843 maneuver_msg.stop_and_wait_maneuver.start_dist = current_dist;
844 maneuver_msg.stop_and_wait_maneuver.end_dist = end_dist;
845 maneuver_msg.stop_and_wait_maneuver.start_time = start_time;
846 maneuver_msg.stop_and_wait_maneuver.end_time = end_time;
847 maneuver_msg.stop_and_wait_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
848 maneuver_msg.stop_and_wait_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
851 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
853 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Creating stop and wait start dist: " << current_dist <<
" end dist: " << end_dist);
859 double start_speed,
double target_speed,
860 rclcpp::Time start_time, rclcpp::Time end_time,
862 const lanelet::Id& starting_lane_id,
863 const lanelet::Id& ending_lane_id)
const
865 carma_planning_msgs::msg::Maneuver maneuver_msg;
868 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN;
869 maneuver_msg.intersection_transit_left_turn_maneuver.parameters.planning_strategic_plugin =
871 maneuver_msg.intersection_transit_left_turn_maneuver.parameters.planning_tactical_plugin =
873 maneuver_msg.intersection_transit_left_turn_maneuver.parameters.presence_vector =
874 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
875 maneuver_msg.intersection_transit_left_turn_maneuver.parameters.negotiation_type =
876 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
877 maneuver_msg.intersection_transit_left_turn_maneuver.start_dist = start_dist;
878 maneuver_msg.intersection_transit_left_turn_maneuver.end_dist = end_dist;
879 maneuver_msg.intersection_transit_left_turn_maneuver.start_speed = start_speed;
880 maneuver_msg.intersection_transit_left_turn_maneuver.end_speed = target_speed;
881 maneuver_msg.intersection_transit_left_turn_maneuver.start_time = start_time;
882 maneuver_msg.intersection_transit_left_turn_maneuver.end_time = end_time;
883 maneuver_msg.intersection_transit_left_turn_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
884 maneuver_msg.intersection_transit_left_turn_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
889 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN;
890 maneuver_msg.intersection_transit_right_turn_maneuver.parameters.planning_strategic_plugin =
892 maneuver_msg.intersection_transit_right_turn_maneuver.parameters.planning_tactical_plugin =
894 maneuver_msg.intersection_transit_right_turn_maneuver.parameters.presence_vector =
895 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
896 maneuver_msg.intersection_transit_right_turn_maneuver.parameters.negotiation_type =
897 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
898 maneuver_msg.intersection_transit_right_turn_maneuver.start_dist = start_dist;
899 maneuver_msg.intersection_transit_right_turn_maneuver.end_dist = end_dist;
900 maneuver_msg.intersection_transit_right_turn_maneuver.start_speed = start_speed;
901 maneuver_msg.intersection_transit_right_turn_maneuver.end_speed = target_speed;
902 maneuver_msg.intersection_transit_right_turn_maneuver.start_time = start_time;
903 maneuver_msg.intersection_transit_right_turn_maneuver.end_time = end_time;
904 maneuver_msg.intersection_transit_right_turn_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
905 maneuver_msg.intersection_transit_right_turn_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
910 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT;
911 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_strategic_plugin =
913 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_tactical_plugin =
915 maneuver_msg.intersection_transit_straight_maneuver.parameters.presence_vector =
916 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
917 maneuver_msg.intersection_transit_straight_maneuver.parameters.negotiation_type =
918 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
919 maneuver_msg.intersection_transit_straight_maneuver.start_dist = start_dist;
920 maneuver_msg.intersection_transit_straight_maneuver.end_dist = end_dist;
921 maneuver_msg.intersection_transit_straight_maneuver.start_speed = start_speed;
922 maneuver_msg.intersection_transit_straight_maneuver.end_speed = target_speed;
923 maneuver_msg.intersection_transit_straight_maneuver.start_time = start_time;
924 maneuver_msg.intersection_transit_straight_maneuver.end_time = end_time;
925 maneuver_msg.intersection_transit_straight_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
926 maneuver_msg.intersection_transit_straight_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
934 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"sci_strategic_plugin"),
"Creating IntersectionTransitManeuver start dist: " << start_dist <<
" end dist: " << end_dist
935 <<
" From lanelet: " << starting_lane_id
936 <<
" to lanelet: " << ending_lane_id);
953#include "rclcpp_components/register_node_macro.hpp"
virtual carma_wm::WorldModelConstPtr get_world_model() final
Method to return the default world model provided as a convience by this base class If this method or...
carma_wm::WorldModelConstPtr wm_
World Model pointer.
unsigned long long scheduled_depart_time_
std::vector< lanelet::ConstLanelet > getLaneletsBetweenWithException(double start_downtrack, double end_downtrack, bool shortest_path_only=false, bool bounds_inclusive=true) const
Helper method which calls carma_wm::WorldModel::getLaneletsBetween(start_downtrack,...
double calcEstimatedStopTime(double stop_dist, double current_speed) const
calculate the time vehicle will stop with optimal decelarion
void guidance_state_cb(const carma_planning_msgs::msg::GuidanceState::UniquePtr msg)
Callback for the Guidance State.
int determine_speed_profile_case(double stop_dist, double current_speed, double schedule_stop_time, double speed_limit)
Determine the speed profile case fpr approaching an intersection.
unsigned long long street_msg_timestamp_
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > current_pose_sub_
uint32_t scheduled_departure_position_
unsigned long long scheduled_enter_time_
VehicleState extractInitialState(const carma_planning_msgs::srv::PlanManeuvers::Request &req) const
Helper method to extract the initial vehicle state from the planning request method based on if the p...
void parseStrategyParams(const std::string &strategy_params)
parse strategy parameters
void BSMCb(carma_v2x_msgs::msg::BSM::UniquePtr msg)
BSM callback function.
TurnDirection getTurnDirectionAtIntersection(std::vector< lanelet::ConstLanelet > lanelets_list)
Determine the turn direction at intersection.
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > ¶meters)
Callback for dynamic parameter updates.
unsigned long long scheduled_stop_time_
double caseThreeSpeedProfile(double stop_dist, double current_speed, double stop_time) const
Determine the desired speed profile parameters for Case 3.
bool approaching_stop_controlled_interction_
void plan_maneuvers_callback(std::shared_ptr< rmw_request_id_t > srv_header, carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
Service callback for arbitrator maneuver planning.
double current_downtrack_
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::GuidanceState > guidance_state_sub_
carma_ros2_utils::CallbackReturn on_activate_plugin()
Method which is triggered when this plugin is moved from the INACTIVE to ACTIVE states....
std::string previous_strategy_params_
rclcpp::TimerBase::SharedPtr mob_op_pub_timer_
bool get_availability()
Get the availability status of this plugin based on the current operating environment....
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityOperation > mobility_operation_pub_
void currentPoseCb(geometry_msgs::msg::PoseStamped::UniquePtr msg)
callback function for current pose
void publishMobilityOperation()
Method to publish mobility operation msgs at a fixed rate of 10hz if approaching intersection.
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_sub_
carma_ros2_utils::CallbackReturn on_configure_plugin()
Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states....
carma_planning_msgs::msg::Maneuver composeIntersectionTransitMessage(double start_dist, double end_dist, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, TurnDirection turn_direction, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id) const
std::string stop_controlled_intersection_strategy_
double calc_speed_before_decel(double stop_time, double stop_dist, double current_speed) const
calculate the speed, right before the car starts to decelerate for stopping
SCIStrategicPluginConfig config_
Config containing configurable algorithm parameters.
carma_v2x_msgs::msg::MobilityOperation generateMobilityOperation()
Generates Mobility Operation messages.
void mobilityOperationCb(carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
callback function for mobility operation
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::BSM > bsm_sub_
double findSpeedLimit(const lanelet::ConstLanelet &llt) const
Given a Lanelet, find it's associated Speed Limit.
std::string get_version_id()
Returns the version id of this plugin.
void caseOneSpeedProfile(double speed_before_decel, double current_speed, double stop_time, std::vector< double > *float_metadata_list) const
Determine the desired speed profile parameters for Case 1.
carma_planning_msgs::msg::Maneuver composeStopAndWaitManeuverMessage(double current_dist, double end_dist, double start_speed, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id, double stopping_accel, rclcpp::Time start_time, rclcpp::Time end_time) const
SCIStrategicPlugin(const rclcpp::NodeOptions &)
Default constructor for RouteFollowingPlugin class.
carma_planning_msgs::msg::Maneuver composeLaneFollowingManeuverMessage(int case_num, double start_dist, double end_dist, double start_speed, double target_speed, rclcpp::Time start_time, double time_to_stop, std::vector< lanelet::Id > lane_ids)
Compose a lane keeping maneuver message based on input params.
void caseTwoSpeedProfile(double stop_dist, double speed_before_decel, double current_speed, double stop_time, double speed_limit, std::vector< double > *float_metadata_list) const
Determine the desired speed profile parameters for Case 2.
TurnDirection intersection_turn_direction_
auto to_string(const UtmZone &zone) -> std::string
double getManeuverEndSpeed(const carma_planning_msgs::msg::Maneuver &mvr)
Anonymous function to extract maneuver end speed which can not be optained with GET_MANEUVER_PROPERY ...
#define GET_MANEUVER_PROPERTY(mvr, property)
Struct to store the configuration settings for the WzStrategicPlugin class.
double intersection_exit_zone_length
std::string strategic_plugin_name
The name to use for this plugin during comminications with the arbitrator.
double min_maneuver_planning_period
The minimum period in seconds which a maneuver plan must cover if the plugin wishes to control the wh...
std::string lane_following_plugin_name
The name of the tactical plugin to use for Lane Following trajectory planning.
double vehicle_accel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle acceleration limit so we plan under our capabi...
double vehicle_decel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle deceleration limit so we plan under our capabi...
double vehicle_decel_limit
The maximum allowable vehicle deceleration limit in m/s.
std::string stop_and_wait_plugin_name
The name of the plugin to use for stop and wait trajectory planning.
std::string vehicle_id
License plate of the vehicle.
std::string intersection_transit_plugin_name
The name of the plugin to use for intersection transit trajectory planning.
double stop_line_buffer
A buffer infront of the stopping location which will still be considered a valid stop.
double vehicle_accel_limit
The maximum allowable vehicle acceleration limit in m/s.
Struct representing a vehicle state for the purposes of planning.