MSEmitControl.cpp
Go to the documentation of this file.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 <iostream>
00031 #include <algorithm>
00032 #include <cassert>
00033 #include "MSEmitControl.h"
00034 #include "MSVehicle.h"
00035 #include "MSLane.h"
00036
00037 #ifdef CHECK_MEMORY_LEAKS
00038 #include <foreign/nvwa/debug_new.h>
00039 #endif // CHECK_MEMORY_LEAKS
00040
00041
00042
00043
00044
00045 MSEmitControl::MSEmitControl(MSVehicleControl &vc,
00046 SUMOTime maxDepartDelay,
00047 bool checkEdgesOnce) throw()
00048 : myVehicleControl(vc), myMaxDepartDelay(maxDepartDelay),
00049 myCheckEdgesOnce(checkEdgesOnce) {}
00050
00051
00052 MSEmitControl::~MSEmitControl() throw() {
00053 for (std::vector<Flow>::iterator i=myFlows.begin(); i!=myFlows.end(); ++i) {
00054 delete(i->pars);
00055 }
00056 }
00057
00058
00059 void
00060 MSEmitControl::add(MSVehicle *veh) throw() {
00061 myAllVeh.add(veh);
00062 }
00063
00064
00065 void
00066 MSEmitControl::add(SUMOVehicleParameter *pars) throw() {
00067 Flow flow;
00068 flow.pars = pars;
00069 flow.isVolatile = pars->departLaneProcedure==DEPART_LANE_RANDOM ||
00070 pars->departPosProcedure==DEPART_POS_RANDOM ||
00071 MSNet::getInstance()->getVehicleControl().hasVTypeDistribution(pars->vtypeid);
00072 if (!flow.isVolatile) {
00073 RandomDistributor<const MSRoute*> *dist = MSRoute::distDictionary(pars->routeid);
00074 if (dist != 0) {
00075 const std::vector<const MSRoute*>& routes = dist->getVals();
00076 const MSEdge* e = 0;
00077 for (std::vector<const MSRoute*>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
00078 if (e == 0) {
00079 e = (*i)->getEdges()[0];
00080 } else {
00081 if (e != (*i)->getEdges()[0]) {
00082 flow.isVolatile = true;
00083 break;
00084 }
00085 }
00086 }
00087 }
00088 }
00089 flow.vehicle = 0;
00090 myFlows.push_back(flow);
00091 }
00092
00093
00094 unsigned int
00095 MSEmitControl::emitVehicles(SUMOTime time) throw(ProcessError) {
00096 checkPrevious(time);
00097
00098 if (!myAllVeh.anyWaitingFor(time)&&myRefusedEmits1.empty()&&myRefusedEmits2.empty()&&myFlows.empty()) {
00099 return 0;
00100 }
00101 unsigned int noEmitted = 0;
00102
00103
00104
00105
00106 assert(myRefusedEmits1.size()==0||myRefusedEmits2.size()==0);
00107 MSVehicleContainer::VehicleVector &refusedEmits =
00108 myRefusedEmits1.size()==0 ? myRefusedEmits1 : myRefusedEmits2;
00109 MSVehicleContainer::VehicleVector &previousRefused =
00110 myRefusedEmits2.size()==0 ? myRefusedEmits1 : myRefusedEmits2;
00111
00112
00113 MSVehicleContainer::VehicleVector::const_iterator veh;
00114 for (veh=previousRefused.begin(); veh!=previousRefused.end(); veh++) {
00115 noEmitted += tryEmit(time, *veh, refusedEmits);
00116 }
00117
00118 previousRefused.clear();
00119
00120
00121
00122
00123
00124 noEmitted += checkFlows(time, refusedEmits);
00125 while (myAllVeh.anyWaitingFor(time)) {
00126 const MSVehicleContainer::VehicleVector &next = myAllVeh.top();
00127
00128 for (veh=next.begin(); veh!=next.end(); veh++) {
00129 noEmitted += tryEmit(time, *veh, refusedEmits);
00130 }
00131
00132 myAllVeh.pop();
00133 }
00134
00135 return noEmitted;
00136 }
00137
00138
00139 unsigned int
00140 MSEmitControl::tryEmit(SUMOTime time, MSVehicle *veh,
00141 MSVehicleContainer::VehicleVector &refusedEmits) throw(ProcessError) {
00142 assert(veh->getDesiredDepart() <= time);
00143 veh->onTryEmit();
00144 const MSEdge &edge = veh->getDepartEdge();
00145 if ((!myCheckEdgesOnce || edge.getLastFailedEmissionTime()!=time) && edge.emit(*veh, time)) {
00146
00147 checkFlowWait(veh);
00148 veh->onDepart();
00149 return 1;
00150 }
00151 if (myMaxDepartDelay != -1 && time - veh->getDesiredDepart() > myMaxDepartDelay) {
00152
00153 checkFlowWait(veh);
00154 myVehicleControl.deleteVehicle(veh);
00155 } else if (edge.isVaporizing()) {
00156
00157 checkFlowWait(veh);
00158 veh->setWasVaporized(true);
00159 myVehicleControl.deleteVehicle(veh);
00160 } else {
00161
00162 refusedEmits.push_back(veh);
00163 }
00164 edge.setLastFailedEmissionTime(time);
00165 return 0;
00166 }
00167
00168
00169 void
00170 MSEmitControl::checkFlowWait(MSVehicle *veh) throw() {
00171 for (std::vector<Flow>::iterator i=myFlows.begin(); i!=myFlows.end(); ++i) {
00172 if (i->vehicle == veh) {
00173 i->vehicle = 0;
00174 break;
00175 }
00176 }
00177 }
00178
00179
00180 void
00181 MSEmitControl::checkPrevious(SUMOTime time) throw() {
00182
00183 MSVehicleContainer::VehicleVector &previousRefused =
00184 myRefusedEmits2.size()==0 ? myRefusedEmits1 : myRefusedEmits2;
00185 while (!myAllVeh.isEmpty()&&myAllVeh.topTime()<time) {
00186 const MSVehicleContainer::VehicleVector &top = myAllVeh.top();
00187 copy(top.begin(), top.end(), back_inserter(previousRefused));
00188 myAllVeh.pop();
00189 }
00190 }
00191
00192
00193 unsigned int
00194 MSEmitControl::checkFlows(SUMOTime time,
00195 MSVehicleContainer::VehicleVector &refusedEmits) throw(ProcessError) {
00196 unsigned int noEmitted = 0;
00197 for (std::vector<Flow>::iterator i=myFlows.begin(); i!=myFlows.end();) {
00198 SUMOVehicleParameter* pars = i->pars;
00199 if (!i->isVolatile && i->vehicle!=0) {
00200 ++i;
00201 continue;
00202 }
00203 while (pars->repetitionsDone < pars->repetitionNumber &&
00204 pars->depart + pars->repetitionsDone * pars->repetitionOffset < time + DELTA_T) {
00205 SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
00206 newPars->id = pars->id + "." + toString(pars->repetitionsDone);
00207 newPars->depart = (SUMOTime)(pars->depart + pars->repetitionsDone * pars->repetitionOffset);
00208 pars->repetitionsDone++;
00209
00210 if (MSNet::getInstance()->getVehicleControl().getVehicle(newPars->id)==0) {
00211 const MSRoute *route = MSRoute::dictionary(pars->routeid);
00212 const MSVehicleType *vtype = MSNet::getInstance()->getVehicleControl().getVType(pars->vtypeid);
00213 i->vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(newPars, route, vtype);
00214 MSNet::getInstance()->getVehicleControl().addVehicle(newPars->id, i->vehicle);
00215 noEmitted += tryEmit(time, i->vehicle, refusedEmits);
00216 if (!i->isVolatile && i->vehicle!=0) {
00217 break;
00218 }
00219 } else {
00220
00221 #ifdef HAVE_MESOSIM
00222 if (MSGlobals::gStateLoaded) {
00223 break;
00224 }
00225 #endif
00226 throw ProcessError("Another vehicle with the id '" + newPars->id + "' exists.");
00227 }
00228 }
00229 if (pars->repetitionsDone == pars->repetitionNumber) {
00230 i = myFlows.erase(i);
00231 delete(pars);
00232 } else {
00233 ++i;
00234 }
00235 }
00236 return noEmitted;
00237 }
00238
00239
00240 unsigned int
00241 MSEmitControl::getWaitingVehicleNo() const throw() {
00242 return (unsigned int)(myRefusedEmits1.size() + myRefusedEmits2.size());
00243 }
00244
00245
00246 bool
00247 MSEmitControl::hasPendingFlows() const throw() {
00248 return !myFlows.empty();
00249 }
00250
00251
00252
00253