22 namespace waypoint_generation
25 carma_planning_msgs::msg::VehicleState &ending_state_before_buffer,
const carma_planning_msgs::msg::VehicleState& state,
27 std::vector<PointSpeedPair> points_and_target_speeds;
30 std::unordered_set<lanelet::Id> visited_lanelets;
32 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"VehDowntrack:"<<max_starting_downtrack);
33 for(
const auto &maneuver : maneuvers)
38 starting_downtrack = std::min(starting_downtrack, max_starting_downtrack);
41 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Used downtrack: " << starting_downtrack);
43 if(maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING){
45 std::vector<PointSpeedPair> lane_follow_points =
create_lanefollow_geometry(maneuver, starting_downtrack, wm, general_config, detailed_config, visited_lanelets);
46 points_and_target_speeds.insert(points_and_target_speeds.end(), lane_follow_points.begin(), lane_follow_points.end());
48 else if(maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE){
50 std::vector<PointSpeedPair> lane_change_points =
get_lanechange_points_from_maneuver(maneuver, starting_downtrack, wm, ending_state_before_buffer, state, general_config, detailed_config);
51 points_and_target_speeds.insert(points_and_target_speeds.end(), lane_change_points.begin(), lane_change_points.end());
54 throw std::invalid_argument(
"This maneuver type is not supported");
60 if(maneuvers.back().type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING){
61 points_and_target_speeds =
add_lanefollow_buffer(wm, points_and_target_speeds, maneuvers, ending_state_before_buffer, detailed_config);
64 return points_and_target_speeds;
70 const DetailedTrajConfig &detailed_config, std::unordered_set<lanelet::Id> &visited_lanelets)
72 if(maneuver.type != carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING){
73 throw std::invalid_argument(
"Create_lanefollow called on a maneuver type which is not LANE_FOLLOW");
75 std::vector<PointSpeedPair> points_and_target_speeds;
77 carma_planning_msgs::msg::LaneFollowingManeuver lane_following_maneuver = maneuver.lane_following_maneuver;
79 if (maneuver.lane_following_maneuver.lane_ids.empty())
81 throw std::invalid_argument(
"No lanelets are defined for lanefollow maneuver");
84 std::vector<lanelet::ConstLanelet> lanelets = { wm->getMap()->laneletLayer.get(stoi(lane_following_maneuver.lane_ids[0]))};
85 for (
size_t i = 1;
i < lane_following_maneuver.lane_ids.size();
i++)
87 auto ll_id = lane_following_maneuver.lane_ids[
i];
88 int cur_id = stoi(ll_id);
89 auto cur_ll = wm->getMap()->laneletLayer.get(cur_id);
90 auto following_lanelets = wm->getMapRoutingGraph()->following(lanelets.back());
92 bool is_follower =
false;
93 for (
auto follower_ll : following_lanelets )
95 if (follower_ll.id() == cur_ll.id())
104 throw std::invalid_argument(
"Invalid list of lanelets they are not followers");
107 lanelets.push_back(cur_ll);
112 auto extra_following_lanelets = wm->getMapRoutingGraph()->following(lanelets.back());
114 for (
auto llt : wm->getRoute()->shortestPath())
116 for (
size_t i = 0;
i < extra_following_lanelets.size();
i++)
118 if (llt.id() == extra_following_lanelets[
i].id())
120 lanelets.push_back(extra_following_lanelets[
i]);
126 if (lanelets.empty())
128 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Detected no lanelets between starting downtrack: "<< starting_downtrack <<
", and lane_following_maneuver.end_dist: "<< lane_following_maneuver.end_dist);
129 throw std::invalid_argument(
"Detected no lanelets between starting_downtrack and end_dist");
134 lanelet::BasicLineString2d downsampled_centerline;
137 downsampled_centerline.reserve(400);
143 auto following_lanelets = wm->getMapRoutingGraph()->following(lanelets[curr_idx]);
144 lanelet::ConstLanelets straight_lanelets;
146 if(lanelets.size() <= 1)
148 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Detected one straight lanelet Id:" << lanelets[curr_idx].
id());
149 straight_lanelets = lanelets;
154 while (curr_idx + 1 < lanelets.size() &&
155 std::find(following_lanelets.begin(),following_lanelets.end(), lanelets[curr_idx + 1]) == following_lanelets.end())
157 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"As there were no directly following lanelets after this, skipping lanelet id: " << lanelets[curr_idx].
id());
159 following_lanelets = wm->getMapRoutingGraph()->following(lanelets[curr_idx]);
162 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Added lanelet Id for lane follow: " << lanelets[curr_idx].
id());
164 straight_lanelets.push_back(lanelets[curr_idx]);
166 while (curr_idx + 1 < lanelets.size() &&
167 std::find(following_lanelets.begin(),following_lanelets.end(), lanelets[curr_idx + 1]) != following_lanelets.end())
170 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Added lanelet Id forlane follow: " << lanelets[curr_idx].
id());
171 straight_lanelets.push_back(lanelets[curr_idx]);
172 following_lanelets = wm->getMapRoutingGraph()->following(lanelets[curr_idx]);
177 for (
auto l : straight_lanelets)
180 if (visited_lanelets.find(l.id()) == visited_lanelets.end())
183 bool is_turn =
false;
184 if(l.hasAttribute(
"turn_direction")) {
185 std::string turn_direction = l.attribute(
"turn_direction").value();
186 is_turn = turn_direction.compare(
"left") == 0 || turn_direction.compare(
"right") == 0;
189 lanelet::BasicLineString2d centerline = l.centerline2d().basicLineString();
190 lanelet::BasicLineString2d downsampled_points;
192 downsampled_points = carma_ros2_utils::containers::downsample_vector(centerline, general_config.
turn_downsample_ratio);
194 downsampled_points = carma_ros2_utils::containers::downsample_vector(centerline, general_config.
default_downsample_ratio);
197 if(downsampled_centerline.size() != 0 && downsampled_points.size() != 0
198 && lanelet::geometry::distance2d(downsampled_points.front(), downsampled_centerline.back()) <1.2){
199 downsampled_points = lanelet::BasicLineString2d(downsampled_points.begin() + 1, downsampled_points.end());
203 visited_lanelets.insert(l.id());
208 for (
auto p : downsampled_centerline)
210 if (first && !points_and_target_speeds.empty())
217 pair.
speed = lane_following_maneuver.end_speed;
218 points_and_target_speeds.push_back(pair);
221 return points_and_target_speeds;
226 carma_planning_msgs::msg::VehicleState &ending_state_before_buffer,
const DetailedTrajConfig &detailed_config){
229 double starting_route_downtrack = wm->routeTrackPos(points_and_target_speeds.front().point).downtrack;
234 double ending_downtrack = maneuvers.back().lane_following_maneuver.end_dist + detailed_config.
buffer_ending_downtrack;
236 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Add lanefollow buffer: ending_downtrack: " << ending_downtrack <<
", maneuvers.back().lane_following_maneuver.end_dist: " << maneuvers.back().lane_following_maneuver.end_dist <<
239 size_t max_i = points_and_target_speeds.size() - 1;
240 size_t unbuffered_idx = points_and_target_speeds.size() - 1;
241 bool found_unbuffered_idx =
false;
242 double dist_accumulator = starting_route_downtrack;
243 lanelet::BasicPoint2d prev_point;
245 boost::optional<lanelet::BasicPoint2d> delta_point;
246 for (
size_t i = 0;
i < points_and_target_speeds.size(); ++
i) {
247 auto current_point = points_and_target_speeds[
i].point;
250 prev_point = current_point;
254 double delta_d = lanelet::geometry::distance2d(prev_point, current_point);
256 dist_accumulator += delta_d;
257 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Index i: " <<
i <<
", delta_d: " << delta_d <<
", dist_accumulator:" << dist_accumulator <<
", current_point.x():" << current_point.x() <<
258 "current_point.y():" << current_point.y());
259 if (dist_accumulator > maneuvers.back().lane_following_maneuver.end_dist && !found_unbuffered_idx)
261 unbuffered_idx =
i - 1;
262 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Found index unbuffered_idx at: " << unbuffered_idx);
263 found_unbuffered_idx =
true;
266 if (dist_accumulator > ending_downtrack) {
268 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Max_i breaking at: i: " <<
i <<
", max_i: " << max_i);
275 if (
i == points_and_target_speeds.size() - 1)
278 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Extending trajectory using buffer beyond end of target lanelet");
280 while (delta_d < epsilon_ && j >= 0 && !delta_point)
282 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Looking at index j: " << j <<
", where i: " <<
i);
283 prev_point = points_and_target_speeds.at(j).point;
285 delta_d = lanelet::geometry::distance2d(prev_point, current_point);
292 delta_point = (current_point - prev_point) * 0.25;
296 auto new_point = current_point + delta_point.get();
299 new_pair.
point = new_point;
300 new_pair.
speed = points_and_target_speeds.back().speed;
303 points_and_target_speeds.push_back(new_pair);
306 prev_point = current_point;
309 ending_state_before_buffer.x_pos_global = points_and_target_speeds[unbuffered_idx].point.x();
310 ending_state_before_buffer.y_pos_global = points_and_target_speeds[unbuffered_idx].point.y();
311 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Here ending_state_before_buffer.x_pos_global: " << ending_state_before_buffer.x_pos_global <<
312 ", and y_pos_global" << ending_state_before_buffer.y_pos_global);
314 std::vector<PointSpeedPair> constrained_points(points_and_target_speeds.begin(), points_and_target_speeds.begin() + max_i);
316 return constrained_points;
319 std::vector<lanelet::BasicPoint2d>
create_lanechange_geometry(lanelet::Id starting_lane_id, lanelet::Id ending_lane_id,
double starting_downtrack,
double ending_downtrack,
322 std::vector<lanelet::BasicPoint2d> centerline_points;
325 lanelet::ConstLanelet starting_lanelet = wm->getMap()->laneletLayer.get(starting_lane_id);
326 lanelet::ConstLanelet ending_lanelet = wm->getMap()->laneletLayer.get(ending_lane_id);
328 double lane_change_length = ending_downtrack - starting_downtrack;
335 std::vector<lanelet::BasicPoint2d> reference_centerline =
337 std::vector<lanelet::BasicPoint2d> target_lane_centerline =
350 std::vector<lanelet::BasicPoint2d> downsampled_starting_centerline;
351 downsampled_starting_centerline.reserve(400);
352 downsampled_starting_centerline = carma_ros2_utils::containers::downsample_vector(reference_centerline, downsample_ratio);
354 std::vector<lanelet::BasicPoint2d> downsampled_target_centerline;
355 downsampled_target_centerline.reserve(400);
356 downsampled_target_centerline = carma_ros2_utils::containers::downsample_vector(target_lane_centerline, downsample_ratio);
360 carma_planning_msgs::msg::VehicleState start_state;
361 start_state.x_pos_global = downsampled_starting_centerline[start_index_starting_centerline].x();
362 start_state.y_pos_global = downsampled_starting_centerline[start_index_starting_centerline].y();
366 carma_planning_msgs::msg::VehicleState end_state;
367 end_state.x_pos_global = downsampled_target_centerline[end_index_target_centerline].x();
368 end_state.y_pos_global = downsampled_target_centerline[end_index_target_centerline].y();
371 std::vector<lanelet::BasicPoint2d> constrained_start_centerline(downsampled_starting_centerline.begin() + start_index_starting_centerline, downsampled_starting_centerline.begin() + end_index_starting_centerline);
372 std::vector<lanelet::BasicPoint2d> constrained_target_centerline(downsampled_target_centerline.begin() + start_index_target_centerline, downsampled_target_centerline.begin() + end_index_target_centerline);
375 if(constrained_start_centerline.size() != constrained_target_centerline.size())
378 constrained_start_centerline = centerlines[0];
379 constrained_target_centerline = centerlines[1];
383 double delta_step = 1.0 / constrained_start_centerline.size();
385 for (
size_t i = 0;
i < constrained_start_centerline.size(); ++
i)
387 lanelet::BasicPoint2d current_position;
388 lanelet::BasicPoint2d start_lane_pt = constrained_start_centerline[
i];
389 lanelet::BasicPoint2d target_lane_pt = constrained_target_centerline[
i];
390 double delta = delta_step *
i;
391 current_position.x() = target_lane_pt.x() * delta + (1 - delta) * start_lane_pt.x();
392 current_position.y() = target_lane_pt.y() * delta + (1 - delta) * start_lane_pt.y();
394 centerline_points.push_back(current_position);
402 centerline_points.insert(centerline_points.end(), downsampled_target_centerline.begin() + end_index_target_centerline, downsampled_target_centerline.end());
404 return centerline_points;
409 auto start_time = std::chrono::high_resolution_clock::now();
411 std::vector<std::vector<lanelet::BasicPoint2d>> output;
414 std::unique_ptr<smoothing::SplineI> fit_curve_1 =
compute_fit(line_1);
417 throw std::invalid_argument(
"Could not fit a spline curve along the starting_lane centerline points!");
420 std::unique_ptr<smoothing::SplineI> fit_curve_2 =
compute_fit(line_2);
423 throw std::invalid_argument(
"Could not fit a spline curve along the ending_lane centerline points!");
427 std::vector<lanelet::BasicPoint2d> all_sampling_points_line1;
428 std::vector<lanelet::BasicPoint2d> all_sampling_points_line2;
430 size_t total_point_size = std::min(line_1.size(), line_2.size());
432 all_sampling_points_line1.reserve(1 + total_point_size * 2);
439 all_sampling_points_line2.reserve(1 + total_point_size * 2);
444 double scaled_steps_along_curve = 0.0;
447 all_sampling_points_line2.reserve(1 + total_point_size * 2);
449 for(
size_t i = 0;
i<total_point_size; ++
i){
450 lanelet::BasicPoint2d p1 = (*fit_curve_1)(scaled_steps_along_curve);
451 lanelet::BasicPoint2d p2 = (*fit_curve_2)(scaled_steps_along_curve);
452 all_sampling_points_line1.push_back(p1);
453 all_sampling_points_line2.push_back(p2);
455 scaled_steps_along_curve += 1.0 / total_point_size;
458 output.push_back(all_sampling_points_line1);
459 output.push_back(all_sampling_points_line2);
461 auto end_time = std::chrono::high_resolution_clock::now();
463 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
464 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"ExecutionTime for resample lane change centerlines: " << duration.count() <<
" milliseconds");
473 if(maneuver.type != carma_planning_msgs::msg::Maneuver::LANE_CHANGE){
474 throw std::invalid_argument(
"Create_lanechange called on a maneuver type which is not LANE_CHANGE");
476 std::vector<PointSpeedPair> points_and_target_speeds;
477 std::unordered_set<lanelet::Id> visited_lanelets;
479 carma_planning_msgs::msg::LaneChangeManeuver lane_change_maneuver = maneuver.lane_change_maneuver;
480 double ending_downtrack = lane_change_maneuver.end_dist;
481 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Maneuver ending downtrack:"<<ending_downtrack);
482 if(starting_downtrack >= ending_downtrack)
484 throw(std::invalid_argument(
"Start distance is greater than or equal to ending distance"));
488 std::vector<lanelet::BasicPoint2d> route_geometry =
create_lanechange_geometry(std::stoi(lane_change_maneuver.starting_lane_id),std::stoi(lane_change_maneuver.ending_lane_id),
490 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Route geometry size:"<<route_geometry.size());
492 lanelet::BasicPoint2d state_pos(state.x_pos_global, state.y_pos_global);
493 double current_downtrack = wm->routeTrackPos(state_pos).downtrack;
496 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Nearest pt index in maneuvers to points: "<< nearest_pt_index);
497 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Ending pt index in maneuvers to points: "<< ending_pt_index);
499 ending_state_before_buffer.x_pos_global = route_geometry[ending_pt_index].x();
500 ending_state_before_buffer.y_pos_global = route_geometry[ending_pt_index].y();
502 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"ending_state_before_buffer_:"<<ending_state_before_buffer.x_pos_global <<
503 ", ending_state_before_buffer_.y_pos_global" << ending_state_before_buffer.y_pos_global);
506 double route_length = wm->getRouteEndTrackPos().downtrack;
514 ending_pt_index = route_geometry.size() - 1;
517 lanelet::BasicLineString2d future_route_geometry(route_geometry.begin() + nearest_pt_index, route_geometry.begin() + ending_pt_index);
519 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Future geom size:"<< future_route_geometry.size());
521 for (
auto p : future_route_geometry)
523 if (first && !points_and_target_speeds.empty())
531 pair.
speed = (state.longitudinal_vel > detailed_config.
minimum_speed) ? state.longitudinal_vel : lane_change_maneuver.end_speed;
532 points_and_target_speeds.push_back(pair);
535 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Const speed assigned:"<<points_and_target_speeds.back().speed);
536 return points_and_target_speeds;
542 const std::vector<double> speed_limits)
544 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Speeds list size: " << speeds.size());
545 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"SpeedLimits list size: " << speed_limits.size());
547 if (speeds.size() != speed_limits.size())
549 throw std::invalid_argument(
"Speeds and speed limit lists not same size");
551 std::vector<double> out;
552 for (
size_t i = 0;
i < speeds.size();
i++)
554 out.push_back(std::min(speeds[
i], speed_limits[
i]));
561 const lanelet::BasicPoint2d &p2)
563 Eigen::Rotation2Dd yaw(atan2(p2.y() - p1.y(), p2.x() - p1.x()));
569 const std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint>& trajectory,
572 if (trajectory.empty())
575 "constrain_to_time_boundary received empty trajectory, returning...");
582 "constrain_to_time_boundary received non-positive time span, returning...");
587 if ((rclcpp::Time(trajectory.back().target_time) -
588 rclcpp::Time(trajectory.front().target_time)).seconds() <= time_span)
594 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> constrained_points;
595 auto start_time = rclcpp::Time(trajectory.front().target_time);
596 auto end_time = start_time + rclcpp::Duration::from_seconds(time_span);
597 for (
const auto& tpp : trajectory)
599 if (rclcpp::Time(tpp.target_time) > end_time)
603 constrained_points.push_back(tpp);
606 return constrained_points;
612 std::vector<lanelet::BasicPoint2d> basic_points;
613 std::vector<double> speeds;
618 size_t time_boundary_exclusive_index =
619 trajectory_utils::time_boundary_index(downtracks, speeds, time_span);
621 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"time_boundary_exclusive_index = " << time_boundary_exclusive_index);
623 if (time_boundary_exclusive_index == 0)
625 throw std::invalid_argument(
"No points to fit in timespan");
628 std::vector<PointSpeedPair> time_bound_points;
629 time_bound_points.reserve(time_boundary_exclusive_index);
631 if (time_boundary_exclusive_index == points.size())
633 time_bound_points.insert(time_bound_points.end(), points.begin(),
638 time_bound_points.insert(time_bound_points.end(), points.begin(),
639 points.begin() + time_boundary_exclusive_index - 1);
642 return time_bound_points;
645 std::pair<double, size_t>
min_with_exclusions(
const std::vector<double> &values,
const std::unordered_set<size_t> &excluded)
647 double min = std::numeric_limits<double>::max();
648 size_t best_idx = -1;
649 for (
size_t i = 0;
i < values.size();
i++)
651 if (excluded.find(
i) != excluded.end())
662 return std::make_pair(min, best_idx);
665 std::vector<double>
optimize_speed(
const std::vector<double> &downtracks,
const std::vector<double> &curv_speeds,
double accel_limit)
667 if (downtracks.size() != curv_speeds.size())
669 throw std::invalid_argument(
"Downtracks and speeds do not have the same size");
672 if (accel_limit <= 0)
674 throw std::invalid_argument(
"Accel limits should be positive");
677 bool optimize =
true;
678 std::unordered_set<size_t> visited_idx;
679 visited_idx.reserve(curv_speeds.size());
681 std::vector<double> output = curv_speeds;
686 int min_idx = std::get<1>(min_pair);
692 visited_idx.insert(min_idx);
694 double v_i = std::get<0>(min_pair);
695 double x_i = downtracks[min_idx];
696 for (
int i = min_idx - 1;
i > 0;
i--)
699 double v_f = curv_speeds[
i];
700 double dv = v_f - v_i;
702 double x_f = downtracks[
i];
703 double dx = x_f - x_i;
707 v_f = std::min(v_f, sqrt(v_i * v_i - 2 * accel_limit *
dx));
708 visited_idx.insert(
i);
722 output = trajectory_utils::apply_accel_limits_by_distance(downtracks, output, accel_limit, accel_limit);
729 const std::vector<lanelet::BasicPoint2d> &points,
const std::vector<double> ×,
const std::vector<double> &yaws,
730 rclcpp::Time startTime,
const std::string &desired_controller_plugin)
732 if (points.size() != times.size() || points.size() != yaws.size())
734 throw std::invalid_argument(
"All input vectors must have the same size");
737 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> traj;
738 traj.reserve(points.size());
740 for (
size_t i = 0;
i < points.size();
i++)
742 carma_planning_msgs::msg::TrajectoryPlanPoint tpp;
743 rclcpp::Duration relative_time = rclcpp::Duration::from_nanoseconds(
static_cast<int64_t
>(times[
i] * 1e9));
744 tpp.target_time = startTime + relative_time;
745 tpp.x = points[
i].x();
746 tpp.y = points[
i].y();
749 tpp.controller_plugin_name = desired_controller_plugin;
759 std::vector<PointSpeedPair>
attach_past_points(
const std::vector<PointSpeedPair> &points_set, std::vector<PointSpeedPair> future_points,
760 const int nearest_pt_index,
double back_distance)
762 std::vector<PointSpeedPair> back_and_future;
763 back_and_future.reserve(points_set.size());
764 double total_dist = 0;
768 for (
int i = nearest_pt_index;
i >= 0; --
i)
771 total_dist += lanelet::geometry::distance2d(points_set[
i].
point, points_set[
i - 1].
point);
773 if (total_dist > back_distance)
779 back_and_future.insert(back_and_future.end(), points_set.begin() + min_i, points_set.begin() + nearest_pt_index + 1);
780 back_and_future.insert(back_and_future.end(), future_points.begin(), future_points.end());
781 return back_and_future;
784 std::unique_ptr<basic_autonomy::smoothing::SplineI>
compute_fit(
const std::vector<lanelet::BasicPoint2d> &basic_points)
786 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Original basic_points size: " << basic_points.size());
790 auto points_with_min_dis = downsample_pts_with_min_meters
791 <std::vector<lanelet::BasicPoint2d>>(basic_points);
793 if (points_with_min_dis.size() < 4)
799 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"points_with_min_dis size: " << points_with_min_dis.size());
801 std::vector<lanelet::BasicPoint2d> resized_points_with_min_dis = points_with_min_dis;
805 if (resized_points_with_min_dis.size() > 400)
807 resized_points_with_min_dis.resize(400);
808 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"resized_points_with_min_dis size: " << resized_points_with_min_dis.size());
810 size_t left_points_size = points_with_min_dis.size() - resized_points_with_min_dis.size();
811 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Left out points size: " << left_points_size);
813 float percent_points_lost = 100.0f
814 *
static_cast<float>(left_points_size) /
815 static_cast<float>(points_with_min_dis.size());
817 if (percent_points_lost > 50.0)
819 RCLCPP_WARN_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"More than half of basic points are ignored for spline fitting");
823 std::unique_ptr<basic_autonomy::smoothing::SplineI> spl = std::make_unique<basic_autonomy::smoothing::BSpline>();
825 spl->setPoints(resized_points_with_min_dis);
832 lanelet::BasicPoint2d f_prime_pt = fit_curve.
first_deriv(step_along_the_curve);
833 lanelet::BasicPoint2d f_prime_prime_pt = fit_curve.
second_deriv(step_along_the_curve);
835 Eigen::Vector3d f_prime = {f_prime_pt.x(), f_prime_pt.y(), 0};
836 Eigen::Vector3d f_prime_prime = {f_prime_prime_pt.x(), f_prime_prime_pt.y(), 0};
837 return (f_prime.cross(f_prime_prime)).norm() / (pow(f_prime.norm(), 3));
841 const std::vector<PointSpeedPair> &points,
const carma_planning_msgs::msg::VehicleState &state,
const rclcpp::Time &state_time,
const carma_wm::WorldModelConstPtr &wm,
842 const carma_planning_msgs::msg::VehicleState &ending_state_before_buffer, carma_debug_ros2_msgs::msg::TrajectoryCurvatureSpeeds& debug_msg,
const DetailedTrajConfig &detailed_config)
845 <<
" x: " << state.x_pos_global <<
" y: " << state.y_pos_global <<
" yaw: " << state.orientation
846 <<
" speed: " << state.longitudinal_vel);
852 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"NearestPtIndex: " << nearest_pt_index);
854 std::vector<PointSpeedPair> future_points(points.begin() + nearest_pt_index + 1, points.end());
856 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Ready to call constrain_to_time_boundary: future_points size = " << future_points.size() <<
", trajectory_time_length = " << detailed_config.
trajectory_time_length);
860 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Got time_bound_points with size:" << time_bound_points.size());
865 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Got back_and_future points with size" << back_and_future.size());
868 std::vector<double> speed_limits;
869 std::vector<lanelet::BasicPoint2d> curve_points;
872 std::unique_ptr<smoothing::SplineI> fit_curve =
compute_fit(curve_points);
875 throw std::invalid_argument(
"Could not fit a spline curve along the given trajectory!");
880 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"speed_limits.size() " << speed_limits.size());
882 std::vector<lanelet::BasicPoint2d> all_sampling_points;
883 all_sampling_points.reserve(1 + curve_points.size() * 2);
885 std::vector<double> distributed_speed_limits;
886 distributed_speed_limits.reserve(1 + curve_points.size() * 2);
894 int current_speed_index = 0;
895 size_t total_point_size = curve_points.size();
897 double step_threshold_for_next_speed = (double)total_step_along_curve / (
double)total_point_size;
898 double scaled_steps_along_curve = 0.0;
899 std::vector<double> better_curvature;
900 better_curvature.reserve(1 + curve_points.size() * 2);
902 for (
int steps_along_curve = 0; steps_along_curve < total_step_along_curve; steps_along_curve++)
904 lanelet::BasicPoint2d p = (*fit_curve)(scaled_steps_along_curve);
906 all_sampling_points.push_back(p);
908 better_curvature.push_back(
c);
909 if ((
double)steps_along_curve > step_threshold_for_next_speed)
911 step_threshold_for_next_speed += (double)total_step_along_curve / (
double)total_point_size;
912 current_speed_index++;
914 distributed_speed_limits.push_back(speed_limits[current_speed_index]);
915 scaled_steps_along_curve += 1.0 / total_step_along_curve;
918 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Got sampled points with size:" << all_sampling_points.size());
926 std::vector<double> ideal_speeds =
927 trajectory_utils::constrained_speeds_for_curvatures(curvatures, detailed_config.
lateral_accel_limit);
933 std::vector<double> constrained_speed_limits =
apply_speed_limits(ideal_speeds, distributed_speed_limits);
935 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Processed all points in computed fit");
937 if (all_sampling_points.empty())
939 RCLCPP_WARN_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"No trajectory points could be generated");
946 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Current state's nearest_pt_index: " << nearest_pt_index);
947 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Curvature right now: " << better_curvature[nearest_pt_index] <<
", at state x: " << state.x_pos_global <<
", state y: " << state.y_pos_global);
948 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Corresponding to point: x: " << all_sampling_points[nearest_pt_index].
x() <<
", y:" << all_sampling_points[nearest_pt_index].
y());
951 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Ending state's index before applying buffer (buffer_pt_index): " << buffer_pt_index);
952 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Corresponding to point: x: " << all_sampling_points[buffer_pt_index].
x() <<
", y:" << all_sampling_points[buffer_pt_index].
y());
954 if(nearest_pt_index + 1 >= buffer_pt_index){
956 lanelet::BasicPoint2d current_pos(state.x_pos_global, state.y_pos_global);
957 lanelet::BasicPoint2d ending_pos(ending_state_before_buffer.x_pos_global, ending_state_before_buffer.y_pos_global);
959 if(wm->routeTrackPos(ending_pos).downtrack < wm->routeTrackPos(current_pos).downtrack ){
961 RCLCPP_WARN_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Current state is at or past the planned end distance. Couldn't generate trajectory");
966 RCLCPP_WARN_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Returning the two remaining points in the maneuver");
968 std::vector<lanelet::BasicPoint2d> remaining_traj_points = {current_pos, ending_pos};
971 std::vector<double> speeds = {state.longitudinal_vel, state.longitudinal_vel};
972 std::vector<double> times;
973 trajectory_utils::conversions::speed_to_time(downtracks, speeds, ×);
974 std::vector<double> yaw = {state.orientation, state.orientation};
976 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> traj_points =
986 std::vector<lanelet::BasicPoint2d> future_basic_points(all_sampling_points.begin() + nearest_pt_index + 1,
987 all_sampling_points.begin()+ buffer_pt_index);
989 std::vector<double> future_speeds(constrained_speed_limits.begin() + nearest_pt_index + 1,
990 constrained_speed_limits.begin() + buffer_pt_index);
991 std::vector<double> future_yaw(final_yaw_values.begin() + nearest_pt_index + 1,
992 final_yaw_values.begin() + buffer_pt_index);
993 std::vector<double> final_actual_speeds = future_speeds;
994 all_sampling_points = future_basic_points;
995 final_yaw_values = future_yaw;
996 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Trimmed future points to size: "<< future_basic_points.size());
998 lanelet::BasicPoint2d cur_veh_point(state.x_pos_global, state.y_pos_global);
1000 all_sampling_points.insert(all_sampling_points.begin(),
1003 final_actual_speeds.insert(final_actual_speeds.begin(), state.longitudinal_vel);
1005 final_yaw_values.insert(final_yaw_values.begin(), state.orientation);
1019 for (
auto &s : final_actual_speeds)
1027 std::vector<double> times;
1028 trajectory_utils::conversions::speed_to_time(downtracks, final_actual_speeds, ×);
1033 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> traj_points =
1037 carma_debug_ros2_msgs::msg::TrajectoryCurvatureSpeeds msg;
1038 msg.velocity_profile = final_actual_speeds;
1039 msg.relative_downtrack = downtracks;
1040 msg.tangent_headings = final_yaw_values;
1041 std::vector<double> aligned_speed_limits(constrained_speed_limits.begin() + nearest_pt_index,
1042 constrained_speed_limits.end());
1044 msg.speed_limits = aligned_speed_limits;
1045 std::vector<double> aligned_curvatures(curvatures.begin() + nearest_pt_index,
1047 msg.curvatures = aligned_curvatures;
1049 msg.lon_accel_limit = detailed_config.
max_accel;
1050 msg.starting_state = state;
1058 double curve_resample_step_size,
1059 double minimum_speed,
1061 double lateral_accel_limit,
1062 int speed_moving_average_window_size,
1063 int curvature_moving_average_window_size,
1064 double back_distance,
1065 double buffer_ending_downtrack,
1066 std::string desired_controller_plugin)
1081 return detailed_config;
1085 int default_downsample_ratio,
1086 int turn_downsample_ratio)
1095 return general_config;
1100 const std::vector<PointSpeedPair> &points,
const carma_planning_msgs::msg::VehicleState &state,
const rclcpp::Time &state_time,
1103 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Input points size in compose traj from centerline: "<< points.size());
1105 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"nearest_pt_index: "<< nearest_pt_index);
1107 std::vector<PointSpeedPair> future_points(points.begin() + nearest_pt_index + 1, points.end());
1108 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"future_points size: "<< future_points.size());
1111 std::vector<lanelet::BasicPoint2d> future_geom_points;
1112 std::vector<double> final_actual_speeds;
1115 std::unique_ptr<smoothing::SplineI> fit_curve =
compute_fit(future_geom_points);
1117 throw std::invalid_argument(
"Could not fit a spline curve along the given trajectory!");
1122 lanelet::BasicPoint2d current_vehicle_point(state.x_pos_global, state.y_pos_global);
1123 future_geom_points.insert(future_geom_points.begin(), current_vehicle_point);
1124 final_actual_speeds.insert(final_actual_speeds.begin(), state.longitudinal_vel);
1130 auto total_step_along_curve =
static_cast<int>(original_downtracks.back() / detailed_config.
curve_resample_step_size);
1131 if (total_step_along_curve == 0) {
1133 "Available distance to resample is less than curve_resample_step_size. "
1134 "Only considering the last point of the target destination to generate trajectory."
1136 total_step_along_curve = 1;
1139 std::vector<lanelet::BasicPoint2d> resampled_points;
1140 resampled_points.reserve(total_step_along_curve + 1);
1142 double scaled_steps_along_curve = 0.0;
1143 for(
int step = 0; step <= total_step_along_curve; step++){
1144 scaled_steps_along_curve =
static_cast<double>(step) / total_step_along_curve;
1145 lanelet::BasicPoint2d p = (*fit_curve)(scaled_steps_along_curve);
1146 resampled_points.push_back(p);
1148 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Got resampled points with size:" << resampled_points.size());
1154 std::vector<double> resampled_speeds;
1155 resampled_speeds.reserve(resampled_points.size());
1157 for (
const auto& downtrack : resampled_downtracks) {
1159 auto it = std::upper_bound(original_downtracks.begin(), original_downtracks.end(), downtrack);
1160 size_t idx = it - original_downtracks.begin();
1164 resampled_speeds.push_back(final_actual_speeds[0]);
1165 }
else if (idx >= original_downtracks.size()) {
1167 resampled_speeds.push_back(final_actual_speeds.back());
1171 resampled_speeds.push_back(final_actual_speeds[idx]);
1180 if (!resampled_yaw_values.empty())
1182 resampled_yaw_values[0] = state.orientation;
1186 std::vector<double> times;
1187 trajectory_utils::conversions::speed_to_time(resampled_downtracks, resampled_speeds, ×);
1190 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Before removing extra buffer points, future_geom_points.size()"<< future_geom_points.size());
1196 int end_dist_pt_index =
1198 resampled_points, wm, ending_state_before_buffer)
1202 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Before removing extra buffer points, resampled_points.size(): " << resampled_points.size());
1203 resampled_points.resize(end_dist_pt_index + 1);
1204 times.resize(end_dist_pt_index + 1);
1205 resampled_yaw_values.resize(end_dist_pt_index + 1);
1206 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"After removing extra buffer points, resampled_points.size(): " << resampled_points.size());
1209 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> traj_points =
1215 autoware_auto_msgs::msg::Trajectory
process_trajectory_plan(
const carma_planning_msgs::msg::TrajectoryPlan& tp,
double vehicle_response_lag )
1217 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Processing latest TrajectoryPlan message");
1219 std::vector<double> times;
1220 std::vector<double> downtracks;
1222 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> trajectory_points = tp.trajectory_points;
1224 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Original Trajectory size:"<<trajectory_points.size());
1227 trajectory_utils::conversions::trajectory_to_downtrack_time(trajectory_points, &downtracks, ×);
1230 size_t stopping_index = 0;
1231 for (
size_t i = 1;
i < times.size();
i++)
1233 if (times[
i] == times[
i - 1])
1235 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Detected a stopping case where times is exactly equal: " << times[
i-1]);
1236 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"And index of that is: " <<
i <<
", where size is: " << times.size());
1242 std::vector<double> speeds;
1245 trajectory_utils::conversions::time_to_speed(downtracks, times, tp.initial_longitudinal_velocity, &speeds);
1247 catch(
const std::runtime_error& error)
1252 RCLCPP_WARN_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Detected a negative speed from <point,time> to <point,speed> trajectory conversion with error: "
1253 << error.what() <<
". Replacing the negative speed with 0.0 speed, but please revisit the trajectory logic. "
1254 "Responsible plugin is: " << trajectory_points[std::find(speeds.begin(), speeds.end(), 0.0) - speeds.begin()].planner_plugin_name);
1257 if (speeds.size() != trajectory_points.size())
1259 throw std::invalid_argument(
"Speeds and trajectory points sizes do not match");
1262 for (
size_t i = 0;
i < speeds.size();
i++) {
1263 if (stopping_index != 0 &&
i >= stopping_index - 1)
1271 speeds[
i] = std::max(0.0, speeds[
i]);
1275 std::vector<double> lag_speeds;
1278 autoware_auto_msgs::msg::Trajectory autoware_trajectory;
1279 autoware_trajectory.header = tp.header;
1280 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"size: " << trajectory_points.size());
1282 auto max_size = std::min(99, (
int)trajectory_points.size());
1284 for (
int i = 0;
i < max_size;
i++)
1286 autoware_auto_msgs::msg::TrajectoryPoint autoware_point;
1288 autoware_point.x = trajectory_points[
i].x;
1289 autoware_point.y = trajectory_points[
i].y;
1290 autoware_point.longitudinal_velocity_mps = lag_speeds[
i];
1294 yaw = std::atan2(trajectory_points[
i+1].
y - trajectory_points[
i].
y, trajectory_points[
i+1].
x - trajectory_points[
i].
x);
1299 yaw = std::atan2(trajectory_points[max_size-1].
y - trajectory_points[max_size-2].
y, trajectory_points[max_size-1].
x - trajectory_points[max_size-2].
x);
1302 autoware_point.heading.real = std::cos(yaw/2);
1303 autoware_point.heading.imag = std::sin(yaw/2);
1305 autoware_point.time_from_start = rclcpp::Duration::from_nanoseconds(
static_cast<int64_t
>(times[
i] * 1e9));
1306 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
BASIC_AUTONOMY_LOGGER),
"Setting waypoint idx: " <<
i <<
", with planner: << " << trajectory_points[
i].planner_plugin_name <<
", x: " << trajectory_points[
i].
x <<
1307 ", y: " << trajectory_points[
i].
y <<
1308 ", speed: " << lag_speeds[
i]* 2.23694 <<
"mph");
1309 autoware_trajectory.points.push_back(autoware_point);
1312 return autoware_trajectory;
1316 std::vector<double>
apply_response_lag(
const std::vector<double>& speeds,
const std::vector<double> downtracks,
double response_lag)
1318 if (speeds.size() != downtracks.size()) {
1319 throw std::invalid_argument(
"Speed list and downtrack list are not the same size.");
1322 std::vector<double> output;
1323 if (speeds.empty()) {
1327 double lookahead_distance = speeds[0] * response_lag;
1329 double downtrack_cutoff = downtracks[0] + lookahead_distance;
1330 size_t lookahead_count = std::lower_bound(downtracks.begin(),downtracks.end(), downtrack_cutoff) - downtracks.begin();
1331 output = trajectory_utils::shift_by_lookahead(speeds, (
unsigned int) lookahead_count);
1335 bool is_valid_yield_plan(
const std::shared_ptr<carma_ros2_utils::CarmaLifecycleNode>& node_handler,
const carma_planning_msgs::msg::TrajectoryPlan& yield_plan)
1337 if (yield_plan.trajectory_points.size() < 2)
1339 RCLCPP_WARN(node_handler->get_logger(),
"Invalid Yield Trajectory with less than 2 points!");
1343 RCLCPP_DEBUG_STREAM(node_handler->get_logger(),
"Yield Trajectory Time" << rclcpp::Time(yield_plan.trajectory_points[0].target_time).seconds());
1344 RCLCPP_DEBUG_STREAM(node_handler->get_logger(),
"Now:" << node_handler->now().seconds());
1346 if (rclcpp::Time(yield_plan.trajectory_points[0].target_time) + rclcpp::Duration(5.0, 0) > node_handler->now())
1352 RCLCPP_WARN_STREAM(node_handler->get_logger(),
"Invalid Yield Trajectory with old target_time: " <<
1353 std::to_string(rclcpp::Time(yield_plan.trajectory_points[0].target_time).seconds()) <<
", where now: " <<
1361 const std::shared_ptr<carma_ros2_utils::CarmaLifecycleNode>& node_handler,
1362 const carma_planning_msgs::srv::PlanTrajectory::Request::SharedPtr& req,
1363 const carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr& resp,
1364 const carma_ros2_utils::ClientPtr<carma_planning_msgs::srv::PlanTrajectory>& yield_client,
1365 int yield_plugin_service_call_timeout)
1367 RCLCPP_DEBUG(node_handler->get_logger(),
"Object avoidance activated");
1369 if (!yield_client || !yield_client->service_is_ready())
1371 throw std::runtime_error(
"Yield Client is not set or unavailable after configuration state of lifecycle");
1374 RCLCPP_DEBUG(node_handler->get_logger(),
"Yield Client is valid");
1376 auto yield_srv = std::make_shared<carma_planning_msgs::srv::PlanTrajectory::Request>();
1377 yield_srv->initial_trajectory_plan = resp->trajectory_plan;
1378 yield_srv->vehicle_state = req->vehicle_state;
1380 auto yield_resp = yield_client->async_send_request(yield_srv);
1382 auto future_status = yield_resp.wait_for(std::chrono::milliseconds(yield_plugin_service_call_timeout));
1384 if (future_status != std::future_status::ready)
1388 RCLCPP_WARN(node_handler->get_logger(),
"Service request to yield plugin timed out waiting on a reply from the service server");
1392 RCLCPP_DEBUG(node_handler->get_logger(),
"Received Traj from Yield");
1393 carma_planning_msgs::msg::TrajectoryPlan yield_plan = yield_resp.get()->trajectory_plan;
1396 RCLCPP_DEBUG(node_handler->get_logger(),
"Yield trajectory validated");
1397 resp->trajectory_plan = yield_plan;
1403 RCLCPP_WARN_STREAM(node_handler->get_logger(),
"Invalid yield trajectory detected, returning original trajectory of size: " <<
1404 resp->trajectory_plan.trajectory_points.size());
#define GET_MANEUVER_PROPERTY(mvr, property)
Macro definition to enable easier access to fields shared across the maneuver types.
Interface to a spline interpolator that can be used to smoothly interpolate between points.
virtual lanelet::BasicPoint2d first_deriv(double x) const =0
Get the BasicPoint2d representing the first_deriv along the curve at t-th step.
virtual lanelet::BasicPoint2d second_deriv(double x) const =0
Get the BasicPoint2d representing the first_deriv along the curve at t-th step.
void printDoublesPerLineWithPrefix(const std::string &prefix, const std::vector< double > &values)
Print a RCLCPP_DEBUG_STREAM for each value in values where the printed value is << prefix << value.
std::string basicPointToStream(lanelet::BasicPoint2d point)
Helper function to convert a lanelet::BasicPoint2d to a string.
std::string pointSpeedPairToStream(waypoint_generation::PointSpeedPair point)
Helper function to convert a PointSpeedPair to a string.
void printDebugPerLine(const std::vector< T > &values, std::function< std::string(T)> func)
Print a RCLCPP_DEBUG_STREAM for each value in values where the printed value is a string returned by ...
std::vector< double > moving_average_filter(const std::vector< double > input, int window_size, bool ignore_first_point=true)
Extremely simplie moving average filter.
void split_point_speed_pairs(const std::vector< PointSpeedPair > &points, std::vector< lanelet::BasicPoint2d > *basic_points, std::vector< double > *speeds)
Helper method to split a list of PointSpeedPair into separate point and speed lists.
GeneralTrajConfig compose_general_trajectory_config(const std::string &trajectory_type, int default_downsample_ratio, int turn_downsample_ratio)
void extrapolate_to_length(std::vector< lanelet::BasicPoint2d > ¢erline, double target_length, const std::string &description)
Pads a centerline out to target_length by extrapolating a straight line from its last known heading,...
std::vector< std::vector< lanelet::BasicPoint2d > > resample_linestring_pair_to_same_size(std::vector< lanelet::BasicPoint2d > &line_1, std::vector< lanelet::BasicPoint2d > &line_2)
Resamples a pair of basicpoint2d lines to get lines of same number of points.
std::vector< lanelet::BasicPoint2d > create_lanechange_geometry(lanelet::Id starting_lane_id, lanelet::Id ending_lane_id, double starting_downtrack, double ending_downtrack, const carma_wm::WorldModelConstPtr &wm, int downsample_ratio, double buffer_ending_downtrack)
Creates a vector of lane change points using parameters defined.
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.
std::vector< double > apply_response_lag(const std::vector< double > &speeds, const std::vector< double > downtracks, double response_lag)
Applies a specified response lag in seconds to the trajectory shifting the whole thing by the specifi...
static const std::string BASIC_AUTONOMY_LOGGER
std::vector< lanelet::BasicPoint2d > build_chain_centerline(const carma_wm::WorldModelConstPtr &wm, lanelet::ConstLanelet pivot, double backward_length, double forward_length)
Builds a centerline covering [pivot_end_point - backward_length, pivot_end_point + forward_length] by...
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > compose_lanechange_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, const DetailedTrajConfig &detailed_config)
Method converts a list of lanelet centerline points and current vehicle state into a usable list of t...
std::vector< double > optimize_speed(const std::vector< double > &downtracks, const std::vector< double > &curv_speeds, double accel_limit)
Applies the longitudinal acceleration limit to each point's speed.
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")
int get_nearest_point_index(const std::vector< lanelet::BasicPoint2d > &points, const carma_planning_msgs::msg::VehicleState &state)
Returns the nearest point (in terms of cartesian 2d distance) to the provided vehicle pose in the pro...
bool is_valid_yield_plan(const std::shared_ptr< carma_ros2_utils::CarmaLifecycleNode > &node_handler, const carma_planning_msgs::msg::TrajectoryPlan &yield_plan)
Helper function to verify if the input yield trajectory plan is valid.
std::pair< double, size_t > min_with_exclusions(const std::vector< double > &values, const std::unordered_set< size_t > &excluded)
Returns the min, and its idx, from the vector of values, excluding given set of values.
std::unique_ptr< basic_autonomy::smoothing::SplineI > compute_fit(const std::vector< lanelet::BasicPoint2d > &basic_points)
Computes a spline based on the provided points.
std::vector< PointSpeedPair > create_lanefollow_geometry(const carma_planning_msgs::msg::Maneuver &maneuver, double max_starting_downtrack, const carma_wm::WorldModelConstPtr &wm, const GeneralTrajConfig &general_config, const DetailedTrajConfig &detailed_config, std::unordered_set< lanelet::Id > &visited_lanelets)
Converts a set of requested LANE_FOLLOWING maneuvers to point speed limit pairs.
int get_nearest_index_by_downtrack(const std::vector< lanelet::BasicPoint2d > &points, const carma_wm::WorldModelConstPtr &wm, double target_downtrack)
Returns the nearest "less than" point to the provided vehicle pose in the provided list by utilizing ...
std::vector< double > apply_speed_limits(const std::vector< double > speeds, const std::vector< double > speed_limits)
Applies the provided speed limits to the provided speeds such that each element is capped at its corr...
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > trajectory_from_points_times_orientations(const std::vector< lanelet::BasicPoint2d > &points, const std::vector< double > ×, const std::vector< double > &yaws, rclcpp::Time startTime, const std::string &desired_controller_plugin)
Method combines input points, times, orientations, and an absolute start time to form a valid carma p...
std::vector< PointSpeedPair > create_geometry_profile(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 LANE FOLLOW and LANE CHANGE maneuver...
std::vector< PointSpeedPair > add_lanefollow_buffer(const carma_wm::WorldModelConstPtr &wm, std::vector< PointSpeedPair > &points_and_target_speeds, const std::vector< carma_planning_msgs::msg::Maneuver > &maneuvers, carma_planning_msgs::msg::VehicleState &ending_state_before_buffer, const DetailedTrajConfig &detailed_config)
Adds extra centerline points beyond required message length to lane follow maneuver points so that th...
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...
Eigen::Isometry2d compute_heading_frame(const lanelet::BasicPoint2d &p1, const lanelet::BasicPoint2d &p2)
Returns a 2D coordinate frame which is located at p1 and oriented so p2 lies on the +X axis.
double compute_curvature_at(const basic_autonomy::smoothing::SplineI &fit_curve, double step_along_the_curve)
Given the curvature fit, computes the curvature at the given step along the curve.
autoware_auto_msgs::msg::Trajectory process_trajectory_plan(const carma_planning_msgs::msg::TrajectoryPlan &tp, double vehicle_response_lag)
Given a carma type of trajectory_plan, generate autoware type of trajectory accounting for speed_lag ...
std::vector< PointSpeedPair > constrain_to_time_boundary(const std::vector< PointSpeedPair > &points, double time_span)
Reduces the input points to only those points that fit within the provided time boundary.
std::vector< PointSpeedPair > get_lanechange_points_from_maneuver(const carma_planning_msgs::msg::Maneuver &maneuver, 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)
Converts a set of requested LANE_CHANGE maneuvers to point speed limit pairs.
std::vector< PointSpeedPair > attach_past_points(const std::vector< PointSpeedPair > &points_set, std::vector< PointSpeedPair > future_points, const int nearest_pt_index, double back_distance)
Attaches back_distance length of points behind the future points.
auto to_string(const UtmZone &zone) -> std::string
Eigen::Isometry2d build2dEigenTransform(const Eigen::Vector2d &position, const Eigen::Rotation2Dd &rotation)
Builds a 2D Eigen coordinate frame transform with not applied scaling (only translation and rotation)...
std::vector< double > compute_tangent_orientations(const lanelet::BasicLineString2d ¢erline)
Compute an approximate orientation for the vehicle at each point along the provided centerline.
std::vector< double > compute_arc_lengths(const std::vector< lanelet::BasicPoint2d > &data)
Compute the arc length at each point around the curve.
lanelet::BasicLineString2d concatenate_line_strings(const lanelet::BasicLineString2d &l1, const lanelet::BasicLineString2d &l2)
Helper function to concatenate 2 linestrings together and return the result. Neither LineString is mo...
std::shared_ptr< const WorldModel > WorldModelConstPtr
int speed_moving_average_window_size
int curvature_moving_average_window_size
double lateral_accel_limit
std::string desired_controller_plugin
double buffer_ending_downtrack
double trajectory_time_length
double curve_resample_step_size
int default_downsample_ratio
std::string trajectory_type
int turn_downsample_ratio
lanelet::BasicPoint2d point