21#define GET_MANEUVER_PROPERTY(mvr, property) \
22 (((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN ? \
23 (mvr).intersection_transit_left_turn_maneuver.property : \
24 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN ? \
25 (mvr).intersection_transit_right_turn_maneuver.property : \
26 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT ? \
27 (mvr).intersection_transit_straight_maneuver.property : \
28 ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE ? (mvr).lane_change_maneuver.property : \
29 (mvr).type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING ? (mvr).lane_following_maneuver.property : \
30 throw new std::invalid_argument("GET_MANEUVER_" \
40 namespace std_ph = std::placeholders;
109 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Done loading parameters: " <<
config_);
114 mob_operation_sub_ = create_subscription<carma_v2x_msgs::msg::MobilityOperation>(
"incoming_mobility_operation", 1,
118 bsm_sub_ = create_subscription<carma_v2x_msgs::msg::BSM>(
"bsm_outbound", 1,
125 mobility_operation_pub_ = create_publisher<carma_v2x_msgs::msg::MobilityOperation>(
"outgoing_mobility_operation", 1);
126 case_pub_ = create_publisher<std_msgs::msg::Int8>(
"lci_strategic_plugin/ts_case_num", 1);
127 tf_distance_pub_ = create_publisher<std_msgs::msg::Float64>(
"lci_strategic_plugin/distance_remaining_to_tf", 1);
128 earliest_et_pub_ = create_publisher<std_msgs::msg::Float64>(
"lci_strategic_plugin/earliest_entry_time", 1);
129 et_pub_ = create_publisher<std_msgs::msg::Float64>(
"lci_strategic_plugin/scheduled_entry_time", 1);
132 return CallbackReturn::SUCCESS;
137 auto error_double = update_params<double>({
153 rcl_interfaces::msg::SetParametersResult result;
155 result.successful = !error_double;
162 std_msgs::msg::Int8 case_num_msg;
163 std_msgs::msg::Float64 tf_distance;
164 std_msgs::msg::Float64 earliest_et;
165 std_msgs::msg::Float64 scheduled_et;
175 et_pub_->publish(scheduled_et);
185 std::chrono::duration<double>(0.5),
188 return CallbackReturn::SUCCESS;
197 case lanelet::CarmaTrafficSignalState::STOP_AND_REMAIN:
198 case lanelet::CarmaTrafficSignalState::PROTECTED_CLEARANCE:
199 case lanelet::CarmaTrafficSignalState::PERMISSIVE_MOVEMENT_ALLOWED:
200 case lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED:
205 case lanelet::CarmaTrafficSignalState::PERMISSIVE_CLEARANCE:
208 case lanelet::CarmaTrafficSignalState::DARK:
209 case lanelet::CarmaTrafficSignalState::STOP_THEN_PROCEED:
211 case lanelet::CarmaTrafficSignalState::PRE_MOVEMENT:
213 case lanelet::CarmaTrafficSignalState::CAUTION_CONFLICTING_TRAFFIC:
225 geometry_msgs::msg::TransformStamped tf2 =
tf2_buffer_.lookupTransform(
"base_link",
"vehicle_front", rclcpp::Time(0), rclcpp::Duration(20.0 * 1e9));
227 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"length_to_front_bumper_: " <<
length_to_front_bumper_);
230 catch (
const tf2::TransformException &ex)
232 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"), ex.what());
239 if (!req->prior_plan.maneuvers.empty())
241 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Provided with initial plan...");
249 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"No initial plan provided...");
251 state.
stamp = rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME);
253 state.
speed = req->veh_logitudinal_velocity;
254 state.
lane_id = stoi(req->veh_lane_id);
256 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"extractInitialState >>>> state.stamp: " <<
std::to_string(state.
stamp.seconds()));
257 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"extractInitialState >>>> state.downtrack : " << state.
downtrack );
258 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"extractInitialState >>>> state.speed: " << state.
speed);
259 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"extractInitialState >>>> state.lane_id: " << state.
lane_id);
266 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules =
wm_->getTrafficRules();
269 return (*traffic_rules)->speedLimit(llt).speedLimit.value();
273 throw std::invalid_argument(
"Valid traffic rules object could not be built");
278 const rclcpp::Time& source_time)
const
282 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Traffic light data not available for source_time " <<
std::to_string(source_time.seconds()));
286 lanelet::CarmaTrafficSignalState light_state = optional_state.get().second;
290 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"LCIStrategic Plugin asked to handle CarmaTrafficSignalState: " << light_state
291 <<
" which is not supported.");
300 rclcpp::Time early_arrival_time_by_algo =
303 rclcpp::Time late_arrival_time_by_algo =
306 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"light_arrival_time_by_algo: " <<
std::to_string(light_arrival_time_by_algo.seconds()));
307 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"early_arrival_time_by_algo: " <<
std::to_string(early_arrival_time_by_algo.seconds()));
308 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"late_arrival_time_by_algo: " <<
std::to_string(late_arrival_time_by_algo.seconds()));
310 auto early_arrival_state_by_algo_optional = traffic_light->predictState(lanelet::time::timeFromSec(early_arrival_time_by_algo.seconds()));
312 if (!
validLightState(early_arrival_state_by_algo_optional, early_arrival_time_by_algo))
315 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"early_arrival_state_by_algo: " << early_arrival_state_by_algo_optional.get().second);
317 auto late_arrival_state_by_algo_optional = traffic_light->predictState(lanelet::time::timeFromSec(late_arrival_time_by_algo.seconds()));
319 if (!
validLightState(late_arrival_state_by_algo_optional, late_arrival_time_by_algo))
322 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"late_arrival_state_by_algo: " << late_arrival_state_by_algo_optional.get().second);
324 bool can_make_early_arrival =
true;
325 bool can_make_late_arrival =
true;
328 can_make_early_arrival =
isStateAllowedGreen(early_arrival_state_by_algo_optional.get().second);
331 can_make_late_arrival =
isStateAllowedGreen(late_arrival_state_by_algo_optional.get().second);
334 if (can_make_early_arrival && can_make_late_arrival)
342 return state == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED ||
343 state == lanelet::CarmaTrafficSignalState::PERMISSIVE_MOVEMENT_ALLOWED;
347 double end_downtrack,
348 bool shortest_path_only,
349 bool bounds_inclusive)
const
351 std::vector<lanelet::ConstLanelet> crossed_lanelets =
352 wm_->getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive);
354 if (crossed_lanelets.size() == 0)
356 throw std::invalid_argument(
"getLaneletsBetweenWithException called but inputs do not cross any lanelets going "
361 return crossed_lanelets;
365 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
367 const lanelet::CarmaTrafficSignalPtr& traffic_light,
368 const lanelet::ConstLanelet& entry_lanelet,
const lanelet::ConstLanelet& exit_lanelet,
const lanelet::ConstLanelet& current_lanelet,
369 double traffic_light_down_track,
372 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.
downtrack;
375 std::vector<lanelet::ConstLanelet> crossed_lanelets =
390 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_STOPPING: Planning stop and wait maneuver at decel_rate: " << decel_rate);
393 current_state.
downtrack, traffic_light_down_track, current_state.
speed, crossed_lanelets.front().id(),
394 crossed_lanelets.back().id(), current_state.
stamp,
400 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
402 double current_state_speed,
404 double remaining_time,
405 lanelet::Id exit_lanelet_id,
406 const lanelet::CarmaTrafficSignalPtr& traffic_light,
409 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.
downtrack;
412 std::vector<lanelet::ConstLanelet> crossed_lanelets =
417 if (incomplete_traj_params.is_algorithm_successful ==
false)
419 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Failed to generate maneuver for edge cases...");
424 current_state_speed, incomplete_traj_params.modified_departure_speed, current_state.
stamp, current_state.
stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9), incomplete_traj_params));
428 rclcpp::Time intersection_exit_time =
429 current_state.
stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9) + rclcpp::Duration(intersection_length / incomplete_traj_params.modified_departure_speed * 1e9);
433 incomplete_traj_params.modified_departure_speed, current_state.
stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9), intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
439 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
441 double current_state_speed,
442 const lanelet::CarmaTrafficSignalPtr& traffic_light,
447 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"handleCruisingUntilStop is called but it is not case_8");
451 auto new_ts_params = ts_params;
453 double decel_rate = std::fabs(ts_params.
a3_);
455 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE_8: Planning cruise and stop with decel_rate: " << decel_rate);
457 new_ts_params.t3_ = new_ts_params.t2_;
458 new_ts_params.x3_ = new_ts_params.x2_;
459 new_ts_params.v3_ = new_ts_params.v2_;
460 new_ts_params.a3_ = new_ts_params.a2_;
463 std::vector<lanelet::ConstLanelet> lane_follow_crossed_lanelets =
467 current_state_speed, new_ts_params.v2_, current_state.
stamp, rclcpp::Time(new_ts_params.t2_ * 1e9), new_ts_params));
470 std::vector<lanelet::ConstLanelet> case_8_crossed_lanelets =
474 new_ts_params.x2_, traffic_light_down_track, new_ts_params.v2_, case_8_crossed_lanelets.front().id(),
475 case_8_crossed_lanelets.back().id(), rclcpp::Time(new_ts_params.t2_ * 1e9),
482 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
484 double current_state_speed,
485 const lanelet::CarmaTrafficSignalPtr& traffic_light,
486 const lanelet::ConstLanelet& entry_lanelet,
const lanelet::ConstLanelet& exit_lanelet,
487 double traffic_light_down_track,
const TrajectoryParams& ts_params,
bool is_certainty_check_optional)
494 rclcpp::Time light_arrival_time_by_algo = rclcpp::Time(ts_params.
t3_ * 1e9);
495 double remaining_time = light_arrival_time_by_algo.seconds() - rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds();
496 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Algo initially successful: New light_arrival_time_by_algo: " <<
std::to_string(light_arrival_time_by_algo.seconds()) <<
", with remaining_time: " <<
std::to_string(remaining_time));
500 std::vector<lanelet::ConstLanelet> crossed_lanelets =
504 if (!can_make_green_optional)
507 if (can_make_green_optional.get() || is_certainty_check_optional)
509 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_SUCCESSFULL: Algorithm successful, and able to make it at green with certainty. Planning traj smooth and intersection transit maneuvers");
512 current_state_speed, ts_params.
v3_, current_state.
stamp, light_arrival_time_by_algo, ts_params));
516 rclcpp::Time intersection_exit_time =
517 light_arrival_time_by_algo + rclcpp::Duration(intersection_length /
intersection_speed_.get() * 1e9);
521 intersection_speed_.get(), light_arrival_time_by_algo, intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
534 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_LAST_RESORT_CASE: Starting...");
535 double starting_downtrack = traffic_light_downtrack - remaining_downtrack;
536 double modified_remaining_time_upper;
537 double modified_remaining_time_lower;
538 double modified_departure_speed_upper;
539 double modified_departure_speed_lower;
540 bool calculation_success_upper =
true;
544 traj_upper.
t0_ = current_time;
545 traj_upper.
v0_ = starting_speed;
546 traj_upper.
x0_ = starting_downtrack;
550 if (departure_speed >= starting_speed)
552 if ((pow(departure_speed,2) - pow(starting_speed,2))/(2*
max_comfort_accel_) >= remaining_downtrack)
554 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HandleFailureCase -> Upper Trajectory -> Current Speed <= Desired Departure Speed, Actual Departure Speed < Desired Departure Speed");
556 modified_departure_speed_upper = sqrt(pow(starting_speed, 2) + (2 *
max_comfort_accel_ * remaining_downtrack));
557 modified_remaining_time_upper = (modified_departure_speed_upper - starting_speed) /
max_comfort_accel_;
559 traj_upper.
t1_ = current_time + modified_remaining_time_upper;
560 traj_upper.
v1_ = modified_departure_speed_upper;
562 traj_upper.
x1_ = traffic_light_downtrack;
564 traj_upper.
t2_ = traj_upper.
t1_;
565 traj_upper.
v2_ = traj_upper.
v1_;
566 traj_upper.
a2_ = traj_upper.
a1_;
567 traj_upper.
x2_ = traj_upper.
x1_;
574 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HandleFailureCase -> Upper Trajectory -> Current Speed < Desired Departure Speed, Actual Departure Speed = Desired Departure Speed");
576 double cruising_distance = remaining_downtrack - (pow(departure_speed, 2) - pow(starting_speed, 2))/ ( 2 *
max_comfort_accel_);
577 if (cruising_distance < -
EPSILON)
579 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected calculation failure in upper case 2");
580 calculation_success_upper =
false;
582 modified_remaining_time_upper = ((departure_speed - starting_speed) /
max_comfort_accel_) + (cruising_distance / departure_speed);
585 traj_upper.
v1_ = departure_speed;
587 traj_upper.
x1_ = starting_downtrack + (pow(departure_speed, 2) - pow(starting_speed, 2)) / (2 *
max_comfort_accel_);
589 traj_upper.
t2_ = current_time + modified_remaining_time_upper;
590 traj_upper.
v2_ = departure_speed;
592 traj_upper.
x2_ = traffic_light_downtrack;
599 if (departure_speed < starting_speed)
601 if ((pow(departure_speed,2) - pow(starting_speed,2))/(2*
max_comfort_decel_) >= remaining_downtrack)
603 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HandleFailureCase -> Upper Trajectory -> Current Speed > Desired Departure Speed, Actual Departure Speed > Desired Departure Speed");
605 modified_departure_speed_upper = sqrt(pow(starting_speed, 2) + (2 *
max_comfort_decel_ * remaining_downtrack));
606 modified_remaining_time_upper = (modified_departure_speed_upper - starting_speed) /
max_comfort_decel_;
608 traj_upper.
t1_ = current_time + modified_remaining_time_upper;
609 traj_upper.
v1_ = modified_departure_speed_upper;
611 traj_upper.
x1_ = traffic_light_downtrack;
613 traj_upper.
t2_ = traj_upper.
t1_;
614 traj_upper.
v2_ = traj_upper.
v1_;
615 traj_upper.
a2_ = traj_upper.
a1_;
616 traj_upper.
x2_ = traj_upper.
x1_;
623 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HandleFailureCase -> Upper Trajectory -> Current Speed > Desired Departure Speed, Actual Departure Speed = Desired Departure Speed");
625 double cruising_distance = remaining_downtrack - (pow(departure_speed, 2) - pow(starting_speed, 2))/ ( 2 *
max_comfort_decel_);
627 if (cruising_distance < -
EPSILON)
629 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected calculation failure in upper case 4");
630 calculation_success_upper =
false;
633 modified_remaining_time_upper = cruising_distance / starting_speed + (departure_speed - starting_speed) /
max_comfort_decel_ ;
635 traj_upper.
t1_ = current_time + cruising_distance / starting_speed;
636 traj_upper.
v1_ = starting_speed;
637 traj_upper.
a1_ = 0.0;
638 traj_upper.
x1_ = starting_downtrack + cruising_distance;
640 traj_upper.
t2_ = current_time + modified_remaining_time_upper;
641 traj_upper.
v2_ = departure_speed;
643 traj_upper.
x2_ = traffic_light_downtrack;
650 traj_upper.
t3_ = traj_upper.
t2_;
651 traj_upper.
v3_ = traj_upper.
v2_;
652 traj_upper.
a3_ = traj_upper.
a2_;
653 traj_upper.
x3_ = traj_upper.
x2_;
657 modified_departure_speed_lower = sqrt(pow(starting_speed, 2) + (2 *
max_comfort_decel_ * remaining_downtrack));
658 modified_remaining_time_lower = (modified_departure_speed_lower - starting_speed) /
max_comfort_decel_;
660 traj_lower.
t0_ = current_time;
661 traj_lower.
v0_ = starting_speed;
662 traj_lower.
x0_ = starting_downtrack;
666 traj_lower.
t1_ = current_time + modified_remaining_time_lower;
667 traj_lower.
v1_ = modified_departure_speed_lower;
669 traj_lower.
x1_ = traffic_light_downtrack;
671 traj_lower.
t2_ = traj_lower.
t1_;
672 traj_lower.
v2_ = traj_lower.
v1_;
673 traj_lower.
a2_ = traj_lower.
a1_;
674 traj_lower.
x2_ = traj_lower.
x1_;
676 traj_lower.
t3_ = traj_lower.
t2_;
677 traj_lower.
v3_ = traj_lower.
v2_;
678 traj_lower.
a3_ = traj_lower.
a2_;
679 traj_lower.
x3_ = traj_lower.
x2_;
685 bool is_return_params_found =
false;
687 if (calculation_success_upper)
689 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Checking this time!: " << current_time + modified_remaining_time_upper);
691 auto upper_optional = traffic_light->predictState(lanelet::time::timeFromSec(current_time + modified_remaining_time_upper));
693 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Checking this time! state: " << upper_optional.get().second);
695 if (!
validLightState(upper_optional, rclcpp::Time((current_time + modified_remaining_time_upper) * 1e9)))
697 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve give signal for modified_remaining_time_upper: " <<
std::to_string(current_time + modified_remaining_time_upper));
703 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected Upper GREEN case");
704 return_params = traj_upper;
705 is_return_params_found =
true;
710 if (!is_return_params_found)
712 auto lower_optional = traffic_light->predictState(lanelet::time::timeFromSec(current_time + modified_remaining_time_lower));
714 if (!
validLightState(lower_optional, rclcpp::Time((current_time + modified_remaining_time_lower) * 1e9)))
716 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve give signal for modified_remaining_time_lower:" <<
std::to_string(current_time + modified_remaining_time_lower));
722 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected Lower GREEN case");
723 return_params = traj_lower;
724 is_return_params_found =
true;
733 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Updated the speed, and using modified_departure_speed: " << return_params.
modified_departure_speed);
735 return return_params;
739 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to handle edge case gracefully");
742 return return_params;
748 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
const VehicleState& current_state,
749 const lanelet::CarmaTrafficSignalPtr& traffic_light,
const lanelet::ConstLanelet& entry_lanelet,
const lanelet::ConstLanelet& exit_lanelet,
const lanelet::ConstLanelet& current_lanelet)
759 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"No lights found along route. Returning maneuver plan unchanged");
766 auto stop_line = traffic_light->getStopLine(entry_lanelet);
770 throw std::invalid_argument(
"Given entry lanelet doesn't have stop_line...");
773 double traffic_light_down_track =
774 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
776 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"traffic_light_down_track: " << traffic_light_down_track);
778 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.
downtrack;
780 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light <<
781 ", current_state.downtrack: " << current_state.
downtrack);
787 current_state_speed = std::min(speed_limit, current_state_speed);
789 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"speed_limit (free flow speed): " << speed_limit);
796 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Stopping distance: " << stopping_dist);
802 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"plugin_activation_distance: " << plugin_activation_distance);
804 if (distance_remaining_to_traffic_light <= plugin_activation_distance)
806 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Within intersection range");
812 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Not within intersection range");
818 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
const VehicleState& current_state,
819 const lanelet::CarmaTrafficSignalPtr& traffic_light,
const lanelet::ConstLanelet& entry_lanelet,
const lanelet::ConstLanelet& exit_lanelet,
const lanelet::ConstLanelet& current_lanelet)
832 auto stop_line = traffic_light->getStopLine(entry_lanelet);
836 throw std::invalid_argument(
"Given entry lanelet doesn't have stop_line...");
839 double traffic_light_down_track =
840 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
842 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"traffic_light_down_track: " << traffic_light_down_track);
844 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.
downtrack;
848 if (distance_remaining_to_traffic_light < 0)
850 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Crossed the bar distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light);
857 lanelet::ConstLanelet intersection_lanelet;
859 auto route =
wm_->getRoute()->shortestPath();
860 auto entry_llt_iter = std::find(
route.begin(),
route.end(), entry_lanelet);
861 if (entry_llt_iter !=
route.end())
863 intersection_lanelet = *(entry_llt_iter + 1);
866 if (intersection_lanelet.id() != lanelet::InvalId)
880 current_state_speed = std::min(current_state_speed, speed_limit - 5 *
epsilon_);
882 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"current_state_speed: " << current_state_speed);
883 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"intersection_speed_: " <<
intersection_speed_.get());
884 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light);
887 wm_->routeTrackPos(exit_lanelet.centerline2d().front().basicPoint2d()).downtrack;
889 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"intersection_end_downtrack_: " <<
intersection_end_downtrack_.get());
892 constexpr double HALF_MPH_IN_MPS = 0.22352;
893 if (current_state.
speed < HALF_MPH_IN_MPS &&
897 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CARMA has detected that the vehicle stopped at the stop bar. Transitioning to WAITING STATE");
907 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"earliest_entry_time: " <<
std::to_string(earliest_entry_time.seconds()) <<
", with : " <<
std::to_string((earliest_entry_time - current_state.
stamp).seconds()) <<
" left at: " <<
std::to_string(current_state.
stamp.seconds()));
911 if (nearest_green_entry_time == rclcpp::Time(0))
914 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Final nearest_green_entry_time: " <<
std::to_string(nearest_green_entry_time.seconds()));
916 auto et_state = traffic_light->predictState(lanelet::time::timeFromSec(nearest_green_entry_time.seconds()));
917 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Signal at ET: " << et_state.get().second);
921 double remaining_time = nearest_green_entry_time.seconds() - current_state.
stamp.seconds();
922 double remaining_time_earliest_entry = earliest_entry_time.seconds() - current_state.
stamp.seconds();
929 auto boundary_traj_params =
get_boundary_traj_params(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds(), current_state_speed,
intersection_speed_.get(), speed_limit,
config_.
algo_minimum_speed,
max_comfort_accel_,
max_comfort_decel_, current_state.
downtrack, traffic_light_down_track, distance_remaining_to_traffic_light, boundary_distances);
931 TrajectoryParams ts_params =
get_ts_case(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds(), nearest_green_entry_time.seconds(), current_state_speed,
intersection_speed_.get(), speed_limit,
config_.
algo_minimum_speed,
max_comfort_accel_,
max_comfort_decel_, current_state.
downtrack, traffic_light_down_track, distance_remaining_to_traffic_light, boundary_distances, boundary_traj_params);
934 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"SPEED PROFILE CASE:" << ts_params.
case_num);
938 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"emergency_distance_to_stop at emergency_decel_norm_ (with stopping_location_buffer/2): " << emergency_distance_to_stop <<
", emergency_decel_norm_: " <<
emergency_decel_norm_);
941 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"safe_distance_to_stop at max_comfort_decel (with stopping_location_buffer/2): " << safe_distance_to_stop <<
", max_comfort_decel_norm_: " <<
max_comfort_decel_norm_);
950 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"new emergency_distance_to_stop: " << emergency_distance_to_stop);
951 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"new safe_distance_to_stop: " << safe_distance_to_stop);
952 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"new desired_distance_to_stop: " << desired_distance_to_stop);
954 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light <<
", current_state.speed: " << current_state.
speed);
961 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"ET is still in TBD despite the vehicle being in desired distance to start stopping. Trying to handle this edge case gracefully...");
966 rclcpp::Time stopping_arrival_time =
967 current_state.
stamp + rclcpp::Duration(stopping_time * 1e9);
969 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"stopping_arrival_time: " <<
std::to_string(stopping_arrival_time.seconds()));
971 auto stopping_arrival_state_optional = traffic_light->predictState(lanelet::time::timeFromSec(stopping_arrival_time.seconds()));
973 if (!
validLightState(stopping_arrival_state_optional, stopping_arrival_time))
975 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve give signal for stopping_arrival_state_optional: " <<
std::to_string(stopping_arrival_time.seconds()));
981 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected possible RED light violation! Stopping!");
982 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track,
true);
991 (distance_remaining_to_traffic_light >= desired_distance_to_stop || !in_tbd) &&
992 is_entry_time_within_green_or_tbd)
994 handleGreenSignalScenario(req, resp, current_state, current_state_speed, traffic_light, entry_lanelet, exit_lanelet, traffic_light_down_track, ts_params, in_tbd);
996 if (!resp->new_plan.maneuvers.empty())
1002 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Not able to make it with certainty: TSCase: " << ts_params.
case_num <<
", changing it to 8");
1003 ts_params = boundary_traj_params[7];
1009 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Not able to make it with certainty: NEW TSCase: " << ts_params.
case_num);
1014 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Way too early to stop. Cruising at CASE8");
1015 handleCruisingUntilStop(req, resp, current_state, current_state_speed, traffic_light, traffic_light_down_track, ts_params);
1017 if (!resp->new_plan.maneuvers.empty())
1024 if ((safe_distance_to_stop <= distance_remaining_to_traffic_light && desired_distance_to_stop >= distance_remaining_to_traffic_light) ||
1027 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Planning stopping now. last case:" <<
static_cast<int>(
last_case_num_));
1028 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track);
1032 if (safe_distance_to_stop > distance_remaining_to_traffic_light)
1034 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"No longer within safe distance to stop! Decide to continue stopping or continue into intersection");
1039 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_LAST_RESORT: The vehicle is not able to stop at red/yellow light nor is able to reach target speed at green. Attempting its best to pass through at green!");
1041 handleFailureCase(req, resp, current_state, current_state_speed, speed_limit, remaining_time,
1042 exit_lanelet.id(), traffic_light, traffic_light_down_track, ts_params);
1044 if (resp->new_plan.maneuvers.empty())
1046 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_SAFETY: Planning forced slow-down... last case:" <<
static_cast<int>(
last_case_num_));
1047 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track,
true);
1052 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"HANDLE_SAFETY: Planning to keep stopping now. last case:" <<
static_cast<int>(
last_case_num_));
1053 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track);
1061 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
const VehicleState& current_state,
1062 const lanelet::CarmaTrafficSignalPtr& traffic_light,
const lanelet::ConstLanelet& entry_lanelet,
const lanelet::ConstLanelet& exit_lanelet,
const lanelet::ConstLanelet& current_lanelet)
1068 throw std::invalid_argument(
"While in WAITING state, the traffic lights disappeared.");
1071 auto stop_line = traffic_light->getStopLine(entry_lanelet);
1075 throw std::invalid_argument(
"Given entry lanelet doesn't have stop_line...");
1078 double traffic_light_down_track =
1079 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
1081 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"traffic_light_down_track: "<< traffic_light_down_track);
1083 double entering_time = current_state.
stamp.seconds();
1085 auto current_light_state_optional = traffic_light->predictState(lanelet::time::timeFromSec(entering_time));
1087 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"WAITING STATE: requested time to rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME) check: " <<
std::to_string(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds()));
1088 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"WAITING STATE: requested time to CURRENT STATE check: " <<
std::to_string(entering_time));
1090 if (!
validLightState(current_light_state_optional, rclcpp::Time(entering_time * 1e9)))
1095 if (!bool_optional_late_certainty)
1097 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve green light...");
1101 bool should_enter =
true;
1104 should_enter =
false;
1106 if (
isStateAllowedGreen(current_light_state_optional.get().second) && bool_optional_late_certainty.get() && should_enter)
1115 constexpr double stop_maneuver_buffer = 10.0;
1121 current_state.
downtrack - stop_maneuver_buffer, traffic_light_down_track, current_state.
speed,
1122 current_state.
lane_id, current_state.
lane_id, rclcpp::Time(entering_time * 1e9),
1127 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp,
const VehicleState& current_state,
1128 double intersection_end_downtrack,
double intersection_speed_limit)
1132 if (current_state.
downtrack > intersection_end_downtrack)
1139 rclcpp::Time intersection_exit_time =
1140 current_state.
stamp +
1141 rclcpp::Duration(2.0 * (intersection_end_downtrack - current_state.
downtrack) / (current_state.
speed + intersection_speed_limit) * 1e9);
1144 std::vector<lanelet::ConstLanelet> crossed_lanelets =
1149 current_state.
downtrack, intersection_end_downtrack, current_state.
speed, intersection_speed_limit,
1150 current_state.
stamp, intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
1159 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Received Schedule message with id: " << msg->m_header.plan_id);
1166 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"street_msg_timestamp_: " <<
street_msg_timestamp_);
1176 std::vector<uint8_t> bsm_id_vec = msg->core_data.id;
1177 bsm_id_ = BSMHelper::BSMHelper::bsmIDtoString(bsm_id_vec);
1185 std::string params = strategy_params;
1186 std::vector<std::string> inputsParams;
1189 std::vector<std::string> et_parsed;
1191 auto new_scheduled_enter_time = std::stoull(et_parsed[1]);
1197 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"scheduled_enter_time_: " <<
scheduled_enter_time_);
1203 carma_v2x_msgs::msg::MobilityOperation mo_;
1204 mo_.m_header.timestamp = now().nanoseconds()/1000000;
1207 mo_.m_header.sender_bsm_id =
bsm_id_;
1213 std::string intersection_turn_direction =
"straight";
1217 mo_.strategy_params =
"access: 1, max_accel: " +
std::to_string(vehicle_acceleration_limit_) +
1229 for (
auto l:lanelets_list)
1231 if(l.hasAttribute(
"turn_direction")) {
1232 std::string direction_attribute = l.attribute(
"turn_direction").value();
1233 if (direction_attribute ==
"right")
1238 else if (direction_attribute ==
"left")
1252 return turn_direction;
1267 std::shared_ptr<rmw_request_id_t> srv_header,
1268 carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req,
1269 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
1271 std::chrono::system_clock::time_point execution_start_time = std::chrono::system_clock::now();
1273 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"<<<<<<<<<<<<<<<<< STARTING LCI_STRATEGIC_PLAN!!!!!!!!! >>>>>>>>>>>>>>>>");
1275 if (!
wm_->getRoute())
1277 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Could not plan maneuvers as route was not available");
1285 resp->new_plan.maneuvers = {};
1286 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Not approaching light-controlled intersection so no maneuvers");
1291 if (is_empty_schedule_msg)
1293 resp->new_plan.maneuvers = {};
1294 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Receiving empty schedule message");
1299 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Finding car information");
1305 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"State is NOT UNAVAILABLE AND Maneuvers in request is NOT empty");
1309 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"\n\nFinding traffic_light information");
1311 auto inter_list =
wm_->getSignalizedIntersectionsAlongRoute({ req->veh_x, req->veh_y });
1314 auto traffic_list =
wm_->getSignalsAlongRoute({ req->veh_x, req->veh_y });
1316 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Found traffic lights of size: " << traffic_list.size());
1318 auto current_lanelets =
wm_->getLaneletsFromPoint({ req->veh_x, req->veh_y});
1319 lanelet::ConstLanelet current_lanelet;
1321 if (current_lanelets.empty())
1323 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Given vehicle position is not on the road! Returning...");
1328 auto llt_on_route_optional =
wm_->getFirstLaneletOnShortestPath(current_lanelets);
1330 if (llt_on_route_optional){
1331 current_lanelet = llt_on_route_optional.value();
1334 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"When identifying the corresponding lanelet for requested maneuever's state, x: "
1335 << req->veh_x <<
", y: " << req->veh_y <<
", no possible lanelet was found to be on the shortest path."
1336 <<
"Picking arbitrary lanelet: " << current_lanelets[0].id() <<
", instead");
1337 current_lanelet = current_lanelets[0];
1340 lanelet::CarmaTrafficSignalPtr nearest_traffic_signal =
nullptr;
1342 lanelet::ConstLanelet entry_lanelet;
1343 lanelet::ConstLanelet exit_lanelet;
1345 for (
auto signal : traffic_list)
1347 auto optional_entry_exit =
wm_->getEntryExitOfSignalAlongRoute(signal);
1349 if (!optional_entry_exit)
1351 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Did not find entry.exit along the route");
1355 entry_lanelet = optional_entry_exit.get().first;
1356 exit_lanelet = optional_entry_exit.get().second;
1358 nearest_traffic_signal = signal;
1369 resp->new_plan = carma_planning_msgs::msg::ManeuverPlan();
1375 boost::optional<std::pair<boost::posix_time::ptime, lanelet::CarmaTrafficSignalState>> current_light_state_optional = boost::none;
1376 if (nearest_traffic_signal)
1378 current_light_state_optional = nearest_traffic_signal->predictState(lanelet::time::timeFromSec(current_state.
stamp.seconds()));
1379 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Real-time current signal: " << current_light_state_optional.get().second <<
", for Id: " << nearest_traffic_signal->id());
1382 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Signal state not available returning..." );
1389 planWhenUNAVAILABLE(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1393 planWhenAPPROACHING(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1397 planWhenWAITING(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1404 throw std::invalid_argument(
"State is DEPARTING but the intersection variables are not available");
1410 throw std::invalid_argument(
"LCIStrategic Strategic Plugin entered unknown state");
1416 std::chrono::system_clock::time_point execution_end_time = std::chrono::system_clock::now();
1418 auto execution_duration = execution_end_time - execution_start_time;
1419 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"ExecutionTime lci_strategic_plugin: " << std::chrono::duration<double>(execution_duration).count());
1426 double target_speed, rclcpp::Time start_time, rclcpp::Time end_time,
1429 carma_planning_msgs::msg::Maneuver maneuver_msg;
1430 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
1431 maneuver_msg.lane_following_maneuver.parameters.negotiation_type =
1432 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1433 maneuver_msg.lane_following_maneuver.parameters.presence_vector =
1434 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA | carma_planning_msgs::msg::ManeuverParameters::HAS_INT_META_DATA;
1435 maneuver_msg.lane_following_maneuver.parameters.planning_tactical_plugin =
1437 maneuver_msg.lane_following_maneuver.parameters.planning_strategic_plugin =
1439 maneuver_msg.lane_following_maneuver.start_dist = start_dist;
1440 maneuver_msg.lane_following_maneuver.start_speed = start_speed;
1441 maneuver_msg.lane_following_maneuver.start_time = start_time;
1442 maneuver_msg.lane_following_maneuver.end_dist = end_dist;
1443 maneuver_msg.lane_following_maneuver.end_speed = target_speed;
1444 maneuver_msg.lane_following_maneuver.end_time = end_time;
1448 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
a1_);
1449 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
v1_);
1450 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
x1_);
1452 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
a2_);
1453 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
v2_);
1454 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
x2_);
1456 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
a3_);
1457 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
v3_);
1458 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.
x3_);
1460 maneuver_msg.lane_following_maneuver.parameters.int_valued_meta_data.push_back(
static_cast<int>(tsp.
case_num));
1461 maneuver_msg.lane_following_maneuver.parameters.int_valued_meta_data.push_back(
static_cast<int>(tsp.
is_algorithm_successful));
1463 for (
auto llt : crossed_lanelets)
1465 maneuver_msg.lane_following_maneuver.lane_ids.push_back(
std::to_string(llt.id()));
1469 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Creating TrajectorySmoothingManeuver start dist: " << start_dist <<
" end dist: " << end_dist
1473 return maneuver_msg;
1478 const lanelet::Id& starting_lane_id,
1479 const lanelet::Id& ending_lane_id,
1480 rclcpp::Time start_time, rclcpp::Time end_time,
double stopping_accel)
const
1482 carma_planning_msgs::msg::Maneuver maneuver_msg;
1483 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
1484 maneuver_msg.stop_and_wait_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1485 maneuver_msg.stop_and_wait_maneuver.parameters.presence_vector =
1486 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA;
1489 maneuver_msg.stop_and_wait_maneuver.start_dist = current_dist;
1490 maneuver_msg.stop_and_wait_maneuver.end_dist = end_dist;
1491 maneuver_msg.stop_and_wait_maneuver.start_speed = start_speed;
1492 maneuver_msg.stop_and_wait_maneuver.start_time = start_time;
1493 maneuver_msg.stop_and_wait_maneuver.end_time = end_time;
1494 maneuver_msg.stop_and_wait_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
1495 maneuver_msg.stop_and_wait_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
1499 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
1501 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Creating stop and wait start dist: " << current_dist <<
" end dist: " << end_dist
1504 <<
" stopping_accel: " << stopping_accel);
1506 return maneuver_msg;
1510 double start_speed,
double target_speed,
1511 rclcpp::Time start_time, rclcpp::Time end_time,
1512 const lanelet::Id& starting_lane_id,
1513 const lanelet::Id& ending_lane_id)
const
1515 carma_planning_msgs::msg::Maneuver maneuver_msg;
1516 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT;
1517 maneuver_msg.intersection_transit_straight_maneuver.parameters.negotiation_type =
1518 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1519 maneuver_msg.intersection_transit_straight_maneuver.parameters.presence_vector =
1520 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
1521 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_tactical_plugin =
1523 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_strategic_plugin =
1525 maneuver_msg.intersection_transit_straight_maneuver.start_dist = start_dist;
1526 maneuver_msg.intersection_transit_straight_maneuver.start_speed = start_speed;
1527 maneuver_msg.intersection_transit_straight_maneuver.start_time = start_time;
1528 maneuver_msg.intersection_transit_straight_maneuver.end_dist = end_dist;
1529 maneuver_msg.intersection_transit_straight_maneuver.end_speed = target_speed;
1530 maneuver_msg.intersection_transit_straight_maneuver.end_time = end_time;
1531 maneuver_msg.intersection_transit_straight_maneuver.starting_lane_id =
std::to_string(starting_lane_id);
1532 maneuver_msg.intersection_transit_straight_maneuver.ending_lane_id =
std::to_string(ending_lane_id);
1536 RCLCPP_INFO_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Creating IntersectionTransitManeuver start dist: " << start_dist <<
" end dist: " << end_dist
1537 <<
" From lanelet: " << starting_lane_id
1538 <<
" to lanelet: " << ending_lane_id
1542 return maneuver_msg;
1558#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...
void handleStopping(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet ¤t_lanelet, double traffic_light_down_track, bool is_emergency=false)
This function returns stopping maneuver if the vehicle is able to stop at red and in safe stopping di...
void handleGreenSignalScenario(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, double traffic_light_down_track, const TrajectoryParams &ts_params, bool is_certainty_check_optional)
This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing paramete...
void lookupFrontBumperTransform()
Lookup transfrom from front bumper to base link.
LCIStrategicPluginConfig config_
Config containing configurable algorithm parameters.
boost::optional< bool > canArriveAtGreenWithCertainty(const rclcpp::Time &light_arrival_time_by_algo, const lanelet::CarmaTrafficSignalPtr &traffic_light, bool check_late, bool check_early) const
Return true if the car can arrive at given arrival time within green light time buffer.
BoundaryDistances get_delta_x(double v0, double v1, double v_max, double v_min, double a_max, double a_min)
Get boundary distances used to compare against current state in order to create trajectory smoothing ...
carma_ros2_utils::CallbackReturn on_activate_plugin()
Method which is triggered when this plugin is moved from the INACTIVE to ACTIVE states....
bool validLightState(const boost::optional< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > &optional_state, const rclcpp::Time &source_time) const
Helper method that checks both if the input optional light state is set and if the state it contains ...
TrajectoryParams handleFailureCaseHelper(const lanelet::CarmaTrafficSignalPtr &traffic_light, double current_time, double starting_speed, double departure_speed, double speed_limit, double remaining_downtrack, double traffic_light_downtrack)
Helper function to handleFailureCase that modifies ts_params to desired new parameters....
VehicleState extractInitialState(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req) const
Helper method to extract the initial vehicle state from the planning request method based on if the p...
boost::optional< rclcpp::Time > nearest_green_entry_time_cached_
carma_wm::WorldModelConstPtr wm_
World Model pointer.
void mobilityOperationCb(carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
callback function for mobility operation
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > tf_distance_pub_
double emergency_decel_norm_
unsigned long long scheduled_enter_time_
double findSpeedLimit(const lanelet::ConstLanelet &llt) const
Given a Lanelet, find it's associated Speed Limit.
carma_planning_msgs::msg::Maneuver composeTrajectorySmoothingManeuverMessage(double start_dist, double end_dist, const std::vector< lanelet::ConstLanelet > &crossed_lanelets, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, const TrajectoryParams &tsp) const
Compose a trajectory smoothing maneuver msg (sent as transit maneuver message)
rclcpp::Duration get_earliest_entry_time(double remaining_distance, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Gets the earliest entry time into the intersection that is kinematically possible for the vehicle....
double max_comfort_decel_norm_
void planWhenDEPARTING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, double intersection_end_downtrack, double intersection_speed_limit)
Method for performing maneuver planning when the current plugin state is TransitState::DEPARTING Ther...
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_sub_
tf2_ros::Buffer tf2_buffer_
carma_ros2_utils::CallbackReturn on_configure_plugin()
Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states....
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::BSM > bsm_sub_
carma_ros2_utils::PubPtr< std_msgs::msg::Int8 > case_pub_
bool get_availability()
Get the availability status of this plugin based on the current operating environment....
void handleFailureCase(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, double current_state_speed, double speed_limit, double remaining_time, lanelet::Id exit_lanelet_id, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
When the vehicle is not able to successfully run the algorithm or not able to stop,...
std::tuple< rclcpp::Time, bool, bool > get_final_entry_time_and_conditions(const VehicleState ¤t_state, const rclcpp::Time &earliest_entry_time, lanelet::CarmaTrafficSignalPtr traffic_light)
Get the final entry time from either vehicle's own internal ET calculation (TSMO UC2) or from carma-s...
unsigned long long street_msg_timestamp_
double length_to_front_bumper_
double max_comfort_accel_
LCIStrategicPlugin(const rclcpp::NodeOptions &)
Default constructor for RouteFollowingPlugin class.
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,...
void planWhenWAITING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet ¤t_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::WAITING Theref...
void BSMCb(carma_v2x_msgs::msg::BSM::UniquePtr msg)
BSM callback function.
double distance_remaining_to_tf_
void print_params(TrajectoryParams params)
Helper method to print TrajectoryParams.
void parseStrategyParams(const std::string &strategy_params)
parse strategy parameters
carma_v2x_msgs::msg::MobilityOperation generateMobilityOperation()
Generates Mobility Operation messages.
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > earliest_et_pub_
TrajectoryParams get_ts_case(double t, double et, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances, std::vector< TrajectoryParams > params)
void planWhenUNAVAILABLE(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet ¤t_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::UNAVAILABLE Th...
double max_comfort_decel_
void publishTrajectorySmoothingInfo()
Publish trajectory smoothing info at a fixed rate.
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityOperation > mobility_operation_pub_
TurnDirection intersection_turn_direction_
std::string previous_strategy_params_
bool approaching_light_controlled_intersection_
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, rclcpp::Time start_time, rclcpp::Time end_time, double stopping_accel) const
Compose a stop and wait maneuver message based on input params.
std::string light_controlled_intersection_strategy_
std::string get_version_id()
Returns the version id of this plugin.
void handleCruisingUntilStop(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing paramete...
boost::optional< double > intersection_end_downtrack_
double estimate_distance_to_stop(double v, double a) const
Helper method to use basic kinematics to compute an estimated stopping distance from from the inputs.
double earliest_entry_time_
bool isStateAllowedGreen(const lanelet::CarmaTrafficSignalState &state) const
Method to check if the state is an allowed green movement state. Currently Permissive and Protected g...
TurnDirection getTurnDirectionAtIntersection(std::vector< lanelet::ConstLanelet > lanelets_list)
Determine the turn direction at intersection.
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 scheduled_entry_time_
void planWhenAPPROACHING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState ¤t_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet ¤t_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::APPROACHING Th...
LCIStrategicStateTransitionTable transition_table_
State Machine Transition table.
std::vector< TrajectoryParams > get_boundary_traj_params(double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances)
Get all possible trajectory smoothing parameters for each segments. Later this will be used to genera...
TSCase last_case_num_
Useful metrics for LCI Plugin.
void print_boundary_distances(BoundaryDistances delta_xs)
Helper method to print TrajectoryParams.
boost::optional< double > intersection_speed_
Cache variables for storing the current intersection state between state machine transitions.
void publishMobilityOperation()
Publish mobility operation at a fixed rate.
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > ¶meters)
Callback for dynamic parameter updates.
bool supportedLightState(lanelet::CarmaTrafficSignalState state) const
Helper method to evaluate if the given traffic light state is supported by this plugin.
std::unique_ptr< tf2_ros::TransformListener > tf2_listener_
rclcpp::TimerBase::SharedPtr ts_info_pub_timer_
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > et_pub_
rclcpp::TimerBase::SharedPtr mob_op_pub_timer_
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, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id) const
Compose a intersection transit maneuver message based on input params.
TransitState getState() const
Returns the current state.
void signal(TransitEvent signal)
Trigger signal for the transition table.
#define GET_MANEUVER_PROPERTY(mvr, property)
auto to_string(const UtmZone &zone) -> std::string
TransitState
Enum describing the possible states of the LCIStrategic Strategic Plugin.
Struct to store the configuration settings for the LCIStrategicPlugin class.
std::string intersection_transit_plugin_name
bool enable_carma_streets_connection
Bool: Enable carma streets connection.
std::string vehicle_id
License plate of the vehicle.
double trajectory_smoothing_activation_distance
Downtrack distance until nearest intersection where the Trajectory Smoothing algorithm should activat...
double algo_minimum_speed
Minimum allowable speed TS algorithm in m/s.
double vehicle_accel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle acceleration limit so we plan under our capabi...
double min_maneuver_planning_period
The minimum period in seconds which a maneuver plan must cover if the plugin wishes to control the wh...
double green_light_time_buffer
A buffer in seconds around the green phase which will reduce the phase length such that vehicle still...
std::string stop_and_wait_plugin_name
The name of the plugin to use for stop and wait trajectory planning.
double stopping_location_buffer
A buffer infront of the stopping location which will still be considered a valid stop....
double reaction_time
Double: Vehicle reaction time to a received schedule in seconds (approximate value,...
std::string lane_following_plugin_name
double vehicle_decel_limit
The maximum allowable vehicle deceleration limit in m/s.
double vehicle_decel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle deceleration limit so we plan under our capabi...
double min_approach_distance
The minimum distance in meters that the vehicle can be at before requiring a transition to the APPROA...
double vehicle_accel_limit
The maximum allowable vehicle acceleration limit in m/s.
std::string strategic_plugin_name
The name to use for this plugin during comminications with the arbitrator.
double deceleration_fraction
double mobility_rate
Double: Mobility operation rate.
double desired_distance_to_stop_buffer
Double: Desired distance to stop buffer in meters.
double min_gap
Double: Minimum inter-vehicle gap.
Struct representing a vehicle state for the purposes of planning.
bool is_algorithm_successful
double modified_remaining_time
double modified_departure_speed