24namespace waypoint_generation
27 const carma_planning_msgs::msg::VehicleState& state)
29 lanelet::BasicPoint2d veh_point(state.x_pos_global, state.y_pos_global);
30 double min_distance = std::numeric_limits<double>::max();
33 for (
const auto& p : points)
35 double distance = lanelet::geometry::distance2d(p, veh_point);
36 if (distance < min_distance)
39 min_distance = distance;
47 const carma_planning_msgs::msg::VehicleState& state)
49 lanelet::BasicPoint2d veh_point(state.x_pos_global, state.y_pos_global);
51 double min_distance = std::numeric_limits<double>::max();
54 for (
const auto& p : points)
56 double distance = lanelet::geometry::distance2d(p.point, veh_point);
57 if (distance < min_distance)
60 min_distance = distance;
68 const std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint>& trajectory,
69 const lanelet::BasicPoint2d& position)
71 size_t closest_idx = 0;
72 double min_dist = std::numeric_limits<double>::max();
74 for (
size_t i = 0;
i < trajectory.size();
i++)
76 auto dist = sqrt(pow(position.x() - trajectory.at(
i).x, 2) +
77 pow(position.y() - trajectory.at(
i).y, 2));
91 if(std::empty(points)){
97 const auto itr = std::find_if(std::cbegin(points), std::cend(points),
98 [&wm = std::as_const(wm), target_downtrack](
const auto &
point) {
return wm->routeTrackPos(
point).downtrack > target_downtrack; });
100 int best_index = std::size(points) - 1;
103 if(itr != std::cbegin(points)){
104 best_index = std::distance(std::cbegin(points), std::prev(itr));
110 RCLCPP_DEBUG_STREAM(
basic_autonomy::get_logger(),
"get_nearest_index_by_downtrack>> Found best_index: " << best_index<<
", points[i].x(): " << points.at(best_index).x() <<
", points[i].y(): " << points.at(best_index).y());
116 std::vector<lanelet::BasicPoint2d>* basic_points,
117 std::vector<double>* speeds)
119 basic_points->reserve(points.size());
120 speeds->reserve(points.size());
122 for (
const auto& p : points)
124 basic_points->push_back(p.point);
125 speeds->push_back(p.speed);
130 const carma_planning_msgs::msg::VehicleState& state)
132 lanelet::BasicPoint2d state_pos(state.x_pos_global, state.y_pos_global);
133 double ending_downtrack = wm->routeTrackPos(state_pos).downtrack;
134 std::vector<lanelet::BasicPoint2d> basic_points;
135 std::vector<double> speeds;
141 const carma_planning_msgs::msg::VehicleState& state)
143 lanelet::BasicPoint2d state_pos(state.x_pos_global, state.y_pos_global);
144 double ending_downtrack = wm->routeTrackPos(state_pos).downtrack;
149 lanelet::ConstLanelet pivot,
150 double backward_length,
151 double forward_length)
153 std::vector<lanelet::ConstLanelet> chain{pivot};
154 std::unordered_set<lanelet::Id> visited{pivot.id()};
157 while (covered_back < backward_length)
159 auto previous = wm->getMapRoutingGraph()->previous(chain.front(),
false);
160 bool no_predecessor = previous.empty();
161 bool loop_detected = !no_predecessor && visited.count(previous.front().id()) > 0;
166 "create_lanechange_geometry: No routable predecessor lanelet found before lanelet "
167 << chain.front().id() <<
" (possibly closed or missing from the map). Using the "
168 << covered_back <<
"m of centerline that was reachable going backward.");
174 "create_lanechange_geometry: Detected a loop in lanelet connectivity before lanelet "
175 << chain.front().id() <<
"; stopping centerline extension.");
178 if (no_predecessor || loop_detected)
183 lanelet::ConstLanelet prev = previous.front();
184 visited.insert(prev.id());
186 chain.insert(chain.begin(), prev);
189 double covered_fwd = 0.0;
190 while (covered_fwd < forward_length)
192 auto following = wm->getMapRoutingGraph()->following(chain.back(),
false);
193 bool no_successor = following.empty();
194 bool loop_detected = !no_successor && visited.count(following.front().id()) > 0;
199 "create_lanechange_geometry: No routable successor lanelet found after lanelet "
200 << chain.back().id() <<
" (possibly closed or missing from the map). Using the "
201 << covered_fwd <<
"m of centerline that was reachable going forward.");
207 "create_lanechange_geometry: Detected a loop in lanelet connectivity after lanelet "
208 << chain.back().id() <<
"; stopping centerline extension.");
211 if (no_successor || loop_detected)
216 lanelet::ConstLanelet next = following.front();
217 visited.insert(next.id());
219 chain.push_back(next);
222 std::vector<lanelet::BasicPoint2d> centerline;
223 centerline.reserve(400);
224 for (
size_t i = 0;
i < chain.size(); ++
i)
226 auto ls = chain[
i].centerline2d().basicLineString();
229 centerline.insert(centerline.end(), ls.begin(), ls.end());
234 centerline.insert(centerline.end(), ls.begin() + 1, ls.end());
240 void extrapolate_to_length(std::vector<lanelet::BasicPoint2d>& centerline,
double target_length,
const std::string& description)
242 if (centerline.size() < 2)
244 throw std::invalid_argument(
"create_lanechange_geometry: " + description +
245 " has fewer than 2 centerline points; cannot build or extrapolate a lane change trajectory from this map data");
249 if (current_length >= target_length)
255 "create_lanechange_geometry: Only " << current_length <<
"m of connected lanelet centerline was "
256 <<
"available for " << description <<
" (needed " << target_length <<
"m). Extrapolating a "
257 <<
"straight line from the last known heading so a lane change trajectory can still be produced.");
259 lanelet::BasicPoint2d last = centerline.back();
260 lanelet::BasicPoint2d prev = centerline[centerline.size() - 2];
261 lanelet::BasicPoint2d direction = last - prev;
262 if (direction.norm() < 1e-6)
265 direction = last - centerline.front();
267 direction.normalize();
269 constexpr double step = 1.0;
270 double remaining = target_length - current_length;
271 for (
int step_count = 1; step_count * step < remaining; ++step_count)
273 centerline.push_back(last + direction * (step_count * step));
275 centerline.push_back(last + direction * remaining);
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.
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< 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...
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...
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 ...
rclcpp::Logger get_logger()
Return the module-level logger used by all basic_autonomy functions.
double get_lanelet_centerline_length(const lanelet::ConstLanelet &ll)
Returns the total 2d arc length of a lanelet's centerline.
std::vector< double > compute_arc_lengths(const std::vector< lanelet::BasicPoint2d > &data)
Compute the arc length at each point around the curve.
std::shared_ptr< const WorldModel > WorldModelConstPtr