Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 42753 : MSVehicleControl::MSVehicleControl() :
47 42753 : myLoadedVehNo(0),
48 42753 : myRunningVehNo(0),
49 42753 : myEndedVehNo(0),
50 42753 : myDiscarded(0),
51 42753 : myCollisions(0),
52 42753 : myTeleportsCollision(0),
53 42753 : myTeleportsJam(0),
54 42753 : myTeleportsYield(0),
55 42753 : myTeleportsWrongLane(0),
56 42753 : myEmergencyStops(0),
57 42753 : myEmergencyBrakingCount(0),
58 42753 : myStoppedVehicles(0),
59 42753 : myTotalDepartureDelay(0),
60 42753 : myTotalTravelTime(0),
61 42753 : myWaitingForTransportable(0),
62 42753 : myMaxSpeedFactor(1),
63 42753 : myMinDeceleration(SUMOVTypeParameter::getDefaultDecel(SVC_IGNORING)),
64 42753 : myMinDecelerationRail(SUMOVTypeParameter::getDefaultDecel(SVC_RAIL)),
65 85506 : myPendingRemovals(MSGlobals::gNumSimThreads > 1) {
66 :
67 42753 : initDefaultTypes();
68 42753 : myScale = OptionsCont::getOptions().getFloat("scale");
69 42753 : myKeepTime = string2time(OptionsCont::getOptions().getString("keep-after-arrival"));
70 42753 : }
71 :
72 :
73 69317 : MSVehicleControl::~MSVehicleControl() {
74 39793 : clearState(false);
75 69317 : }
76 :
77 :
78 : void
79 42939 : MSVehicleControl::initDefaultTypes() {
80 42939 : SUMOVTypeParameter defType(DEFAULT_VTYPE_ID, SVC_PASSENGER);
81 42939 : myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
82 :
83 42939 : SUMOVTypeParameter defPedType(DEFAULT_PEDTYPE_ID, SVC_PEDESTRIAN);
84 42939 : defPedType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
85 42939 : myVTypeDict[DEFAULT_PEDTYPE_ID] = MSVehicleType::build(defPedType);
86 :
87 42939 : SUMOVTypeParameter defBikeType(DEFAULT_BIKETYPE_ID, SVC_BICYCLE);
88 42939 : defBikeType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
89 42939 : myVTypeDict[DEFAULT_BIKETYPE_ID] = MSVehicleType::build(defBikeType);
90 :
91 42939 : SUMOVTypeParameter defTaxiType(DEFAULT_TAXITYPE_ID, SVC_TAXI);
92 42939 : defTaxiType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
93 42939 : myVTypeDict[DEFAULT_TAXITYPE_ID] = MSVehicleType::build(defTaxiType);
94 :
95 42939 : SUMOVTypeParameter defRailType(DEFAULT_RAILTYPE_ID, SVC_RAIL);
96 42939 : defRailType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
97 42939 : myVTypeDict[DEFAULT_RAILTYPE_ID] = MSVehicleType::build(defRailType);
98 :
99 42939 : SUMOVTypeParameter defContainerType(DEFAULT_CONTAINERTYPE_ID, SVC_CONTAINER);
100 : // ISO Container TEU (cannot set this based on vClass)
101 42939 : defContainerType.length = 6.1;
102 42939 : defContainerType.width = 2.4;
103 42939 : defContainerType.height = 2.6;
104 42939 : defContainerType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
105 42939 : myVTypeDict[DEFAULT_CONTAINERTYPE_ID] = MSVehicleType::build(defContainerType);
106 :
107 : myReplaceableDefaultVTypes = DEFAULT_VTYPES;
108 42939 : }
109 :
110 :
111 : SUMOVehicle*
112 3418561 : MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
113 : ConstMSRoutePtr route, MSVehicleType* type,
114 : const bool ignoreStopErrors, const VehicleDefinitionSource source, bool addRouteStops) {
115 6936319 : MSVehicle* built = new MSVehicle(defs, route, type, type->computeChosenSpeedDeviation(source == VehicleDefinitionSource::ROUTEFILE || source == VehicleDefinitionSource::STATE ? MSRouteHandler::getParsingRNG() : nullptr));
116 3418561 : initVehicle(built, ignoreStopErrors, addRouteStops, source);
117 3418505 : return built;
118 : }
119 :
120 :
121 : void
122 4613642 : MSVehicleControl::initVehicle(MSBaseVehicle* built, const bool ignoreStopErrors, bool addRouteStops, const VehicleDefinitionSource source) {
123 4613642 : myLoadedVehNo++;
124 : try {
125 4613642 : built->initDevices();
126 4613604 : if (source != VehicleDefinitionSource::STATE) {
127 4609176 : built->addStops(ignoreStopErrors, nullptr, addRouteStops);
128 : }
129 71 : } catch (ProcessError&) {
130 71 : delete built;
131 71 : throw;
132 71 : }
133 4613571 : MSNet::getInstance()->informVehicleStateListener(built, MSNet::VehicleState::BUILT);
134 4613571 : }
135 :
136 :
137 : void
138 3179474 : MSVehicleControl::scheduleVehicleRemoval(SUMOVehicle* veh, bool checkDuplicate) {
139 : assert(myRunningVehNo > 0);
140 3179474 : if (!checkDuplicate || !isPendingRemoval(veh)) {
141 3179474 : myPendingRemovals.push_back(veh);
142 : }
143 3179474 : }
144 :
145 :
146 : bool
147 16967 : MSVehicleControl::isPendingRemoval(SUMOVehicle* veh) {
148 : #ifdef HAVE_FOX
149 16967 : return myPendingRemovals.contains(veh);
150 : #else
151 : return std::find(myPendingRemovals.begin(), myPendingRemovals.end(), veh) == myPendingRemovals.end();
152 : #endif
153 : }
154 :
155 :
156 : void
157 160692159 : MSVehicleControl::removePending() {
158 168185520 : OutputDevice* const tripinfoOut = OptionsCont::getOptions().isSet("tripinfo-output") ? &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr;
159 : #ifdef HAVE_FOX
160 : std::vector<SUMOVehicle*>& vehs = myPendingRemovals.getContainer();
161 : #else
162 : std::vector<SUMOVehicle*>& vehs = myPendingRemovals;
163 : #endif
164 160692159 : std::sort(vehs.begin(), vehs.end(), ComparatorNumericalIdLess());
165 163871629 : for (SUMOVehicle* const veh : vehs) {
166 3179470 : myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
167 3179470 : myRunningVehNo--;
168 3179470 : MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VehicleState::ARRIVED);
169 : // vehicle is equipped with tripinfo device (not all vehicles are)
170 3179470 : const bool hasTripinfo = veh->getDevice(typeid(MSDevice_Tripinfo)) != nullptr;
171 5793861 : for (MSVehicleDevice* const dev : veh->getDevices()) {
172 3173260 : dev->generateOutput(hasTripinfo ? tripinfoOut : nullptr);
173 : }
174 3179470 : if (tripinfoOut != nullptr && hasTripinfo) {
175 : // close tag after tripinfo (possibly including emissions from another device) have been written
176 458818 : tripinfoOut->closeTag();
177 : }
178 3179470 : if (myKeepTime == 0) {
179 3179462 : deleteVehicle(veh);
180 : } else {
181 8 : deleteKeptVehicle(veh);
182 : }
183 : }
184 : vehs.clear();
185 160692159 : if (tripinfoOut != nullptr) {
186 : // there seem to be people who think reading an unfinished xml is a good idea ;-)
187 : tripinfoOut->flush();
188 : }
189 : #ifdef HAVE_FOX
190 : myPendingRemovals.unlock();
191 : #endif
192 160692159 : }
193 :
194 :
195 : void
196 11 : MSVehicleControl::deleteKeptVehicle(SUMOVehicle* veh) {
197 11 : myEndedVehNo++;
198 11 : MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(new DeleteKeptVehicle(veh), SIMSTEP + myKeepTime);
199 11 : }
200 :
201 : void
202 3312499 : MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) {
203 3312499 : ++myRunningVehNo;
204 3312499 : myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart));
205 3312499 : MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VehicleState::DEPARTED);
206 3312499 : myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor());
207 3312499 : if ((v.getVClass() & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) {
208 : // only worry about deceleration of road users
209 6423602 : myMinDeceleration = MIN2(myMinDeceleration, v.getVehicleType().getCarFollowModel().getMaxDecel());
210 6321 : } else if ((v.getVClass() & SVC_RAIL_CLASSES) != 0) {
211 11112 : myMinDecelerationRail = MIN2(myMinDecelerationRail, v.getVehicleType().getCarFollowModel().getMaxDecel());
212 : }
213 3312499 : }
214 :
215 :
216 : void
217 394 : MSVehicleControl::setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime) {
218 394 : myRunningVehNo = runningVehNo;
219 394 : myLoadedVehNo = loadedVehNo;
220 394 : myEndedVehNo = endedVehNo;
221 394 : myTotalDepartureDelay = totalDepartureDelay;
222 394 : myTotalTravelTime = totalTravelTime;
223 394 : }
224 :
225 :
226 : void
227 424 : MSVehicleControl::saveState(OutputDevice& out) {
228 424 : out.openTag(SUMO_TAG_DELAY);
229 424 : out.writeAttr(SUMO_ATTR_NUMBER, myRunningVehNo);
230 424 : out.writeAttr(SUMO_ATTR_BEGIN, myLoadedVehNo);
231 424 : out.writeAttr(SUMO_ATTR_END, myEndedVehNo);
232 424 : out.writeAttr(SUMO_ATTR_DEPART, myTotalDepartureDelay);
233 1272 : out.writeAttr(SUMO_ATTR_TIME, myTotalTravelTime).closeTag();
234 : // save vehicle types
235 3700 : for (const auto& item : myVTypeDict) {
236 3276 : if (myReplaceableDefaultVTypes.count(item.first) == 0) {
237 912 : item.second->getParameter().write(out);
238 : }
239 : }
240 602 : for (const auto& item : myVTypeDistDict) {
241 178 : out.openTag(SUMO_TAG_VTYPE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, item.first);
242 178 : out.writeAttr(SUMO_ATTR_VTYPES, item.second->getVals());
243 178 : out.writeAttr(SUMO_ATTR_PROBS, item.second->getProbs());
244 356 : out.closeTag();
245 : }
246 3241 : for (const auto& item : myVehicleDict) {
247 2817 : item.second->saveState(out);
248 : }
249 424 : }
250 :
251 :
252 : void
253 39979 : MSVehicleControl::clearState(const bool reinit) {
254 876349 : for (const auto& item : myVehicleDict) {
255 836370 : delete item.second;
256 : }
257 : myVehicleDict.clear();
258 : // delete vehicle type distributions
259 40421 : for (const auto& item : myVTypeDistDict) {
260 884 : delete item.second;
261 : }
262 : myVTypeDistDict.clear();
263 : // delete vehicle types
264 328721 : for (const auto& item : myVTypeDict) {
265 288742 : delete item.second;
266 : }
267 : myVTypeDict.clear();
268 39979 : myPendingRemovals.clear(); // could be leftovers from MSVehicleTransfer::checkInsertions (teleport beyond arrival)
269 39979 : if (reinit) {
270 186 : initDefaultTypes();
271 : }
272 39979 : myLoadedVehNo = 0;
273 39979 : myRunningVehNo = 0;
274 39979 : myEndedVehNo = 0;
275 39979 : myDiscarded = 0;
276 39979 : myCollisions = 0;
277 39979 : myTeleportsCollision = 0;
278 39979 : myTeleportsJam = 0;
279 39979 : myTeleportsYield = 0;
280 39979 : myTeleportsWrongLane = 0;
281 39979 : myEmergencyStops = 0;
282 39979 : myEmergencyBrakingCount = 0;
283 39979 : myStoppedVehicles = 0;
284 39979 : myTotalDepartureDelay = 0;
285 39979 : myTotalTravelTime = 0;
286 39979 : }
287 :
288 :
289 : bool
290 4511261 : MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
291 : VehicleDictType::iterator it = myVehicleDict.find(id);
292 4511261 : if (it == myVehicleDict.end()) {
293 : // id not in myVehicleDict.
294 4511261 : myVehicleDict[id] = v;
295 4511261 : handleTriggeredDepart(v, true);
296 4511261 : const SUMOVehicleParameter& pars = v->getParameter();
297 4511261 : if (v->getVClass() != SVC_TAXI && pars.line != "" && pars.repetitionNumber < 0) {
298 1044 : myPTVehicles.push_back(v);
299 : }
300 4511261 : return true;
301 : }
302 : return false;
303 : }
304 :
305 :
306 : void
307 4515061 : MSVehicleControl::handleTriggeredDepart(SUMOVehicle* v, bool add) {
308 4515061 : const SUMOVehicleParameter& pars = v->getParameter();
309 4515061 : if (pars.departProcedure == DepartDefinition::TRIGGERED || pars.departProcedure == DepartDefinition::CONTAINER_TRIGGERED || pars.departProcedure == DepartDefinition::SPLIT) {
310 4136 : const MSEdge* const firstEdge = v->getRoute().getEdges()[pars.departEdge];
311 4136 : if (add) {
312 2133 : if (!MSGlobals::gUseMesoSim) {
313 : // position will be checked against person position later
314 1750 : static_cast<MSVehicle*>(v)->setTentativeLaneAndPosition(nullptr, v->getParameter().departPos);
315 : }
316 2133 : if (firstEdge->isTazConnector()) {
317 78 : for (MSEdge* out : firstEdge->getSuccessors()) {
318 51 : out->addWaiting(v);
319 : }
320 : } else {
321 2106 : firstEdge->addWaiting(v);
322 : }
323 : registerOneWaiting();
324 : } else {
325 2003 : if (firstEdge->isTazConnector()) {
326 14 : for (MSEdge* out : firstEdge->getSuccessors()) {
327 7 : out->removeWaiting(v);
328 : }
329 : } else {
330 1996 : firstEdge->removeWaiting(v);
331 : }
332 : unregisterOneWaiting();
333 : }
334 : }
335 4515061 : }
336 :
337 :
338 : SUMOVehicle*
339 21300513 : MSVehicleControl::getVehicle(const std::string& id) const {
340 : VehicleDictType::const_iterator it = myVehicleDict.find(id);
341 21300513 : if (it == myVehicleDict.end()) {
342 : return nullptr;
343 : }
344 16601930 : return it->second;
345 : }
346 :
347 :
348 : void
349 3777110 : MSVehicleControl::deleteVehicle(SUMOVehicle* veh, bool discard, bool wasKept) {
350 3777110 : if (!wasKept) {
351 3777102 : myEndedVehNo++;
352 3777102 : if (discard) {
353 597640 : myDiscarded++;
354 : }
355 : }
356 3777110 : if (veh != nullptr) {
357 : myVehicleDict.erase(veh->getID());
358 : }
359 3777110 : auto ptVehIt = std::find(myPTVehicles.begin(), myPTVehicles.end(), veh);
360 3777110 : if (ptVehIt != myPTVehicles.end()) {
361 908 : myPTVehicles.erase(ptVehIt);
362 : }
363 3777110 : delete veh;
364 3777110 : }
365 :
366 :
367 : bool
368 60045 : MSVehicleControl::checkVType(const std::string& id) {
369 60045 : if (myReplaceableDefaultVTypes.erase(id) > 0) {
370 9232 : delete myVTypeDict[id];
371 : myVTypeDict.erase(myVTypeDict.find(id));
372 : } else {
373 50813 : if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
374 179 : return false;
375 : }
376 : }
377 : return true;
378 : }
379 :
380 :
381 : bool
382 59603 : MSVehicleControl::addVType(MSVehicleType* vehType) {
383 59603 : if (checkVType(vehType->getID())) {
384 59424 : myVTypeDict[vehType->getID()] = vehType;
385 59424 : return true;
386 : }
387 : return false;
388 : }
389 :
390 :
391 : void
392 1197 : MSVehicleControl::removeVType(const MSVehicleType* vehType) {
393 : assert(vehType != nullptr);
394 : assert(myVTypeDict.find(vehType->getID()) != myVTypeDict.end());
395 : myVTypeDict.erase(vehType->getID());
396 1197 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
397 : myVTypeToDist.erase(vehType->getID());
398 : }
399 1197 : delete vehType;
400 1197 : }
401 :
402 :
403 : bool
404 442 : MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
405 442 : if (checkVType(id)) {
406 442 : myVTypeDistDict[id] = vehTypeDistribution;
407 442 : std::vector<MSVehicleType*> vehTypes = vehTypeDistribution->getVals();
408 1658 : for (auto vehType : vehTypes) {
409 1216 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
410 28 : myVTypeToDist[vehType->getID()].insert(id);
411 : } else {
412 3564 : myVTypeToDist[vehType->getID()] = { id };
413 : }
414 : }
415 : return true;
416 442 : }
417 : return false;
418 : }
419 :
420 :
421 : bool
422 43085 : MSVehicleControl::hasVType(const std::string& id) const {
423 43085 : return myVTypeDict.count(id) > 0 || myVTypeDistDict.count(id) > 0;
424 : }
425 :
426 :
427 : bool
428 21869 : MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
429 21869 : return myVTypeDistDict.count(id) > 0;
430 : }
431 :
432 :
433 : MSVehicleType*
434 5390330 : MSVehicleControl::getVType(const std::string& id, SumoRNG* rng, bool readOnly) {
435 : VTypeDictType::iterator it = myVTypeDict.find(id);
436 5390330 : if (it == myVTypeDict.end()) {
437 : VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
438 84535 : if (it2 == myVTypeDistDict.end()) {
439 : return nullptr;
440 : }
441 84531 : return it2->second->get(rng);
442 : }
443 10588592 : if (!readOnly && myReplaceableDefaultVTypes.erase(id) > 0) {
444 21147 : it->second->check();
445 : }
446 5305795 : return it->second;
447 : }
448 :
449 :
450 : void
451 293 : MSVehicleControl::insertVTypeIDs(std::vector<std::string>& into) const {
452 293 : into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
453 2320 : for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
454 2027 : into.push_back((*i).first);
455 : }
456 293 : for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
457 0 : into.push_back((*i).first);
458 : }
459 293 : }
460 :
461 :
462 : const std::set<std::string>
463 143713 : MSVehicleControl::getVTypeDistributionMembership(const std::string& id) const {
464 : std::map<std::string, std::set<std::string>>::const_iterator it = myVTypeToDist.find(id);
465 143713 : if (it == myVTypeToDist.end()) {
466 57744 : return std::set<std::string>();
467 : }
468 : return it->second;
469 : }
470 :
471 :
472 : const RandomDistributor<MSVehicleType*>*
473 121515 : MSVehicleControl::getVTypeDistribution(const std::string& typeDistID) const {
474 : const auto it = myVTypeDistDict.find(typeDistID);
475 121515 : if (it != myVTypeDistDict.end()) {
476 2168 : return it->second;
477 : }
478 : return nullptr;
479 : }
480 :
481 :
482 : const std::vector<MSVehicleType*>
483 0 : MSVehicleControl::getPedestrianTypes(void) const {
484 : std::vector<MSVehicleType*> pedestrianTypes;
485 0 : for (auto const& e : myVTypeDict)
486 0 : if (e.second->getVehicleClass() == SUMOVehicleClass::SVC_PEDESTRIAN) {
487 0 : pedestrianTypes.push_back(e.second);
488 : }
489 0 : return pedestrianTypes;
490 0 : }
491 :
492 :
493 : void
494 19907 : MSVehicleControl::abortWaiting() {
495 20701 : for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
496 794 : SUMOVehicle* veh = i->second;
497 : std::string waitReason;
498 794 : if (veh->isStoppedTriggered()) {
499 766 : const MSStop& stop = veh->getNextStop();
500 766 : if (stop.triggered) {
501 : waitReason = "for a person that will never come";
502 100 : } else if (stop.containerTriggered) {
503 : waitReason = "for a container that will never come";
504 12 : } else if (stop.joinTriggered) {
505 12 : if (stop.pars.join != "") {
506 18 : waitReason = "to be joined to vehicle '" + stop.pars.join + "'";
507 : } else {
508 : waitReason = "for a joining vehicle that will never come";
509 : }
510 : } else {
511 : waitReason = "for an unknown trigger";
512 : }
513 28 : } else if (!veh->hasDeparted()) {
514 28 : if (veh->getParameter().departProcedure == DepartDefinition::SPLIT) {
515 : waitReason = "for a train from which to split";
516 12 : } else if (veh->getParameter().departProcedure == DepartDefinition::TRIGGERED) {
517 : waitReason = "at insertion for a person that will never come";
518 0 : } else if (veh->getParameter().departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
519 : waitReason = "at insertion for a container that will never come";
520 : } else {
521 : waitReason = "for an unknown departure trigger";
522 : }
523 : } else {
524 : waitReason = "for an unknown reason";
525 : }
526 2382 : WRITE_WARNINGF(TL("Vehicle '%' aborted waiting %."), i->first, waitReason);
527 : }
528 19907 : }
529 :
530 :
531 : int
532 517886 : MSVehicleControl::getHaltingVehicleNo() const {
533 : int result = 0;
534 75162589 : for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
535 74644703 : const SUMOVehicle* veh = it->second;
536 74644703 : if ((veh->isOnRoad() || veh->isRemoteControlled()) && veh->getSpeed() < SUMO_const_haltingSpeed) {
537 18828209 : result++;
538 : }
539 : }
540 517886 : return result;
541 : }
542 :
543 :
544 : std::pair<double, double>
545 517886 : MSVehicleControl::getVehicleMeanSpeeds() const {
546 : double speedSum = 0;
547 : double relSpeedSum = 0;
548 : int count = 0;
549 75162589 : for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
550 74644703 : const SUMOVehicle* veh = it->second;
551 74644703 : if ((veh->isOnRoad() || veh->isRemoteControlled()) && !veh->isStopped()) {
552 41902319 : count++;
553 41902319 : speedSum += veh->getSpeed();
554 41902319 : relSpeedSum += veh->getEdge()->getSpeedLimit() > 0 ? veh->getSpeed() / veh->getEdge()->getSpeedLimit() : 0;
555 : }
556 : }
557 517886 : if (count > 0) {
558 423346 : return std::make_pair(speedSum / count, relSpeedSum / count);
559 : } else {
560 94540 : return std::make_pair(-1, -1);
561 : }
562 : }
563 :
564 :
565 : int
566 1282517 : MSVehicleControl::getQuota(double frac, int loaded) const {
567 1282517 : frac = frac < 0 ? myScale : frac;
568 : const int origLoaded = (loaded < 1
569 : // the vehicle in question has already been loaded, hence the '-1'
570 1282517 : ? frac > 1. ? (int)(myLoadedVehNo / frac) : myLoadedVehNo - 1
571 : // given transportable number reflects only previously loaded
572 494241 : : frac > 1. ? (int)(loaded / frac) : loaded);
573 1282517 : return getScalingQuota(frac, origLoaded);
574 : }
575 :
576 :
577 : int
578 545567 : MSVehicleControl::getTeleportCount() const {
579 545567 : return myTeleportsCollision + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
580 : }
581 :
582 :
583 : void
584 4220 : MSVehicleControl::adaptIntermodalRouter(MSTransportableRouter& router) const {
585 4414 : for (const SUMOVehicle* const veh : myPTVehicles) {
586 : // add single vehicles with line attribute which are not part of a flow
587 194 : ConstMSRoutePtr const route = MSRoute::dictionary(veh->getParameter().routeid);
588 194 : router.getNetwork()->addSchedule(veh->getParameter(), route == nullptr ? nullptr : &route->getStops());
589 : }
590 4220 : }
591 :
592 : // ===========================================================================
593 : // MSVehicleControl::DeleteKeptVehicle method definitions
594 : // ===========================================================================
595 :
596 : SUMOTime
597 8 : MSVehicleControl::DeleteKeptVehicle::execute(SUMOTime /*currentTime*/) {
598 8 : MSNet::getInstance()->getVehicleControl().deleteVehicle(myVehicle, false, true);
599 8 : return 0;
600 : }
601 :
602 : /****************************************************************************/
|