Function to process the light controlled intersection tactical plugin service call for trajectory planning.
32 {
33 std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
34
35 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Starting light controlled intersection trajectory planning");
36
37 if(req->maneuver_index_to_plan >= req->maneuver_plan.maneuvers.size())
38 {
39 throw std::invalid_argument(
40 "Light Control Intersection Plugin asked to plan invalid maneuver index: " +
std::to_string(req->maneuver_index_to_plan) +
41 " for plan of size: " +
std::to_string(req->maneuver_plan.maneuvers.size()));
42 }
43
44 std::vector<carma_planning_msgs::msg::Maneuver> maneuver_plan;
45
46 if(req->maneuver_plan.maneuvers[req->maneuver_index_to_plan].type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING
48 {
49 maneuver_plan.push_back(req->maneuver_plan.maneuvers[req->maneuver_index_to_plan]);
50 resp->related_maneuvers.push_back(req->maneuver_index_to_plan);
51 }
52 else
53 {
54 throw std::invalid_argument("Light Control Intersection Plugin asked to plan unsupported maneuver");
55 }
56
57 lanelet::BasicPoint2d veh_pos(req->vehicle_state.x_pos_global, req->vehicle_state.y_pos_global);
58 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Planning state x:" << req->vehicle_state.x_pos_global << " , y: " << req->vehicle_state.y_pos_global);
59
61
62 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"Current_downtrack: "<<
current_downtrack_);
63
64 auto current_lanelets =
wm_->getLaneletsFromPoint({req->vehicle_state.x_pos_global, req->vehicle_state.y_pos_global});
65 lanelet::ConstLanelet current_lanelet;
66
67 if (current_lanelets.empty())
68 {
69 RCLCPP_ERROR_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Given vehicle position is not on the road! Returning...");
70 return;
71 }
72
73
74 auto llt_on_route_optional =
wm_->getFirstLaneletOnShortestPath(current_lanelets);
75
76 if (llt_on_route_optional){
77 current_lanelet = llt_on_route_optional.value();
78 }
79 else{
80 RCLCPP_WARN_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "When identifying the corresponding lanelet for requested trajectory plan's state, x: "
81 << req->vehicle_state.x_pos_global << ", y: " << req->vehicle_state.y_pos_global << ", no possible lanelet was found to be on the shortest path."
82 << "Picking arbitrary lanelet: " << current_lanelets[0].id() << ", instead");
83 current_lanelet = current_lanelets[0];
84 }
85
86 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Current_lanelet: " << current_lanelet.id());
87
89
90 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"speed_limit_: " <<
speed_limit_);
91
94
98
106
107
108
109 bool is_new_case_successful =
GET_MANEUVER_PROPERTY(maneuver_plan.front(), parameters.int_valued_meta_data[1]);
111
113 {
114 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "all variables are set!");
115 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"is_last_case_successful_.get(): " << (
int)
is_last_case_successful_.get());
117
119 }
120 else
121 {
122 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Not all variables are set...");
123 }
124
125
126
127 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"traj points size: " <<
last_trajectory_.trajectory_points.size() <<
", last_final_speeds_ size: " <<
129
130 size_t idx_to_start_new_traj = 0;
132 {
134
135 if (dist < 2.0)
136 {
137 idx_to_start_new_traj =
i;
138 break;
139 }
140 }
141
144
147 && is_new_case_successful == true
149 && rclcpp::Time(
last_trajectory_.trajectory_points.back().target_time) > rclcpp::Time(req->header.stamp) + rclcpp::Duration(1 * 1e9))
150 {
152 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"Last TRAJ's target time: " <<
std::to_string(rclcpp::Time(
last_trajectory_.trajectory_points.back().target_time).seconds()) <<
", and stamp:" <<
std::to_string(rclcpp::Time(req->header.stamp).seconds()));
153 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"USING LAST TRAJ: " << (
int)
last_case_.get());
154 }
157 && is_new_case_successful == false
161 && rclcpp::Time(
last_trajectory_.trajectory_points.back().target_time).seconds() > rclcpp::Time(req->header.stamp).seconds())
162 {
165 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"EDGE CASE: USING LAST TRAJ: " << (
int)
last_case_.get());
166 }
167
168 if (!resp->trajectory_plan.trajectory_points.empty())
169 {
170 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Debug: new case:" << (int) new_case << ", is_new_case_successful: " << is_new_case_successful);
171
173
174 resp->maneuver_status.push_back(carma_planning_msgs::srv::PlanTrajectory::Response::MANEUVER_IN_PROGRESS);
175
176 std::chrono::system_clock::time_point end_time = std::chrono::system_clock::now();
177
178 auto duration = end_time - start_time;
179 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "ExecutionTime Using New: " << std::chrono::duration<double>(duration).count());
180
181 return;
182 }
183
184
185
186
189
190
192
193 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "points_and_target_speeds: " << points_and_target_speeds.size());
194
195 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "PlanTrajectory");
196
197
198 carma_planning_msgs::msg::TrajectoryPlan trajectory;
199 trajectory.header.frame_id = "map";
200 trajectory.header.stamp = req->header.stamp;
202
203
206 wpg_detail_config);
207
208
209 for (auto& p : trajectory.trajectory_points) {
211 }
212
213 if (trajectory.trajectory_points.size () < 2)
214 {
216 && rclcpp::Time(
last_trajectory_.trajectory_points.back().target_time) > rclcpp::Time(req->header.stamp))
217 {
219 RCLCPP_WARN_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Failed to generate new trajectory, so using last valid trajectory!");
220 }
221 else
222 {
223 resp->trajectory_plan = trajectory;
224 RCLCPP_WARN_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Failed to generate new trajectory or use old valid trajectory, so returning empty/invalid trajectory!");
225 }
226 }
227 else
228 {
230 resp->trajectory_plan = trajectory;
234 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"USING NEW: Target time: " <<
std::to_string(rclcpp::Time(
last_trajectory_.trajectory_points.back().target_time).seconds()) <<
", and stamp:" <<
std::to_string(rclcpp::Time(req->header.stamp).seconds()));
235 if (is_new_case_successful)
236 {
240 }
241 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"light_controlled_intersection_tactical_plugin"),
"USING NEW CASE!!! : " << (
int)
last_case_.get());
242
243 }
244 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Debug: new case:" << (int) new_case << ", is_new_case_successful: " << is_new_case_successful);
245
247
248
249
251 {
253 }
254 else
255 {
256 RCLCPP_DEBUG(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "Ignored Object Avoidance");
257 }
258
259 resp->maneuver_status.push_back(carma_planning_msgs::srv::PlanTrajectory::Response::MANEUVER_IN_PROGRESS);
260
261 std::chrono::system_clock::time_point end_time = std::chrono::system_clock::now();
262
263 auto duration = end_time - start_time;
264 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("light_controlled_intersection_tactical_plugin"), "ExecutionTime Using Last: " << std::chrono::duration<double>(duration).count());
265
266 return;
267 }
carma_planning_msgs::msg::VehicleState ending_state_before_buffer_
carma_ros2_utils::ClientPtr< carma_planning_msgs::srv::PlanTrajectory > yield_client_
carma_debug_ros2_msgs::msg::TrajectoryCurvatureSpeeds debug_msg_
std::string light_controlled_intersection_strategy_
double last_successful_scheduled_entry_time_
double current_downtrack_
std::vector< double > last_final_speeds_
boost::optional< bool > is_last_case_successful_
carma_planning_msgs::msg::TrajectoryPlan last_trajectory_
void applyOptimizedTargetSpeedProfile(const carma_planning_msgs::msg::Maneuver &maneuver, const double starting_speed, std::vector< PointSpeedPair > &points_and_target_speeds)
Apply optimized target speeds to the trajectory determined for fixed-time and actuated signals....
double findSpeedLimit(const lanelet::ConstLanelet &llt, const carma_wm::WorldModelConstPtr &wm) const
Given a Lanelet, find it's associated Speed Limit.
boost::optional< TSCase > last_case_
double last_successful_ending_downtrack_
std::vector< PointSpeedPair > createGeometryProfile(const std::vector< carma_planning_msgs::msg::Maneuver > &maneuvers, double max_starting_downtrack, const carma_wm::WorldModelConstPtr &wm, carma_planning_msgs::msg::VehicleState &ending_state_before_buffer, const carma_planning_msgs::msg::VehicleState &state, const GeneralTrajConfig &general_config, const DetailedTrajConfig &detailed_config)
Creates geometry profile to return a point speed pair struct for INTERSECTION_TRANSIT maneuver types ...
GeneralTrajConfig compose_general_trajectory_config(const std::string &trajectory_type, int default_downsample_ratio, int turn_downsample_ratio)
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.
DetailedTrajConfig compose_detailed_trajectory_config(double trajectory_time_length, double curve_resample_step_size, double minimum_speed, double max_accel, double lateral_accel_limit, int speed_moving_average_window_size, int curvature_moving_average_window_size, double back_distance, double buffer_ending_downtrack, std::string desired_controller_plugin="default")
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > compose_lanefollow_trajectory_from_path(const std::vector< PointSpeedPair > &points, const carma_planning_msgs::msg::VehicleState &state, const rclcpp::Time &state_time, const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::VehicleState &ending_state_before_buffer, carma_debug_ros2_msgs::msg::TrajectoryCurvatureSpeeds &debug_msg, const DetailedTrajConfig &detailed_config)
Method converts a list of lanelet centerline points and current vehicle state into a usable list of t...
auto to_string(const UtmZone &zone) -> std::string
basic_autonomy::waypoint_generation::DetailedTrajConfig DetailedTrajConfig
basic_autonomy::waypoint_generation::GeneralTrajConfig GeneralTrajConfig
int curvature_moving_average_window_size
int turn_downsample_ratio
double lateral_accel_limit
double buffer_ending_downtrack
double curve_resample_step_size
double algorithm_evaluation_period
bool enable_object_avoidance
int default_downsample_ratio
double trajectory_time_length
double algorithm_evaluation_distance
int speed_moving_average_window_size
double vehicle_accel_limit
int tactical_plugin_service_call_timeout