@@ -638,6 +638,99 @@ namespace dsm {
638638 Logger::debug (std::format (" Green light on street {} and direction {}" ,
639639 pStreet->id (),
640640 directionToString.at (direction)));
641+ } else if (destinationNode->isIntersection () &&
642+ pAgentTemp->nextStreetId ().has_value ()) {
643+ auto & intersection = static_cast <Intersection&>(*destinationNode);
644+ bool bCanPass{true };
645+ auto const & thisDirection{this ->graph ()
646+ .edge (pAgentTemp->nextStreetId ().value ())
647+ ->turnDirection (pStreet->angle ())};
648+ if (!intersection.streetPriorities ().contains (pStreet->id ())) {
649+ // I have to check if the agent has right of way
650+ auto const & inNeighbours{
651+ this ->graph ().adjacencyMatrix ().getCol (destinationNode->id ())};
652+ for (auto const & sourceId : inNeighbours) {
653+ auto const & streetId{sourceId * this ->graph ().nNodes () +
654+ destinationNode->id ()};
655+ if (streetId == pStreet->id ()) {
656+ continue ;
657+ }
658+ auto const & pStreetTemp{this ->graph ().edge (streetId)};
659+ if (pStreetTemp->nExitingAgents () == 0 ) {
660+ continue ;
661+ }
662+ if (intersection.streetPriorities ().contains (streetId)) {
663+ Logger::debug (std::format (
664+ " Skipping agent emission from street {} -> {} due to right of way." ,
665+ pStreet->source (),
666+ pStreet->target ()));
667+ bCanPass = false ;
668+ break ;
669+ } else if (thisDirection >= Direction::LEFT) {
670+ // Check if the agent has right of way using direction
671+ // The problem arises only when you have to turn left
672+ for (auto i{0 }; i < pStreetTemp->nLanes (); ++i) {
673+ // check queue is not empty and take the top agent
674+ if (pStreetTemp->queue (i).empty ()) {
675+ continue ;
676+ }
677+ auto const & pAgentTemp2{pStreetTemp->queue (i).front ()};
678+ if (!pAgentTemp2->streetId ().has_value ()) {
679+ continue ;
680+ }
681+ auto const & otherDirection{
682+ this ->graph ()
683+ .edge (pAgentTemp2->nextStreetId ().value ())
684+ ->turnDirection (this ->graph ()
685+ .edge (pAgentTemp2->streetId ().value ())
686+ ->angle ())};
687+ if (otherDirection < Direction::LEFT) {
688+ Logger::debug (std::format (
689+ " Skipping agent emission from street {} -> {} due to right of "
690+ " way with other agents." ,
691+ pStreet->source (),
692+ pStreet->target ()));
693+ bCanPass = false ;
694+ break ;
695+ }
696+ }
697+ }
698+ }
699+ } else if (thisDirection >= Direction::LEFT) {
700+ for (auto const & streetId : intersection.streetPriorities ()) {
701+ if (streetId == pStreet->id ()) {
702+ continue ;
703+ }
704+ auto const & pStreetTemp{this ->graph ().edge (streetId)};
705+ for (auto i{0 }; i < pStreetTemp->nLanes (); ++i) {
706+ // check queue is not empty and take the top agent
707+ if (pStreetTemp->queue (i).empty ()) {
708+ continue ;
709+ }
710+ auto const & pAgentTemp2{pStreetTemp->queue (i).front ()};
711+ if (!pAgentTemp2->streetId ().has_value ()) {
712+ continue ;
713+ }
714+ auto const & otherDirection{
715+ this ->graph ()
716+ .edge (pAgentTemp2->nextStreetId ().value ())
717+ ->turnDirection (
718+ this ->graph ().edge (pAgentTemp2->streetId ().value ())->angle ())};
719+ if (otherDirection < thisDirection) {
720+ Logger::debug (std::format (
721+ " Skipping agent emission from street {} -> {} due to right of "
722+ " way with other agents." ,
723+ pStreet->source (),
724+ pStreet->target ()));
725+ bCanPass = false ;
726+ break ;
727+ }
728+ }
729+ }
730+ }
731+ if (!bCanPass) {
732+ continue ;
733+ }
641734 }
642735 bool bArrived{false };
643736 if (!(uniformDist (this ->m_generator ) < m_passageProbability.value_or (1.1 ))) {
@@ -1055,10 +1148,10 @@ namespace dsm {
10551148 tbb::blocked_range<size_t >(0 , numNodes, grainSize),
10561149 [&](const tbb::blocked_range<size_t >& range) {
10571150 for (size_t i = range.begin (); i != range.end (); ++i) {
1058- const auto & pNode = nodes.at (i);
1151+ auto const & pNode = nodes.at (i);
10591152 for (auto const & sourceId :
10601153 this ->graph ().adjacencyMatrix ().getCol (pNode->id ())) {
1061- auto const streetId = sourceId * N + pNode->id ();
1154+ auto const streetId{ sourceId * N + pNode->id ()} ;
10621155 auto const & pStreet{this ->graph ().edge (streetId)};
10631156 if (bUpdateData && pNode->isTrafficLight ()) {
10641157 if (!m_queuesAtTrafficLights.contains (streetId)) {
@@ -1107,10 +1200,16 @@ namespace dsm {
11071200 pStreet->enqueue (0 );
11081201 continue ;
11091202 }
1110- auto const deltaAngle{pNextStreet->deltaAngle (pStreet->angle ())};
1111- if (std::abs (deltaAngle) < std::numbers::pi) {
1112- // Lanes are counted as 0 is the far right lane
1113- if (std::abs (deltaAngle) < std::numbers::pi / 8 ) {
1203+ auto const direction{pNextStreet->turnDirection (pStreet->angle ())};
1204+ switch (direction) {
1205+ case Direction::UTURN:
1206+ case Direction::LEFT:
1207+ pStreet->enqueue (nLanes - 1 );
1208+ break ;
1209+ case Direction::RIGHT:
1210+ pStreet->enqueue (0 );
1211+ break ;
1212+ default :
11141213 std::vector<double > weights;
11151214 for (auto const & queue : pStreet->exitQueues ()) {
11161215 weights.push_back (1 . / (queue.size () + 1 ));
@@ -1134,13 +1233,6 @@ namespace dsm {
11341233 std::discrete_distribution<size_t > laneDist{weights.begin (),
11351234 weights.end ()};
11361235 pStreet->enqueue (laneDist (this ->m_generator ));
1137- } else if (deltaAngle < 0 .) { // Right
1138- pStreet->enqueue (0 ); // Always the first lane
1139- } else { // Left (deltaAngle > 0.)
1140- pStreet->enqueue (nLanes - 1 ); // Always the last lane
1141- }
1142- } else { // U turn
1143- pStreet->enqueue (nLanes - 1 ); // Always the last lane
11441236 }
11451237 }
11461238 }
0 commit comments