47 #ifdef CHECK_MEMORY_LEAKS 49 #endif // CHECK_MEMORY_LEAKS 63 #define ZIPPER_ADAPT_TIME 10 68 #ifndef HAVE_INTERNAL_LANES 78 myKeepClear(keepClear),
91 myKeepClear(keepClear),
93 myJunctionInlane(via),
94 myInternalLaneBefore(0),
105 const std::vector<MSLink*>& foeLinks,
106 const std::vector<MSLane*>& foeLanes,
107 MSLane* internalLaneBefore) {
112 for (std::vector<MSLane*>::const_iterator it_lane = foeLanes.begin(); it_lane != foeLanes.end(); ++it_lane) {
117 #ifdef HAVE_INTERNAL_LANES 118 myInternalLaneBefore = internalLaneBefore;
120 if (internalLaneBefore != 0) {
122 lane = internalLaneBefore;
128 #ifdef MSLink_DEBUG_CROSSING_POINTS 132 const bool beforeInternalJunction = lane->
getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal();
135 for (std::vector<const MSLane*>::const_iterator it_lane =
myFoeLanes.begin(); it_lane !=
myFoeLanes.end(); ++it_lane) {
137 if (sameTarget && !beforeInternalJunction) {
140 myLengthsBehindCrossing.push_back(std::make_pair(0, 0));
141 #ifdef MSLink_DEBUG_CROSSING_POINTS 143 <<
" " << lane->
getID()
144 <<
" merges with " << (*it_lane)->getID()
145 <<
" nextLane " << lane->
getLinkCont()[0]->getViaLaneOrLane()->getID()
146 <<
" dist1=" << myLengthsBehindCrossing.back().first
147 <<
" dist2=" << myLengthsBehindCrossing.back().second
152 #ifdef MSLink_DEBUG_CROSSING_POINTS 155 bool haveIntersection =
true;
156 if (intersections1.size() == 0) {
157 intersections1.push_back(-10000.0);
158 haveIntersection =
false;
159 }
else if (intersections1.size() > 1) {
160 std::sort(intersections1.begin(), intersections1.end());
162 std::vector<SUMOReal> intersections2 = (*it_lane)->getShape().intersectsAtLengths2D(lane->
getShape());
163 #ifdef MSLink_DEBUG_CROSSING_POINTS 166 if (intersections2.size() == 0) {
167 intersections2.push_back(0);
168 }
else if (intersections2.size() > 1) {
169 std::sort(intersections2.begin(), intersections2.end());
171 if (haveIntersection) {
173 intersections1.back() -= (*it_lane)->getWidth() / 2;
174 intersections2.back() -= lane->
getWidth() / 2;
177 intersections2.back() = (*it_lane)->interpolateGeometryPosToLanePos(intersections2.back());
182 intersections1.back() = 0;
186 myLengthsBehindCrossing.push_back(std::make_pair(
187 lane->
getLength() - intersections1.back(),
188 (*it_lane)->getLength() - intersections2.back()));
190 #ifdef MSLink_DEBUG_CROSSING_POINTS 192 <<
" intersection of " << lane->
getID()
194 <<
" with " << (*it_lane)->getID()
195 <<
" totalLength=" << (*it_lane)->getLength()
196 <<
" dist1=" << myLengthsBehindCrossing.back().first
197 <<
" dist2=" << myLengthsBehindCrossing.back().second
207 for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
208 const MSLane* sibling = (*it)->getViaLane();
209 if (sibling != lane && sibling != 0) {
211 #ifdef MSLink_DEBUG_CROSSING_POINTS 214 if (intersections1.size() > 0) {
215 std::sort(intersections1.begin(), intersections1.end());
218 myLengthsBehindCrossing.push_back(std::make_pair(
219 lane->
getLength() - intersections1.back(),
220 sibling->
getLength() - intersections1.back()));
222 #ifdef MSLink_DEBUG_CROSSING_POINTS 223 std::cout <<
" adding same-origin foe" << sibling->
getID()
224 <<
" dist1=" << myLengthsBehindCrossing.back().first
225 <<
" dist2=" << myLengthsBehindCrossing.back().second
239 std::pair<SUMOReal, SUMOReal>
248 arrivalTimeBraking, arrivalSpeedBraking, waitingTime, dist)));
262 if ((*i)->isBlockingAnyone()) {
278 std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i =
myApproachingVehicles.find(veh);
297 std::vector<const SUMOVehicle*>* collectFoes)
const {
314 if ((*i)->haveRed()) {
318 if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed,
myLane == (*i)->getLane(),
319 impatience, decel, waitingTime, collectFoes)) {
323 if (collectFoes != 0 && collectFoes->size() > 0) {
333 std::vector<const SUMOVehicle*>* collectFoes)
const {
335 if (!i->second.willPass) {
339 assert(waitingTime > 0);
340 if (waitingTime > i->second.waitingTime) {
343 if (waitingTime == i->second.waitingTime && arrivalTime < i->second.arrivalTime) {
347 const SUMOTime foeArrivalTime = (
SUMOTime)((1.0 - impatience) * i->second.arrivalTime + impatience * i->second.arrivalTimeBraking);
349 if (i->second.leavingTime < arrivalTime) {
351 if (sameTargetLane && (arrivalTime - i->second.leavingTime < lookAhead
353 i->first->getVehicleType().getCarFollowModel().getMaxDecel(), decel))) {
354 if (collectFoes == 0) {
357 collectFoes->push_back(i->first);
360 }
else if (foeArrivalTime > leaveTime) {
362 if (sameTargetLane && (foeArrivalTime - leaveTime < lookAhead
364 decel, i->first->getVehicleType().getCarFollowModel().getMaxDecel()))) {
365 if (collectFoes == 0) {
368 collectFoes->push_back(i->first);
373 if (collectFoes == 0) {
376 collectFoes->push_back(i->first);
397 assert(distLeft > 0);
408 if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed,
myLane == (*i)->getLane(), 0, decel, 0)) {
412 for (std::vector<const MSLane*>::const_iterator i =
myFoeLanes.begin(); i !=
myFoeLanes.end(); ++i) {
413 if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
444 #ifdef HAVE_INTERNAL_LANES 445 if (myJunctionInlane != 0) {
446 approachedLane = myJunctionInlane;
453 const std::vector<MSLane::IncomingLaneInfo> possibleLanes = approachedLane->
getIncomingLanes();
454 std::vector<MSLane::IncomingLaneInfo>::const_iterator i;
455 for (i = possibleLanes.begin(); i != possibleLanes.end(); i++) {
458 for (MSLinkCont::const_iterator j = outgoingLinks.begin(); j != outgoingLinks.end(); j++) {
471 #ifdef HAVE_INTERNAL_LANES 472 if (myJunctionInlane == 0 ||
myAmCont) {
482 assert(predLink != 0);
497 #ifdef HAVE_INTERNAL_LANES 498 const std::string via = getViaLane() == 0 ?
"" : getViaLane()->getID();
500 const std::string via =
"";
504 std::vector<std::pair<SUMOTime, const SUMOVehicle*> > toSort;
506 toSort.push_back(std::make_pair(it->second.arrivalTime, it->first));
508 std::sort(toSort.begin(), toSort.end());
509 for (std::vector<std::pair<SUMOTime, const SUMOVehicle*> >::const_iterator it = toSort.begin(); it != toSort.end(); ++it) {
528 #ifdef HAVE_INTERNAL_LANES 530 MSLink::getViaLane()
const {
531 return myJunctionInlane;
551 || (myJunctionInlane != 0 && myJunctionInlane->getLogicalPredecessorLane()->getEdge().isInternal())));
555 MSLink::getLeaderInfo(
SUMOReal dist,
SUMOReal minGap, std::vector<const MSPerson*>* collectBlockers)
const {
562 for (
size_t i = 0; i <
myFoeLanes.size(); ++i) {
565 const SUMOReal distToCrossing = dist - myLengthsBehindCrossing[i].first;
567 const bool sameSource = (myInternalLaneBefore != 0 && myInternalLaneBefore->getLogicalPredecessorLane() == foeLane->
getLogicalPredecessorLane());
568 const SUMOReal crossingWidth = (sameTarget || sameSource) ? 0 : foeLane->
getWidth();
569 const SUMOReal foeCrossingWidth = (sameTarget || sameSource) ? 0 : myInternalLaneBefore->getWidth();
571 if (distToCrossing + crossingWidth < 0) {
574 const SUMOReal foeDistToCrossing = foeLane->
getLength() - myLengthsBehindCrossing[i].second;
582 const bool cannotIgnore = contLane || sameTarget || sameSource;
585 for (MSLane::VehCont::const_iterator it_veh = vehicles.begin(); it_veh != vehicles.end(); ++it_veh) {
587 if (!cannotIgnore && !foeLane->
getLinkCont()[0]->getApproaching(leader).willPass) {
594 if (contLane && !sameSource) {
598 const SUMOReal leaderBackDist = foeDistToCrossing - leaderBack;
600 if (leaderBackDist + foeCrossingWidth < 0) {
605 gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
607 result.push_back(
LinkLeader(leader, gap, cannotIgnore ? -1 : distToCrossing));
617 if (contLane && !sameSource) {
622 if (leaderBackDist + foeCrossingWidth < 0) {
627 gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
629 result.push_back(
LinkLeader(leader, gap, sameTarget ? -1 : distToCrossing));
634 if (distToPeds >= -MSPModel::SAFETY_GAP &&
MSPModel::getModel()->blockedAtDist(foeLane, foeDistToCrossing, collectBlockers)) {
646 #ifdef HAVE_INTERNAL_LANES 647 if (myJunctionInlane != 0) {
648 return myJunctionInlane;
675 #ifdef HAVE_INTERNAL_LANES 676 return myInternalLaneBefore;
686 std::vector<const SUMOVehicle*>* collectFoes)
const {
693 throw ProcessError(
"Zipper junctions with more than two conflicting lanes are not supported (at junction '" 712 for (std::vector<const SUMOVehicle*>::const_iterator i = collectFoes->begin(); i != collectFoes->end(); ++i) {
737 const SUMOReal followInTime = vSafeOrig + (follow - vSafeOrig) /
MAX2((
SUMOReal)1, secondsToArrival /
TS);
738 vSafe =
MIN2(vSafe, followInTime);
759 followDist > leaderDist &&
SUMOReal getZipperSpeed(const MSVehicle *ego, const SUMOReal dist, SUMOReal vSafe, SUMOTime arrivalTime, std::vector< const SUMOVehicle * > *collectFoes) const
return the speed at which ego vehicle must approach the zipper link
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
MSEdge & getEdge() const
Returns the lane's edge.
int myIndex
The position within this respond.
Representation of a vehicle in the micro simulation.
bool hasFoes() const
Returns whether this link belongs to a junction where more than one edge is incoming.
bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed, SUMOReal decel) const
Returns the information whether a vehicle is approaching on one of the link's foe streams...
static const SUMOReal SAFETY_GAP
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
MSLane * myLane
The lane (but the internal one) approached by this link.
void addBlockedLink(MSLink *link)
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
LinkState myState
The state of the link.
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
std::pair< SUMOReal, SUMOReal > getLastIntersections(const MSLane *lane, const MSLane *foe)
void setRequestInformation(int index, bool hasFoes, bool isCont, const std::vector< MSLink * > &foeLinks, const std::vector< MSLane * > &foeLanes, MSLane *internalLaneBefore=0)
Sets the request information.
void setApproaching(const SUMOVehicle *approaching, const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed, const bool setRequest, const SUMOTime arrivalTimeBraking, const SUMOReal arrivalSpeedBraking, const SUMOTime waitingTime, SUMOReal dist)
Sets the information about an approaching vehicle.
const std::map< const SUMOVehicle *, ApproachingVehicleInformation > & getApproaching() const
return all approaching vehicles
static const SUMOReal ZIPPER_ADAPT_DIST
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
bool myHasFoes
Whether any foe links exist.
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle's follow speed (no dawdling)
This is an uncontrolled, minor link, has to stop.
SUMOReal getLength() const
Returns the lane's length.
The base class for an intersection.
SUMOTime myLastStateChange
The time of the last state change.
std::vector< MSLink * > myFoeLinks
#define ZIPPER_ADAPT_TIME
void setTLState(LinkState state, SUMOTime t)
Sets the current tl-state.
std::vector< MSVehicle * > VehCont
Container for vehicles.
std::string time2string(SUMOTime t)
SUMOReal getLength() const
Get vehicle's length [m].
static bool couldBrakeForLeader(SUMOReal followDist, SUMOReal leaderDist, const MSVehicle *follow, const MSVehicle *leader)
whether fllower could stay behind leader (possibly by braking)
LinkDirection myDirection
An abstract (hopefully human readable) definition of the link's direction.
SUMOReal getWidth() const
Returns the lane's width.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
static const SUMOTime myLookaheadTime
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
std::map< const SUMOVehicle *, ApproachingVehicleInformation > myApproachingVehicles
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
bool lastWasContMajor() const
whether this is a link past an internal junction which currently has priority
This is an uncontrolled, all-way stop link.
bool fromInternalLane() const
return whether the fromLane of this link is an internal lane
#define UNUSED_PARAMETER(x)
This is an uncontrolled, zipper-merge link.
#define WRITE_WARNING(msg)
bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, bool sameTargetLane, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime, std::vector< const SUMOVehicle * > *collectFoes=0) const
Returns the information whether this link is blocked Valid after the vehicles have set their requests...
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle's end.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
int getIndex() const
Returns the respond index (for visualization)
SUMOTime getLeaveTime(const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed, const SUMOReal vehicleLength) const
return the expected time at which the given vehicle will clear the link
const std::string & getID() const
Returns the id.
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
void passedJunction(const MSVehicle *vehicle)
erase vehicle from myLinkLeaders
Representation of a vehicle.
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
static MSPModel * getModel()
bool isInternalJunctionLink() const
return whether the fromLane and the toLane of this link are internal lanes
MSLane * getLane() const
Returns the connected lane.
static const SUMOTime myLookaheadTimeZipper
std::set< MSLink * > myBlockedFoeLinks
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
bool isLeader(const MSVehicle *ego, const MSVehicle *foe)
std::vector< LinkLeader > LinkLeaders
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
MSVehicle * getLastVehicle() const
returns the last vehicle
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
MSLink(MSLane *succLane, LinkDirection dir, LinkState state, SUMOReal length, bool keepClear)
Constructor for simulation not using internal lanes.
int getIndex() const
Returns the lane's index.
bool isInternal() const
return whether this edge is an internal edge
static bool unsafeMergeSpeeds(SUMOReal leaderSpeed, SUMOReal followerSpeed, SUMOReal leaderDecel, SUMOReal followerDecel)
return whether the given vehicles may NOT merge safely
SUMOReal getLength() const
Returns the length of this link.
static bool maybeOccupied(MSLane *lane)
returns whether the given lane may still be occupied by a vehicle currently on it ...
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
MSLane * getApproachingLane() const
Returns the lane leading to this link.
bool havePriority() const
Returns whether this link is a major link.
bool willHaveBlockedFoe() const
static MSLink * getConnectingLink(const MSLane &from, const MSLane &to)
Returns the link connecting both lanes Both lanes have to be non-internal; 0 may be returned if no co...
The edge is a normal street.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
MSJunction * myJunction
the junction to which this link belongs
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
SUMOReal getSpeed() const
Returns the vehicle's current speed.
void writeApproaching(OutputDevice &od, const std::string fromLaneID) const
write information about all approaching vehicles to the given output device
static SUMOTime gIgnoreJunctionBlocker
Information whether the simulation regards internal lanes.
const PositionVector & getShape() const
Returns this lane's shape.
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Static storage of an output device and its base (abstract) implementation.
bool closeTag()
Closes the most recently opened tag.
const MSJunction * getFromJunction() const
void removeApproaching(const SUMOVehicle *veh)
removes the vehicle from myApproachingVehicles
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
MSLane * getLane() const
Returns the lane the vehicle is on.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
The edge is an internal edge.
SUMOReal interpolateGeometryPosToLanePos(SUMOReal geometryPos) const
std::vector< SUMOReal > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
Representation of a lane in the micro simulation.
bool isLeader(const MSVehicle *ego, const MSVehicle *foe)
void passedJunction(const MSVehicle *vehicle)
erase vehicle from myLinkLeaders of this links junction
bool opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime, std::vector< const SUMOVehicle * > *collectFoes=0) const
Returns the information whether the link may be passed.
bool isExitLink() const
return whether the fromLane of this link is an internal lane and toLane is a normal lane ...
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
std::vector< const MSLane * > myFoeLanes
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.