00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <map>
00031 #include <string>
00032 #include <vector>
00033 #include <list>
00034 #include <algorithm>
00035 #include <microsim/MSJunctionLogic.h>
00036 #include <microsim/MSNoLogicJunction.h>
00037 #include <microsim/MSRightOfWayJunction.h>
00038 #include <microsim/MSInternalJunction.h>
00039 #include <microsim/MSJunctionControl.h>
00040 #include <microsim/traffic_lights/MSTrafficLightLogic.h>
00041 #include <microsim/traffic_lights/MSSimpleTrafficLightLogic.h>
00042 #include <microsim/MSEventControl.h>
00043 #include <microsim/MSGlobals.h>
00044 #include "NLBuilder.h"
00045 #include <microsim/traffic_lights/MSAgentbasedTrafficLightLogic.h>
00046 #include <utils/common/UtilExceptions.h>
00047 #include "NLJunctionControlBuilder.h"
00048 #include <microsim/traffic_lights/MSTLLogicControl.h>
00049
00050 #ifdef CHECK_MEMORY_LEAKS
00051 #include <foreign/nvwa/debug_new.h>
00052 #endif // CHECK_MEMORY_LEAKS
00053
00054
00055
00056
00057
00058 NLJunctionControlBuilder::NLJunctionControlBuilder(MSNet &net,
00059 OptionsCont &oc) throw()
00060 : myNet(net), myOffset(0), myJunctions(0) {
00061 myStdDetectorPositions = oc.getFloat("actuated-tl.detector-pos");
00062 myStdDetectorLengths = oc.getFloat("agent-tl.detector-len");
00063 myStdLearnHorizon = oc.getInt("agent-tl.learn-horizon");
00064 myStdDecisionHorizon = oc.getInt("agent-tl.decision-horizon");
00065 myStdDeltaLimit = oc.getFloat("agent-tl.min-diff");
00066 myStdTCycle = oc.getInt("agent-tl.tcycle");
00067 myStdActuatedMaxGap = oc.getFloat("actuated-tl.max-gap");
00068 myStdActuatedPassingTime = oc.getFloat("actuated-tl.passing-time");
00069 myStdActuatedDetectorGap = oc.getFloat("actuated-tl.detector-gap");
00070 myLogicControl = new MSTLLogicControl();
00071 myJunctions = new MSJunctionControl();
00072 }
00073
00074
00075 NLJunctionControlBuilder::~NLJunctionControlBuilder() throw() {
00076 delete myLogicControl;
00077 delete myJunctions;
00078 }
00079
00080 void
00081 NLJunctionControlBuilder::openJunction(const std::string &id,
00082 const std::string &key,
00083 const std::string &type,
00084 SUMOReal x, SUMOReal y,
00085 const Position2DVector &shape) throw(InvalidArgument) {
00086 #ifdef HAVE_INTERNAL_LANES
00087 myActiveInternalLanes.clear();
00088 #endif
00089 myActiveIncomingLanes.clear();
00090 myActiveID = id;
00091 myActiveKey = key;
00092 myType = TYPE_UNKNOWN;
00093 if (type=="right_before_left") {
00094 myType = TYPE_RIGHT_BEFORE_LEFT;
00095 } else if (type=="priority") {
00096 myType = TYPE_PRIORITY_JUNCTION;
00097 } else if (type=="DEAD_END"||type=="district") {
00098 myType = TYPE_DEAD_END;
00099 } else if (type=="internal") {
00100 myType = TYPE_INTERNAL;
00101 } else if (type=="unregulated"||type=="none") {
00102 myType = TYPE_NOJUNCTION;
00103 }
00104 if (myType==TYPE_UNKNOWN) {
00105 throw InvalidArgument("An unknown or invalid junction type '" + type + "' occured in junction '" + id + "'.");
00106 }
00107 myPosition.set(x, y);
00108 myShape = shape;
00109 }
00110
00111
00112 #ifdef HAVE_INTERNAL_LANES
00113 void
00114 NLJunctionControlBuilder::addInternalLane(MSLane *lane) throw() {
00115 myActiveInternalLanes.push_back(lane);
00116 }
00117 #endif
00118
00119
00120 void
00121 NLJunctionControlBuilder::addIncomingLane(MSLane *lane) throw() {
00122 myActiveIncomingLanes.push_back(lane);
00123 }
00124
00125
00126 void
00127 NLJunctionControlBuilder::addJunctionShape(const Position2DVector &shape) throw() {
00128
00129 myShape = shape;
00130 }
00131
00132
00133 void
00134 NLJunctionControlBuilder::closeJunction() throw(InvalidArgument, ProcessError) {
00135 if (myJunctions==0) {
00136 throw ProcessError("Information about the number of nodes was missing.");
00137 }
00138 MSJunction *junction = 0;
00139 switch (myType) {
00140 case TYPE_NOJUNCTION:
00141 junction = buildNoLogicJunction();
00142 break;
00143 case TYPE_RIGHT_BEFORE_LEFT:
00144 case TYPE_PRIORITY_JUNCTION:
00145 junction = buildLogicJunction();
00146 break;
00147 case TYPE_DEAD_END:
00148 junction = buildNoLogicJunction();
00149 break;
00150 case TYPE_INTERNAL:
00151 #ifdef HAVE_INTERNAL_LANES
00152 if (MSGlobals::gUsingInternalLanes) {
00153 junction = buildInternalJunction();
00154 }
00155 #endif
00156 break;
00157 default:
00158 throw InvalidArgument("False junction logic type.");
00159 }
00160 if (junction!=0) {
00161 if (!myJunctions->add(myActiveID, junction)) {
00162 throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
00163 }
00164 }
00165 }
00166
00167
00168 MSJunctionControl *
00169 NLJunctionControlBuilder::build() const throw() {
00170 MSJunctionControl *js = myJunctions;
00171 myJunctions = 0;
00172 return js;
00173 }
00174
00175
00176 MSJunction *
00177 NLJunctionControlBuilder::buildNoLogicJunction() throw() {
00178 return new MSNoLogicJunction(myActiveID, myPosition, myShape, myActiveIncomingLanes
00179 #ifdef HAVE_INTERNAL_LANES
00180 , myActiveInternalLanes
00181 #endif
00182 );
00183 }
00184
00185
00186 MSJunction *
00187 NLJunctionControlBuilder::buildLogicJunction() throw(InvalidArgument) {
00188 MSJunctionLogic *jtype = getJunctionLogicSecure();
00189
00190 return new MSRightOfWayJunction(myActiveID, myPosition, myShape, myActiveIncomingLanes,
00191 #ifdef HAVE_INTERNAL_LANES
00192 myActiveInternalLanes,
00193 #endif
00194 jtype);
00195 }
00196
00197
00198 #ifdef HAVE_INTERNAL_LANES
00199 MSJunction *
00200 NLJunctionControlBuilder::buildInternalJunction() throw() {
00201
00202 return new MSInternalJunction(myActiveID, myPosition, myShape, myActiveIncomingLanes,
00203 myActiveInternalLanes);
00204 }
00205 #endif
00206
00207
00208 MSJunctionLogic *
00209 NLJunctionControlBuilder::getJunctionLogicSecure() throw(InvalidArgument) {
00210
00211 if (myLogics.find(myActiveID)==myLogics.end()) {
00212 throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
00213 }
00214 return myLogics[myActiveID];
00215 }
00216
00217
00218 void
00219 NLJunctionControlBuilder::initIncomingLanes() throw() {
00220 myActiveIncomingLanes.clear();
00221 }
00222
00223
00224 MSTLLogicControl::TLSLogicVariants &
00225 NLJunctionControlBuilder::getTLLogic(const std::string &id) const throw(InvalidArgument) {
00226 return getTLLogicControlToUse().get(id);
00227 }
00228
00229
00230 void
00231 NLJunctionControlBuilder::closeTrafficLightLogic() throw(InvalidArgument, ProcessError) {
00232 if (myAbsDuration==0) {
00233 throw InvalidArgument("TLS program '" + myActiveSubKey + "' for TLS '" + myActiveKey + "' has a duration of 0.");
00234 }
00235
00236 unsigned int step = 0;
00237 SUMOTime firstEventOffset = 0;
00238 SUMOTime offset = (myNet.getCurrentTimeStep() + myOffset % myAbsDuration) % myAbsDuration;
00239 MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
00240 while (offset>=(*i)->duration) {
00241 step++;
00242 offset -= (*i)->duration;
00243 ++i;
00244 }
00245 firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
00246
00247
00248 if (myActiveSubKey=="") {
00249 myActiveSubKey = "default";
00250 }
00251 MSTrafficLightLogic *tlLogic = 0;
00252
00253 if (myLogicType=="actuated") {
00254
00255 tlLogic =
00256 new MSActuatedTrafficLightLogic(getTLLogicControlToUse(),
00257 myActiveKey, myActiveSubKey,
00258 myActivePhases, step, firstEventOffset, myStdActuatedMaxGap,
00259 myStdActuatedPassingTime, myStdActuatedDetectorGap);
00260 } else if (myLogicType=="agentbased") {
00261
00262 tlLogic =
00263 new MSAgentbasedTrafficLightLogic(getTLLogicControlToUse(),
00264 myActiveKey, myActiveSubKey,
00265 myActivePhases, step, firstEventOffset, myStdLearnHorizon,
00266 myStdDecisionHorizon, myStdDeltaLimit, myStdTCycle);
00267 } else {
00268
00269 tlLogic =
00270 new MSSimpleTrafficLightLogic(getTLLogicControlToUse(),
00271 myActiveKey, myActiveSubKey,
00272 myActivePhases, step, firstEventOffset);
00273 tlLogic->setParameter(myAdditionalParameter);
00274 }
00275 TLInitInfo ii;
00276 ii.logic = tlLogic;
00277 ii.params = myAdditionalParameter;
00278 ii.params["detector_offset"] = toString(myDetectorOffset);
00279 myJunctions2PostLoadInit.push_back(ii);
00280 myActivePhases.clear();
00281 if (tlLogic!=0) {
00282 try {
00283 if (!getTLLogicControlToUse().add(myActiveKey, myActiveSubKey, tlLogic)) {
00284 throw InvalidArgument("Another logic with id '" + myActiveKey + "' and subid '" + myActiveSubKey + "' exists.");
00285 }
00286 } catch (InvalidArgument &) {
00287 delete tlLogic;
00288 throw;
00289 }
00290 }
00291 }
00292
00293
00294 void
00295 NLJunctionControlBuilder::initJunctionLogic(const std::string &id, int requestSize, int laneNumber) throw() {
00296 myActiveKey = id;
00297 myActiveSubKey = "";
00298 myActiveLogic = new MSBitsetLogic::Logic();
00299 myActiveFoes = new MSBitsetLogic::Foes();
00300 myActiveConts.reset();
00301 myRequestSize = requestSize;
00302 myLaneNumber = laneNumber;
00303 myRequestItemNumber = 0;
00304 myCurrentHasError = false;
00305 if (myRequestSize>0) {
00306 myActiveLogic->resize(myRequestSize);
00307 myActiveFoes->resize(myRequestSize);
00308 }
00309 }
00310
00311
00312 void
00313 NLJunctionControlBuilder::addLogicItem(int request,
00314 const std::string &response,
00315 const std::string &foes,
00316 bool cont) throw(InvalidArgument) {
00317 if (myCurrentHasError) {
00318
00319 return;
00320 }
00321 if (request>63) {
00322
00323 myCurrentHasError = true;
00324 throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
00325 }
00326 if (myRequestSize<=0) {
00327 throw InvalidArgument("The request size, the response size or the number of lanes is not given! Contact your net supplier");
00328 }
00329
00330 std::bitset<64> use(response);
00331 assert(myActiveLogic->size()>(size_t) request);
00332 (*myActiveLogic)[request] = use;
00333
00334 std::bitset<64> use2(foes);
00335 assert(myActiveFoes->size()>(size_t) request);
00336 (*myActiveFoes)[request] = use2;
00337
00338 myActiveConts.set(request, cont);
00339
00340 myRequestItemNumber++;
00341 }
00342
00343
00344 void
00345 NLJunctionControlBuilder::initTrafficLightLogic(const std::string &id, const std::string &programID,
00346 const std::string &type, int offset, SUMOReal detectorOffset) throw() {
00347 myActiveKey = id;
00348 myActiveSubKey = programID;
00349 myActivePhases.clear();
00350 myAbsDuration = 0;
00351 myRequestSize = -1;
00352 initIncomingLanes();
00353 myLogicType = type;
00354 myDetectorOffset = detectorOffset;
00355 myOffset = offset;
00356 myAdditionalParameter.clear();
00357 if (myDetectorOffset==-1) {
00358
00359 if (myLogicType=="agentbased") {
00360 myDetectorOffset = myStdDetectorLengths;
00361 }
00362
00363 if (myLogicType=="actuated") {
00364 myDetectorOffset = myStdDetectorPositions;
00365 }
00366 }
00367 }
00368
00369
00370 void
00371 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string &state,
00372 int minDuration, int maxDuration) throw() {
00373
00374 myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
00375
00376 myAbsDuration += duration;
00377 }
00378
00379
00380 void
00381 NLJunctionControlBuilder::setRequestSize(int size) throw() {
00382
00383 myRequestSize = size;
00384 myActiveLogic->resize(myRequestSize);
00385 myActiveFoes->resize(myRequestSize);
00386 }
00387
00388
00389
00390 void
00391 NLJunctionControlBuilder::setLaneNumber(int val) throw() {
00392
00393 myLaneNumber = val;
00394 }
00395
00396
00397 void
00398 NLJunctionControlBuilder::setOffset(int val) throw() {
00399
00400 myOffset = val;
00401 }
00402
00403
00404 void
00405 NLJunctionControlBuilder::setKey(const std::string &key) throw() {
00406
00407 myActiveKey = key;
00408 }
00409
00410
00411 void
00412 NLJunctionControlBuilder::setSubKey(const std::string &subkey) throw() {
00413
00414 myActiveSubKey = subkey;
00415 }
00416
00417
00418 void
00419 NLJunctionControlBuilder::closeJunctionLogic() throw(InvalidArgument) {
00420 if (myCurrentHasError) {
00421
00422 return;
00423 }
00424 if (myRequestItemNumber!=myRequestSize) {
00425 throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
00426 }
00427 MSJunctionLogic *logic =
00428 new MSBitsetLogic(myRequestSize, myLaneNumber, myActiveLogic, myActiveFoes, myActiveConts);
00429 if (myLogics.find(myActiveKey)!=myLogics.end()) {
00430 throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
00431 }
00432 myLogics[myActiveKey] = logic;
00433 }
00434
00435
00436 void
00437 NLJunctionControlBuilder::closeJunctions(NLDetectorBuilder &db) throw() {
00438 for (std::vector<TLInitInfo>::iterator i=myJunctions2PostLoadInit.begin(); i!=myJunctions2PostLoadInit.end(); i++) {
00439 (*i).logic->setParameter((*i).params);
00440 (*i).logic->init(db);
00441 }
00442 }
00443
00444
00445 MSTLLogicControl *
00446 NLJunctionControlBuilder::buildTLLogics() const throw(ProcessError) {
00447 if (!myLogicControl->closeNetworkReading()) {
00448 throw ProcessError("Traffic lights could not be built.");
00449 }
00450 MSTLLogicControl *ret = myLogicControl;
00451 myLogicControl = 0;
00452 return ret;
00453 }
00454
00455
00456 void
00457 NLJunctionControlBuilder::addParam(const std::string &key,
00458 const std::string &value) throw() {
00459 myAdditionalParameter[key] = value;
00460 }
00461
00462
00463 MSTLLogicControl &
00464 NLJunctionControlBuilder::getTLLogicControlToUse() const throw() {
00465 if (myLogicControl!=0) {
00466 return *myLogicControl;
00467 }
00468 return myNet.getTLSControl();
00469 }
00470
00471
00472 const std::string &
00473 NLJunctionControlBuilder::getActiveID() const throw() {
00474 return myActiveID;
00475 }
00476
00477
00478 const std::string &
00479 NLJunctionControlBuilder::getActiveKey() const throw() {
00480 return myActiveKey;
00481 }
00482
00483
00484 const std::string &
00485 NLJunctionControlBuilder::getActiveSubKey() const throw() {
00486 return myActiveSubKey;
00487 }
00488
00489
00490