@@ -66,6 +66,19 @@ namespace dsm {
6666 }
6767 newStreetIds.emplace (streetId, newStreetId);
6868 }
69+ std::for_each (
70+ m_edges.cbegin (), m_edges.cend (), [this , &newStreetIds](auto const & pair) {
71+ auto const & pStreet{pair.second };
72+ auto const & forbiddenTurns{pStreet->forbiddenTurns ()};
73+ if (forbiddenTurns.empty ()) {
74+ return ;
75+ }
76+ std::set<Id> newForbiddenTurns;
77+ for (auto const & streetId : forbiddenTurns) {
78+ newForbiddenTurns.insert (newStreetIds.at (streetId));
79+ }
80+ pStreet->setForbiddenTurns (newForbiddenTurns);
81+ });
6982 for (const auto & [nodeId, node] : m_nodes) {
7083 // This is probably not the best way to do this
7184 if (node->isIntersection ()) {
@@ -267,7 +280,6 @@ namespace dsm {
267280 if (nLanes == 1 ) {
268281 return ;
269282 }
270- // auto const& laneMapping{pInStreet->laneMapping()};
271283 std::multiset<Direction> allowedTurns;
272284 std::for_each (
273285 outNeighbours.cbegin (),
@@ -276,14 +288,17 @@ namespace dsm {
276288 auto const & outNodeId) {
277289 auto const & pOutStreet{
278290 m_edges.at (pair.first * m_nodes.size () + outNodeId)};
279- if (pOutStreet->target () == pInStreet->source ()) {
291+ if (pOutStreet->target () == pInStreet->source () ||
292+ pInStreet->forbiddenTurns ().contains (pOutStreet->id ())) {
280293 return ;
281294 }
282295 auto const deltaAngle{pOutStreet->deltaAngle (pInStreet->angle ())};
283296 auto const & outOppositeStreet{this ->street (pair.first , outNodeId)};
297+ if (!outOppositeStreet) {
298+ return ;
299+ }
284300 // Actually going straight means remain on the same road, thus...
285- if (outOppositeStreet &&
286- ((pInStreet->priority () == maxPriority) ==
301+ if (((pInStreet->priority () == maxPriority) ==
287302 (outOppositeStreet->get ()->priority () == maxPriority)) &&
288303 !allowedTurns.contains (Direction::STRAIGHT)) {
289304 Logger::debug (
@@ -298,43 +313,29 @@ namespace dsm {
298313 // allowedTurns.emplace(Direction::STRAIGHT);
299314 // return;
300315 // }
301- } else if (std::abs (deltaAngle) < 5 * std::numbers::pi / 6 ) {
316+ } else if (std::abs (deltaAngle) < std::numbers::pi) {
302317 // Logger::debug(std::format("Angle in {} - angle out {}",
303318 // pInStreet->angle(),
304319 // pOutStreet->angle()));
305320 // Logger::debug(std::format("Delta: {}", deltaAngle));
306- if (deltaAngle < -std::numbers::pi / 6 .) {
307- Logger::debug (
308- std::format (" Street {} can turn RIGHT" , pInStreet->id ()));
321+ if (std::abs (deltaAngle) < std::numbers::pi / 8 ) {
322+ Logger::debug (std::format (" Street {} -> {} can turn STRAIGHT" ,
323+ pInStreet->source (),
324+ pInStreet->target ()));
325+ allowedTurns.emplace (Direction::STRAIGHT);
326+ } else if (deltaAngle < 0 .) {
327+ Logger::debug (std::format (" Street {} -> {} can turn RIGHT" ,
328+ pInStreet->source (),
329+ pInStreet->target ()));
309330 allowedTurns.emplace (Direction::RIGHT);
310- } else if (deltaAngle > std::numbers::pi / 6 .) {
311- Logger::debug (
312- std::format (" Street {} can turn LEFT" , pInStreet->id ()));
331+ } else if (deltaAngle > 0 .) {
332+ Logger::debug (std::format (" Street {} -> {} can turn LEFT" ,
333+ pInStreet->source (),
334+ pInStreet->target ()));
313335 allowedTurns.emplace (Direction::LEFT);
314- } else {
315- Logger::debug (
316- std::format (" Street {} can go STRAIGHT" , pInStreet->id ()));
317- if (!allowedTurns.contains (Direction::STRAIGHT)) {
318- allowedTurns.emplace (Direction::STRAIGHT);
319- } else if (deltaAngle > 0 .) {
320- allowedTurns.emplace (Direction::LEFT);
321- } else {
322- allowedTurns.emplace (Direction::RIGHT);
323- }
324336 }
325337 }
326338 });
327- // if (!allowedTurns.contains(Direction::RIGHT)) {
328- // std::multiset<Direction> updatedTurns;
329- // for (auto turn : allowedTurns) {
330- // if (turn > Direction::RIGHT && turn <= Direction::UTURN) {
331- // updatedTurns.insert(static_cast<Direction>(turn - 1));
332- // } else {
333- // updatedTurns.insert(turn);
334- // }
335- // }
336- // allowedTurns = std::move(updatedTurns); // Replace with the updated set
337- // }
338339 while (allowedTurns.size () < static_cast <size_t >(nLanes)) {
339340 if (allowedTurns.contains (Direction::STRAIGHT)) {
340341 allowedTurns.emplace (Direction::STRAIGHT);
@@ -347,11 +348,36 @@ namespace dsm {
347348 }
348349 }
349350 // If allowedTurns contains all RIGHT, STRAIGHT and LEFT, transform RIGHT into RIGHTANDSTRAIGHT
350- if (allowedTurns.contains (Direction::STRAIGHT) &&
351- allowedTurns.contains (Direction::RIGHT) &&
352- allowedTurns.contains (Direction::LEFT)) {
353- allowedTurns.erase (Direction::RIGHT);
354- allowedTurns.emplace (Direction::RIGHTANDSTRAIGHT);
351+ if (allowedTurns.size () > static_cast <size_t >(nLanes)) {
352+ if (pair.second ->isTrafficLight ()) {
353+ auto & tl = dynamic_cast <TrafficLight&>(*pair.second );
354+ auto const & cycles{tl.cycles ()};
355+ if (cycles.contains (pInStreet->id ())) {
356+ if (cycles.size () == static_cast <size_t >(nLanes)) {
357+ // Replace with the traffic light cycles
358+ Logger::debug (
359+ std::format (" Using traffic light {} cycles for street {} -> {}" ,
360+ tl.id (),
361+ pInStreet->source (),
362+ pInStreet->target ()));
363+ auto const & cycle{cycles.at (pInStreet->id ())};
364+ allowedTurns.clear ();
365+ for (auto const & [direction, cycle] : cycle) {
366+ allowedTurns.emplace (direction);
367+ }
368+ } else if (cycles.at (pInStreet->id ())
369+ .contains (Direction::LEFTANDSTRAIGHT)) {
370+ allowedTurns.erase (Direction::LEFT);
371+ allowedTurns.erase (Direction::STRAIGHT);
372+ allowedTurns.emplace (Direction::LEFTANDSTRAIGHT);
373+ } else if (cycles.at (pInStreet->id ())
374+ .contains (Direction::RIGHTANDSTRAIGHT)) {
375+ allowedTurns.erase (Direction::RIGHT);
376+ allowedTurns.erase (Direction::STRAIGHT);
377+ allowedTurns.emplace (Direction::RIGHTANDSTRAIGHT);
378+ }
379+ }
380+ }
355381 }
356382 switch (nLanes) {
357383 case 1 :
@@ -361,11 +387,44 @@ namespace dsm {
361387 if (allowedTurns.contains (Direction::STRAIGHT) &&
362388 allowedTurns.contains (Direction::RIGHT) &&
363389 allowedTurns.contains (Direction::LEFT)) {
364- break ;
390+ if (pair.second ->isTrafficLight ()) {
391+ auto & tl = dynamic_cast <TrafficLight&>(*pair.second );
392+ auto const & cycles{tl.cycles ()};
393+ if (cycles.contains (pInStreet->id ())) {
394+ auto const & cycle{cycles.at (pInStreet->id ())};
395+ if (cycle.contains (Direction::LEFTANDSTRAIGHT) &&
396+ cycle.contains (Direction::RIGHT)) {
397+ allowedTurns.erase (Direction::LEFT);
398+ allowedTurns.erase (Direction::STRAIGHT);
399+ allowedTurns.emplace (Direction::LEFTANDSTRAIGHT);
400+ break ;
401+ }
402+ }
403+ }
404+ allowedTurns.clear ();
405+ allowedTurns.emplace (Direction::RIGHTANDSTRAIGHT);
406+ allowedTurns.emplace (Direction::LEFT);
407+ }
408+ if (allowedTurns.size () > 2 ) {
409+ // Remove duplicates
410+ std::set<Direction> uniqueDirections;
411+ std::copy (allowedTurns.begin (),
412+ allowedTurns.end (),
413+ std::inserter (uniqueDirections, uniqueDirections.begin ()));
414+ allowedTurns.clear ();
415+ std::copy (uniqueDirections.begin (),
416+ uniqueDirections.end (),
417+ std::inserter (allowedTurns, allowedTurns.begin ()));
365418 }
366419 [[fallthrough]];
367420 default :
368421 assert (allowedTurns.size () == static_cast <size_t >(nLanes));
422+ // Logger::info(
423+ // std::format("Street {}->{} with {} lanes and {} allowed turns",
424+ // pInStreet->source(),
425+ // pInStreet->target(),
426+ // nLanes,
427+ // allowedTurns.size()));
369428 std::vector<Direction> newMapping (nLanes);
370429 auto it{allowedTurns.cbegin ()};
371430 for (size_t i{0 }; i < allowedTurns.size (); ++i, ++it) {
0 commit comments