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 "MSCORN.h"
00031 #include "MSVehicleControl.h"
00032 #include "MSVehicle.h"
00033 #include "MSGlobals.h"
00034 #include "MSLane.h"
00035 #include <microsim/devices/MSDevice.h>
00036 #include <utils/common/FileHelpers.h>
00037 #include <utils/common/RGBColor.h>
00038 #include <utils/common/SUMOVTypeParameter.h>
00039 #include <utils/options/OptionsCont.h>
00040 #include <utils/iodevices/BinaryInputDevice.h>
00041 #include <utils/iodevices/OutputDevice.h>
00042
00043 #ifdef HAVE_MESOSIM
00044 #include <mesosim/MELoop.h>
00045 #endif
00046
00047 #ifdef CHECK_MEMORY_LEAKS
00048 #include <foreign/nvwa/debug_new.h>
00049 #endif // CHECK_MEMORY_LEAKS
00050
00051
00052
00053
00054
00055 MSVehicleControl::MSVehicleControl() throw()
00056 : myLoadedVehNo(0), myRunningVehNo(0), myEndedVehNo(0),
00057 myAbsVehWaitingTime(0), myAbsVehTravelTime(0),
00058 myDefaultVTypeMayBeDeleted(true) {
00059 SUMOVTypeParameter defType;
00060 myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
00061 }
00062
00063
00064 MSVehicleControl::~MSVehicleControl() throw() {
00065
00066 for (VehicleDictType::iterator i=myVehicleDict.begin(); i!=myVehicleDict.end(); ++i) {
00067 delete(*i).second;
00068 }
00069 myVehicleDict.clear();
00070
00071 for (VTypeDistDictType::iterator i=myVTypeDistDict.begin(); i!=myVTypeDistDict.end(); ++i) {
00072 delete(*i).second;
00073 }
00074 myVTypeDistDict.clear();
00075
00076 for (VTypeDictType::iterator i=myVTypeDict.begin(); i!=myVTypeDict.end(); ++i) {
00077 delete(*i).second;
00078 }
00079 myVTypeDict.clear();
00080 }
00081
00082
00083 MSVehicle *
00084 MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
00085 const MSRoute* route,
00086 const MSVehicleType* type) throw(ProcessError) {
00087 myLoadedVehNo++;
00088 MSVehicle *built = new MSVehicle(defs, route, type, myLoadedVehNo-1);
00089 MSNet::getInstance()->informVehicleStateListener(built, MSNet::VEHICLE_STATE_BUILT);
00090 return built;
00091 }
00092
00093
00094 void
00095 MSVehicleControl::scheduleVehicleRemoval(MSVehicle *v) throw() {
00096 assert(myRunningVehNo>0);
00097
00098 if (MSCORN::wished(MSCORN::CORN_OUT_TRIPDURATIONS)) {
00099 OutputDevice& od = OutputDevice::getDeviceByOption("tripinfo-output");
00100
00101 MSVehicle::DepartArrivalInformation *departInfo = v->hasCORNPointerValue(MSCORN::CORN_P_VEH_DEPART_INFO)
00102 ? (MSVehicle::DepartArrivalInformation*) v->getCORNPointerValue(MSCORN::CORN_P_VEH_DEPART_INFO)
00103 : 0;
00104 MSVehicle::DepartArrivalInformation *arrivalInfo = v->hasCORNPointerValue(MSCORN::CORN_P_VEH_ARRIVAL_INFO)
00105 ? (MSVehicle::DepartArrivalInformation*) v->getCORNPointerValue(MSCORN::CORN_P_VEH_ARRIVAL_INFO)
00106 : 0;
00107 SUMOReal routeLength = v->getRoute().getLength();
00108
00109 od.openTag("tripinfo") << " id=\"" << v->getID() << "\" ";
00110 SUMOTime departTime = -1;
00111 if (departInfo!=0) {
00112 routeLength -= departInfo->pos;
00113 std::string laneID = departInfo->lane!=0 ? departInfo->lane->getID() : "";
00114 od << "depart=\"" << time2string(departInfo->time) << "\" "
00115 << "departLane=\"" << laneID << "\" "
00116 << "departPos=\"" << departInfo->pos << "\" "
00117 << "departSpeed=\"" << departInfo->speed << "\" "
00118 << "departDelay=\"" << time2string(departInfo->time - v->getDesiredDepart()) << "\" ";
00119 departTime = departInfo->time;
00120 } else {
00121 if (v->hasCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME)) {
00122 departTime = v->getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME);
00123 od << "depart=\"" << time2string(departTime) << "\" ";
00124 } else {
00125 od << "depart=\"\" ";
00126 }
00127 od << "departLane=\"\" "
00128 << "departPos=\"\" "
00129 << "departSpeed=\"\" "
00130 << "departDelay=\"\" ";
00131 }
00132 SUMOTime arrivalTime = -1;
00133 if (arrivalInfo!=0) {
00134 std::string laneID = "";
00135 if (arrivalInfo->lane!=0) {
00136 routeLength -= arrivalInfo->lane->getLength() - arrivalInfo->pos;
00137 laneID = arrivalInfo->lane->getID();
00138 }
00139 od << "arrival=\"" << time2string(arrivalInfo->time) << "\" "
00140 << "arrivalLane=\"" << laneID << "\" "
00141 << "arrivalPos=\"" << arrivalInfo->pos << "\" "
00142 << "arrivalSpeed=\"" << arrivalInfo->speed << "\" ";
00143 arrivalTime = arrivalInfo->time;
00144 } else {
00145 arrivalTime = MSNet::getInstance()->getCurrentTimeStep();
00146 od << "arrival=\"" << time2string(arrivalTime) << "\" "
00147 << "arrivalLane=\"\" "
00148 << "arrivalPos=\"\" "
00149 << "arrivalSpeed=\"\" ";
00150 }
00151 if (departTime!=-1&&arrivalTime!=-1) {
00152 od << "duration=\"" << time2string(arrivalTime - departTime) << "\" ";
00153 } else {
00154 od << "duration=\"\" ";
00155 }
00156 od << "routeLength=\"" << routeLength << "\" "
00157 << "waitSteps=\"" << v->getCORNIntValue(MSCORN::CORN_VEH_WAITINGTIME) << "\" "
00158 << "rerouteNo=\"";
00159 if (v->hasCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE)) {
00160 od << v->getCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE);
00161 } else {
00162 od << '0';
00163 }
00164
00165 const std::vector<MSDevice*> &devices = v->getDevices();
00166 std::string deviceIDs;
00167 if (devices.size()!=0) {
00168 std::ostringstream str;
00169 bool addSem = false;
00170 for (std::vector<MSDevice*>::const_iterator i=devices.begin(); i!=devices.end(); ++i) {
00171 if (addSem) {
00172 str << ' ';
00173 }
00174 addSem = true;
00175 str << (*i)->getID();
00176 }
00177 deviceIDs = str.str();
00178 }
00179
00180 od << "\" devices=\"" << deviceIDs
00181 << "\" vtype=\"" << v->getVehicleType().getID()
00182 << "\" vaporized=\"";
00183 if (v->hasCORNIntValue(MSCORN::CORN_VEH_VAPORIZED)) {
00184 od << v->getCORNIntValue(MSCORN::CORN_VEH_VAPORIZED);
00185 }
00186 od << "\"";
00187
00188 if (devices.size()!=0) {
00189 od << ">\n";
00190 for (std::vector<MSDevice*>::const_iterator i=devices.begin(); i!=devices.end(); ++i) {
00191 (*i)->tripInfoOutput(od);
00192 }
00193 }
00194 od.closeTag(devices.size()==0);
00195 }
00196
00197
00198 if (MSCORN::wished(MSCORN::CORN_OUT_VEHROUTES)) {
00199
00200 MSNet *net = MSNet::getInstance();
00201 OutputDevice& od = OutputDevice::getDeviceByOption("vehroute-output");
00202 SUMOTime realDepart = (SUMOTime) v->getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME);
00203 SUMOTime time = net->getCurrentTimeStep();
00204 od.openTag("vehicle") << " id=\"" << v->getID() << "\" depart=\""
00205 << time2string(v->getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME))
00206 << "\" arrival=\"" << time2string(MSNet::getInstance()->getCurrentTimeStep());
00207 if (MSCORN::wished(MSCORN::CORN_OUT_TAZ)) {
00208 od << "\" fromtaz=\"" << v->getParameter().fromTaz << "\" totaz=\"" << v->getParameter().toTaz;
00209 }
00210 od << "\">\n";
00211 if (MSCORN::wished(MSCORN::CORN_OUT_OLDROUTES) && v->hasCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE)) {
00212 od.openTag("routeDistribution") << ">\n";
00213 int noReroutes = v->getCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE);
00214 for (int i=0; i<noReroutes; ++i) {
00215 v->writeXMLRoute(od, i);
00216 }
00217 }
00218 v->writeXMLRoute(od);
00219 if (MSCORN::wished(MSCORN::CORN_OUT_OLDROUTES) && v->hasCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE)) {
00220 od.closeTag();
00221 }
00222 od.closeTag();
00223 od << "\n";
00224 }
00225
00226 if (MSCORN::wished(MSCORN::CORN_MEAN_VEH_TRAVELTIME)) {
00227 myAbsVehTravelTime +=
00228 (MSNet::getInstance()->getCurrentTimeStep()
00229 - v->getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME));
00230 }
00231 myRunningVehNo--;
00232 MSNet::getInstance()->informVehicleStateListener(v, MSNet::VEHICLE_STATE_ARRIVED);
00233 deleteVehicle(v);
00234 }
00235
00236
00237 SUMOReal
00238 MSVehicleControl::getMeanWaitingTime() const throw() {
00239 if (getEmittedVehicleNo()==0) {
00240 return -1;
00241 }
00242 return (SUMOReal) myAbsVehWaitingTime / (SUMOReal) getEmittedVehicleNo();
00243 }
00244
00245
00246 SUMOReal
00247 MSVehicleControl::getMeanTravelTime() const throw() {
00248 if (myEndedVehNo==0) {
00249 return -1;
00250 }
00251 return (SUMOReal) myAbsVehTravelTime / (SUMOReal) myEndedVehNo;
00252 }
00253
00254
00255 void
00256 MSVehicleControl::vehicleEmitted(const MSVehicle &v) throw() {
00257 ++myRunningVehNo;
00258 if (MSCORN::wished(MSCORN::CORN_MEAN_VEH_WAITINGTIME)) {
00259 myAbsVehWaitingTime += MAX2(v.getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME) - v.getDesiredDepart(), (int) 0);
00260 }
00261 MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VEHICLE_STATE_DEPARTED);
00262 }
00263
00264
00265 #ifdef HAVE_MESOSIM
00266 void
00267 MSVehicleControl::saveState(std::ostream &os) throw() {
00268 FileHelpers::writeUInt(os, myRunningVehNo);
00269 FileHelpers::writeUInt(os, myEndedVehNo);
00270
00271 FileHelpers::writeTime(os, myAbsVehWaitingTime);
00272 FileHelpers::writeTime(os, myAbsVehTravelTime);
00273
00274 FileHelpers::writeUInt(os, (unsigned) myVTypeDict.size());
00275 for (VTypeDictType::iterator it=myVTypeDict.begin(); it!=myVTypeDict.end(); ++it) {
00276 (*it).second->saveState(os);
00277 }
00278 FileHelpers::writeUInt(os, (unsigned) myVTypeDistDict.size());
00279 for (VTypeDistDictType::iterator it=myVTypeDistDict.begin(); it!=myVTypeDistDict.end(); ++it) {
00280 FileHelpers::writeString(os, (*it).first);
00281 const unsigned int size = (unsigned int)(*it).second->getVals().size();
00282 FileHelpers::writeUInt(os, size);
00283 for (unsigned int i = 0; i < size; ++i) {
00284 FileHelpers::writeString(os, (*it).second->getVals()[i]->getID());
00285 FileHelpers::writeFloat(os, (*it).second->getProbs()[i]);
00286 }
00287 }
00288 MSRoute::dict_saveState(os);
00289
00290 FileHelpers::writeUInt(os, (unsigned) myVehicleDict.size());
00291 for (VehicleDictType::iterator it = myVehicleDict.begin(); it!=myVehicleDict.end(); ++it) {
00292 (*it).second->saveState(os);
00293 }
00294 }
00295
00296 void
00297 MSVehicleControl::loadState(BinaryInputDevice &bis) throw() {
00298 const SUMOTime offset = string2time(OptionsCont::getOptions().getString("load-state.offset"));
00299 bis >> myRunningVehNo;
00300 bis >> myEndedVehNo;
00301 myLoadedVehNo = myEndedVehNo;
00302
00303 bis >> myAbsVehWaitingTime;
00304 bis >> myAbsVehTravelTime;
00305
00306
00307 unsigned int size;
00308 bis >> size;
00309 while (size-->0) {
00310 SUMOReal r, g, b;
00311 SUMOVTypeParameter defType;
00312 int vehicleClass, emissionClass, shape;
00313
00314 bis >> defType.id;
00315 bis >> defType.length;
00316 bis >> defType.maxSpeed;
00317 bis >> vehicleClass;
00318 defType.vehicleClass = (SUMOVehicleClass) vehicleClass;
00319 bis >> emissionClass;
00320 defType.emissionClass = (SUMOEmissionClass) emissionClass;
00321 bis >> shape;
00322 defType.shape = (SUMOVehicleShape) shape;
00323 bis >> defType.width;
00324 bis >> defType.offset;
00325 bis >> defType.defaultProbability;
00326 bis >> defType.speedFactor;
00327 bis >> defType.speedDev;
00328 bis >> r;
00329 bis >> g;
00330 bis >> b;
00331 defType.color = RGBColor(r,g,b);
00332 bis >> defType.cfModel;
00333 bis >> defType.lcModel;
00334 MSVehicleType *t = MSVehicleType::build(defType);
00335 addVType(t);
00336 }
00337 unsigned int numVTypeDists;
00338 bis >> numVTypeDists;
00339 for (; numVTypeDists>0; numVTypeDists--) {
00340 std::string id;
00341 bis >> id;
00342 unsigned int no;
00343 bis >> no;
00344 if (getVType(id)==0) {
00345 RandomDistributor<MSVehicleType*> *dist = new RandomDistributor<MSVehicleType*>();
00346 for (; no>0; no--) {
00347 std::string vtypeID;
00348 bis >> vtypeID;
00349 MSVehicleType *t = getVType(vtypeID);
00350 assert(t!=0);
00351 SUMOReal prob;
00352 bis >> prob;
00353 dist->add(prob, t);
00354 }
00355 addVTypeDistribution(id, dist);
00356 } else {
00357 for (; no>0; no--) {
00358 std::string vtypeID;
00359 bis >> vtypeID;
00360 SUMOReal prob;
00361 bis >> prob;
00362 }
00363 }
00364 }
00365 MSRoute::dict_loadState(bis);
00366
00367 bis >> size;
00368 while (size-->0) {
00369 SUMOVehicleParameter* p = new SUMOVehicleParameter();
00370 bis >> p->id;
00371 SUMOReal lastLaneChangeOffset;
00372 bis >> lastLaneChangeOffset;
00373 SUMOReal waitingTime;
00374 bis >> waitingTime;
00375 bis >> p->repetitionNumber;
00376 bis >> p->repetitionOffset;
00377 bis >> p->routeid;
00378 const MSRoute* route;
00379 SUMOTime desiredDepart;
00380 bis >> desiredDepart;
00381 p->depart = desiredDepart - offset;
00382 bis >> p->vtypeid;
00383 const MSVehicleType* type;
00384 unsigned int routeOffset;
00385 bis >> routeOffset;
00386 int wasEmitted;
00387 bis >> wasEmitted;
00388 #ifdef HAVE_MESOSIM
00389 unsigned int segIndex;
00390 bis >> segIndex;
00391 unsigned int queIndex;
00392 bis >> queIndex;
00393 SUMOTime tEvent;
00394 bis >> tEvent;
00395 SUMOTime tLastEntry;
00396 bis >> tLastEntry;
00397 #endif
00398 route = MSRoute::dictionary(p->routeid);
00399 assert(route!=0);
00400 type = getVType(p->vtypeid);
00401 assert(type!=0);
00402 assert(getVehicle(p->id)==0);
00403
00404 MSVehicle *v = buildVehicle(p, route, type);
00405 if (wasEmitted != -1) {
00406 v->myIntCORNMap[MSCORN::CORN_VEH_DEPART_TIME] = wasEmitted;
00407 }
00408 while (routeOffset>0) {
00409 v->myCurrEdge++;
00410 routeOffset--;
00411 }
00412 #ifdef HAVE_MESOSIM
00413 if (MSGlobals::gUseMesoSim) {
00414 v->mySegment = MSGlobals::gMesoNet->getSegmentForEdge(**(v->myCurrEdge));
00415 while (v->mySegment->getIndex()!=segIndex) {
00416 v->mySegment = MSGlobals::gMesoNet->next_segment(v->mySegment, v);
00417 }
00418 v->myQueIndex = queIndex;
00419 v->myEventTime = tEvent - offset;
00420 v->myLastEntryTime = tLastEntry - offset;
00421 }
00422 #endif
00423 if (!addVehicle(p->id, v)) {
00424 MsgHandler::getErrorInstance()->inform("Error: Could not build vehicle " + p->id + "!");
00425 }
00426 }
00427 }
00428 #endif
00429
00430
00431 bool
00432 MSVehicleControl::addVehicle(const std::string &id, MSVehicle *v) throw() {
00433 VehicleDictType::iterator it = myVehicleDict.find(id);
00434 if (it == myVehicleDict.end()) {
00435
00436 myVehicleDict[id] = v;
00437 return true;
00438 }
00439 return false;
00440 }
00441
00442
00443 MSVehicle *
00444 MSVehicleControl::getVehicle(const std::string &id) const throw() {
00445 VehicleDictType::const_iterator it = myVehicleDict.find(id);
00446 if (it == myVehicleDict.end()) {
00447 return 0;
00448 }
00449 return it->second;
00450 }
00451
00452
00453 void
00454 MSVehicleControl::deleteVehicle(MSVehicle *veh) throw() {
00455 myEndedVehNo++;
00456 myVehicleDict.erase(veh->getID());
00457 delete veh;
00458 }
00459
00460
00461 MSVehicleControl::constVehIt
00462 MSVehicleControl::loadedVehBegin() const throw() {
00463 return myVehicleDict.begin();
00464 }
00465
00466
00467 MSVehicleControl::constVehIt
00468 MSVehicleControl::loadedVehEnd() const throw() {
00469 return myVehicleDict.end();
00470 }
00471
00472
00473 bool
00474 MSVehicleControl::checkVType(const std::string &id) throw() {
00475 if (id == DEFAULT_VTYPE_ID) {
00476 if (myDefaultVTypeMayBeDeleted) {
00477 delete myVTypeDict[id];
00478 myVTypeDict.erase(myVTypeDict.find(id));
00479 myDefaultVTypeMayBeDeleted = false;
00480 } else {
00481 return false;
00482 }
00483 } else {
00484 if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
00485 return false;
00486 }
00487 }
00488 return true;
00489 }
00490
00491 bool
00492 MSVehicleControl::addVType(MSVehicleType* vehType) throw() {
00493 if (checkVType(vehType->getID())) {
00494 myVTypeDict[vehType->getID()] = vehType;
00495 return true;
00496 }
00497 return false;
00498 }
00499
00500
00501 bool
00502 MSVehicleControl::addVTypeDistribution(const std::string &id, RandomDistributor<MSVehicleType*> *vehTypeDistribution) throw() {
00503 if (checkVType(id)) {
00504 myVTypeDistDict[id] = vehTypeDistribution;
00505 return true;
00506 }
00507 return false;
00508 }
00509
00510
00511 bool
00512 MSVehicleControl::hasVTypeDistribution(const std::string &id) const throw() {
00513 return myVTypeDistDict.find(id) != myVTypeDistDict.end();
00514 }
00515
00516
00517 MSVehicleType*
00518 MSVehicleControl::getVType(const std::string &id) throw() {
00519 VTypeDictType::iterator it = myVTypeDict.find(id);
00520 if (it == myVTypeDict.end()) {
00521 VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
00522 if (it2 == myVTypeDistDict.end()) {
00523 return 0;
00524 }
00525 return it2->second->get();
00526 }
00527 if (id == DEFAULT_VTYPE_ID) {
00528 myDefaultVTypeMayBeDeleted = false;
00529 }
00530 return it->second;
00531 }
00532
00533
00534 void
00535 MSVehicleControl::insertVTypeIDs(std::vector<std::string> &into) const throw() {
00536 into.reserve(into.size()+myVTypeDict.size()+myVTypeDistDict.size());
00537 for (VTypeDictType::const_iterator i=myVTypeDict.begin(); i!=myVTypeDict.end(); ++i) {
00538 into.push_back((*i).first);
00539 }
00540 for (VTypeDistDictType::const_iterator i=myVTypeDistDict.begin(); i!=myVTypeDistDict.end(); ++i) {
00541 into.push_back((*i).first);
00542 }
00543 }
00544
00545
00546 void
00547 MSVehicleControl::addWaiting(const MSEdge* const edge, MSVehicle *vehicle) throw() {
00548 if (myWaiting.find(edge) == myWaiting.end()) {
00549 myWaiting[edge] = std::vector<MSVehicle*>();
00550 }
00551 myWaiting[edge].push_back(vehicle);
00552 }
00553
00554
00555 void
00556 MSVehicleControl::removeWaiting(const MSEdge* const edge, MSVehicle *vehicle) throw() {
00557 if (myWaiting.find(edge) != myWaiting.end()) {
00558 std::vector<MSVehicle*>::iterator it = std::find(myWaiting[edge].begin(), myWaiting[edge].end(), vehicle);
00559 if (it != myWaiting[edge].end()) {
00560 myWaiting[edge].erase(it);
00561 }
00562 }
00563 }
00564
00565
00566 MSVehicle *
00567 MSVehicleControl::getWaitingVehicle(const MSEdge* const edge, const std::set<std::string> &lines) throw() {
00568 if (myWaiting.find(edge) != myWaiting.end()) {
00569 for (std::vector<MSVehicle*>::const_iterator it = myWaiting[edge].begin(); it != myWaiting[edge].end(); ++it) {
00570 const std::string &line = (*it)->getParameter().line == "" ? (*it)->getParameter().id : (*it)->getParameter().line;
00571 if (lines.count(line)) {
00572 return (*it);
00573 }
00574 }
00575 }
00576 return 0;
00577 }
00578
00579
00580
00581