47 #ifdef CHECK_MEMORY_LEAKS 49 #endif // CHECK_MEMORY_LEAKS 61 #define ZIPPER_ADAPT_TIME 10 63 #define ZIPPER_ADAPT_DIST 100 68 #ifndef HAVE_INTERNAL_LANES 73 myLastStateChange(-1),
78 myKeepClear(keepClear),
85 myLastStateChange(-1),
90 myKeepClear(keepClear),
91 myJunctionInlane(via),
92 myInternalLaneBefore(0),
103 const std::vector<MSLink*>& foeLinks,
104 const std::vector<MSLane*>& foeLanes,
105 MSLane* internalLaneBefore) {
110 for (std::vector<MSLane*>::const_iterator it_lane = foeLanes.begin(); it_lane != foeLanes.end(); ++it_lane) {
115 #ifdef HAVE_INTERNAL_LANES 116 myInternalLaneBefore = internalLaneBefore;
118 if (internalLaneBefore != 0) {
120 lane = internalLaneBefore;
126 #ifdef MSLink_DEBUG_CROSSING_POINTS 130 const bool beforeInternalJunction = lane->
getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal();
133 for (std::vector<const MSLane*>::const_iterator it_lane =
myFoeLanes.begin(); it_lane !=
myFoeLanes.end(); ++it_lane) {
135 if (sameTarget && !beforeInternalJunction) {
138 myLengthsBehindCrossing.push_back(std::make_pair(0, 0));
139 #ifdef MSLink_DEBUG_CROSSING_POINTS 141 <<
" " << lane->
getID()
142 <<
" merges with " << (*it_lane)->getID()
143 <<
" nextLane " << lane->
getLinkCont()[0]->getViaLaneOrLane()->getID()
144 <<
" dist1=" << myLengthsBehindCrossing.back().first
145 <<
" dist2=" << myLengthsBehindCrossing.back().second
150 #ifdef MSLink_DEBUG_CROSSING_POINTS 153 bool haveIntersection =
true;
154 if (intersections1.size() == 0) {
155 intersections1.push_back(-10000.0);
156 haveIntersection =
false;
157 }
else if (intersections1.size() > 1) {
158 std::sort(intersections1.begin(), intersections1.end());
160 std::vector<SUMOReal> intersections2 = (*it_lane)->getShape().intersectsAtLengths2D(lane->
getShape());
161 #ifdef MSLink_DEBUG_CROSSING_POINTS 164 if (intersections2.size() == 0) {
165 intersections2.push_back(0);
166 }
else if (intersections2.size() > 1) {
167 std::sort(intersections2.begin(), intersections2.end());
169 if (haveIntersection) {
171 intersections1.back() -= (*it_lane)->getWidth() / 2;
172 intersections2.back() -= lane->
getWidth() / 2;
175 intersections2.back() = (*it_lane)->interpolateGeometryPosToLanePos(intersections2.back());
180 intersections1.back() = 0;
184 myLengthsBehindCrossing.push_back(std::make_pair(
185 lane->
getLength() - intersections1.back(),
186 (*it_lane)->getLength() - intersections2.back()));
188 #ifdef MSLink_DEBUG_CROSSING_POINTS 190 <<
" intersection of " << lane->
getID()
192 <<
" with " << (*it_lane)->getID()
193 <<
" totalLength=" << (*it_lane)->getLength()
194 <<
" dist1=" << myLengthsBehindCrossing.back().first
195 <<
" dist2=" << myLengthsBehindCrossing.back().second
205 for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
206 const MSLane* sibling = (*it)->getViaLane();
207 if (sibling != lane && sibling != 0) {
209 #ifdef MSLink_DEBUG_CROSSING_POINTS 212 if (intersections1.size() > 0) {
213 std::sort(intersections1.begin(), intersections1.end());
216 myLengthsBehindCrossing.push_back(std::make_pair(
217 lane->
getLength() - intersections1.back(),
218 sibling->
getLength() - intersections1.back()));
220 #ifdef MSLink_DEBUG_CROSSING_POINTS 221 std::cout <<
" adding same-origin foe" << sibling->
getID()
222 <<
" dist1=" << myLengthsBehindCrossing.back().first
223 <<
" dist2=" << myLengthsBehindCrossing.back().second
237 std::pair<SUMOReal, SUMOReal>
246 arrivalTimeBraking, arrivalSpeedBraking, waitingTime, dist)));
260 if ((*i)->isBlockingAnyone()) {
276 std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i =
myApproachingVehicles.find(veh);
295 std::vector<const SUMOVehicle*>* collectFoes)
const {
313 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;
536 MSLink::getLeaderInfo(
SUMOReal dist,
SUMOReal minGap, std::vector<const MSPerson*>* collectBlockers)
const {
542 || (myJunctionInlane != 0 && myJunctionInlane->getLogicalPredecessorLane()->getEdge().isInternal()))) {
545 for (
size_t i = 0; i <
myFoeLanes.size(); ++i) {
548 const SUMOReal distToCrossing = dist - myLengthsBehindCrossing[i].first;
550 const bool sameSource = (myInternalLaneBefore != 0 && myInternalLaneBefore->getLogicalPredecessorLane() == foeLane->
getLogicalPredecessorLane());
551 const SUMOReal crossingWidth = (sameTarget || sameSource) ? 0 : foeLane->
getWidth();
552 const SUMOReal foeCrossingWidth = (sameTarget || sameSource) ? 0 : myInternalLaneBefore->getWidth();
554 if (distToCrossing + crossingWidth < 0) {
557 const SUMOReal foeDistToCrossing = foeLane->
getLength() - myLengthsBehindCrossing[i].second;
565 const bool cannotIgnore = contLane || sameTarget || sameSource;
568 for (MSLane::VehCont::const_iterator it_veh = vehicles.begin(); it_veh != vehicles.end(); ++it_veh) {
570 if (!cannotIgnore && !foeLane->
getLinkCont()[0]->getApproaching(leader).willPass) {
577 if (contLane && !sameSource) {
581 const SUMOReal leaderBackDist = foeDistToCrossing - leaderBack;
583 if (leaderBackDist + foeCrossingWidth < 0) {
588 gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
590 result.push_back(
LinkLeader(leader, gap, cannotIgnore ? -1 : distToCrossing));
600 if (contLane && !sameSource) {
605 if (leaderBackDist + foeCrossingWidth < 0) {
610 gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
612 result.push_back(
LinkLeader(leader, gap, sameTarget ? -1 : distToCrossing));
617 if (distToPeds >= -MSPModel::SAFETY_GAP &&
MSPModel::getModel()->blockedAtDist(foeLane, foeDistToCrossing, collectBlockers)) {
629 #ifdef HAVE_INTERNAL_LANES 630 if (myJunctionInlane != 0) {
631 return myJunctionInlane;
658 #ifdef HAVE_INTERNAL_LANES 659 return myInternalLaneBefore;
668 std::vector<const SUMOVehicle*>* collectFoes)
const {
675 throw ProcessError(
"Zipper junctions with more than two conflicting lanes are not supported (at junction '" 693 for (std::vector<const SUMOVehicle*>::const_iterator i = collectFoes->begin(); i != collectFoes->end(); ++i) {
717 vSafe =
MIN2(vSafe, followInTime);
738 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.
#define 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.
#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()
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.
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.
static const bool gUseMesoSim
const MSJunction * getFromJunction() const
void removeApproaching(const SUMOVehicle *veh)
removes the vehicle from myApproachingVehicles
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
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.
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.