16#include <rclcpp/rclcpp.hpp>
17#include <rclcpp/parameter_client.hpp>
20#include <boost/uuid/uuid_generators.hpp>
21#include <boost/uuid/uuid_io.hpp>
23#include <lanelet2_core/geometry/Lanelet.h>
24#include <lanelet2_core/geometry/BoundingBox.h>
25#include <lanelet2_extension/traffic_rules/CarmaUSTrafficRules.h>
30 namespace std_ph = std::placeholders;
38 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
39 return mvr.lane_following_maneuver.end_speed;
40 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
41 return mvr.lane_change_maneuver.end_speed;
42 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
43 return mvr.intersection_transit_straight_maneuver.end_speed;
44 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
45 return mvr.intersection_transit_left_turn_maneuver.end_speed;
46 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
47 return mvr.intersection_transit_right_turn_maneuver.end_speed;
48 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
61 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
62 mvr.lane_change_maneuver.starting_lane_id =
std::to_string(start_id);
65 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
66 mvr.intersection_transit_straight_maneuver.starting_lane_id =
std::to_string(start_id);
67 mvr.intersection_transit_straight_maneuver.ending_lane_id =
std::to_string(end_id);
69 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
70 mvr.intersection_transit_left_turn_maneuver.starting_lane_id =
std::to_string(start_id);
71 mvr.intersection_transit_left_turn_maneuver.ending_lane_id =
std::to_string(end_id);
73 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
74 mvr.intersection_transit_right_turn_maneuver.starting_lane_id =
std::to_string(start_id);
75 mvr.intersection_transit_right_turn_maneuver.ending_lane_id =
std::to_string(end_id);
77 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
78 mvr.stop_and_wait_maneuver.starting_lane_id =
std::to_string(start_id);
79 mvr.stop_and_wait_maneuver.ending_lane_id =
std::to_string(end_id);
82 throw std::invalid_argument(
"Maneuver type does not have start,end lane ids");
118 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"route_following_plugin"),
"RouteFollowingPlugin Config: " <<
config_);
121 twist_sub_ = create_subscription<geometry_msgs::msg::TwistStamped>(
"current_velocity", 50,
132 wml_->setRouteCallback([
this]() {
133 RCLCPP_INFO_STREAM(get_logger(),
"Recomputing maneuvers due to a route update");
137 wml_->setMapCallback([
this]() {
138 if (
wm_->getRoute()) {
139 RCLCPP_INFO_STREAM(get_logger(),
"Recomputing maneuvers due to map update");
147 return CallbackReturn::SUCCESS;
153 std::chrono::milliseconds(100),
157 return CallbackReturn::SUCCESS;
173 for (
const auto& ll:route_shortest_path)
177 std::vector<carma_planning_msgs::msg::Maneuver> maneuvers;
179 RCLCPP_DEBUG_STREAM(get_logger(),
"New route created");
182 auto nearest_lanelets = lanelet::geometry::findNearest(
wm_->getMap()->laneletLayer,
current_loc_, 10);
183 if (nearest_lanelets.empty())
185 RCLCPP_WARN_STREAM(get_logger(),
"Cannot find any lanelet in map!");
190 maneuvers.reserve(route_shortest_path.size());
192 double route_length =
wm_->getRouteEndTrackPos().downtrack;
193 double start_dist = 0.0;
194 double end_dist = 0.0;
195 double start_speed = 0.0;
197 size_t shortest_path_index;
199 for (shortest_path_index = 0; shortest_path_index < route_shortest_path.size() - 1; ++shortest_path_index)
201 RCLCPP_DEBUG_STREAM(get_logger(),
"current shortest_path_index:" << shortest_path_index);
203 auto following_lanelets =
wm_->getRoute()->followingRelations(route_shortest_path[shortest_path_index]);
204 RCLCPP_DEBUG_STREAM(get_logger(),
"following_lanelets.size():" << following_lanelets.size());
206 double target_speed_in_lanelet =
findSpeedLimit(route_shortest_path[shortest_path_index]);
209 start_dist = (maneuvers.empty()) ?
wm_->routeTrackPos(route_shortest_path[shortest_path_index].centerline2d().front()).downtrack :
GET_MANEUVER_PROPERTY(maneuvers.back(), end_dist);
211 RCLCPP_DEBUG_STREAM(get_logger(),
"start_dist:" << start_dist <<
", start_speed:" << start_speed);
213 end_dist =
wm_->routeTrackPos(route_shortest_path[shortest_path_index].centerline2d().back()).downtrack;
214 RCLCPP_DEBUG_STREAM(get_logger(),
"end_dist:" << end_dist);
215 end_dist = std::min(end_dist, route_length);
216 RCLCPP_DEBUG_STREAM(get_logger(),
"min end_dist:" << end_dist);
218 if (std::fabs(start_dist - end_dist) < 0.1)
220 RCLCPP_WARN_STREAM(get_logger(),
"start and end dist are equal! shortest path id" << shortest_path_index <<
", lanelet id:" << route_shortest_path[shortest_path_index].
id() <<
221 ", start and end dist:" << start_dist);
227 if (
isLaneChangeNeeded(following_lanelets, route_shortest_path[shortest_path_index + 1].
id()))
229 RCLCPP_DEBUG_STREAM(get_logger(),
"LaneChangeNeeded");
232 RCLCPP_DEBUG_STREAM(get_logger(),
"Recording lanechange start_dist <<" << start_dist <<
", from llt id:" << route_shortest_path[shortest_path_index].
id() <<
" to llt id: " <<
233 route_shortest_path[shortest_path_index+ 1].
id());
235 maneuvers.push_back(
composeLaneChangeManeuverMessage(start_dist, end_dist, start_speed, target_speed_in_lanelet, route_shortest_path[shortest_path_index].
id(), route_shortest_path[shortest_path_index + 1].
id()));
236 ++shortest_path_index;
241 RCLCPP_DEBUG_STREAM(get_logger(),
"Lanechange NOT Needed ");
247 if (shortest_path_index < route_shortest_path.size())
261 RCLCPP_DEBUG_STREAM(get_logger(),
"Maneuver plan along route successfully generated");
266 const std::vector<carma_planning_msgs::msg::Maneuver>& input_maneuvers,
267 double route_end_downtrack,
double stopping_entry_speed,
double stopping_logitudinal_accel,
268 double lateral_accel_limit,
double min_maneuver_length
271 RCLCPP_INFO_STREAM(get_logger(),
"Attempting to plan Stop and Wait Maneuver");
280 std::vector<carma_planning_msgs::msg::Maneuver> maneuvers = input_maneuvers;
285 double stopping_distance = 0.5 * (stopping_entry_speed * stopping_entry_speed) / stopping_logitudinal_accel;
288 double required_start_downtrack = std::max(0.0, route_end_downtrack - stopping_distance);
293 RCLCPP_WARN_STREAM(get_logger(),
"Dropping maneuver with id: " <<
GET_MANEUVER_PROPERTY(maneuvers.back(), parameters.maneuver_id) );
295 if (maneuvers.back().type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE) {
298 throw std::invalid_argument(
"Stopping at the end of the route requires replanning a lane change. RouteFollowing cannot yet handle this case");
301 maneuvers.pop_back();
305 double last_maneuver_end_downtrack = required_start_downtrack;
307 if ( !maneuvers.empty() ) {
312 if ( required_start_downtrack >= last_maneuver_end_downtrack ) {
316 if (required_start_downtrack - last_maneuver_end_downtrack > min_maneuver_length) {
319 std::vector<lanelet::ConstLanelet> crossed_lanelets =
wm_->getLaneletsBetween(last_maneuver_end_downtrack, required_start_downtrack,
true,
false);
321 if (crossed_lanelets.empty()) {
322 throw std::invalid_argument(
"The new lane follow maneuver does not cross any lanelets going from: " +
std::to_string(last_maneuver_end_downtrack) +
" to: " +
std::to_string(required_start_downtrack));
326 maneuvers.push_back(
composeLaneFollowingManeuverMessage(last_maneuver_end_downtrack, required_start_downtrack, stopping_entry_speed, stopping_entry_speed, lanelet::utils::transform(crossed_lanelets, [](
auto ll) {
return ll.id(); })));
329 last_maneuver_end_downtrack = required_start_downtrack;
331 RCLCPP_DEBUG_STREAM(get_logger(),
"Stop and wait maneuver being extended to nearest maneuver which is closer than the minimum maneuver length");
340 std::vector<lanelet::ConstLanelet> crossed_lanelets =
wm_->getLaneletsBetween(
GET_MANEUVER_PROPERTY(maneuvers.back(), start_dist), required_start_downtrack,
true,
false);
342 if (crossed_lanelets.empty()) {
347 if (maneuvers.back().type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING) {
349 maneuvers.back().lane_following_maneuver.lane_ids = lanelet::utils::transform(crossed_lanelets, [](
auto ll) {
return std::to_string(ll.id()); });
353 setManeuverLaneletIds(maneuvers.back(), crossed_lanelets.front().id(), crossed_lanelets.back().id());
357 last_maneuver_end_downtrack = required_start_downtrack;
363 std::vector<lanelet::ConstLanelet> crossed_lanelets =
wm_->getLaneletsBetween(last_maneuver_end_downtrack, route_end_downtrack,
true,
false);
365 if (crossed_lanelets.empty()) {
367 throw std::invalid_argument(
"Stopping maneuver does not cross any lanelets going from: " +
std::to_string(last_maneuver_end_downtrack) +
" to: " +
std::to_string(route_end_downtrack));
371 lanelet::Id start_lane = crossed_lanelets.front().id();
372 lanelet::Id end_lane = crossed_lanelets.back().id();
375 maneuvers.push_back(
composeStopAndWaitManeuverMessage(last_maneuver_end_downtrack, route_end_downtrack, stopping_entry_speed, start_lane, end_lane,stopping_logitudinal_accel));
383 if (maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE) {
386 double lane_change_time = sqrt(0.5 *
MAX_LANE_WIDTH / lateral_accel);
389 double min_lane_change_distance = std::max(
414 std::shared_ptr<rmw_request_id_t> srv_header,
415 carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req,
416 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
421 RCLCPP_ERROR_STREAM(get_logger(),
"A maneuver plan has not been generated");
425 double current_downtrack;
427 if (!req->prior_plan.maneuvers.empty())
430 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected a prior plan! Using back maneuver's end_dist:"<< current_downtrack);
434 current_downtrack = req->veh_downtrack;
435 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected NO prior plan! Using req.veh_downtrack: "<< current_downtrack);
440 double planned_time = 0.0;
442 std::vector<carma_planning_msgs::msg::Maneuver> new_maneuvers;
446 RCLCPP_DEBUG_STREAM(get_logger(),
"Checking maneuver id " <<
i);
450 RCLCPP_DEBUG_STREAM(get_logger(),
"Skipping maneuver id " <<
i);
455 if(planned_time == 0.0){
465 if (new_maneuvers.empty())
467 RCLCPP_WARN_STREAM(get_logger(),
"Cannot plan maneuver because no route is found");
472 if (!req->prior_plan.maneuvers.empty())
475 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected a prior plan! Using back maneuver's end time:"<<
std::to_string(rclcpp::Time(
GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_time)).seconds()));
476 RCLCPP_DEBUG_STREAM(get_logger(),
"Where plan_completion_time was:"<<
std::to_string(rclcpp::Time(req->prior_plan.planning_completion_time).seconds()));
481 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected NO prior plan! Using this->now():"<<
std::to_string(this->now().seconds()));
485 if (!req->prior_plan.maneuvers.empty())
488 switch (req->prior_plan.maneuvers.back().type)
490 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
491 start_speed = req->prior_plan.maneuvers.back().lane_following_maneuver.end_speed;
493 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
494 start_speed = req->prior_plan.maneuvers.back().lane_change_maneuver.end_speed;
496 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
497 start_speed = req->prior_plan.maneuvers.back().intersection_transit_straight_maneuver.end_speed;
499 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
500 start_speed = req->prior_plan.maneuvers.back().intersection_transit_left_turn_maneuver.end_speed;
502 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
503 start_speed = req->prior_plan.maneuvers.back().intersection_transit_right_turn_maneuver.end_speed;
506 throw std::invalid_argument(
"Invalid maneuver type, cannot update starting speed for maneuver");
510 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected a prior plan! Using back maneuver's end speed:"<< start_speed);
515 RCLCPP_DEBUG_STREAM(get_logger(),
"Detected NO prior plan! Using req->veh_logitudinal_velocity:"<< req->veh_logitudinal_velocity);
518 resp->new_plan = req->prior_plan;
519 RCLCPP_DEBUG_STREAM(get_logger(),
"Updating maneuvers before returning... Prior plan size:" << req->prior_plan.maneuvers.size());
520 for (
const auto& mvr : new_maneuvers)
522 resp->new_plan.maneuvers.push_back(mvr);
525 RCLCPP_DEBUG_STREAM(get_logger(),
"Returning total of maneuver size: " << resp->new_plan.maneuvers.size());
526 resp->new_plan.planning_completion_time = this->now();
533 RCLCPP_DEBUG_STREAM(get_logger(),
"Entering pose_cb");
535 RCLCPP_DEBUG_STREAM(get_logger(),
"Looking up front bumper pose...");
539 tf_ =
tf2_buffer_.lookupTransform(
"map",
"vehicle_front", rclcpp::Time(0), rclcpp::Duration(1, 0));
542 catch (
const tf2::TransformException &ex)
544 RCLCPP_WARN_STREAM(get_logger(),std::string(ex.what()));
547 geometry_msgs::msg::Pose front_bumper_pose;
551 if (!
wm_->getRoute())
554 lanelet::BasicPoint2d current_loc(front_bumper_pose.position.x, front_bumper_pose.position.y);
556 double current_progress =
wm_->routeTrackPos(current_loc).downtrack;
558 RCLCPP_DEBUG_STREAM(get_logger(),
"pose_cb : current_progress" << current_progress);
566 auto llts =
wm_->getLaneletsFromPoint(current_loc, 10);
568 llts.erase(std::remove_if(llts.begin(), llts.end(),
569 [&](
auto lanelet) ->
bool { return !wm_->getRoute()->contains(lanelet); }),
576 if (llts.size() > 1) {
580 RCLCPP_WARN_STREAM(get_logger(),
"ANOMALOUS SIZE DETECTED FOR CURRENT LANELET CANDIDATES! SIZE: " << llts.size());
581 }
else if (llts.size() < 1) {
583 RCLCPP_ERROR_STREAM(get_logger(),
"Vehicle has left the route entirely. Unable to compute new shortest path.");
584 throw std::domain_error(
"Vehicle not on route, unable to compute shortest path.");
587 const auto& current_lanelet = llts[0];
588 RCLCPP_DEBUG_STREAM(get_logger(),
"Vehicle is currently in lanelet " << current_lanelet.id());
593 RCLCPP_DEBUG_STREAM(get_logger(),
"Generating a new shortest path since the vehicle is not on the shortest path");
601 RCLCPP_DEBUG_STREAM(get_logger(),
"Generating a new shortest path since vehicle is positioned in a lane change but the previous maneuver plan was not generated by route_following_plugin");
613 double cur_plus_target = maneuver_start_speed + manever_end_speed;
614 if(cur_plus_target < epsilon){
615 throw std::invalid_argument(
"Maneuver start and ending speed is zero");
617 rclcpp::Duration duration{0,0};
621 RCLCPP_DEBUG_STREAM(get_logger(),
"maneuver_end_dist: " << maneuver_end_dist <<
", maneuver_start_dist: " << maneuver_start_dist <<
", cur_plus_target: " << cur_plus_target);
623 duration = rclcpp::Duration((maneuver_end_dist - maneuver_start_dist) / (0.5 * cur_plus_target) * 1e9);
630 rclcpp::Time time_progress = start_time;
631 rclcpp::Time prev_time = time_progress;
633 for (
auto &maneuver : maneuvers)
636 switch (maneuver.type)
638 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
639 maneuver.lane_following_maneuver.start_time = prev_time;
640 maneuver.lane_following_maneuver.end_time = time_progress;
642 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
643 maneuver.lane_change_maneuver.start_time = prev_time;
644 maneuver.lane_change_maneuver.end_time = time_progress;
646 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
647 maneuver.intersection_transit_straight_maneuver.start_time = prev_time;
648 maneuver.intersection_transit_straight_maneuver.end_time = time_progress;
650 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
651 maneuver.intersection_transit_left_turn_maneuver.start_time = prev_time;
652 maneuver.intersection_transit_left_turn_maneuver.end_time = time_progress;
654 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
655 maneuver.intersection_transit_right_turn_maneuver.start_time = prev_time;
656 maneuver.intersection_transit_right_turn_maneuver.end_time = time_progress;
658 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
659 maneuver.stop_and_wait_maneuver.start_time = prev_time;
660 maneuver.stop_and_wait_maneuver.start_time = time_progress;
661 maneuver.stop_and_wait_maneuver.end_time = start_time + rclcpp::Duration(86400, 0);
664 throw std::invalid_argument(
"Invalid maneuver type, cannot update time progress for maneuver");
666 prev_time = time_progress;
672 switch (maneuver.type)
674 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
675 maneuver.lane_following_maneuver.start_speed = start_speed;
677 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
678 maneuver.lane_change_maneuver.start_speed = start_speed;
680 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
681 maneuver.intersection_transit_straight_maneuver.start_speed = start_speed;
683 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
684 maneuver.intersection_transit_left_turn_maneuver.start_speed = start_speed;
686 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
687 maneuver.intersection_transit_right_turn_maneuver.start_speed = start_speed;
689 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
690 maneuver.stop_and_wait_maneuver.start_speed = start_speed;
693 throw std::invalid_argument(
"Invalid maneuver type, cannot update starting speed for maneuver");
699 switch (maneuver.type)
701 case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
702 maneuver.lane_following_maneuver.start_dist = start_dist;
704 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
705 maneuver.lane_change_maneuver.start_dist = start_dist;
707 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
708 maneuver.intersection_transit_straight_maneuver.start_dist = start_dist;
710 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
711 maneuver.intersection_transit_left_turn_maneuver.start_dist = start_dist;
713 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
714 maneuver.intersection_transit_right_turn_maneuver.start_dist = start_dist;
716 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
717 maneuver.stop_and_wait_maneuver.start_dist = start_dist;
720 throw std::invalid_argument(
"Invalid maneuver type");
726 carma_planning_msgs::msg::Maneuver maneuver_msg;
727 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
728 maneuver_msg.lane_following_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
729 maneuver_msg.lane_following_maneuver.parameters.presence_vector = carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
732 maneuver_msg.lane_following_maneuver.start_dist = start_dist;
733 maneuver_msg.lane_following_maneuver.start_speed = start_speed;
734 maneuver_msg.lane_following_maneuver.end_dist = end_dist;
735 maneuver_msg.lane_following_maneuver.end_speed = target_speed;
736 maneuver_msg.lane_following_maneuver.lane_ids = lanelet::utils::transform(lane_ids, [](
auto id) {
return std::to_string(
id); });
741 maneuver_msg.lane_following_maneuver.parameters.maneuver_id =
getNewManeuverId();
743 std::stringstream ss;
744 for (
const auto&
id : maneuver_msg.lane_following_maneuver.lane_ids)
747 RCLCPP_DEBUG_STREAM(get_logger(),
"Creating lane follow id: " << maneuver_msg.lane_following_maneuver.parameters.maneuver_id
748 <<
" start dist: " << start_dist <<
" end dist: " << end_dist <<
"lane_ids: " << ss.str());
755 carma_planning_msgs::msg::Maneuver maneuver_msg;
756 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_CHANGE;
757 maneuver_msg.lane_change_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
758 maneuver_msg.lane_change_maneuver.parameters.presence_vector = carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
759 maneuver_msg.lane_change_maneuver.parameters.planning_tactical_plugin =
lane_change_plugin_;
761 maneuver_msg.lane_change_maneuver.start_dist = start_dist;
762 maneuver_msg.lane_change_maneuver.start_speed = start_speed;
763 maneuver_msg.lane_change_maneuver.end_dist = end_dist;
764 maneuver_msg.lane_change_maneuver.end_speed = target_speed;
765 maneuver_msg.lane_change_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
766 maneuver_msg.lane_change_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
771 maneuver_msg.lane_change_maneuver.parameters.maneuver_id =
getNewManeuverId();
773 RCLCPP_DEBUG_STREAM(get_logger(),
"Creating lane change id: " << maneuver_msg.lane_change_maneuver.parameters.maneuver_id <<
"start dist: " << start_dist <<
" end dist: " << end_dist <<
" Starting llt: " << starting_lane_id <<
" Ending llt: " << ending_lane_id);
779 static auto gen = boost::uuids::random_generator();
781 return boost::lexical_cast<std::string>(gen());
786 carma_planning_msgs::msg::Maneuver maneuver_msg;
787 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
788 maneuver_msg.stop_and_wait_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
789 maneuver_msg.stop_and_wait_maneuver.parameters.presence_vector = carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN
790 | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA;
793 maneuver_msg.stop_and_wait_maneuver.start_dist = start_dist;
794 maneuver_msg.stop_and_wait_maneuver.start_speed = start_speed;
795 maneuver_msg.stop_and_wait_maneuver.end_dist = end_dist;
796 maneuver_msg.stop_and_wait_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
797 maneuver_msg.stop_and_wait_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
802 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
806 maneuver_msg.stop_and_wait_maneuver.parameters.maneuver_id =
getNewManeuverId();
808 RCLCPP_DEBUG_STREAM(get_logger(),
"Creating stop and wait maneuver id:" << maneuver_msg.stop_and_wait_maneuver.parameters.maneuver_id <<
"start dist: " << start_dist <<
" end dist: " << end_dist <<
" start_speed: " << start_speed <<
" Starting llt: " << starting_lane_id <<
" Ending llt: " << ending_lane_id);
816 for (
auto &relation : relations)
818 if (relation.lanelet.id() == target_id && relation.relationType == lanelet::routing::RelationType::Successor)
828 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules =
wm_->getTrafficRules();
831 return (*traffic_rules)->speedLimit(llt).speedLimit.value();
835 throw std::invalid_argument(
"Valid traffic rules object could not be built");
847 auto original_shortestpath =
wm_->getRoute()->shortestPath();
848 RCLCPP_DEBUG_STREAM(get_logger(),
"The vehicle has left the shortest path");
849 auto routing_graph =
wm_->getMapRoutingGraph();
852 auto current_lane_following_lanelets = routing_graph->following(current_lanelet);
853 lanelet::ConstLanelet current_lane_following_lanelet;
854 if(!current_lane_following_lanelets.empty()){
855 current_lane_following_lanelet = current_lane_following_lanelets[0];
858 throw std::invalid_argument(
"The current lanelet does not have a following lanelet. Vehicle cannot return to shortest path!");
863 auto adjacent_lanelets = routing_graph->besides(current_lane_following_lanelet);
864 if (!adjacent_lanelets.empty())
866 for (
const auto& adjacent:adjacent_lanelets)
870 auto following_lanelets = routing_graph->following(adjacent);
871 const auto& target_following_lanelet = following_lanelets[0];
872 RCLCPP_DEBUG_STREAM(get_logger(),
"The target_following_lanelet id is: " << target_following_lanelet.id());
873 lanelet::ConstLanelets interm;
874 interm.push_back(
static_cast<lanelet::ConstLanelet
>(current_lane_following_lanelet));
875 interm.push_back(
static_cast<lanelet::ConstLanelet
>(target_following_lanelet));
877 auto new_shortestpath = routing_graph->shortestPathVia(current_lanelet, interm, original_shortestpath.back());
878 RCLCPP_DEBUG_STREAM(get_logger(),
"a new shortestpath is generated to return to original shortestpath");
886 lanelet::ConstLanelets new_interm;
887 new_interm.push_back(
static_cast<lanelet::ConstLanelet
>(current_lane_following_lanelet));
888 auto new_shortestpath = routing_graph->shortestPathVia(current_lanelet, new_interm, original_shortestpath.back());
889 RCLCPP_DEBUG_STREAM(get_logger(),
"Cannot return to the original shortestpath from adjacent lanes, so a new shortestpath is generated");
898 RCLCPP_WARN_STREAM(get_logger(),
"Alternative shortest path cannot be generated");
905#include "rclcpp_components/register_node_macro.hpp"
#define GET_MANEUVER_PROPERTY(mvr, property)
Macro definition to enable easier access to fields shared across the maneuver types.
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...
virtual std::shared_ptr< carma_wm::WMListener > get_world_model_listener() final
Method to return the default world model listener provided as a convience by this base class If this ...
carma_ros2_utils::CallbackReturn on_configure_plugin()
Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states....
std::string get_version_id()
Returns the version id of this plugin.
void initializeBumperTransformLookup()
Initialize transform lookup from front bumper to map.
static constexpr double MAX_LANE_WIDTH
std::vector< carma_planning_msgs::msg::Maneuver > latest_maneuver_plan_
std::string lane_change_plugin_
std::unordered_set< lanelet::Id > shortest_path_set_
std::unique_ptr< tf2_ros::TransformListener > tf2_listener_
std::string stop_and_wait_plugin_
tf2::Stamped< tf2::Transform > frontbumper_transform_
void updateTimeProgress(std::vector< carma_planning_msgs::msg::Maneuver > &maneuvers, rclcpp::Time start_time) const
Given an array of maneuvers update the starting time for each.
carma_planning_msgs::msg::Maneuver composeLaneChangeManeuverMessage(double start_dist, double end_dist, double start_speed, double target_speed, lanelet::Id starting_lane_id, lanelet::Id ending_lane_id) const
Compose a lane change maneuver message based on input params NOTE: The start and stop time are not se...
std::string getNewManeuverId() const
This method returns a new UUID as a string for assignment to a Maneuver message.
lanelet::BasicPoint2d current_loc_
std::string lanefollow_planning_tactical_plugin_
bool maneuverWithBufferStartsAfterDowntrack(const carma_planning_msgs::msg::Maneuver &maneuver, double downtrack, double lateral_accel, double min_maneuver_length) const
Identifies if a maneuver starts after the provided downtrack with compensation for a dynamic buffer s...
std::vector< carma_planning_msgs::msg::Maneuver > routeCb(const lanelet::routing::LaneletPath &route_shortest_path)
Calculate maneuver plan for remaining route. This callback is triggered when a new route has been rec...
carma_planning_msgs::msg::Maneuver composeLaneFollowingManeuverMessage(double start_dist, double end_dist, double start_speed, double target_speed, const std::vector< lanelet::Id > &lane_ids) const
Compose a lane keeping maneuver message based on input params.
void setManeuverStartDist(carma_planning_msgs::msg::Maneuver &maneuver, double start_dist) const
Set the start distance of a maneuver based on the progress along the route.
carma_planning_msgs::msg::ManeuverPlan::UniquePtr current_maneuver_plan_
void bumper_pose_cb()
Callback for the front bumper pose transform.
void updateStartingSpeed(carma_planning_msgs::msg::Maneuver &maneuver, double start_speed) const
Given an maneuver update the starting speed.
rclcpp::TimerBase::SharedPtr bumper_pose_timer_
void current_maneuver_plan_cb(carma_planning_msgs::msg::ManeuverPlan::UniquePtr msg)
Callback for the ManeuverPlan subscriber, will store the current maneuver plan received locally....
void twist_cb(geometry_msgs::msg::TwistStamped::UniquePtr msg)
Callback for the twist subscriber, which will store latest twist locally.
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 findSpeedLimit(const lanelet::ConstLanelet &llt)
Given a Lanelet, find it's associated Speed Limit.
bool isLaneChangeNeeded(lanelet::routing::LaneletRelations relations, lanelet::Id target_id) const
Given a LaneletRelations and ID of the next lanelet in the shortest path.
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::ManeuverPlan > current_maneuver_plan_sub_
carma_ros2_utils::CallbackReturn on_activate_plugin()
Method which is triggered when this plugin is moved from the INACTIVE to ACTIVE states....
std::shared_ptr< carma_wm::WMListener > wml_
rclcpp::Duration getManeuverDuration(carma_planning_msgs::msg::Maneuver &maneuver, double epsilon) const
returns duration as ros::Duration required to complete maneuver given its start dist,...
void returnToShortestPath(const lanelet::ConstLanelet ¤t_lanelet)
This method re-routes the vehicle back to the shortest path, if the vehicle has left the shortest pat...
carma_ros2_utils::SubPtr< geometry_msgs::msg::TwistStamped > twist_sub_
std::string planning_strategic_plugin_
RouteFollowingPlugin(const rclcpp::NodeOptions &)
Default constructor for RouteFollowingPlugin class.
carma_planning_msgs::msg::Maneuver composeStopAndWaitManeuverMessage(double start_dist, double end_dist, double start_speed, lanelet::Id starting_lane_id, lanelet::Id ending_lane_id, double stopping_accel) const
Compose a stop and wait maneuver message based on input params. NOTE: The start and stop time are not...
tf2_ros::Buffer tf2_buffer_
geometry_msgs::msg::TransformStamped tf_
std::vector< carma_planning_msgs::msg::Maneuver > addStopAndWaitAtRouteEnd(const std::vector< carma_planning_msgs::msg::Maneuver > &input_maneuvers, double route_end_downtrack, double stopping_entry_speed, double stopping_logitudinal_accel, double lateral_accel_limit, double min_maneuver_length) const
Adds a StopAndWait maneuver to the end of a maneuver set stopping at the provided downtrack value NOT...
bool get_availability()
Get the availability status of this plugin based on the current operating environment....
carma_wm::WorldModelConstPtr wm_
auto to_string(const UtmZone &zone) -> std::string
void setManeuverLaneletIds(carma_planning_msgs::msg::Maneuver &mvr, lanelet::Id start_id, lanelet::Id end_id)
Anonymous function to set the lanelet ids for all maneuver types except lane following.
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 SET_MANEUVER_PROPERTY(mvr, property, value)
Struct containing config values values for route_following_plugin.
double min_plan_duration_
std::string lanefollow_planning_tactical_plugin_
double route_end_point_buffer_
std::string lane_change_plugin_
std::string stop_and_wait_plugin_
double lateral_accel_limit_
double min_maneuver_length_
double stopping_accel_limit_multiplier_