121 unsigned long pos = 0;
122 std::vector<CachedSimpleWaypoint> cached_waypoints;
123 std::unordered_map<uint64_t, uint32_t> id2index;
129 const auto fail = [
this](
const char *what) {
130 log_warning(
"InMemoryMap cache rejected:", what,
"- rebuilding the local map from the OpenDRIVE");
137 if (content.size() <
sizeof(total)) {
138 return fail(
"truncated header");
140 memcpy(&total, &content[pos],
sizeof(total));
141 pos +=
sizeof(total);
144 for (uint32_t i=0; i < total; i++) {
146 return fail(
"truncated waypoint records");
149 cached_wp.
Read(content, pos);
150 if (pos > content.size()) {
151 return fail(
"truncated waypoint records");
153 cached_waypoints.push_back(cached_wp);
157 if (waypoint_ptr ==
nullptr) {
158 return fail(
"it references a road/lane the current map does not have");
169 const auto it = id2index.find(
id);
170 return it == id2index.end() ? nullptr :
dense_topology.at(it->second);
174 auto cached_wp = cached_waypoints.at(i);
176 std::vector<SimpleWaypointPtr> next_waypoints;
177 for (
auto id : cached_wp.next_waypoints) {
178 const auto next = lookup(
id);
179 if (next ==
nullptr) {
180 return fail(
"it links waypoints that are not in the cache");
182 next_waypoints.push_back(next);
184 std::vector<SimpleWaypointPtr> previous_waypoints;
185 for (
auto id : cached_wp.previous_waypoints) {
186 const auto previous = lookup(
id);
187 if (previous ==
nullptr) {
188 return fail(
"it links waypoints that are not in the cache");
190 previous_waypoints.push_back(previous);
192 wp->SetNextWaypoint(next_waypoints);
193 wp->SetPreviousWaypoint(previous_waypoints);
194 if (cached_wp.next_left_waypoint > 0) {
195 auto left = lookup(cached_wp.next_left_waypoint);
196 if (left ==
nullptr) {
197 return fail(
"it links waypoints that are not in the cache");
199 wp->SetLeftWaypoint(left);
201 if (cached_wp.next_right_waypoint > 0) {
202 auto right = lookup(cached_wp.next_right_waypoint);
203 if (right ==
nullptr) {
204 return fail(
"it links waypoints that are not in the cache");
206 wp->SetRightWaypoint(right);
219 assert(
_world_map !=
nullptr &&
"No map reference found.");
220 auto waypoint_topology =
_world_map->GetTopology();
223 std::unordered_map<int64_t, std::pair<std::set<crd::RoadId>, std::set<crd::RoadId>>> std_road_connectivity;
224 std::unordered_map<crd::RoadId, bool> is_real_junction;
226 for (
auto &connection : waypoint_topology) {
227 auto &waypoint = connection.first;
228 auto &successor = connection.second;
233 if (waypoint_segment_id == successor_segment_id){
238 using SegIdVectorPair = std::pair<std::vector<SegmentId>, std::vector<SegmentId>>;
239 SegIdVectorPair &connection_first = segment_topology[waypoint_segment_id];
240 SegIdVectorPair &connection_second = segment_topology[successor_segment_id];
241 connection_first.second.push_back(successor_segment_id);
242 connection_second.first.push_back(waypoint_segment_id);
245 bool waypoint_is_junction = waypoint->IsJunction();
246 bool successor_is_junction = successor->IsJunction();
247 if (waypoint_is_junction && !successor_is_junction) {
249 int64_t std_road_id =
static_cast<int64_t
>(successor->GetRoadId());
250 std_road_id = (successor->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
252 std::set<crd::RoadId> &in_paths = std_road_connectivity[std_road_id].first;
253 in_paths.insert(path_id);
255 if (in_paths.size() >= 2) {
256 for (
auto &in_path_id: in_paths) {
257 is_real_junction[in_path_id] =
true;
263 if (!waypoint_is_junction && successor_is_junction) {
265 int64_t std_road_id =
static_cast<int64_t
>(waypoint->GetRoadId());
266 std_road_id = (waypoint->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
268 std::set<crd::RoadId> &out_paths = std_road_connectivity[std_road_id].second;
269 out_paths.insert(path_id);
271 if (out_paths.size() >= 2) {
272 for (
auto &out_path_id: out_paths) {
273 is_real_junction[out_path_id] =
true;
281 assert(
_world_map !=
nullptr &&
"No map reference found.");
282 auto raw_dense_topology =
_world_map->GenerateWaypoints(MAP_RESOLUTION);
283 for (
auto &waypoint_ptr: raw_dense_topology) {
286 segment_map[
GetSegmentId(waypoint_ptr)].emplace_back(std::make_shared<SimpleWaypoint>(waypoint_ptr));
292 return cg::Math::DistanceSquared(l1, l2);
294 auto square = [](
float input) {
return std::pow(input, 2);};
296 return (swp1->GetWaypoint()->GetDistance() < swp2->GetWaypoint()->GetDistance());
299 return cg::Math::GetVectorAngle(l1, l2);
301 auto max = [](int16_t
x, int16_t
y) {
302 return x ^ ((
x ^
y) & -(
x <
y));
306 for (
auto &segment: segment_map) {
307 auto &segment_waypoints = segment.second;
310 ++geodesic_grid_id_counter;
313 std::sort(segment_waypoints.begin(), segment_waypoints.end(), compare_s);
314 auto is_positive_direction = segment_waypoints.front()->GetWaypoint()->IsPositiveDirection();
315 if (!is_positive_direction) {
316 std::reverse(segment_waypoints.begin(), segment_waypoints.end());
320 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
321 double distance = std::abs(segment_waypoints.at(i)->GetWaypoint()->GetDistance() - segment_waypoints.at(i+1)->GetWaypoint()->GetDistance());
322 double angle = wpt_angle(segment_waypoints.at(i)->GetTransform().GetForwardVector(), segment_waypoints.at(i+1)->GetTransform().GetForwardVector());
325 auto max_splits = max(angle_splits, distance_splits);
326 if (max_splits >= 1) {
328 for (uint16_t j = 0; j < max_splits; ++j) {
329 auto next_waypoints = segment_waypoints.at(i)->GetWaypoint()->GetNext(
distance/(max_splits+1));
330 if (next_waypoints.size() != 0) {
331 auto new_waypoint = next_waypoints.front();
333 segment_waypoints.insert(segment_waypoints.begin()+
static_cast<int64_t
>(i), std::make_shared<SimpleWaypoint>(new_waypoint));
343 cg::Location grid_edge_location = segment_waypoints.front()->GetLocation();
344 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
348 if (distance_squared(grid_edge_location, current_waypoint->GetLocation()) >
350 ++geodesic_grid_id_counter;
351 grid_edge_location = current_waypoint->GetLocation();
353 current_waypoint->SetGeodesicGridId(geodesic_grid_id_counter);
355 current_waypoint->SetNextWaypoint({next_waypoint});
356 next_waypoint->SetPreviousWaypoint({current_waypoint});
359 segment_waypoints.back()->SetGeodesicGridId(geodesic_grid_id_counter);
362 for (
auto swp: segment_waypoints) {
364 auto wpt = swp->GetWaypoint();
365 auto road_id = wpt->GetRoadId();
366 if (wpt->IsJunction() && !is_real_junction.count(
road_id)) {
367 swp->SetIsJunction(
false);
369 swp->SetIsJunction(swp->GetWaypoint()->IsJunction());
379 for (
auto &segment : segment_map) {
381 auto &segment_waypoints = segment.second;
383 auto successors =
GetSuccessors(segment_id, segment_topology, segment_map);
384 auto predecessors =
GetPredecessors(segment_id, segment_topology, segment_map);
386 segment_waypoints.front()->SetPreviousWaypoint(predecessors);
387 segment_waypoints.back()->SetNextWaypoint(successors);
392 if (!swp->CheckJunction()) {
399 if (swp->GetNextWaypoint().empty()) {
400 auto neighbour = swp->GetRightWaypoint();
402 neighbour = swp->GetLeftWaypoint();
406 swp->SetNextWaypoint(neighbour->GetNextWaypoint());
407 for (
auto next_waypoint : neighbour->GetNextWaypoint()) {
408 next_waypoint->SetPreviousWaypoint({swp});
430 std::vector<SimpleWaypointPtr> next_waypoints = swp->GetNextWaypoint();
431 std::size_t next_swp_size = next_waypoints.size();
433 if (next_swp_size == 0) {
438 else if (next_swp_size > 1 || (!swp->CheckJunction() && next_waypoints.front()->CheckJunction())) {
442 bool found_landmark=
false;
443 if (next_swp_size <= 1) {
445 auto all_landmarks = swp->GetWaypoint()->GetAllLandmarksInDistance(15.0);
447 if (all_landmarks.empty()) {
451 for (
auto &landmark : all_landmarks) {
452 auto landmark_type = landmark->GetType();
453 if (landmark_type ==
"1000001" || landmark_type ==
"206" || landmark_type ==
"205") {
455 found_landmark=
true;
459 if (!found_landmark) {
467 if (found_landmark || next_swp_size > 1) {
469 for (
auto &next_swp : next_waypoints) {
470 std::vector<SimpleWaypointPtr> traversed_waypoints;
473 if (next_swp_size > 1) {
474 junction_end_waypoint = next_swp;
476 junction_end_waypoint = next_waypoints.front();
479 while (junction_end_waypoint->CheckJunction()){
480 traversed_waypoints.push_back(junction_end_waypoint);
481 std::vector<SimpleWaypointPtr> temp = junction_end_waypoint->GetNextWaypoint();
485 junction_end_waypoint = temp.front();
488 if (traversed_waypoints.empty()) {
500 int16_t current_angle =
static_cast<int16_t
>(traversed_waypoints.front()->GetTransform().rotation.yaw);
501 int16_t junction_end_angle =
static_cast<int16_t
>(traversed_waypoints.back()->GetTransform().rotation.yaw);
502 int16_t diff_angle = (junction_end_angle - current_angle) % 360;
503 bool straight = (diff_angle < STRAIGHT_DEG && diff_angle > -
STRAIGHT_DEG) ||
506 bool right = (diff_angle >=
STRAIGHT_DEG && diff_angle <= 180) ||
507 (diff_angle <= -180 && diff_angle >= -360+
STRAIGHT_DEG);
509 auto assign_option = [](
RoadOption ro, std::vector<SimpleWaypointPtr> traversed_waypoints) {
510 for (
auto &twp : traversed_waypoints) {
511 twp->SetRoadOption(ro);
582 const WaypointPtr raw_waypoint = reference_waypoint->GetWaypoint();
583 const crd::element::LaneMarking::LaneChange lane_change = raw_waypoint->GetLaneChange();
589 case crd::element::LaneMarking::LaneChange::Left:
591 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
592 if (left_waypoint !=
nullptr &&
593 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
594 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
597 reference_waypoint->SetLeftWaypoint(closest_simple_waypoint);
603 case crd::element::LaneMarking::LaneChange::Right:
605 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
606 if(right_waypoint !=
nullptr &&
607 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
608 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
611 reference_waypoint->SetRightWaypoint(closest_simple_waypoint);
617 case crd::element::LaneMarking::LaneChange::Both:
620 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
621 if (right_waypoint !=
nullptr &&
622 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
623 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
626 reference_waypoint->SetRightWaypoint(closest_simple_waypointR);
630 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
631 if (left_waypoint !=
nullptr &&
632 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
633 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
636 reference_waypoint->SetLeftWaypoint(closest_simple_waypointL);