11#include <boost/geometry/geometries/box.hpp>
14namespace traffic_manager {
18 using namespace constants::Map;
20 using TopologyList = std::vector<std::pair<WaypointPtr, WaypointPtr>>;
31 return std::make_tuple(wp->GetRoadId(), wp->GetLaneId(), wp->GetSectionId());
47 if (segment_topology.find(segment_id) == segment_topology.end()) {
51 for (
const auto &successor_segment_id : segment_topology.at(segment_id).second) {
52 if (segment_map.find(successor_segment_id) == segment_map.end()) {
53 auto successors =
GetSuccessors(successor_segment_id, segment_topology, segment_map);
54 result.insert(result.end(), successors.begin(), successors.end());
56 result.emplace_back(segment_map.at(successor_segment_id).front());
66 if (segment_topology.find(segment_id) == segment_topology.end()) {
70 for (
const auto &predecessor_segment_id : segment_topology.at(segment_id).first) {
71 if (segment_map.find(predecessor_segment_id) == segment_map.end()) {
72 auto predecessors =
GetPredecessors(predecessor_segment_id, segment_topology, segment_map);
73 result.insert(result.end(), predecessors.begin(), predecessors.end());
75 result.emplace_back(segment_map.at(predecessor_segment_id).back());
95 std::ofstream out_file;
96 out_file.open(filename, std::ios::binary);
97 if (!out_file.is_open()) {
104 out_file.write(
reinterpret_cast<const char *
>(&total),
sizeof(uint32_t));
107 std::unordered_set<uint64_t> used_ids;
109 if (used_ids.find(wp->GetId()) != used_ids.end()) {
110 log_error(
"Could not generate the binary file. There are repeated waypoints");
113 cached_wp.
Write(out_file);
115 used_ids.insert(wp->GetId());
123 unsigned long pos = 0;
124 std::vector<CachedSimpleWaypoint> cached_waypoints;
125 std::unordered_map<uint64_t, uint32_t> id2index;
129 memcpy(&total, &content[pos],
sizeof(total));
130 pos +=
sizeof(total);
133 for (uint32_t i=0; i < total; i++) {
135 cached_wp.
Read(content, pos);
136 cached_waypoints.push_back(cached_wp);
150 auto cached_wp = cached_waypoints.at(i);
152 std::vector<SimpleWaypointPtr> next_waypoints;
153 for (
auto id : cached_wp.next_waypoints) {
156 std::vector<SimpleWaypointPtr> previous_waypoints;
157 for (
auto id : cached_wp.previous_waypoints) {
160 wp->SetNextWaypoint(next_waypoints);
161 wp->SetPreviousWaypoint(previous_waypoints);
162 if (cached_wp.next_left_waypoint > 0) {
163 wp->SetLeftWaypoint(
dense_topology.at(id2index.at(cached_wp.next_left_waypoint)));
165 if (cached_wp.next_right_waypoint > 0) {
166 wp->SetRightWaypoint(
dense_topology.at(id2index.at(cached_wp.next_right_waypoint)));
179 assert(
_world_map !=
nullptr &&
"No map reference found.");
180 auto waypoint_topology =
_world_map->GetTopology();
183 std::unordered_map<int64_t, std::pair<std::set<crd::RoadId>, std::set<crd::RoadId>>> std_road_connectivity;
184 std::unordered_map<crd::RoadId, bool> is_real_junction;
186 for (
auto &connection : waypoint_topology) {
187 auto &waypoint = connection.first;
188 auto &successor = connection.second;
193 if (waypoint_segment_id == successor_segment_id){
198 using SegIdVectorPair = std::pair<std::vector<SegmentId>, std::vector<SegmentId>>;
199 SegIdVectorPair &connection_first = segment_topology[waypoint_segment_id];
200 SegIdVectorPair &connection_second = segment_topology[successor_segment_id];
201 connection_first.second.push_back(successor_segment_id);
202 connection_second.first.push_back(waypoint_segment_id);
205 bool waypoint_is_junction = waypoint->IsJunction();
206 bool successor_is_junction = successor->IsJunction();
207 if (waypoint_is_junction && !successor_is_junction) {
209 int64_t std_road_id =
static_cast<int64_t
>(successor->GetRoadId());
210 std_road_id = (successor->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
212 std::set<crd::RoadId> &in_paths = std_road_connectivity[std_road_id].first;
213 in_paths.insert(path_id);
215 if (in_paths.size() >= 2) {
216 for (
auto &in_path_id: in_paths) {
217 is_real_junction[in_path_id] =
true;
223 if (!waypoint_is_junction && successor_is_junction) {
225 int64_t std_road_id =
static_cast<int64_t
>(waypoint->GetRoadId());
226 std_road_id = (waypoint->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
228 std::set<crd::RoadId> &out_paths = std_road_connectivity[std_road_id].second;
229 out_paths.insert(path_id);
231 if (out_paths.size() >= 2) {
232 for (
auto &out_path_id: out_paths) {
233 is_real_junction[out_path_id] =
true;
241 assert(
_world_map !=
nullptr &&
"No map reference found.");
242 auto raw_dense_topology =
_world_map->GenerateWaypoints(MAP_RESOLUTION);
243 for (
auto &waypoint_ptr: raw_dense_topology) {
246 segment_map[
GetSegmentId(waypoint_ptr)].emplace_back(std::make_shared<SimpleWaypoint>(waypoint_ptr));
252 return cg::Math::DistanceSquared(l1, l2);
254 auto square = [](
float input) {
return std::pow(input, 2);};
256 return (swp1->GetWaypoint()->GetDistance() < swp2->GetWaypoint()->GetDistance());
259 return cg::Math::GetVectorAngle(l1, l2);
261 auto max = [](int16_t x, int16_t y) {
262 return x ^ ((x ^ y) & -(x < y));
266 for (
auto &segment: segment_map) {
267 auto &segment_waypoints = segment.second;
270 ++geodesic_grid_id_counter;
273 std::sort(segment_waypoints.begin(), segment_waypoints.end(), compare_s);
274 auto lane_id = segment_waypoints.front()->GetWaypoint()->GetLaneId();
276 std::reverse(segment_waypoints.begin(), segment_waypoints.end());
280 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
281 double distance = std::abs(segment_waypoints.at(i)->GetWaypoint()->GetDistance() - segment_waypoints.at(i+1)->GetWaypoint()->GetDistance());
282 double angle = wpt_angle(segment_waypoints.at(i)->GetTransform().GetForwardVector(), segment_waypoints.at(i+1)->GetTransform().GetForwardVector());
284 int16_t distance_splits =
static_cast<int16_t
>((distance*distance)/
MAX_WPT_DISTANCE);
285 auto max_splits = max(angle_splits, distance_splits);
286 if (max_splits >= 1) {
288 for (uint16_t j = 0; j < max_splits; ++j) {
289 auto next_waypoints = segment_waypoints.at(i)->GetWaypoint()->GetNext(distance/(max_splits+1));
290 if (next_waypoints.size() != 0) {
291 auto new_waypoint = next_waypoints.front();
293 segment_waypoints.insert(segment_waypoints.begin()+
static_cast<int64_t
>(i), std::make_shared<SimpleWaypoint>(new_waypoint));
303 cg::Location grid_edge_location = segment_waypoints.front()->GetLocation();
304 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
308 if (distance_squared(grid_edge_location, current_waypoint->GetLocation()) >
310 ++geodesic_grid_id_counter;
311 grid_edge_location = current_waypoint->GetLocation();
313 current_waypoint->SetGeodesicGridId(geodesic_grid_id_counter);
315 current_waypoint->SetNextWaypoint({next_waypoint});
316 next_waypoint->SetPreviousWaypoint({current_waypoint});
319 segment_waypoints.back()->SetGeodesicGridId(geodesic_grid_id_counter);
322 for (
auto swp: segment_waypoints) {
324 auto wpt = swp->GetWaypoint();
325 auto road_id = wpt->GetRoadId();
326 if (wpt->IsJunction() && !is_real_junction.count(road_id)) {
327 swp->SetIsJunction(
false);
329 swp->SetIsJunction(swp->GetWaypoint()->IsJunction());
339 for (
auto &segment : segment_map) {
341 auto &segment_waypoints = segment.second;
343 auto successors =
GetSuccessors(segment_id, segment_topology, segment_map);
344 auto predecessors =
GetPredecessors(segment_id, segment_topology, segment_map);
346 segment_waypoints.front()->SetPreviousWaypoint(predecessors);
347 segment_waypoints.back()->SetNextWaypoint(successors);
352 if (!swp->CheckJunction()) {
359 if (swp->GetNextWaypoint().empty()) {
360 auto neighbour = swp->GetRightWaypoint();
362 neighbour = swp->GetLeftWaypoint();
366 swp->SetNextWaypoint(neighbour->GetNextWaypoint());
367 for (
auto next_waypoint : neighbour->GetNextWaypoint()) {
368 next_waypoint->SetPreviousWaypoint({swp});
380 if (simple_waypoint !=
nullptr) {
381 const cg::Location loc = simple_waypoint->GetLocation();
383 rtree.insert(std::make_pair(point, simple_waypoint));
390 std::vector<SimpleWaypointPtr> next_waypoints = swp->GetNextWaypoint();
391 std::size_t next_swp_size = next_waypoints.size();
393 if (next_swp_size == 0) {
398 else if (next_swp_size > 1 || (!swp->CheckJunction() && next_waypoints.front()->CheckJunction())) {
401 bool found_landmark=
false;
402 if (next_swp_size <= 1) {
404 auto all_landmarks = swp->GetWaypoint()->GetAllLandmarksInDistance(15.0);
406 if (all_landmarks.empty()) {
410 for (
auto &landmark : all_landmarks) {
411 auto landmark_type = landmark->GetType();
412 if (landmark_type ==
"1000001" || landmark_type ==
"206" || landmark_type ==
"205") {
414 found_landmark=
true;
418 if (!found_landmark) {
426 if (found_landmark || next_swp_size > 1) {
428 for (
auto &next_swp : next_waypoints) {
429 std::vector<SimpleWaypointPtr> traversed_waypoints;
432 if (next_swp_size > 1) {
433 junction_end_waypoint = next_swp;
435 junction_end_waypoint = next_waypoints.front();
438 while (junction_end_waypoint->CheckJunction()){
439 traversed_waypoints.push_back(junction_end_waypoint);
440 std::vector<SimpleWaypointPtr> temp = junction_end_waypoint->GetNextWaypoint();
444 junction_end_waypoint = temp.front();
448 int16_t current_angle =
static_cast<int16_t
>(traversed_waypoints.front()->GetTransform().rotation.yaw);
449 int16_t junction_end_angle =
static_cast<int16_t
>(traversed_waypoints.back()->GetTransform().rotation.yaw);
450 int16_t diff_angle = (junction_end_angle - current_angle) % 360;
451 bool straight = (diff_angle < STRAIGHT_DEG && diff_angle > -
STRAIGHT_DEG) ||
454 bool right = (diff_angle >=
STRAIGHT_DEG && diff_angle <= 180) ||
455 (diff_angle <= -180 && diff_angle >= -360+
STRAIGHT_DEG);
457 auto assign_option = [](
RoadOption ro, std::vector<SimpleWaypointPtr> traversed_waypoints) {
458 for (
auto &twp : traversed_waypoints) {
459 twp->SetRoadOption(ro);
479 std::vector<SpatialTreeEntry> result_1;
481 rtree.query(bgi::nearest(query_point, 1), std::back_inserter(result_1));
486 return closest_point;
497 Box lower_query_box(lower_p2, lower_p1);
498 Box upper_query_box(upper_p2, upper_p1);
502 for (Rtree::const_query_iterator
503 it =
rtree.qbegin(bgi::within(upper_query_box)
504 && !bgi::within(lower_query_box)
505 && bgi::satisfies([&](
SpatialTreeEntry const& v) { return !v.second->CheckJunction();}));
509 result.push_back(it->second);
523 const WaypointPtr raw_waypoint = reference_waypoint->GetWaypoint();
524 const crd::element::LaneMarking::LaneChange lane_change = raw_waypoint->GetLaneChange();
530 case crd::element::LaneMarking::LaneChange::Left:
532 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
533 if (left_waypoint !=
nullptr &&
534 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
535 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
538 reference_waypoint->SetLeftWaypoint(closest_simple_waypoint);
544 case crd::element::LaneMarking::LaneChange::Right:
546 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
547 if(right_waypoint !=
nullptr &&
548 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
549 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
552 reference_waypoint->SetRightWaypoint(closest_simple_waypoint);
558 case crd::element::LaneMarking::LaneChange::Both:
561 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
562 if (right_waypoint !=
nullptr &&
563 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
564 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
567 reference_waypoint->SetRightWaypoint(closest_simple_waypointR);
571 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
572 if (left_waypoint !=
nullptr &&
573 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
574 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
577 reference_waypoint->SetLeftWaypoint(closest_simple_waypointL);
588 assert(
_world_map !=
nullptr &&
"No map reference found.");
void Read(const std::vector< uint8_t > &content, unsigned long &start)
void Write(std::ofstream &out_file)
此类构建一个离散的本地地图缓存。 使用世界实例化该类并运行SetUp()构造本地地图。
InMemoryMap(WorldMap world_map)
bool Load(const std::vector< uint8_t > &content)
WorldMap _world_map
保存构造函数接收的世界地图对象。
const cc::Map & GetMap() const
void FindAndLinkLaneChange(SimpleWaypointPtr reference_waypoint)
此方法用于查找和链接车道变更连接。
NodeList GetPredecessors(const SegmentId segment_id, const SegmentTopology &segment_topology, const SegmentMap &segment_map)
static void Cook(WorldMap world_map, const std::string &path)
SegmentId GetSegmentId(const WaypointPtr &wp) const
计算给定路径点的段ID。 ID考虑了OpenDrive的道路ID、车道ID和分段ID。
NodeList GetDenseTopology() const
此方法返回本地缓存中离散样本的完整列表。
void SetUp()
此方法以采样分辨率构建本地地图。
NodeList GetWaypointsInDelta(const cg::Location loc, const uint16_t n_points, const float random_sample) const
此方法返回与自我车辆距离一定范围内的n个路径点。
NodeList GetSuccessors(const SegmentId segment_id, const SegmentTopology &segment_topology, const SegmentMap &segment_map)
SimpleWaypointPtr GetWaypoint(const cg::Location loc) const
此方法返回给定位置上最近的路径点。
Rtree rtree
用于索引和查询路径点的空间二维R树。
NodeList dense_topology
存储所有自定义路径点对象的结构,经过稀疏拓扑插值处理。
void Save(const std::string &path)
static const float MAX_WPT_DISTANCE
static float const Z_DELTA
static float const STRAIGHT_DEG
static const float MAX_WPT_RADIANS
static const float MAX_GEODESIC_GRID_LENGTH
static const double MIN_LANE_WIDTH
bg::model::box< Point3D > Box
carla::SharedPtr< cc::Waypoint > WaypointPtr
Waypoint的智能指针类型别名。
std::map< SegmentId, std::pair< std::vector< SegmentId >, std::vector< SegmentId > > > SegmentTopology
std::vector< std::pair< WaypointPtr, WaypointPtr > > TopologyList
std::map< SegmentId, std::vector< SimpleWaypointPtr > > SegmentMap
std::vector< SimpleWaypointPtr > NodeList
bg::model::point< float, 3, bg::cs::cartesian > Point3D
carla::SharedPtr< const cc::Map > WorldMap
std::tuple< crd::RoadId, crd::LaneId, crd::SectionId > SegmentId
std::pair< Point3D, SimpleWaypointPtr > SpatialTreeEntry
std::vector< WaypointPtr > RawNodeList
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
static void log_error(Args &&... args)