Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSVehicleControl.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Wed, 10. Dec 2003
19 : ///
20 : // The class responsible for building and deletion of vehicles
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include "MSVehicleControl.h"
25 : #include "MSVehicle.h"
26 : #include "MSLane.h"
27 : #include "MSEdge.h"
28 : #include "MSNet.h"
29 : #include "MSRouteHandler.h"
30 : #include "MSEventControl.h"
31 : #include "MSStop.h"
32 : #include <microsim/devices/MSVehicleDevice.h>
33 : #include <microsim/devices/MSDevice_Tripinfo.h>
34 : #include <utils/common/FileHelpers.h>
35 : #include <utils/common/Named.h>
36 : #include <utils/common/RGBColor.h>
37 : #include <utils/vehicle/SUMOVTypeParameter.h>
38 : #include <utils/iodevices/OutputDevice.h>
39 : #include <utils/options/OptionsCont.h>
40 : #include <utils/router/IntermodalRouter.h>
41 :
42 :
43 : // ===========================================================================
44 : // member method definitions
45 : // ===========================================================================
46 42780 : MSVehicleControl::MSVehicleControl() :
47 42780 : myLoadedVehNo(0),
48 42780 : myRunningVehNo(0),
49 42780 : myEndedVehNo(0),
50 42780 : myDiscarded(0),
51 42780 : myCollisions(0),
52 42780 : myTeleportsCollision(0),
53 42780 : myTeleportsJam(0),
54 42780 : myTeleportsYield(0),
55 42780 : myTeleportsWrongLane(0),
56 42780 : myEmergencyStops(0),
57 42780 : myEmergencyBrakingCount(0),
58 42780 : myStoppedVehicles(0),
59 42780 : myTotalDepartureDelay(0),
60 42780 : myTotalTravelTime(0),
61 42780 : myWaitingForTransportable(0),
62 42780 : myMaxSpeedFactor(1),
63 42780 : myMinDeceleration(SUMOVTypeParameter::getDefaultDecel(SVC_IGNORING)),
64 42780 : myMinDecelerationRail(SUMOVTypeParameter::getDefaultDecel(SVC_RAIL)),
65 42780 : myMaxMinGap(0),
66 85560 : myPendingRemovals(MSGlobals::gNumSimThreads > 1) {
67 :
68 42780 : initDefaultTypes();
69 42780 : myScale = OptionsCont::getOptions().getFloat("scale");
70 42780 : myKeepTime = string2time(OptionsCont::getOptions().getString("keep-after-arrival"));
71 42780 : }
72 :
73 :
74 71579 : MSVehicleControl::~MSVehicleControl() {
75 42167 : clearState(false);
76 71579 : }
77 :
78 :
79 : void
80 42944 : MSVehicleControl::initDefaultTypes() {
81 42944 : SUMOVTypeParameter defType(DEFAULT_VTYPE_ID, SVC_PASSENGER);
82 42944 : myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
83 :
84 42944 : SUMOVTypeParameter defPedType(DEFAULT_PEDTYPE_ID, SVC_PEDESTRIAN);
85 42944 : defPedType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
86 42944 : myVTypeDict[DEFAULT_PEDTYPE_ID] = MSVehicleType::build(defPedType);
87 :
88 42944 : SUMOVTypeParameter defBikeType(DEFAULT_BIKETYPE_ID, SVC_BICYCLE);
89 42944 : defBikeType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
90 42944 : myVTypeDict[DEFAULT_BIKETYPE_ID] = MSVehicleType::build(defBikeType);
91 :
92 42944 : SUMOVTypeParameter defTaxiType(DEFAULT_TAXITYPE_ID, SVC_TAXI);
93 42944 : defTaxiType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
94 42944 : myVTypeDict[DEFAULT_TAXITYPE_ID] = MSVehicleType::build(defTaxiType);
95 :
96 42944 : SUMOVTypeParameter defRailType(DEFAULT_RAILTYPE_ID, SVC_RAIL);
97 42944 : defRailType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
98 42944 : myVTypeDict[DEFAULT_RAILTYPE_ID] = MSVehicleType::build(defRailType);
99 :
100 42944 : SUMOVTypeParameter defContainerType(DEFAULT_CONTAINERTYPE_ID, SVC_CONTAINER);
101 42944 : defContainerType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
102 42944 : myVTypeDict[DEFAULT_CONTAINERTYPE_ID] = MSVehicleType::build(defContainerType);
103 :
104 : myReplaceableDefaultVTypes = DEFAULT_VTYPES;
105 42944 : }
106 :
107 :
108 : SUMOVehicle*
109 3875563 : MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
110 : ConstMSRoutePtr route, MSVehicleType* type,
111 : const bool ignoreStopErrors, const VehicleDefinitionSource source, bool addRouteStops) {
112 3980663 : const double speedFactor = type->computeChosenSpeedDeviation(defs->speedFactor, source == VehicleDefinitionSource::ROUTEFILE ? MSRouteHandler::getParsingRNG() : nullptr);
113 7751126 : MSVehicle* built = new MSVehicle(defs, route, type, speedFactor);
114 3875563 : initVehicle(built, ignoreStopErrors, addRouteStops, source);
115 3875507 : return built;
116 : }
117 :
118 :
119 : void
120 5414190 : MSVehicleControl::initVehicle(MSBaseVehicle* built, const bool ignoreStopErrors, bool addRouteStops, const VehicleDefinitionSource source) {
121 5414190 : myLoadedVehNo++;
122 : try {
123 5414190 : built->initDevices();
124 5414151 : if (source != VehicleDefinitionSource::STATE) {
125 5409233 : built->addStops(ignoreStopErrors, nullptr, addRouteStops);
126 : }
127 116 : } catch (ProcessError&) {
128 116 : delete built;
129 116 : throw;
130 116 : }
131 5414073 : MSNet::getInstance()->informVehicleStateListener(built, MSNet::VehicleState::BUILT);
132 5414073 : }
133 :
134 :
135 : void
136 4153759 : MSVehicleControl::scheduleVehicleRemoval(SUMOVehicle* veh, bool checkDuplicate) {
137 : assert(myRunningVehNo > 0);
138 4153759 : if (!checkDuplicate || !isPendingRemoval(veh)) {
139 4153759 : myPendingRemovals.push_back(veh);
140 : }
141 4153759 : }
142 :
143 :
144 : bool
145 17549 : MSVehicleControl::isPendingRemoval(SUMOVehicle* veh) {
146 : #ifdef HAVE_FOX
147 17549 : return myPendingRemovals.contains(veh);
148 : #else
149 : return std::find(myPendingRemovals.begin(), myPendingRemovals.end(), veh) == myPendingRemovals.end();
150 : #endif
151 : }
152 :
153 :
154 : void
155 106797285 : MSVehicleControl::removePending() {
156 123883496 : OutputDevice* const tripinfoOut = OptionsCont::getOptions().isSet("tripinfo-output") ? &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr;
157 : #ifdef HAVE_FOX
158 : std::vector<SUMOVehicle*>& vehs = myPendingRemovals.getContainer();
159 : #else
160 : std::vector<SUMOVehicle*>& vehs = myPendingRemovals;
161 : #endif
162 106797285 : std::sort(vehs.begin(), vehs.end(), ComparatorNumericalIdLess());
163 110951040 : for (SUMOVehicle* const veh : vehs) {
164 4153755 : myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
165 4153755 : myRunningVehNo--;
166 4153755 : MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VehicleState::ARRIVED);
167 : // vehicle is equipped with tripinfo device (not all vehicles are)
168 4153755 : const bool hasTripinfo = veh->getDevice(typeid(MSDevice_Tripinfo)) != nullptr;
169 7335032 : for (MSVehicleDevice* const dev : veh->getDevices()) {
170 3897975 : dev->generateOutput(hasTripinfo ? tripinfoOut : nullptr);
171 : }
172 4153755 : if (tripinfoOut != nullptr && hasTripinfo) {
173 : // close tag after tripinfo (possibly including emissions from another device) have been written
174 481584 : tripinfoOut->closeTag();
175 : }
176 4153755 : if (myKeepTime == 0) {
177 4153741 : deleteVehicle(veh);
178 : } else {
179 14 : deleteKeptVehicle(veh);
180 : }
181 : }
182 : vehs.clear();
183 106797285 : if (tripinfoOut != nullptr) {
184 : // there seem to be people who think reading an unfinished xml is a good idea ;-)
185 : tripinfoOut->flush();
186 : }
187 : #ifdef HAVE_FOX
188 : myPendingRemovals.unlock();
189 : #endif
190 106797285 : }
191 :
192 :
193 : void
194 18 : MSVehicleControl::deleteKeptVehicle(SUMOVehicle* veh) {
195 18 : myEndedVehNo++;
196 18 : MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(new DeleteKeptVehicle(veh), SIMSTEP + myKeepTime);
197 18 : }
198 :
199 : void
200 4304367 : MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) {
201 4304367 : ++myRunningVehNo;
202 4304367 : myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart));
203 4304367 : MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VehicleState::DEPARTED);
204 4304367 : myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor());
205 4304367 : myMaxMinGap = MAX2(myMaxMinGap, v.getVehicleType().getMinGap());
206 4304367 : const double maxDecel = v.getVehicleType().getCarFollowModel().getMaxDecel();
207 4304367 : if ((v.getVClass() & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) {
208 : // only worry about deceleration of road users
209 8390411 : myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
210 8097 : } else if ((v.getVClass() & SVC_RAIL_CLASSES) != 0) {
211 7779 : myMinDecelerationRail = MIN2(myMinDecelerationRail, maxDecel);
212 7779 : if ((v.getEdge()->getPermissions() & SVC_ROAD_MOTOR_CLASSES) != 0) {
213 : // shared rail/road
214 956 : myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
215 : }
216 : }
217 4304367 : }
218 :
219 :
220 : void
221 457 : MSVehicleControl::setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime, double maxSpeedFactor, double minDecel) {
222 457 : myRunningVehNo = runningVehNo;
223 457 : myLoadedVehNo = loadedVehNo;
224 457 : myEndedVehNo = endedVehNo;
225 457 : myTotalDepartureDelay = totalDepartureDelay;
226 457 : myTotalTravelTime = totalTravelTime;
227 457 : myMaxSpeedFactor = maxSpeedFactor;
228 457 : myMinDeceleration = minDecel;
229 457 : }
230 :
231 :
232 : void
233 536 : MSVehicleControl::saveState(OutputDevice& out) {
234 536 : out.openTag(SUMO_TAG_DELAY);
235 536 : out.writeAttr(SUMO_ATTR_NUMBER, myRunningVehNo);
236 536 : out.writeAttr(SUMO_ATTR_BEGIN, myLoadedVehNo);
237 536 : out.writeAttr(SUMO_ATTR_END, myEndedVehNo);
238 536 : out.writeAttr(SUMO_ATTR_DEPART, myTotalDepartureDelay);
239 536 : out.writeAttr(SUMO_ATTR_TIME, myTotalTravelTime);
240 536 : out.writeAttr(SUMO_ATTR_SPEEDFACTOR, myMaxSpeedFactor);
241 536 : out.writeAttr(SUMO_ATTR_DECEL, myMinDeceleration);
242 536 : const SUMOTime loaderTime = MSNet::getInstance()->getLoaderTime();
243 536 : if (loaderTime > 0 && loaderTime != SUMOTime_MAX) {
244 35 : out.writeAttr(SUMO_ATTR_LOADERTIME, MSNet::getInstance()->getLoaderTime());
245 : }
246 1072 : out.closeTag();
247 : // save vehicle types
248 4585 : for (const auto& item : myVTypeDict) {
249 4049 : if (myReplaceableDefaultVTypes.count(item.first) == 0) {
250 1097 : item.second->getParameter().write(out);
251 : }
252 : }
253 718 : for (const auto& item : myVTypeDistDict) {
254 182 : out.openTag(SUMO_TAG_VTYPE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, item.first);
255 182 : out.writeAttr(SUMO_ATTR_VTYPES, item.second->getVals());
256 182 : out.writeAttr(SUMO_ATTR_PROBS, item.second->getProbs());
257 364 : out.closeTag();
258 : }
259 : std::vector<SUMOVehicle*> sortedVehs;
260 5007 : for (const auto& item : myVehicleDict) {
261 4471 : sortedVehs.push_back(item.second);
262 : }
263 536 : std::sort(sortedVehs.begin(), sortedVehs.end(), ComparatorNumericalIdLess());
264 5007 : for (SUMOVehicle* veh : sortedVehs) {
265 4471 : veh->saveState(out);
266 : }
267 536 : }
268 :
269 :
270 : void
271 42331 : MSVehicleControl::clearState(const bool reinit) {
272 357892 : for (const auto& item : myVehicleDict) {
273 315561 : delete item.second;
274 : }
275 : myVehicleDict.clear();
276 : // delete vehicle type distributions
277 42830 : for (const auto& item : myVTypeDistDict) {
278 998 : delete item.second;
279 : }
280 : myVTypeDistDict.clear();
281 : // delete vehicle types
282 347895 : for (const auto& item : myVTypeDict) {
283 305564 : delete item.second;
284 : }
285 : myVTypeDict.clear();
286 42331 : myPendingRemovals.clear(); // could be leftovers from MSVehicleTransfer::checkInsertions (teleport beyond arrival)
287 42331 : if (reinit) {
288 164 : initDefaultTypes();
289 : }
290 42331 : myLoadedVehNo = 0;
291 42331 : myRunningVehNo = 0;
292 42331 : myEndedVehNo = 0;
293 42331 : myDiscarded = 0;
294 42331 : myCollisions = 0;
295 42331 : myTeleportsCollision = 0;
296 42331 : myTeleportsJam = 0;
297 42331 : myTeleportsYield = 0;
298 42331 : myTeleportsWrongLane = 0;
299 42331 : myEmergencyStops = 0;
300 42331 : myEmergencyBrakingCount = 0;
301 42331 : myStoppedVehicles = 0;
302 42331 : myTotalDepartureDelay = 0;
303 42331 : myTotalTravelTime = 0;
304 42331 : }
305 :
306 :
307 : bool
308 5308331 : MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
309 : VehicleDictType::iterator it = myVehicleDict.find(id);
310 5308331 : if (it == myVehicleDict.end()) {
311 : // id not in myVehicleDict.
312 5308331 : myVehicleDict[id] = v;
313 5308331 : handleTriggeredDepart(v, true);
314 5308331 : const SUMOVehicleParameter& pars = v->getParameter();
315 5308331 : if (v->getVClass() != SVC_TAXI && pars.line != "" && pars.repetitionNumber < 0) {
316 1155 : myPTVehicles.push_back(v);
317 : }
318 5308331 : return true;
319 : }
320 : return false;
321 : }
322 :
323 :
324 : void
325 5312839 : MSVehicleControl::handleTriggeredDepart(SUMOVehicle* v, bool add) {
326 5312839 : const SUMOVehicleParameter& pars = v->getParameter();
327 5312839 : if (pars.departProcedure == DepartDefinition::TRIGGERED || pars.departProcedure == DepartDefinition::CONTAINER_TRIGGERED || pars.departProcedure == DepartDefinition::SPLIT) {
328 4296 : const MSEdge* const firstEdge = v->getRoute().getEdges()[pars.departEdge];
329 4296 : if (add) {
330 2213 : if (!MSGlobals::gUseMesoSim) {
331 : // position will be checked against person position later
332 1804 : static_cast<MSVehicle*>(v)->setTentativeLaneAndPosition(nullptr, v->getParameter().departPos);
333 : }
334 2213 : if (firstEdge->isTazConnector()) {
335 78 : for (MSEdge* out : firstEdge->getSuccessors()) {
336 51 : out->addWaiting(v);
337 : }
338 : } else {
339 2186 : firstEdge->addWaiting(v);
340 : }
341 : registerOneWaiting();
342 : } else {
343 2083 : if (firstEdge->isTazConnector()) {
344 14 : for (MSEdge* out : firstEdge->getSuccessors()) {
345 7 : out->removeWaiting(v);
346 : }
347 : } else {
348 2076 : firstEdge->removeWaiting(v);
349 : }
350 : unregisterOneWaiting();
351 : }
352 : }
353 5312839 : }
354 :
355 :
356 : SUMOVehicle*
357 22724117 : MSVehicleControl::getVehicle(const std::string& id) const {
358 : VehicleDictType::const_iterator it = myVehicleDict.find(id);
359 22724117 : if (it == myVehicleDict.end()) {
360 : return nullptr;
361 : }
362 17219970 : return it->second;
363 : }
364 :
365 :
366 : void
367 5098433 : MSVehicleControl::deleteVehicle(SUMOVehicle* veh, bool discard, bool wasKept) {
368 5098433 : if (!wasKept) {
369 5098419 : myEndedVehNo++;
370 5098419 : if (discard) {
371 944678 : myDiscarded++;
372 : }
373 : }
374 5098433 : if (veh != nullptr) {
375 : myVehicleDict.erase(veh->getID());
376 : }
377 5098433 : auto ptVehIt = std::find(myPTVehicles.begin(), myPTVehicles.end(), veh);
378 5098433 : if (ptVehIt != myPTVehicles.end()) {
379 945 : myPTVehicles.erase(ptVehIt);
380 : }
381 5098433 : delete veh;
382 5098433 : }
383 :
384 :
385 : bool
386 64059 : MSVehicleControl::checkVType(const std::string& id) {
387 64059 : if (myReplaceableDefaultVTypes.erase(id) > 0) {
388 10199 : delete myVTypeDict[id];
389 : myVTypeDict.erase(myVTypeDict.find(id));
390 : } else {
391 53860 : if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
392 194 : return false;
393 : }
394 : }
395 : return true;
396 : }
397 :
398 :
399 : bool
400 63560 : MSVehicleControl::addVType(MSVehicleType* vehType) {
401 63560 : if (checkVType(vehType->getID())) {
402 63366 : myVTypeDict[vehType->getID()] = vehType;
403 63366 : return true;
404 : }
405 : return false;
406 : }
407 :
408 :
409 : void
410 1436 : MSVehicleControl::removeVType(const MSVehicleType* vehType) {
411 : assert(vehType != nullptr);
412 : assert(myVTypeDict.find(vehType->getID()) != myVTypeDict.end());
413 : myVTypeDict.erase(vehType->getID());
414 1436 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
415 : myVTypeToDist.erase(vehType->getID());
416 : }
417 1436 : delete vehType;
418 1436 : }
419 :
420 :
421 : bool
422 499 : MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
423 499 : if (checkVType(id)) {
424 499 : myVTypeDistDict[id] = vehTypeDistribution;
425 499 : std::vector<MSVehicleType*> vehTypes = vehTypeDistribution->getVals();
426 1845 : for (auto vehType : vehTypes) {
427 1346 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
428 88 : myVTypeToDist[vehType->getID()].insert(id);
429 : } else {
430 3774 : myVTypeToDist[vehType->getID()] = { id };
431 : }
432 : }
433 : return true;
434 499 : }
435 : return false;
436 : }
437 :
438 :
439 : bool
440 46336 : MSVehicleControl::hasVType(const std::string& id) const {
441 46336 : return myVTypeDict.count(id) > 0 || myVTypeDistDict.count(id) > 0;
442 : }
443 :
444 :
445 : bool
446 19928 : MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
447 19928 : return myVTypeDistDict.count(id) > 0;
448 : }
449 :
450 :
451 : MSVehicleType*
452 8672734 : MSVehicleControl::getVType(const std::string& id, SumoRNG* rng, bool readOnly) {
453 : VTypeDictType::iterator it = myVTypeDict.find(id);
454 8672734 : if (it == myVTypeDict.end()) {
455 : VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
456 2573118 : if (it2 == myVTypeDistDict.end()) {
457 : return nullptr;
458 : }
459 87430 : return it2->second->get(rng);
460 : }
461 12174379 : if (!readOnly && myReplaceableDefaultVTypes.erase(id) > 0) {
462 20253 : it->second->check();
463 : }
464 6099616 : return it->second;
465 : }
466 :
467 :
468 : void
469 310 : MSVehicleControl::insertVTypeIDs(std::vector<std::string>& into) const {
470 310 : into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
471 2460 : for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
472 2150 : into.push_back((*i).first);
473 : }
474 310 : for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
475 0 : into.push_back((*i).first);
476 : }
477 310 : }
478 :
479 :
480 : const std::set<std::string>
481 151081 : MSVehicleControl::getVTypeDistributionMembership(const std::string& id) const {
482 : std::map<std::string, std::set<std::string>>::const_iterator it = myVTypeToDist.find(id);
483 151081 : if (it == myVTypeToDist.end()) {
484 60214 : return std::set<std::string>();
485 : }
486 : return it->second;
487 : }
488 :
489 :
490 : const RandomDistributor<MSVehicleType*>*
491 136093 : MSVehicleControl::getVTypeDistribution(const std::string& typeDistID) const {
492 : const auto it = myVTypeDistDict.find(typeDistID);
493 136093 : if (it != myVTypeDistDict.end()) {
494 2278 : return it->second;
495 : }
496 : return nullptr;
497 : }
498 :
499 :
500 : const std::vector<MSVehicleType*>
501 0 : MSVehicleControl::getPedestrianTypes(void) const {
502 : std::vector<MSVehicleType*> pedestrianTypes;
503 0 : for (auto const& e : myVTypeDict)
504 0 : if (e.second->getVehicleClass() == SUMOVehicleClass::SVC_PEDESTRIAN) {
505 0 : pedestrianTypes.push_back(e.second);
506 : }
507 0 : return pedestrianTypes;
508 0 : }
509 :
510 :
511 : void
512 28332 : MSVehicleControl::abortWaiting() {
513 30274 : for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
514 1942 : SUMOVehicle* veh = i->second;
515 : std::string waitReason;
516 1942 : if (veh->isStoppedTriggered()) {
517 1868 : const MSStop& stop = veh->getNextStop();
518 1868 : if (stop.triggered) {
519 : waitReason = "for a person that will never come";
520 124 : } else if (stop.containerTriggered) {
521 : waitReason = "for a container that will never come";
522 36 : } else if (stop.joinTriggered) {
523 36 : if (stop.pars.join != "") {
524 48 : waitReason = "to be joined to vehicle '" + stop.pars.join + "'";
525 : } else {
526 : waitReason = "for a joining vehicle that will never come";
527 : }
528 : } else {
529 : waitReason = "for an unknown trigger";
530 : }
531 74 : } else if (!veh->hasDeparted()) {
532 74 : if (veh->getParameter().departProcedure == DepartDefinition::SPLIT) {
533 : waitReason = "for a train from which to split";
534 58 : } else if (veh->getParameter().departProcedure == DepartDefinition::TRIGGERED) {
535 : waitReason = "at insertion for a person that will never come";
536 22 : } else if (veh->getParameter().departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
537 : waitReason = "at insertion for a container that will never come";
538 : } else {
539 : waitReason = "for an unknown departure trigger";
540 : }
541 : } else {
542 : waitReason = "for an unknown reason";
543 : }
544 5826 : WRITE_WARNINGF(TL("Vehicle '%' aborted waiting %."), i->first, waitReason);
545 : }
546 28332 : }
547 :
548 :
549 : int
550 522721 : MSVehicleControl::getHaltingVehicleNo() const {
551 : int result = 0;
552 75575773 : for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
553 75053052 : const SUMOVehicle* veh = it->second;
554 75053052 : if ((veh->isOnRoad() || veh->isRemoteControlled()) && veh->getSpeed() < SUMO_const_haltingSpeed) {
555 18905441 : result++;
556 : }
557 : }
558 522721 : return result;
559 : }
560 :
561 :
562 : std::pair<double, double>
563 522721 : MSVehicleControl::getVehicleMeanSpeeds() const {
564 : double speedSum = 0;
565 : double relSpeedSum = 0;
566 : int count = 0;
567 75575773 : for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
568 75053052 : const SUMOVehicle* veh = it->second;
569 75053052 : if ((veh->isOnRoad() || veh->isRemoteControlled()) && !veh->isStopped()) {
570 42243186 : count++;
571 42243186 : speedSum += veh->getSpeed();
572 42243186 : relSpeedSum += veh->getEdge()->getSpeedLimit() > 0 ? veh->getSpeed() / veh->getEdge()->getSpeedLimit() : 0;
573 : }
574 : }
575 522721 : if (count > 0) {
576 427718 : return std::make_pair(speedSum / count, relSpeedSum / count);
577 : } else {
578 95003 : return std::make_pair(-1, -1);
579 : }
580 : }
581 :
582 :
583 : int
584 1394666 : MSVehicleControl::getQuota(double frac, int loaded) const {
585 1394666 : frac = frac < 0 ? myScale : frac;
586 : const int origLoaded = (loaded < 1
587 : // the vehicle in question has already been loaded, hence the '-1'
588 1394666 : ? frac > 1. ? (int)(myLoadedVehNo / frac) : myLoadedVehNo - 1
589 : // given transportable number reflects only previously loaded
590 518714 : : frac > 1. ? (int)(loaded / frac) : loaded);
591 1394666 : return getScalingQuota(frac, origLoaded);
592 : }
593 :
594 :
595 : int
596 552396 : MSVehicleControl::getTeleportCount() const {
597 552396 : return myTeleportsCollision + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
598 : }
599 :
600 :
601 : void
602 4940 : MSVehicleControl::adaptIntermodalRouter(MSTransportableRouter& router) const {
603 5223 : for (const SUMOVehicle* const veh : myPTVehicles) {
604 : // add single vehicles with line attribute which are not part of a flow
605 283 : ConstMSRoutePtr const route = MSRoute::dictionary(veh->getParameter().routeid);
606 283 : router.getNetwork()->addSchedule(veh->getParameter(), route == nullptr ? nullptr : &route->getStops());
607 : }
608 4940 : }
609 :
610 : // ===========================================================================
611 : // MSVehicleControl::DeleteKeptVehicle method definitions
612 : // ===========================================================================
613 :
614 : SUMOTime
615 14 : MSVehicleControl::DeleteKeptVehicle::execute(SUMOTime /*currentTime*/) {
616 14 : MSNet::getInstance()->getVehicleControl().deleteVehicle(myVehicle, false, true);
617 14 : return 0;
618 : }
619 :
620 : /****************************************************************************/
|