00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _MSC_VER
00024 #include <windows_config.h>
00025 #else
00026 #include <config.h>
00027 #endif
00028
00029 #include "MSLink.h"
00030 #include "MSLane.h"
00031 #include <iostream>
00032 #include <cassert>
00033
00034 #ifdef CHECK_MEMORY_LEAKS
00035 #include <foreign/nvwa/debug_new.h>
00036 #endif // CHECK_MEMORY_LEAKS
00037
00038
00039
00040
00041
00042 #ifndef HAVE_INTERNAL_LANES
00043 MSLink::MSLink(MSLane* succLane, bool yield,
00044 LinkDirection dir, LinkState state,
00045 SUMOReal length) throw()
00046 :
00047 myLane(succLane),
00048 myPrio(!yield), myApproaching(0),
00049 myRequest(0), myRequestIdx(0), myRespond(0), myRespondIdx(0),
00050 myState(state), myDirection(dir), myLength(length) {}
00051 #else
00052 MSLink::MSLink(MSLane* succLane, MSLane *via, bool yield,
00053 LinkDirection dir, LinkState state, bool internalEnd,
00054 SUMOReal length) throw()
00055 :
00056 myLane(succLane),
00057 myPrio(!yield), myApproaching(0),
00058 myRequest(0), myRequestIdx(0), myRespond(0), myRespondIdx(0),
00059 myState(state), myDirection(dir), myLength(length),
00060 myJunctionInlane(via),myIsInternalEnd(internalEnd) {}
00061 #endif
00062
00063
00064 MSLink::~MSLink() throw() {}
00065
00066
00067 void
00068 MSLink::setRequestInformation(MSLogicJunction::Request *request, unsigned int requestIdx,
00069 MSLogicJunction::Respond *respond, unsigned int respondIdx,
00070 const MSLogicJunction::LinkFoes &foes, bool isCrossing, bool isCont,
00071 const std::vector<MSLink*> &foeLinks,
00072 const std::vector<MSLane*> &foeLanes) throw() {
00073 assert(myRequest==0);
00074 assert(myRespond==0);
00075 myRequest = request;
00076 myRequestIdx = requestIdx;
00077 myRespond = respond;
00078 myRespondIdx = respondIdx;
00079 myFoes = foes;
00080 myIsCrossing = isCrossing;
00081 myAmCont = isCont;
00082 myFoeLinks = foeLinks;
00083 myFoeLanes = foeLanes;
00084 }
00085
00086
00087 void
00088 MSLink::setApproaching(MSVehicle *approaching, SUMOTime arrivalTime, SUMOReal speed) throw() {
00089 if (myRequest==0) {
00090 return;
00091 }
00092 myApproaching = approaching;
00093 myRequest->set(myRequestIdx);
00094 std::vector<MSJunction::ApproachingVehicleInformation>::iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), MSJunction::vehicle_in_request_finder(approaching));
00095 if (i!=myApproachingVehicles.end()) {
00096 myApproachingVehicles.erase(i);
00097 }
00098 SUMOReal leaveTime = arrivalTime + getLength() / speed * 1000.;
00099 MSJunction::ApproachingVehicleInformation approachInfo(arrivalTime, leaveTime, approaching);
00100 myApproachingVehicles.push_back(approachInfo);
00101 }
00102
00103
00104 void
00105 MSLink::removeApproaching(MSVehicle *veh) {
00106 if (myRequest==0) {
00107 return;
00108 }
00109 std::vector<MSJunction::ApproachingVehicleInformation>::iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), MSJunction::vehicle_in_request_finder(veh));
00110 if (i!=myApproachingVehicles.end()) {
00111 myApproachingVehicles.erase(i);
00112 }
00113 }
00114
00115
00116 void
00117 MSLink::setPriority(bool prio) throw() {
00118 myPrio = prio;
00119 }
00120
00121
00122 bool
00123 MSLink::opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed) const throw() {
00124 if (myRespond==0) {
00125
00126
00127 return true;
00128 }
00129 if (myAmCont) {
00130 return true;
00131 }
00132 if (myState==LINKSTATE_TL_RED) {
00133 return false;
00134 }
00135 #ifdef HAVE_INTERNAL_LANES
00136 SUMOTime leaveTime = myJunctionInlane==0 ? arrivalTime + TIME2STEPS(getLength() * arrivalSpeed) : arrivalTime + TIME2STEPS(this->myJunctionInlane->getLength() * arrivalSpeed);
00137 #else
00138 SUMOTime leaveTime = arrivalTime + TIME2STEPS(getLength() * arrivalSpeed);
00139 #endif
00140 for (std::vector<MSLink*>::const_iterator i=myFoeLinks.begin(); i!=myFoeLinks.end(); ++i) {
00141 if ((*i)->blockedAtTime(arrivalTime, leaveTime)) {
00142 return false;
00143 }
00144 }
00145 for (std::vector<MSLane*>::const_iterator i=myFoeLanes.begin(); i!=myFoeLanes.end(); ++i) {
00146 if ((*i)->getVehicleNumber()>0||(*i)->getPartialOccupator()!=0) {
00147 return false;
00148 }
00149 }
00150 return true;
00151 }
00152
00153 #define VIEW 3000
00154
00155 bool
00156 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime) const throw() {
00157 for (std::vector<MSJunction::ApproachingVehicleInformation>::const_iterator i=myApproachingVehicles.begin(); i!=myApproachingVehicles.end(); ++i) {
00158 if ((*i).arrivalTime-VIEW<=arrivalTime&&(*i).leavingTime+VIEW>=arrivalTime) {
00159 return true;
00160 }
00161 if ((*i).arrivalTime-VIEW<=leaveTime&&(*i).leavingTime+VIEW>=leaveTime) {
00162 return true;
00163 }
00164 }
00165 return false;
00166 }
00167
00168
00169 bool
00170 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime) const throw() {
00171 if (myRequest==0) {
00172 return false;
00173 }
00174 for (std::vector<MSLink*>::const_iterator i=myFoeLinks.begin(); i!=myFoeLinks.end(); ++i) {
00175 if ((*i)->blockedAtTime(arrivalTime, leaveTime)) {
00176 return true;
00177 }
00178 }
00179 for (std::vector<MSLane*>::const_iterator i=myFoeLanes.begin(); i!=myFoeLanes.end(); ++i) {
00180 if ((*i)->getVehicleNumber()>0||(*i)->getPartialOccupator()!=0) {
00181 return true;
00182 }
00183 }
00184 return false;
00185
00186 }
00187
00188
00189 void
00190 MSLink::deleteRequest() throw() {
00191 if (myRequest!=0) {
00192 myRequest->reset(myRequestIdx);
00193 }
00194 if (myRespond!=0) {
00195 myRespond->reset(myRespondIdx);
00196 }
00197 myApproaching = 0;
00198 }
00199
00200
00201 MSLink::LinkDirection
00202 MSLink::getDirection() const throw() {
00203 return myDirection;
00204 }
00205
00206
00207 void
00208 MSLink::setTLState(LinkState state) throw() {
00209 myState = state;
00210 }
00211
00212
00213 MSLane *
00214 MSLink::getLane() const throw() {
00215 return myLane;
00216 }
00217
00218
00219 #ifdef HAVE_INTERNAL_LANES
00220 MSLane * const
00221 MSLink::getViaLane() const throw() {
00222 return myJunctionInlane;
00223 }
00224 #endif
00225
00226
00227 #ifdef HAVE_INTERNAL_LANES
00228 void
00229 MSLink::resetInternalPriority() throw() {
00230 myPrio = opened(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getCurrentTimeStep());
00231 if (myJunctionInlane!=0&&myLane!=0) {
00232 if (myState==MSLink::LINKSTATE_TL_GREEN_MAJOR||myState==MSLink::LINKSTATE_TL_GREEN_MINOR) {
00233 if (myIsInternalEnd&&myJunctionInlane->getID()[0]==':') {
00234 if (myRequest->test(myRequestIdx)) {
00235 myRespond->set(myRespondIdx, true);
00236 }
00237 }
00238 }
00239 }
00240 }
00241 #endif
00242
00243
00244 unsigned int
00245 MSLink::getRespondIndex() const throw() {
00246 return myRespondIdx;
00247 }
00248
00249
00250
00251
00252