NLJunctionControlBuilder.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Builder of microsim-junctions and tls
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
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 // method definitions
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     // @deprecated: at some time, all junctions should have a shape attribute (moved from characters)
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     // build the junction
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     // build the junction
00202     return new MSInternalJunction(myActiveID, myPosition, myShape, myActiveIncomingLanes,
00203                                   myActiveInternalLanes);
00204 }
00205 #endif
00206 
00207 
00208 MSJunctionLogic *
00209 NLJunctionControlBuilder::getJunctionLogicSecure() throw(InvalidArgument) {
00210     // get and check the junction logic
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     // compute the initial step and first switch time of the tls-logic
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     // build the tls-logic in dependance to its type
00253     if (myLogicType=="actuated") {
00254         // build an actuated logic
00255         tlLogic =
00256             new MSActuatedTrafficLightLogic(getTLLogicControlToUse(),
00257                                             myActiveKey, myActiveSubKey,
00258                                             myActivePhases, step, firstEventOffset, myStdActuatedMaxGap,
00259                                             myStdActuatedPassingTime, myStdActuatedDetectorGap);
00260     } else if (myLogicType=="agentbased") {
00261         // build an agentbased logic
00262         tlLogic =
00263             new MSAgentbasedTrafficLightLogic(getTLLogicControlToUse(),
00264                                               myActiveKey, myActiveSubKey,
00265                                               myActivePhases, step, firstEventOffset, myStdLearnHorizon,
00266                                               myStdDecisionHorizon, myStdDeltaLimit, myStdTCycle);
00267     } else {
00268         // build a fixed tls-logic
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         // had an error
00319         return;
00320     }
00321     if (request>63) {
00322         // bad request
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     // add the read response for the given request index
00330     std::bitset<64> use(response);
00331     assert(myActiveLogic->size()>(size_t) request);
00332     (*myActiveLogic)[request] = use;
00333     // add the read junction-internal foes for the given request index
00334     std::bitset<64> use2(foes);
00335     assert(myActiveFoes->size()>(size_t) request);
00336     (*myActiveFoes)[request] = use2;
00337     // add whether the vehicle may drive a little bit further
00338     myActiveConts.set(request, cont);
00339     // increse number of set information
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         // agentbased
00359         if (myLogicType=="agentbased") {
00360             myDetectorOffset = myStdDetectorLengths;
00361         }
00362         // actuated
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     // build and add the phase definition to the list
00374     myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
00375     // add phase duration to the absolute duration
00376     myAbsDuration += duration;
00377 }
00378 
00379 
00380 void
00381 NLJunctionControlBuilder::setRequestSize(int size) throw() {
00382     // @deprecated: assuming a net could still use characters for the request size
00383     myRequestSize = size;
00384     myActiveLogic->resize(myRequestSize);
00385     myActiveFoes->resize(myRequestSize);
00386 }
00387 
00388 
00389 
00390 void
00391 NLJunctionControlBuilder::setLaneNumber(int val) throw() {
00392     // @deprecated: assuming a net could still use characters for the lane number
00393     myLaneNumber = val;
00394 }
00395 
00396 
00397 void
00398 NLJunctionControlBuilder::setOffset(int val) throw() {
00399     // @deprecated: assuming a net could still use characters for the offset
00400     myOffset = val;
00401 }
00402 
00403 
00404 void
00405 NLJunctionControlBuilder::setKey(const std::string &key) throw() {
00406     // @deprecated: assuming a net could still use characters for the id
00407     myActiveKey = key;
00408 }
00409 
00410 
00411 void
00412 NLJunctionControlBuilder::setSubKey(const std::string &subkey) throw() {
00413     // @deprecated: assuming a net could still use characters for the sub id
00414     myActiveSubKey = subkey;
00415 }
00416 
00417 
00418 void
00419 NLJunctionControlBuilder::closeJunctionLogic() throw(InvalidArgument) {
00420     if (myCurrentHasError) {
00421         // had an error before...
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 /****************************************************************************/

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6