@@ -66,6 +66,19 @@ namespace dsm {
66
66
}
67
67
newStreetIds.emplace (streetId, newStreetId);
68
68
}
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
+ });
69
82
for (const auto & [nodeId, node] : m_nodes) {
70
83
// This is probably not the best way to do this
71
84
if (node->isIntersection ()) {
@@ -267,7 +280,6 @@ namespace dsm {
267
280
if (nLanes == 1 ) {
268
281
return ;
269
282
}
270
- // auto const& laneMapping{pInStreet->laneMapping()};
271
283
std::multiset<Direction> allowedTurns;
272
284
std::for_each (
273
285
outNeighbours.cbegin (),
@@ -276,14 +288,17 @@ namespace dsm {
276
288
auto const & outNodeId) {
277
289
auto const & pOutStreet{
278
290
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 ())) {
280
293
return ;
281
294
}
282
295
auto const deltaAngle{pOutStreet->deltaAngle (pInStreet->angle ())};
283
296
auto const & outOppositeStreet{this ->street (pair.first , outNodeId)};
297
+ if (!outOppositeStreet) {
298
+ return ;
299
+ }
284
300
// Actually going straight means remain on the same road, thus...
285
- if (outOppositeStreet &&
286
- ((pInStreet->priority () == maxPriority) ==
301
+ if (((pInStreet->priority () == maxPriority) ==
287
302
(outOppositeStreet->get ()->priority () == maxPriority)) &&
288
303
!allowedTurns.contains (Direction::STRAIGHT)) {
289
304
Logger::debug (
@@ -298,43 +313,29 @@ namespace dsm {
298
313
// allowedTurns.emplace(Direction::STRAIGHT);
299
314
// return;
300
315
// }
301
- } else if (std::abs (deltaAngle) < 5 * std::numbers::pi / 6 ) {
316
+ } else if (std::abs (deltaAngle) < std::numbers::pi ) {
302
317
// Logger::debug(std::format("Angle in {} - angle out {}",
303
318
// pInStreet->angle(),
304
319
// pOutStreet->angle()));
305
320
// 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 ()));
309
330
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 ()));
313
335
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
- }
324
336
}
325
337
}
326
338
});
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
- // }
338
339
while (allowedTurns.size () < static_cast <size_t >(nLanes)) {
339
340
if (allowedTurns.contains (Direction::STRAIGHT)) {
340
341
allowedTurns.emplace (Direction::STRAIGHT);
@@ -347,11 +348,36 @@ namespace dsm {
347
348
}
348
349
}
349
350
// 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
+ }
355
381
}
356
382
switch (nLanes) {
357
383
case 1 :
@@ -361,11 +387,44 @@ namespace dsm {
361
387
if (allowedTurns.contains (Direction::STRAIGHT) &&
362
388
allowedTurns.contains (Direction::RIGHT) &&
363
389
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 ()));
365
418
}
366
419
[[fallthrough]];
367
420
default :
368
421
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()));
369
428
std::vector<Direction> newMapping (nLanes);
370
429
auto it{allowedTurns.cbegin ()};
371
430
for (size_t i{0 }; i < allowedTurns.size (); ++i, ++it) {
0 commit comments