18#include <unordered_set>
24 namespace std_ph = std::placeholders;
34 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Updating maneuver starting_lane_id to " << start_id);
37 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
38 mvr.lane_change_maneuver.starting_lane_id =
std::to_string(start_id);
40 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
41 mvr.intersection_transit_straight_maneuver.starting_lane_id =
std::to_string(start_id);
43 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
44 mvr.intersection_transit_left_turn_maneuver.starting_lane_id =
std::to_string(start_id);
46 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
47 mvr.intersection_transit_right_turn_maneuver.starting_lane_id =
std::to_string(start_id);
49 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
50 mvr.stop_and_wait_maneuver.starting_lane_id =
std::to_string(start_id);
53 throw std::invalid_argument(
"Maneuver type does not have starting and ending lane ids");
63 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Updating maneuver ending_lane_id to " << end_id);
66 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
69 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
70 mvr.intersection_transit_straight_maneuver.ending_lane_id =
std::to_string(end_id);
72 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
73 mvr.intersection_transit_left_turn_maneuver.ending_lane_id =
std::to_string(end_id);
75 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
76 mvr.intersection_transit_right_turn_maneuver.ending_lane_id =
std::to_string(end_id);
78 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
79 mvr.stop_and_wait_maneuver.ending_lane_id =
std::to_string(end_id);
82 throw std::invalid_argument(
"Maneuver type does not have starting and ending lane ids");
93 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
94 return mvr.lane_change_maneuver.starting_lane_id;
95 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
96 return mvr.intersection_transit_straight_maneuver.starting_lane_id;
97 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
98 return mvr.intersection_transit_left_turn_maneuver.starting_lane_id;
99 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
100 return mvr.intersection_transit_right_turn_maneuver.starting_lane_id;
101 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
102 return mvr.stop_and_wait_maneuver.starting_lane_id;
104 throw std::invalid_argument(
"Maneuver type does not have starting and ending lane ids");
115 case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
116 return mvr.lane_change_maneuver.ending_lane_id;
117 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT:
118 return mvr.intersection_transit_straight_maneuver.ending_lane_id;
119 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN:
120 return mvr.intersection_transit_left_turn_maneuver.ending_lane_id;
121 case carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN:
122 return mvr.intersection_transit_right_turn_maneuver.ending_lane_id;
123 case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
124 return mvr.stop_and_wait_maneuver.ending_lane_id;
126 throw std::invalid_argument(
"Maneuver type does not have starting and ending lane ids");
133 tf2_buffer_(std::make_shared<tf2_ros::Buffer>(this->get_clock())),
134 wml_(this->get_node_base_interface(), this->get_node_logging_interface(),
135 this->get_node_topics_interface(), this->get_node_parameters_interface())
169 traj_pub_ = create_publisher<carma_planning_msgs::msg::TrajectoryPlan>(
"plan_trajectory", 5);
175 yield_client_ = create_client<carma_planning_msgs::srv::PlanTrajectory>(
"plugins/yield_plugin/plan_trajectory");
179 twist_sub_ = create_subscription<geometry_msgs::msg::TwistStamped>(
"current_velocity", 5,
180 [
this](geometry_msgs::msg::TwistStamped::UniquePtr twist) {this->
latest_twist_ = *twist;});
186 return CallbackReturn::SUCCESS;
195 return CallbackReturn::SUCCESS;
205 RCLCPP_INFO_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Received request to delegate plan ID " << std::string(plan->maneuver_plan_id));
207 auto copy_plan = *plan;
220 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Received empty plan, no maneuvers found in plan ID " << std::string(plan->maneuver_plan_id));
227 double current_downtrack =
wm_->routeTrackPos(current_loc).downtrack;
232 if(maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE){
233 if(current_downtrack >= maneuver.lane_change_maneuver.start_dist){
268 lane_change_information.
starting_downtrack = lane_change_maneuver.lane_change_maneuver.start_dist;
271 lanelet::ConstLanelet starting_lanelet =
wm_->getMap()->laneletLayer.get(std::stoi(lane_change_maneuver.lane_change_maneuver.starting_lane_id));
272 lanelet::ConstLanelet ending_lanelet =
wm_->getMap()->laneletLayer.get(std::stoi(lane_change_maneuver.lane_change_maneuver.ending_lane_id));
283 boost::optional<bool> is_right_lane_change;
285 if(starting_lanelet.leftBound() == ending_lanelet.rightBound()){
287 is_right_lane_change =
false;
289 else if(starting_lanelet.rightBound() == ending_lanelet.leftBound()){
291 is_right_lane_change =
true;
295 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Searching for shared boundary with starting lanechange lanelet " <<
std::to_string(starting_lanelet.id()) <<
" and ending lanelet " <<
std::to_string(ending_lanelet.id()));
296 lanelet::ConstLanelet current_lanelet = starting_lanelet;
297 std::unordered_set<lanelet::Id> visited{current_lanelet.id()};
299 while(!is_right_lane_change){
301 auto following_lanelets =
wm_->getMapRoutingGraph()->following(current_lanelet,
false);
302 bool no_successor = following_lanelets.empty();
303 lanelet::ConstLanelet candidate_lanelet = no_successor ? current_lanelet : following_lanelets.front();
304 bool loop_detected = !no_successor && visited.count(candidate_lanelet.id()) > 0;
308 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"No following lanelets from lanelet " << current_lanelet.id()
309 <<
" reachable without a lane change (possibly closed or missing from the map); "
310 <<
"falling back to a geometric left/right estimate for lane change from "
311 << starting_lanelet.id() <<
" to " << ending_lanelet.id());
316 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Detected a routing loop while searching for a shared boundary between lanelet "
317 << starting_lanelet.id() <<
" and " << ending_lanelet.id() <<
"; falling back to a geometric left/right estimate");
320 if(no_successor || loop_detected)
325 current_lanelet = candidate_lanelet;
326 visited.insert(current_lanelet.id());
329 if(current_lanelet.leftBound() == ending_lanelet.rightBound()){
331 is_right_lane_change =
false;
333 else if(current_lanelet.rightBound() == ending_lanelet.leftBound()){
335 is_right_lane_change =
true;
340 if(!is_right_lane_change)
346 lanelet::BasicLineString2d starting_centerline = starting_lanelet.centerline2d().basicLineString();
347 lanelet::BasicPoint2d start_pt = starting_centerline.front();
348 lanelet::BasicPoint2d heading_vec = starting_centerline.back() - start_pt;
349 lanelet::BasicPoint2d to_target = ending_lanelet.centerline2d().basicLineString().front() - start_pt;
350 double cross = heading_vec.x() * to_target.y() - heading_vec.y() * to_target.x();
352 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Could not find a shared lane boundary between starting lanelet "
353 << starting_lanelet.id() <<
" and ending lanelet " << ending_lanelet.id()
354 <<
"; estimating lane change direction geometrically instead.");
356 is_right_lane_change = (cross < 0.0);
360 return lane_change_information;
365 carma_planning_msgs::msg::UpcomingLaneChangeStatus upcoming_lane_change_status;
368 if(upcoming_lane_change_information){
371 double current_downtrack =
wm_->routeTrackPos(current_loc).downtrack;
372 upcoming_lane_change_status.downtrack_until_lanechange = std::max(0.0, upcoming_lane_change_information.get().starting_downtrack - current_downtrack);
375 if(upcoming_lane_change_information.get().is_right_lane_change){
376 upcoming_lane_change_status.lane_change = carma_planning_msgs::msg::UpcomingLaneChangeStatus::RIGHT;
379 upcoming_lane_change_status.lane_change = carma_planning_msgs::msg::UpcomingLaneChangeStatus::LEFT;
383 upcoming_lane_change_status.lane_change = carma_planning_msgs::msg::UpcomingLaneChangeStatus::NONE;
393 void PlanDelegator::publishTurnSignalCommand(
const boost::optional<LaneChangeInformation>& current_lane_change_information,
const carma_planning_msgs::msg::UpcomingLaneChangeStatus& upcoming_lane_change_status)
397 autoware_msgs::msg::LampCmd turn_signal_command;
400 if(current_lane_change_information){
402 if(current_lane_change_information.get().is_right_lane_change){
403 turn_signal_command.r = 1;
406 turn_signal_command.l = 1;
410 else if(upcoming_lane_change_status.lane_change != carma_planning_msgs::msg::UpcomingLaneChangeStatus::NONE){
413 if(upcoming_lane_change_status.lane_change == carma_planning_msgs::msg::UpcomingLaneChangeStatus::RIGHT){
414 turn_signal_command.r = 1;
417 turn_signal_command.l = 1;
433 if(planner_name.size() == 0)
435 throw std::invalid_argument(
"Invalid trajectory planner name because it has zero length!");
439 RCLCPP_INFO_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Discovered new trajectory planner: " << planner_name);
450 return !maneuver_plan.maneuvers.empty();
456 return !(trajectory_plan.trajectory_points.size() < 2);
464 bool isexpired = rclcpp::Time(
GET_MANEUVER_PROPERTY(maneuver, end_time), get_clock()->get_clock_type()) <= current_time;
470 std::shared_ptr<carma_planning_msgs::srv::PlanTrajectory::Request>
472 const carma_planning_msgs::msg::TrajectoryPlan& latest_trajectory_plan,
473 const carma_planning_msgs::msg::ManeuverPlan& locked_maneuver_plan,
474 const uint16_t& current_maneuver_index)
const
476 auto plan_req = std::make_shared<carma_planning_msgs::srv::PlanTrajectory::Request>();
477 plan_req->maneuver_plan = locked_maneuver_plan;
480 if(latest_trajectory_plan.trajectory_points.empty())
486 plan_req->vehicle_state.longitudinal_vel =
latest_twist_.twist.linear.x;
487 plan_req->vehicle_state.x_pos_global =
latest_pose_.pose.position.x;
488 plan_req->vehicle_state.y_pos_global =
latest_pose_.pose.position.y;
489 double roll, pitch, yaw;
491 plan_req->vehicle_state.orientation = yaw;
492 plan_req->maneuver_index_to_plan = current_maneuver_index;
497 carma_planning_msgs::msg::TrajectoryPlanPoint last_point = latest_trajectory_plan.trajectory_points.back();
498 carma_planning_msgs::msg::TrajectoryPlanPoint second_last_point = *(latest_trajectory_plan.trajectory_points.rbegin() + 1);
499 plan_req->vehicle_state.x_pos_global = last_point.x;
500 plan_req->vehicle_state.y_pos_global = last_point.y;
501 auto distance_diff = std::sqrt(std::pow(last_point.x - second_last_point.x, 2) + std::pow(last_point.y - second_last_point.y, 2));
502 rclcpp::Duration time_diff = rclcpp::Time(last_point.target_time) - rclcpp::Time(second_last_point.target_time);
503 auto time_diff_sec = time_diff.seconds();
504 plan_req->maneuver_index_to_plan = current_maneuver_index;
506 plan_req->header.stamp = latest_trajectory_plan.trajectory_points.back().target_time;
509 plan_req->vehicle_state.longitudinal_vel = distance_diff / time_diff_sec;
517 rclcpp::Duration time_diff = rclcpp::Time(plan.trajectory_points.back().target_time) - rclcpp::Time(plan.trajectory_points.front().target_time);
518 return time_diff.seconds() >= config_.max_trajectory_duration;
534 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"original_start_dist:" << original_start_dist);
535 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"adjusted_start_dist:" << adjusted_start_dist);
537 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"original_end_dist:" << original_end_dist);
538 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"adjusted_end_dist:" << adjusted_end_dist);
544 if(maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING && !maneuver.lane_following_maneuver.lane_ids.empty()){
548 lanelet::Id original_starting_lanelet_id = std::stoi(maneuver.lane_following_maneuver.lane_ids.front());
549 lanelet::ConstLanelet original_starting_lanelet =
wm_->getMap()->laneletLayer.get(original_starting_lanelet_id);
552 lanelet::BasicPoint2d original_starting_lanelet_centerline_start_point = lanelet::utils::to2D(original_starting_lanelet.centerline()).front();
553 double original_starting_lanelet_centerline_start_point_dt =
wm_->routeTrackPos(original_starting_lanelet_centerline_start_point).downtrack;
555 if(adjusted_start_dist < original_starting_lanelet_centerline_start_point_dt){
557 auto previous_lanelets =
wm_->getMapRoutingGraph()->previous(original_starting_lanelet,
false);
559 if(!previous_lanelets.empty()){
561 auto llt_on_route_optional =
wm_->getFirstLaneletOnShortestPath(previous_lanelets);
563 lanelet::ConstLanelet previous_lanelet_to_add;
565 if (llt_on_route_optional){
566 previous_lanelet_to_add = llt_on_route_optional.value();
569 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"When adjusting maneuver for lane follow, no previous lanelet found on the shortest path for lanelet "
570 << original_starting_lanelet.id() <<
". Picking arbitrary lanelet: " << previous_lanelets[0].id() <<
", instead");
571 previous_lanelet_to_add = previous_lanelets[0];
575 maneuver.lane_following_maneuver.lane_ids.insert(maneuver.lane_following_maneuver.lane_ids.begin(),
std::to_string(previous_lanelet_to_add.id()));
577 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Inserted lanelet " <<
std::to_string(previous_lanelet_to_add.id()) <<
" to beginning of maneuver.");
580 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"No previous lanelet was found for lanelet " << original_starting_lanelet.id());
585 lanelet::Id original_ending_lanelet_id = std::stoi(maneuver.lane_following_maneuver.lane_ids.back());
586 lanelet::ConstLanelet original_ending_lanelet =
wm_->getMap()->laneletLayer.get(original_ending_lanelet_id);
589 lanelet::BasicPoint2d original_ending_lanelet_centerline_start_point = lanelet::utils::to2D(original_ending_lanelet.centerline()).front();
590 double original_ending_lanelet_centerline_start_point_dt =
wm_->routeTrackPos(original_ending_lanelet_centerline_start_point).downtrack;
592 if(adjusted_end_dist < original_ending_lanelet_centerline_start_point_dt){
593 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Original ending lanelet " << original_ending_lanelet.id() <<
" removed from lane_ids since the updated maneuver no longer crosses it");
596 maneuver.lane_following_maneuver.lane_ids.pop_back();
599 else if (maneuver.type != carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING){
604 lanelet::ConstLanelet original_starting_lanelet =
wm_->getMap()->laneletLayer.get(original_starting_lanelet_id);
607 lanelet::BasicPoint2d original_starting_lanelet_centerline_start_point = lanelet::utils::to2D(original_starting_lanelet.centerline()).front();
608 double original_starting_lanelet_centerline_start_point_dt =
wm_->routeTrackPos(original_starting_lanelet_centerline_start_point).downtrack;
610 if(adjusted_start_dist < original_starting_lanelet_centerline_start_point_dt){
611 auto previous_lanelets =
wm_->getMapRoutingGraph()->previous(original_starting_lanelet,
false);
612 if(!previous_lanelets.empty()){
613 auto llt_on_route_optional =
wm_->getFirstLaneletOnShortestPath(previous_lanelets);
614 lanelet::ConstLanelet previous_lanelet_to_add;
616 if (llt_on_route_optional){
617 previous_lanelet_to_add = llt_on_route_optional.value();
620 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"When adjusting non-lane follow maneuver, no previous lanelet found on the shortest path for lanelet "
621 << original_starting_lanelet.id() <<
". Picking arbitrary lanelet: " << previous_lanelets[0].id() <<
", instead");
622 previous_lanelet_to_add = previous_lanelets[0];
627 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"No previous lanelet was found for lanelet " << original_starting_lanelet.id());
633 lanelet::ConstLanelet original_ending_lanelet =
wm_->getMap()->laneletLayer.get(original_ending_lanelet_id);
636 lanelet::BasicPoint2d original_ending_lanelet_centerline_start_point = lanelet::utils::to2D(original_ending_lanelet.centerline()).front();
637 double original_ending_lanelet_centerline_start_point_dt =
wm_->routeTrackPos(original_ending_lanelet_centerline_start_point).downtrack;
639 if(adjusted_end_dist < original_ending_lanelet_centerline_start_point_dt){
640 auto previous_lanelets =
wm_->getMapRoutingGraph()->previous(original_ending_lanelet,
false);
642 if(!previous_lanelets.empty()){
646 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"No previous lanelet was found for lanelet " << original_starting_lanelet.id());
654 carma_planning_msgs::msg::TrajectoryPlan latest_trajectory_plan;
655 bool full_plan_generation_failed =
false;
658 RCLCPP_INFO_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Guidance is not engaged. Plan delegator will not plan trajectory.");
659 return latest_trajectory_plan;
665 bool first_trajectory_plan =
true;
668 uint16_t current_maneuver_index = 0;
671 while(current_maneuver_index < locked_maneuver_plan.maneuvers.size())
673 auto& maneuver = locked_maneuver_plan.maneuvers[current_maneuver_index];
680 ++current_maneuver_index;
684 double current_downtrack =
wm_->routeTrackPos(current_loc).downtrack;
685 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"current_downtrack" << current_downtrack);
687 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"maneuver_end_dist" << maneuver_end_dist);
690 if (current_downtrack > maneuver_end_dist)
694 ++current_maneuver_index;
703 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Current planner: " << maneuver_planner);
707 latest_trajectory_plan, locked_maneuver_plan, current_maneuver_index);
709 auto future_response = client->async_send_request(plan_req);
713 if (future_status != std::future_status::ready)
715 RCLCPP_WARN_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Unsuccessful service call to trajectory planner:" << maneuver_planner <<
" for plan ID " << std::string(locked_maneuver_plan.maneuver_plan_id));
717 full_plan_generation_failed =
true;
722 auto plan_response = future_response.get();
727 "Found invalid trajectory with less than 2 trajectory "
728 <<
"points for maneuver_plan_id: "
729 << std::string(locked_maneuver_plan.maneuver_plan_id));
730 full_plan_generation_failed =
true;
734 if(latest_trajectory_plan.trajectory_points.size() != 0 &&
735 latest_trajectory_plan.trajectory_points.back().target_time == plan_response->trajectory_plan.trajectory_points.front().target_time)
737 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Removing duplicate point for planner: " << maneuver_planner);
738 plan_response->trajectory_plan.trajectory_points.erase(plan_response->trajectory_plan.trajectory_points.begin());
739 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"plan_response->trajectory_plan size: " << plan_response->trajectory_plan.trajectory_points.size());
741 latest_trajectory_plan.trajectory_points.insert(latest_trajectory_plan.trajectory_points.end(),
742 plan_response->trajectory_plan.trajectory_points.begin(),
743 plan_response->trajectory_plan.trajectory_points.end());
744 RCLCPP_DEBUG_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"new latest_trajectory_plan size: " << latest_trajectory_plan.trajectory_points.size());
747 if(first_trajectory_plan ==
true)
749 latest_trajectory_plan.initial_longitudinal_velocity = plan_response->trajectory_plan.initial_longitudinal_velocity;
750 first_trajectory_plan =
false;
755 RCLCPP_INFO_STREAM(
rclcpp::get_logger(
"plan_delegator"),
"Plan Trajectory completed for " << std::string(locked_maneuver_plan.maneuver_plan_id));
761 if(plan_response->related_maneuvers.size() > 0)
763 current_maneuver_index = plan_response->related_maneuvers.back() + 1;
767 if (full_plan_generation_failed)
770 "Plan_delegator's current run wasn't fully able to generate trajectory!");
772 carma_planning_msgs::msg::TrajectoryPlan empty_plan;
776 return latest_trajectory_plan;
786 carma_planning_msgs::msg::TrajectoryPlan trajectory_plan =
planTrajectory();
791 auto yield_req = std::make_shared<carma_planning_msgs::srv::PlanTrajectory::Request>();
792 yield_req->vehicle_state.longitudinal_vel =
latest_twist_.twist.linear.x;
793 yield_req->vehicle_state.x_pos_global =
latest_pose_.pose.position.x;
794 yield_req->vehicle_state.y_pos_global =
latest_pose_.pose.position.y;
795 double roll, pitch, yaw;
797 yield_req->vehicle_state.orientation = yaw;
799 auto yield_resp = std::make_shared<carma_planning_msgs::srv::PlanTrajectory::Response>();
800 yield_resp->trajectory_plan = trajectory_plan;
805 trajectory_plan = yield_resp->trajectory_plan;
815 trajectory_plan.header.stamp = get_clock()->now();
824 "Guidance is engaged, but new planned trajectory has less than 2 points. " <<
825 "It will not be published! Consecutive failure count: "
834 "Instead, last available trajectory is published with outdated timestamp of:"
845 "Instead, tried publishing last available trajectory, but it's not available!");
850 "No valid trajectory is available to publish! "
851 "Please check the planner plugins and their configurations.");
852 throw std::runtime_error(
"No valid trajectory is available to publish!");
863 geometry_msgs::msg::TransformStamped tf =
tf2_buffer_->lookupTransform(
"base_link",
"vehicle_front", rclcpp::Time(0), rclcpp::Duration(20.0, 0));
868 catch (
const tf2::TransformException &ex)
877#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.
WorldModelConstPtr getWorldModel()
Returns a pointer to an intialized world model instance.
void onTrajPlanTick()
Callback function for triggering trajectory planning.
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::GuidanceState > guidance_state_sub_
bool received_maneuver_plan_
carma_planning_msgs::msg::TrajectoryPlan planTrajectory()
Plan trajectory based on latest maneuver plan via ROS service call to plugins.
LaneChangeInformation getLaneChangeInformation(const carma_planning_msgs::msg::Maneuver &lane_change_maneuver)
Function for generating a LaneChangeInformation object from a provided lane change maneuver.
carma_ros2_utils::ClientPtr< carma_planning_msgs::srv::PlanTrajectory > yield_client_
carma_ros2_utils::ClientPtr< carma_planning_msgs::srv::PlanTrajectory > getPlannerClientByName(const std::string &planner_name)
Get PlanTrajectory service client by plugin name and create new PlanTrajectory service client if spec...
void poseCallback(geometry_msgs::msg::PoseStamped::UniquePtr pose_msg)
Callback function for vehicle pose subscriber. Updates latest_pose_ and makes calls to publishUpcomin...
int consecutive_traj_gen_failure_num_
carma_wm::WorldModelConstPtr wm_
carma_ros2_utils::SubPtr< geometry_msgs::msg::TwistStamped > twist_sub_
std::shared_ptr< carma_planning_msgs::srv::PlanTrajectory::Request > composePlanTrajectoryRequest(const carma_planning_msgs::msg::TrajectoryPlan &latest_trajectory_plan, const carma_planning_msgs::msg::ManeuverPlan &locked_maneuver_plan, const uint16_t ¤t_maneuver_index) const
Generate new PlanTrajecory service request based on current planning progress.
carma_ros2_utils::CallbackReturn handle_on_activate(const rclcpp_lifecycle::State &)
boost::optional< LaneChangeInformation > upcoming_lane_change_information_
carma_ros2_utils::PubPtr< carma_planning_msgs::msg::UpcomingLaneChangeStatus > upcoming_lane_change_status_pub_
carma_planning_msgs::msg::UpcomingLaneChangeStatus upcoming_lane_change_status_
bool isTrajectoryValid(const carma_planning_msgs::msg::TrajectoryPlan &trajectory_plan) const noexcept
Example if a trajectory plan contains at least two trajectory points.
carma_ros2_utils::CallbackReturn handle_on_configure(const rclcpp_lifecycle::State &)
bool isManeuverExpired(const carma_planning_msgs::msg::Maneuver &maneuver, rclcpp::Time current_time) const
Example if a maneuver end time has passed current system time.
void guidanceStateCallback(carma_planning_msgs::msg::GuidanceState::UniquePtr plan)
Callback function of guidance state subscriber.
void updateManeuverParameters(carma_planning_msgs::msg::Maneuver &maneuver)
Update the starting downtrack, ending downtrack, and maneuver-specific Lanelet ID parameters associat...
rclcpp::TimerBase::SharedPtr traj_timer_
std::shared_ptr< tf2_ros::TransformListener > tf2_listener_
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::ManeuverPlan > plan_sub_
bool isTrajectoryLongEnough(const carma_planning_msgs::msg::TrajectoryPlan &plan) const noexcept
Example if a trajectory plan is longer than configured time thresheld.
carma_planning_msgs::msg::ManeuverPlan latest_maneuver_plan_
carma_ros2_utils::PubPtr< carma_planning_msgs::msg::TrajectoryPlan > traj_pub_
carma_ros2_utils::PubPtr< autoware_msgs::msg::LampCmd > turn_signal_command_pub_
boost::optional< LaneChangeInformation > current_lane_change_information_
std::unordered_map< std::string, carma_ros2_utils::ClientPtr< carma_planning_msgs::srv::PlanTrajectory > > trajectory_planners_
bool isManeuverPlanValid(const carma_planning_msgs::msg::ManeuverPlan &maneuver_plan) const noexcept
Example if a maneuver plan contains at least one maneuver.
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > pose_sub_
geometry_msgs::msg::TwistStamped latest_twist_
double length_to_front_bumper_
std::optional< carma_planning_msgs::msg::TrajectoryPlan > last_successful_traj_
rclcpp::CallbackGroup::SharedPtr timer_callback_group_
void lookupFrontBumperTransform()
Lookup transfrom from front bumper to base link.
geometry_msgs::msg::PoseStamped latest_pose_
PlanDelegator(const rclcpp::NodeOptions &)
PlanDelegator constructor.
void maneuverPlanCallback(carma_planning_msgs::msg::ManeuverPlan::UniquePtr plan)
Callback function of maneuver plan subscriber.
std::shared_ptr< tf2_ros::Buffer > tf2_buffer_
autoware_msgs::msg::LampCmd latest_turn_signal_command_
void publishTurnSignalCommand(const boost::optional< LaneChangeInformation > ¤t_lane_change_information, const carma_planning_msgs::msg::UpcomingLaneChangeStatus &upcoming_lane_change_status)
Function for processing an optional LaneChangeInformation object pertaining to the currently-occurrin...
void publishUpcomingLaneChangeStatus(const boost::optional< LaneChangeInformation > &upcoming_lane_change_information)
Function for processing an optional LaneChangeInformation object pertaining to an upcoming lane chang...
carma_wm::WMListener wml_
carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr modify_trajectory_to_yield_to_obstacles(const std::shared_ptr< carma_ros2_utils::CarmaLifecycleNode > &node_handler, const carma_planning_msgs::srv::PlanTrajectory::Request::SharedPtr &req, const carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr &resp, const carma_ros2_utils::ClientPtr< carma_planning_msgs::srv::PlanTrajectory > &yield_client, int yield_plugin_service_call_timeout)
Applies a yield trajectory to the original trajectory set in response.
rclcpp::Logger get_logger()
Return the module-level logger used by all basic_autonomy functions.
auto to_string(const UtmZone &zone) -> std::string
void rpyFromQuaternion(const tf2::Quaternion &q, double &roll, double &pitch, double &yaw)
Extract extrinsic roll-pitch-yaw from quaternion.
std::string getManeuverEndingLaneletId(carma_planning_msgs::msg::Maneuver mvr)
Anonymous function to get the ending lanelet id for all maneuver types except lane following....
void setManeuverEndingLaneletId(carma_planning_msgs::msg::Maneuver &mvr, lanelet::Id end_id)
Anonymous function to set the ending_lane_id for all maneuver types except lane following....
std::string getManeuverStartingLaneletId(carma_planning_msgs::msg::Maneuver mvr)
Anonymous function to get the starting lanelet id for all maneuver types except lane following....
void setManeuverStartingLaneletId(carma_planning_msgs::msg::Maneuver &mvr, lanelet::Id start_id)
Anonymous function to set the starting_lane_id for all maneuver types except lane following....
#define SET_MANEUVER_PROPERTY(mvr, property, value)
bool enable_object_avoidance
double trajectory_planning_rate
std::string planning_topic_suffix
int max_traj_generation_reattempt
std::string planning_topic_prefix
int tactical_plugin_service_call_timeout
double duration_to_signal_before_lane_change
double max_trajectory_duration