21#include "absl/strings/match.h"
40using ::google::protobuf::RepeatedPtrField;
44bool IsAllowedToCross(
const LaneBoundary& boundary) {
45 for (
const auto& boundary_type : boundary.boundary_type()) {
57 const std::string& dump_topo_file_path,
59 : base_map_file_path_(base_map_file_path),
60 dump_topo_file_path_(dump_topo_file_path),
61 routing_conf_(routing_conf) {}
64 if (absl::EndsWith(base_map_file_path_,
".xml")) {
67 AERROR <<
"Failed to load base map file from " << base_map_file_path_;
72 AERROR <<
"Failed to load base map file from " << base_map_file_path_;
77 AINFO <<
"Number of lanes: " << pbmap_.lane_size();
82 node_index_map_.clear();
84 showed_edge_id_set_.clear();
86 for (
const auto& road : pbmap_.
road()) {
87 for (
const auto& section : road.section()) {
88 for (
const auto& lane_id : section.lane_id()) {
89 road_id_map_[lane_id.id()] = road.id().id();
95 const double min_turn_radius =
98 for (
const auto& lane : pbmap_.
lane()) {
99 const auto& lane_id = lane.id().id();
100 if (forbidden_lane_id_set_.find(lane_id) != forbidden_lane_id_set_.end()) {
101 ADEBUG <<
"Ignored lane id: " << lane_id
102 <<
" because its type is NOT CITY_DRIVING.";
106 !IsValidUTurn(lane, min_turn_radius)) {
107 ADEBUG <<
"The u-turn lane radius is too small for the vehicle to turn";
110 AINFO <<
"Current lane id: " << lane_id;
111 node_index_map_[lane_id] = graph_.node_size();
112 const auto iter = road_id_map_.find(lane_id);
113 if (iter != road_id_map_.end()) {
117 AWARN <<
"Failed to find road id of lane " << lane_id;
122 for (
const auto& lane : pbmap_.
lane()) {
123 const auto& lane_id = lane.id().id();
124 if (forbidden_lane_id_set_.find(lane_id) != forbidden_lane_id_set_.end()) {
125 ADEBUG <<
"Ignored lane id: " << lane_id
126 <<
" because its type is NOT CITY_DRIVING.";
129 const auto& from_node = graph_.
node(node_index_map_[lane_id]);
132 if (lane.length() < FLAGS_min_length_for_lane_change) {
135 if (lane.has_left_boundary() && IsAllowedToCross(lane.left_boundary())) {
136 AddEdge(from_node, lane.left_neighbor_forward_lane_id(),
Edge::LEFT);
139 if (lane.has_right_boundary() && IsAllowedToCross(lane.right_boundary())) {
140 AddEdge(from_node, lane.right_neighbor_forward_lane_id(),
Edge::RIGHT);
144 if (!absl::EndsWith(dump_topo_file_path_,
".bin") &&
145 !absl::EndsWith(dump_topo_file_path_,
".txt")) {
146 AERROR <<
"Failed to dump topo data into file, incorrect file type "
147 << dump_topo_file_path_;
150 auto type_pos = dump_topo_file_path_.find_last_of(
".") + 1;
151 std::string bin_file = dump_topo_file_path_.replace(type_pos, 3,
"bin");
152 std::string txt_file = dump_topo_file_path_.replace(type_pos, 3,
"txt");
154 AERROR <<
"Failed to dump topo data into file " << txt_file;
157 AINFO <<
"Txt file is dumped successfully. Path: " << txt_file;
159 AERROR <<
"Failed to dump topo data into file " << bin_file;
162 AINFO <<
"Bin file is dumped successfully. Path: " << bin_file;
166std::string GraphCreator::GetEdgeID(
const std::string& from_id,
167 const std::string& to_id) {
168 return from_id +
"->" + to_id;
171void GraphCreator::AddEdge(
const Node& from_node,
172 const RepeatedPtrField<Id>& to_node_vec,
174 for (
const auto& to_id : to_node_vec) {
175 if (forbidden_lane_id_set_.find(to_id.id()) !=
176 forbidden_lane_id_set_.end()) {
177 ADEBUG <<
"Ignored lane [id = " << to_id.id();
180 const std::string edge_id = GetEdgeID(from_node.lane_id(), to_id.id());
181 if (showed_edge_id_set_.count(edge_id) != 0) {
184 showed_edge_id_set_.insert(edge_id);
185 const auto& iter = node_index_map_.find(to_id.id());
186 if (iter == node_index_map_.end()) {
189 const auto& to_node = graph_.
node(iter->second);
195bool GraphCreator::IsValidUTurn(
const hdmap::Lane& lane,
const double radius) {
200 if (lane.central_curve().segment().empty() ||
201 !lane.central_curve().segment(0).has_line_segment()) {
204 std::vector<PointENU> points;
205 for (
const auto& segment : lane.central_curve().segment()) {
206 points.insert(points.end(), segment.line_segment().point().begin(),
207 segment.line_segment().point().end());
209 if (points.empty()) {
212 Vec2d p1{points.front().x(), points.front().y()};
213 const auto& mid = points[points.size() / 2];
214 Vec2d p2{mid.x(), mid.y()};
215 Vec2d p3{points.back().x(), points.back().y()};
216 Vec2d q1 = ((p1 + p2) / 2);
217 Vec2d q2 = (p2 - p1).rotate(M_PI / 2) + q1;
218 Vec2d q3 = ((p2 + p3) / 2);
219 Vec2d q4 = (p3 - p2).rotate(M_PI / 2) + q3;
221 if (std::fabs(s1) < kMathEpsilon) {
222 return q3.DistanceTo(p1) >= radius;
225 if (std::fabs(s2) < kMathEpsilon) {
226 return q4.DistanceTo(p1) >= radius;
228 if (std::fabs(s1 - s2) < kMathEpsilon) {
231 Vec2d center = q3 + (q4 - q3) * s1 / (s1 - s2);
232 return p1.DistanceTo(center) >= radius;
235void GraphCreator::InitForbiddenLanes() {
236 for (
const auto& lane : pbmap_.lane()) {
238 forbidden_lane_id_set_.insert(lane.id().id());
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Implements a class of 2-dimensional vectors.
static bool LoadData(const std::string &filename, apollo::hdmap::Map *pb_map)
GraphCreator(const std::string &base_map_file_path, const std::string &dump_topo_file_path, const RoutingConfig &routing_conf)
Math-related util functions.
constexpr double kMathEpsilon
double CrossProd(const Vec2d &start_point, const Vec2d &end_point_1, const Vec2d &end_point_2)
Cross product between two 2-D vectors from the common start point, and end at two other points.
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
bool SetProtoToBinaryFile(const google::protobuf::Message &message, const std::string &file_name)
Sets the content of the file specified by the file_name to be the binary representation of the input ...
bool SetProtoToASCIIFile(const google::protobuf::Message &message, int file_descriptor)
void GetPbEdge(const Node &node_from, const Node &node_to, const Edge::DirectionType &type, const RoutingConfig &routing_config, Edge *edge)
void GetPbNode(const hdmap::Lane &lane, const std::string &road_id, const RoutingConfig &routingconfig, Node *const node)
optional VehicleParam vehicle_param
optional double min_turn_radius