SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSLink.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A connnection between lanes
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <iostream>
35 #include "MSNet.h"
36 #include "MSLink.h"
37 #include "MSLane.h"
38 #include "MSEdge.h"
39 #include "MSGlobals.h"
40 #include "MSVehicle.h"
41 
42 #ifdef CHECK_MEMORY_LEAKS
43 #include <foreign/nvwa/debug_new.h>
44 #endif // CHECK_MEMORY_LEAKS
45 
46 
47 // ===========================================================================
48 // static member variables
49 // ===========================================================================
51 
52 
53 // ===========================================================================
54 // member method definitions
55 // ===========================================================================
56 #ifndef HAVE_INTERNAL_LANES
58  LinkDirection dir, LinkState state,
59  SUMOReal length)
60  :
61  myLane(succLane),
62  myRequestIdx(0), myRespondIdx(0),
63  myState(state), myDirection(dir), myLength(length) {}
64 #else
65 MSLink::MSLink(MSLane* succLane, MSLane* via,
66  LinkDirection dir, LinkState state, SUMOReal length)
67  :
68  myLane(succLane),
69  myRequestIdx(0), myRespondIdx(0),
70  myState(state), myDirection(dir), myLength(length),
71  myJunctionInlane(via) {}
72 #endif
73 
74 
76 
77 
78 void
79 MSLink::setRequestInformation(unsigned int requestIdx, unsigned int respondIdx, bool isCrossing, bool isCont,
80  const std::vector<MSLink*>& foeLinks,
81  const std::vector<MSLane*>& foeLanes) {
82  myRequestIdx = requestIdx;
83  myRespondIdx = respondIdx;
85  myAmCont = isCont;
86  myFoeLinks = foeLinks;
87  myFoeLanes = foeLanes;
88 }
89 
90 
91 void
92 MSLink::setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed,
93  const bool setRequest, const SUMOTime arrivalTimeBraking, const SUMOReal arrivalSpeedBraking, const SUMOTime waitingTime) {
94  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, approaching->getVehicleType().getLengthWithGap());
95  myApproachingVehicles.insert(std::make_pair(approaching,
96  ApproachingVehicleInformation(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, setRequest,
97  arrivalTimeBraking, arrivalSpeedBraking, waitingTime)));
98 }
99 
100 
101 void
103  myBlockedFoeLinks.insert(link);
104 }
105 
106 
107 
108 bool
110  for (std::set<MSLink*>::const_iterator i = myBlockedFoeLinks.begin(); i != myBlockedFoeLinks.end(); ++i) {
111  if ((*i)->isBlockingAnyone()) {
112  return true;
113  }
114  }
115  return false;
116 }
117 
118 
119 void
121  myApproachingVehicles.erase(veh);
122 }
123 
124 
127  std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.find(veh);
128  if (i != myApproachingVehicles.end()) {
129  return i->second;
130  } else {
131  return ApproachingVehicleInformation(-1000, -1000, 0, 0, false, -1000, 0, 0);
132  }
133 }
134 
135 
136 SUMOTime
137 MSLink::getLeaveTime(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength) const {
138  return arrivalTime + TIME2STEPS((getLength() + vehicleLength) / (0.5 * (arrivalSpeed + leaveSpeed)));
139 }
140 
141 
142 bool
143 MSLink::opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength,
144  SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime,
145  std::vector<const SUMOVehicle*>* collectFoes) const {
146  if (myState == LINKSTATE_TL_RED) {
147  return false;
148  }
150  return true;
151  }
152  if ((myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP) && waitingTime == 0) {
153  return false;
154  }
155  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, vehicleLength);
156  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
157 #ifdef HAVE_INTERNAL
159  if ((*i)->getState() == LINKSTATE_TL_RED) {
160  continue;
161  }
162  }
163 #endif
164  if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, myLane == (*i)->getLane(),
165  impatience, decel, waitingTime, collectFoes)) {
166  return false;
167  }
168  }
169  return true;
170 }
171 
172 
173 bool
174 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed,
175  bool sameTargetLane, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime,
176  std::vector<const SUMOVehicle*>* collectFoes) const {
177  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.begin(); i != myApproachingVehicles.end(); ++i) {
178  if (!i->second.willPass) {
179  continue;
180  }
182  assert(waitingTime > 0);
183  if (waitingTime > i->second.waitingTime) {
184  continue;
185  }
186  if (waitingTime == i->second.waitingTime && arrivalTime < i->second.arrivalTime) {
187  continue;
188  }
189  }
190  const SUMOTime foeArrivalTime = (SUMOTime)((1.0 - impatience) * i->second.arrivalTime + impatience * i->second.arrivalTimeBraking);
191  if (i->second.leavingTime < arrivalTime) {
192  // ego wants to be follower
193  if (sameTargetLane && (arrivalTime - i->second.leavingTime < myLookaheadTime
194  || unsafeMergeSpeeds(i->second.leaveSpeed, arrivalSpeed,
195  i->first->getVehicleType().getCarFollowModel().getMaxDecel(), decel))) {
196  if (collectFoes == 0) {
197  return true;
198  } else {
199  collectFoes->push_back(i->first);
200  }
201  }
202  } else if (foeArrivalTime > leaveTime) {
203  // ego wants to be leader.
204  if (sameTargetLane && (foeArrivalTime - leaveTime < myLookaheadTime
205  || unsafeMergeSpeeds(leaveSpeed, i->second.arrivalSpeedBraking,
206  decel, i->first->getVehicleType().getCarFollowModel().getMaxDecel()))) {
207  if (collectFoes == 0) {
208  return true;
209  } else {
210  collectFoes->push_back(i->first);
211  }
212  }
213  } else {
214  // even without considering safeHeadwayTime there is already a conflict
215  if (collectFoes == 0) {
216  return true;
217  } else {
218  collectFoes->push_back(i->first);
219  }
220  }
221  }
222  return false;
223 }
224 
225 
226 bool
228  MSVehicle* veh = lane->getLastVehicle();
229  SUMOReal distLeft = 0;
230  if (veh == 0) {
231  veh = lane->getPartialOccupator();
232  distLeft = lane->getLength() - lane->getPartialOccupatorEnd();
233  } else {
234  distLeft = lane->getLength() - veh->getPositionOnLane() + veh->getVehicleType().getLength();
235  }
236  if (veh == 0) {
237  return false;
238  } else {
239  assert(distLeft > 0);
240  // can we be sure that the vehicle leaves this lane in the next step?
241  bool result = distLeft > (veh->getSpeed() - veh->getCarFollowModel().getMaxDecel());
242  return result;
243  }
244 }
245 
246 
247 bool
248 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed, SUMOReal decel) const {
249  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
250  if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed, myLane == (*i)->getLane(), 0, decel, 0)) {
251  return true;
252  }
253  }
254  for (std::vector<MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
255  if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
256  return true;
257  }
258  }
259  return false;
260 }
261 
262 
265  return myDirection;
266 }
267 
268 
269 void
271  myState = state;
272 }
273 
274 
275 MSLane*
277  return myLane;
278 }
279 
280 
281 void
282 MSLink::writeApproaching(OutputDevice& od, const std::string fromLaneID) const {
283  if (myApproachingVehicles.size() > 0) {
284  od.openTag("link");
285  od.writeAttr(SUMO_ATTR_FROM, fromLaneID);
286 #ifdef HAVE_INTERNAL_LANES
287  const std::string via = getViaLane() == 0 ? "" : getViaLane()->getID();
288 #else
289  const std::string via = "";
290 #endif
291  od.writeAttr(SUMO_ATTR_VIA, via);
292  od.writeAttr(SUMO_ATTR_TO, getLane() == 0 ? "" : getLane()->getID());
293  std::vector<std::pair<SUMOTime, const SUMOVehicle*> > toSort; // stabilize output
294  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator it = myApproachingVehicles.begin(); it != myApproachingVehicles.end(); ++it) {
295  toSort.push_back(std::make_pair(it->second.arrivalTime, it->first));
296  }
297  std::sort(toSort.begin(), toSort.end());
298  for (std::vector<std::pair<SUMOTime, const SUMOVehicle*> >::const_iterator it = toSort.begin(); it != toSort.end(); ++it) {
299  od.openTag("approaching");
300  const ApproachingVehicleInformation& avi = myApproachingVehicles.find(it->second)->second;
301  od.writeAttr(SUMO_ATTR_ID, it->second->getID());
302  od.writeAttr("arrivalTime", time2string(avi.arrivalTime));
303  od.writeAttr("leaveTime", time2string(avi.leavingTime));
304  od.writeAttr("arrivalSpeed", toString(avi.arrivalSpeed));
305  od.writeAttr("leaveSpeed", toString(avi.leaveSpeed));
306  od.writeAttr("willPass", toString(avi.willPass));
307  od.closeTag();
308  }
309  od.closeTag();
310  }
311 }
312 
313 
314 #ifdef HAVE_INTERNAL_LANES
315 MSLane*
316 MSLink::getViaLane() const {
317  return myJunctionInlane;
318 }
319 
320 
322 MSLink::getLeaderInfo(SUMOReal dist) const {
323  LinkLeaders result;
324  if (MSGlobals::gUsingInternalLanes && myJunctionInlane == 0) {
325  // this is an exit link
326 
327  for (std::vector<MSLane*>::const_iterator it_lane = myFoeLanes.begin(); it_lane != myFoeLanes.end(); ++it_lane) {
328  // it is not sufficient to return the last vehicle on the foeLane because ego might be its leader
329  // therefore we return all vehicles on the lane
330  //
331  // special care must be taken for continuation lanes. (next lane is also internal)
332  // vehicles on these lanes should always block (gap = -1)
333  const bool contLane = ((*it_lane)->getLinkCont()[0]->getViaLaneOrLane()->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL);
334  const MSLane::VehCont& vehicles = (*it_lane)->getVehiclesSecure();
335  (*it_lane)->releaseVehicles();
336  for (MSLane::VehCont::const_iterator it_veh = vehicles.begin(); it_veh != vehicles.end(); ++it_veh) {
337  MSVehicle* leader = *it_veh;
338  // XXX apply viaLane/foeLane specific distance offset
339  // to account for the fact that the crossing point has different distances from the lane ends
340  result.push_back(std::make_pair(leader,
341  contLane ? -1 :
342  dist - ((*it_lane)->getLength() - leader->getPositionOnLane()) - leader->getVehicleType().getLength()));
343 
344  }
345  // XXX partial occupates should be ignored if they do not extend past the crossing point
346  MSVehicle* leader = (*it_lane)->getPartialOccupator();
347  if (leader != 0) {
348  result.push_back(std::make_pair(leader,
349  contLane ? -1 :
350  dist - ((*it_lane)->getLength() - (*it_lane)->getPartialOccupatorEnd())));
351  }
352  }
353  }
354  return result;
355 }
356 #endif
357 
358 
359 MSLane*
361 #ifdef HAVE_INTERNAL_LANES
362  if (myJunctionInlane != 0) {
363  return myJunctionInlane;
364  }
365 #endif
366  return myLane;
367 }
368 
369 
370 unsigned int
372  return myRespondIdx;
373 }
374 
375 
376 
377 /****************************************************************************/
378 
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:513
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
This is an uncontrolled, minor link, has to stop.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:360
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:84
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
SUMOReal getLength() const
Get vehicle&#39;s length [m].
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:284
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
This is an uncontrolled, all-way stop link.
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:256
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
Representation of a vehicle.
Definition: SUMOVehicle.h:63
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:70
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:165
virtual MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:883
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:94
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:292
int SUMOTime
Definition: SUMOTime.h:43
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:248
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:221
static const bool gUseMesoSim
Definition: MSGlobals.h:95
The edge is an internal edge.
Definition: MSEdge.h:90
Representation of a lane in the micro simulation.
Definition: MSLane.h:73
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.