Eclipse SUMO - Simulation of Urban MObility
MSEdgeControl.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Stores edges and lanes, performs moving of vehicle
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <iostream>
28 #include <queue>
29 #include <vector>
30 #include "MSEdgeControl.h"
31 #include "MSVehicleControl.h"
32 #include "MSGlobals.h"
33 #include "MSEdge.h"
34 #include "MSLane.h"
35 #include "MSVehicle.h"
36 
37 #define PARALLEL_PLAN_MOVE
38 //#define PARALLEL_EXEC_MOVE
39 //#define PARALLEL_CHANGE_LANES
40 //#define LOAD_BALANCING
41 
42 // ===========================================================================
43 // member method definitions
44 // ===========================================================================
45 MSEdgeControl::MSEdgeControl(const std::vector< MSEdge* >& edges)
46  : myEdges(edges),
47  myLanes(MSLane::dictSize()),
48  myWithVehicles2Integrate(MSGlobals::gNumSimThreads > 1),
49  myLastLaneChange(MSEdge::dictSize()) {
50  // build the usage definitions for lanes
51  for (std::vector< MSEdge* >::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
52  const std::vector<MSLane*>& lanes = (*i)->getLanes();
53  if (!(*i)->hasLaneChanger()) {
54  int pos = (*lanes.begin())->getNumericalID();
55  myLanes[pos].lane = *(lanes.begin());
56  myLanes[pos].amActive = false;
57  myLanes[pos].haveNeighbors = false;
58  } else {
59  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
60  int pos = (*j)->getNumericalID();
61  myLanes[pos].lane = *j;
62  myLanes[pos].amActive = false;
63  myLanes[pos].haveNeighbors = true;
64  }
65  myLastLaneChange[(*i)->getNumericalID()] = -1;
66  }
67  }
68 }
69 
70 
72 }
73 
74 
75 void
77  for (std::set<MSLane*, ComparatorNumericalIdLess>::iterator i = myChangedStateLanes.begin(); i != myChangedStateLanes.end(); ++i) {
78  LaneUsage& lu = myLanes[(*i)->getNumericalID()];
79  // if the lane was inactive but is now...
80  if (!lu.amActive && (*i)->getVehicleNumber() > 0) {
81  // ... add to active lanes and mark as such
82  if (lu.haveNeighbors) {
83  myActiveLanes.push_front(*i);
84  } else {
85  myActiveLanes.push_back(*i);
86  }
87  lu.amActive = true;
88  }
89  }
90  myChangedStateLanes.clear();
91 }
92 
93 
94 void
96 #ifdef HAVE_FOX
97  if (MSGlobals::gNumSimThreads > 1) {
98  while (myThreadPool.size() < MSGlobals::gNumSimThreads) {
99  new FXWorkerThread(myThreadPool);
100  }
101  }
102 #endif
103 #ifdef LOAD_BALANCING
104  myRNGLoad = std::priority_queue<std::pair<int, int> >();
105  for (int i = 0; i < MSLane::getNumRNGs(); i++) {
106  myRNGLoad.emplace(0, i);
107  }
108 #endif
109  for (std::list<MSLane*>::iterator i = myActiveLanes.begin(); i != myActiveLanes.end();) {
110  const int vehNum = (*i)->getVehicleNumber();
111  if (vehNum == 0) {
112  myLanes[(*i)->getNumericalID()].amActive = false;
113  i = myActiveLanes.erase(i);
114  } else {
115 #ifdef LOAD_BALANCING
116  std::pair<int, int> minRNG = myRNGLoad.top();
117  (*i)->setRNGIndex(minRNG.second);
118  myRNGLoad.pop();
119  minRNG.first -= vehNum;
120  myRNGLoad.push(minRNG);
121 #endif
122 #ifdef HAVE_FOX
123  if (MSGlobals::gNumSimThreads > 1) {
124  myThreadPool.add((*i)->getPlanMoveTask(t), (*i)->getRNGIndex() % myThreadPool.size());
125  ++i;
126  continue;
127  }
128 #endif
129  (*i)->planMovements(t);
130  ++i;
131  }
132  }
133 #ifdef HAVE_FOX
134  if (MSGlobals::gNumSimThreads > 1) {
135  myThreadPool.waitAll(false);
136  }
137 #endif
138 }
139 
140 
141 void
143  for (MSLane* const lane : myActiveLanes) {
144  lane->setJunctionApproaches(t);
145  }
146 }
147 
148 
149 void
151  std::vector<MSLane*> wasActive(myActiveLanes.begin(), myActiveLanes.end());
153 #ifdef HAVE_FOX
154 #ifdef PARALLEL_EXEC_MOVE
155  if (MSGlobals::gNumSimThreads > 1) {
156 #ifdef LOAD_BALANCING
157  myRNGLoad = std::priority_queue<std::pair<int, int> >();
158  for (int i = 0; i < MSLane::getNumRNGs(); i++) {
159  myRNGLoad.emplace(0, i);
160  }
161 #endif
162  for (MSLane* const lane : myActiveLanes) {
163 #ifdef LOAD_BALANCING
164  std::pair<int, int> minRNG = myRNGLoad.top();
165  lane->setRNGIndex(minRNG.second);
166  myRNGLoad.pop();
167  minRNG.first -= lane->getVehicleNumber();
168  myRNGLoad.push(minRNG);
169 #endif
170  myThreadPool.add(lane->getExecuteMoveTask(t), lane->getRNGIndex() % myThreadPool.size());
171  }
172  myThreadPool.waitAll(false);
173  }
174 #endif
175 #endif
176  for (std::list<MSLane*>::iterator i = myActiveLanes.begin(); i != myActiveLanes.end();) {
177  if (
178 #ifdef PARALLEL_EXEC_MOVE
180 #endif
181  (*i)->getVehicleNumber() > 0) {
182  (*i)->executeMovements(t);
183  }
184  if ((*i)->getVehicleNumber() == 0) {
185  myLanes[(*i)->getNumericalID()].amActive = false;
186  i = myActiveLanes.erase(i);
187  } else {
188  ++i;
189  }
190  }
191  for (MSLane* lane : wasActive) {
192  lane->updateLengthSum();
193  }
195  std::vector<MSLane*>& toIntegrate = myWithVehicles2Integrate.getContainer();
196  std::sort(toIntegrate.begin(), toIntegrate.end(), ComparatorIdLess());
198  for (MSLane* const lane : toIntegrate) {
199  const bool wasInactive = lane->getVehicleNumber() == 0;
200  lane->integrateNewVehicles();
201  if (wasInactive && lane->getVehicleNumber() > 0) {
202  LaneUsage& lu = myLanes[lane->getNumericalID()];
203  if (!lu.amActive) {
204  if (lu.haveNeighbors) {
205  myActiveLanes.push_front(lane);
206  } else {
207  myActiveLanes.push_back(lane);
208  }
209  lu.amActive = true;
210  }
211  }
212  }
213 }
214 
215 
216 void
218  std::vector<MSLane*> toAdd;
219 #ifdef PARALLEL_CHANGE_LANES
220  std::vector<MSEdge*> recheckLaneUsage;
221 #endif
222  MSGlobals::gComputeLC = true;
223  for (std::list<MSLane*>::iterator i = myActiveLanes.begin(); i != myActiveLanes.end();) {
224  LaneUsage& lu = myLanes[(*i)->getNumericalID()];
225  if (lu.haveNeighbors) {
226  MSEdge& edge = (*i)->getEdge();
227  if (myLastLaneChange[edge.getNumericalID()] != t) {
228  myLastLaneChange[edge.getNumericalID()] = t;
229 #ifdef PARALLEL_CHANGE_LANES
230  if (MSGlobals::gNumSimThreads > 1) {
231  MSLane* lane = edge.getLanes()[0];
232  myThreadPool.add(lane->getLaneChangeTask(t), lane->getRNGIndex() % myThreadPool.size());
233  recheckLaneUsage.push_back(&edge);
234  } else {
235 #endif
236  edge.changeLanes(t);
237  const std::vector<MSLane*>& lanes = edge.getLanes();
238  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
239  LaneUsage& lu = myLanes[(*i)->getNumericalID()];
240  //if ((*i)->getID() == "disabled") {
241  // std::cout << SIMTIME << " vehicles=" << toString((*i)->getVehiclesSecure()) << "\n";
242  // (*i)->releaseVehicles();
243  //}
244  if ((*i)->getVehicleNumber() > 0 && !lu.amActive) {
245  toAdd.push_back(*i);
246  lu.amActive = true;
247  }
248  }
249 #ifdef PARALLEL_CHANGE_LANES
250  }
251 #endif
252  }
253  ++i;
254  } else {
255  i = myActiveLanes.end();
256  }
257  }
258 
259 #ifdef PARALLEL_CHANGE_LANES
260  if (MSGlobals::gNumSimThreads > 1) {
261  myThreadPool.waitAll(false);
262  for (MSEdge* e : recheckLaneUsage) {
263  const std::vector<MSLane*>& lanes = e->getLanes();
264  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
265  LaneUsage& lu = myLanes[(*i)->getNumericalID()];
266  if ((*i)->getVehicleNumber() > 0 && !lu.amActive) {
267  toAdd.push_back(*i);
268  lu.amActive = true;
269  }
270  }
271  }
272  }
273 #endif
274 
275  MSGlobals::gComputeLC = false;
276  for (std::vector<MSLane*>::iterator i = toAdd.begin(); i != toAdd.end(); ++i) {
277  myActiveLanes.push_front(*i);
278  }
280  // sort maneuver reservations
281  for (LaneUsageVector::iterator it = myLanes.begin(); it != myLanes.end(); ++it) {
282  (*it).lane->sortManeuverReservations();
283  }
284  }
285 }
286 
287 
288 void
289 MSEdgeControl::detectCollisions(SUMOTime timestep, const std::string& stage) {
290  // Detections is made by the edge's lanes, therefore hand over.
291  for (MSLane* lane : myActiveLanes) {
292  if (lane->needsCollisionCheck()) {
293  lane->detectCollisions(timestep, stage);
294  }
295  }
296  if (myInactiveCheckCollisions.size() > 0) {
297  for (MSLane* lane : myInactiveCheckCollisions) {
298  lane->detectCollisions(timestep, stage);
299  }
301  }
302 }
303 
304 
305 void
307  myChangedStateLanes.insert(l);
308 }
309 
310 void
312  myInactiveCheckCollisions.insert(l);
313 }
314 
315 void
317  for (MSEdgeVector::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
318  const std::vector<MSLane*>& lanes = (*i)->getLanes();
319  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
320  (*j)->initRestrictions();
321  }
322  }
323 }
324 
325 
326 /****************************************************************************/
327 
MSEdgeControl::myInactiveCheckCollisions
std::set< MSLane *, ComparatorNumericalIdLess > myInactiveCheckCollisions
Additional lanes for which collision checking must be performed.
Definition: MSEdgeControl.h:231
MSEdgeControl::gotActive
void gotActive(MSLane *l)
Informs the control that the given lane got active.
Definition: MSEdgeControl.cpp:306
MSEdgeControl::LaneUsage::haveNeighbors
bool haveNeighbors
Information whether this lane belongs to a multi-lane edge.
Definition: MSEdgeControl.h:205
MSEdge::getNumericalID
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:263
MSEdgeControl::setAdditionalRestrictions
void setAdditionalRestrictions()
apply additional restrictions
Definition: MSEdgeControl.cpp:316
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
MSGlobals::gComputeLC
static bool gComputeLC
whether the simulationLoop is in the lane changing phase
Definition: MSGlobals.h:121
FXSynchQue::getContainer
Container & getContainer()
Definition: FXSynchQue.h:74
MSGlobals::gNumSimThreads
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:124
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
MSGlobals
Definition: MSGlobals.h:49
MSEdge.h
ComparatorIdLess
Function-object for stable sorting of objects acting like Named without being derived (SUMOVehicle)
Definition: Named.h:33
MSLane::getRNGIndex
int getRNGIndex() const
returns the associated RNG index
Definition: MSLane.h:218
MSEdgeControl::changeLanes
void changeLanes(const SUMOTime t)
Moves (precomputes) critical vehicles.
Definition: MSEdgeControl.cpp:217
MSGlobals::gLateralResolution
static double gLateralResolution
Definition: MSGlobals.h:85
MSVehicle.h
MSEdgeControl::myChangedStateLanes
std::set< MSLane *, ComparatorNumericalIdLess > myChangedStateLanes
Lanes which changed the state without informing the control.
Definition: MSEdgeControl.h:225
MSEdgeControl::myLanes
LaneUsageVector myLanes
Information about lanes' number of vehicles and neighbors.
Definition: MSEdgeControl.h:216
MSEdgeControl::myLastLaneChange
std::vector< SUMOTime > myLastLaneChange
The list of active (not empty) lanes.
Definition: MSEdgeControl.h:228
MSEdgeControl::checkCollisionForInactive
void checkCollisionForInactive(MSLane *l)
trigger collision checking for inactive lane
Definition: MSEdgeControl.cpp:311
MSEdgeControl::myWithVehicles2Integrate
FXSynchQue< MSLane *, std::vector< MSLane * > > myWithVehicles2Integrate
A storage for lanes which shall be integrated because vehicles have moved onto them.
Definition: MSEdgeControl.h:222
MSGlobals.h
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:76
MSLane::getNumRNGs
static int getNumRNGs()
return the number of RNGs
Definition: MSLane.h:228
MSEdgeControl::detectCollisions
void detectCollisions(SUMOTime timestep, const std::string &stage)
Detect collisions.
Definition: MSEdgeControl.cpp:289
MSEdgeControl::setJunctionApproaches
void setJunctionApproaches(SUMOTime t)
Register junction approaches for all vehicles after velocities have been planned. This is a prerequis...
Definition: MSEdgeControl.cpp:142
MSEdgeControl.h
MSEdgeControl::MSEdgeControl
MSEdgeControl(const std::vector< MSEdge * > &edges)
Constructor.
Definition: MSEdgeControl.cpp:45
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
MSVehicleControl::removePending
void removePending()
Removes a vehicle after it has ended.
Definition: MSVehicleControl.cpp:130
MSEdgeControl::myRNGLoad
std::priority_queue< std::pair< int, int > > myRNGLoad
Definition: MSEdgeControl.h:237
MSEdgeControl::myActiveLanes
std::list< MSLane * > myActiveLanes
The list of active (not empty) lanes.
Definition: MSEdgeControl.h:219
MSEdgeControl::LaneUsage::amActive
bool amActive
Information whether this lane is active.
Definition: MSEdgeControl.h:203
FXSynchQue::clear
void clear()
Definition: FXSynchQue.h:120
MSEdgeControl::myEdges
MSEdgeVector myEdges
Loaded edges.
Definition: MSEdgeControl.h:210
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:165
FXSynchQue::unlock
void unlock()
Definition: FXSynchQue.h:83
MSEdge::changeLanes
virtual void changeLanes(SUMOTime t)
Performs lane changing on this edge.
Definition: MSEdge.cpp:699
config.h
MSEdgeControl::~MSEdgeControl
~MSEdgeControl()
Destructor.
Definition: MSEdgeControl.cpp:71
MSEdgeControl::executeMovements
void executeMovements(SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSEdgeControl.cpp:150
MSEdgeControl::planMovements
void planMovements(SUMOTime t)
Compute safe velocities for all vehicles based on positions and speeds from the last time step....
Definition: MSEdgeControl.cpp:95
MSLane.h
MSEdgeControl::patchActiveLanes
void patchActiveLanes()
Resets information whether a lane is active for all lanes.
Definition: MSEdgeControl.cpp:76
MSVehicleControl.h
MSNet::getVehicleControl
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:337
FXWorkerThread
A thread repeatingly calculating incoming tasks.
Definition: FXWorkerThread.h:49
MSEdgeControl::LaneUsage
A structure holding some basic information about a simulated lane.
Definition: MSEdgeControl.h:199