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 42501 : MSVehicleControl::MSVehicleControl() :
47 42501 : myLoadedVehNo(0),
48 42501 : myRunningVehNo(0),
49 42501 : myEndedVehNo(0),
50 42501 : myDiscarded(0),
51 42501 : myCollisions(0),
52 42501 : myTeleportsCollision(0),
53 42501 : myTeleportsJam(0),
54 42501 : myTeleportsYield(0),
55 42501 : myTeleportsWrongLane(0),
56 42501 : myEmergencyStops(0),
57 42501 : myEmergencyBrakingCount(0),
58 42501 : myStoppedVehicles(0),
59 42501 : myTotalDepartureDelay(0),
60 42501 : myTotalTravelTime(0),
61 42501 : myWaitingForTransportable(0),
62 42501 : myMaxSpeedFactor(1),
63 42501 : myMinDeceleration(SUMOVTypeParameter::getDefaultDecel(SVC_IGNORING)),
64 42501 : myMinDecelerationRail(SUMOVTypeParameter::getDefaultDecel(SVC_RAIL)),
65 42501 : myMaxMinGap(0),
66 85002 : myPendingRemovals(MSGlobals::gNumSimThreads > 1) {
67 :
68 42501 : initDefaultTypes();
69 42501 : myScale = OptionsCont::getOptions().getFloat("scale");
70 42501 : myKeepTime = string2time(OptionsCont::getOptions().getString("keep-after-arrival"));
71 42501 : }
72 :
73 :
74 71230 : MSVehicleControl::~MSVehicleControl() {
75 41881 : clearState(false);
76 71230 : }
77 :
78 :
79 : void
80 42669 : MSVehicleControl::initDefaultTypes() {
81 42669 : SUMOVTypeParameter defType(DEFAULT_VTYPE_ID, SVC_PASSENGER);
82 42669 : myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
83 :
84 42669 : SUMOVTypeParameter defPedType(DEFAULT_PEDTYPE_ID, SVC_PEDESTRIAN);
85 42669 : defPedType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
86 42669 : myVTypeDict[DEFAULT_PEDTYPE_ID] = MSVehicleType::build(defPedType);
87 :
88 42669 : SUMOVTypeParameter defBikeType(DEFAULT_BIKETYPE_ID, SVC_BICYCLE);
89 42669 : defBikeType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
90 42669 : myVTypeDict[DEFAULT_BIKETYPE_ID] = MSVehicleType::build(defBikeType);
91 :
92 42669 : SUMOVTypeParameter defTaxiType(DEFAULT_TAXITYPE_ID, SVC_TAXI);
93 42669 : defTaxiType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
94 42669 : myVTypeDict[DEFAULT_TAXITYPE_ID] = MSVehicleType::build(defTaxiType);
95 :
96 42669 : SUMOVTypeParameter defRailType(DEFAULT_RAILTYPE_ID, SVC_RAIL);
97 42669 : defRailType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
98 42669 : myVTypeDict[DEFAULT_RAILTYPE_ID] = MSVehicleType::build(defRailType);
99 :
100 42669 : SUMOVTypeParameter defContainerType(DEFAULT_CONTAINERTYPE_ID, SVC_CONTAINER);
101 42669 : defContainerType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
102 42669 : myVTypeDict[DEFAULT_CONTAINERTYPE_ID] = MSVehicleType::build(defContainerType);
103 :
104 : myReplaceableDefaultVTypes = DEFAULT_VTYPES;
105 42669 : }
106 :
107 :
108 : SUMOVehicle*
109 3862093 : MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
110 : ConstMSRoutePtr route, MSVehicleType* type,
111 : const bool ignoreStopErrors, const VehicleDefinitionSource source, bool addRouteStops) {
112 3967183 : const double speedFactor = type->computeChosenSpeedDeviation(defs->speedFactor, source == VehicleDefinitionSource::ROUTEFILE ? MSRouteHandler::getParsingRNG() : nullptr);
113 7724186 : MSVehicle* built = new MSVehicle(defs, route, type, speedFactor);
114 3862093 : initVehicle(built, ignoreStopErrors, addRouteStops, source);
115 3862037 : return built;
116 : }
117 :
118 :
119 : void
120 5256339 : MSVehicleControl::initVehicle(MSBaseVehicle* built, const bool ignoreStopErrors, bool addRouteStops, const VehicleDefinitionSource source) {
121 5256339 : myLoadedVehNo++;
122 : try {
123 5256339 : built->initDevices();
124 5256300 : if (source != VehicleDefinitionSource::STATE) {
125 5251392 : built->addStops(ignoreStopErrors, nullptr, addRouteStops);
126 : }
127 116 : } catch (ProcessError&) {
128 116 : delete built;
129 116 : throw;
130 116 : }
131 5256222 : MSNet::getInstance()->informVehicleStateListener(built, MSNet::VehicleState::BUILT);
132 5256222 : }
133 :
134 :
135 : void
136 4017967 : MSVehicleControl::scheduleVehicleRemoval(SUMOVehicle* veh, bool checkDuplicate) {
137 : assert(myRunningVehNo > 0);
138 4017967 : if (!checkDuplicate || !isPendingRemoval(veh)) {
139 4017967 : myPendingRemovals.push_back(veh);
140 : }
141 4017967 : }
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 108861968 : MSVehicleControl::removePending() {
156 125696916 : 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 108861968 : std::sort(vehs.begin(), vehs.end(), ComparatorNumericalIdLess());
163 112879931 : for (SUMOVehicle* const veh : vehs) {
164 4017963 : myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
165 4017963 : myRunningVehNo--;
166 4017963 : MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VehicleState::ARRIVED);
167 : // vehicle is equipped with tripinfo device (not all vehicles are)
168 4017963 : const bool hasTripinfo = veh->getDevice(typeid(MSDevice_Tripinfo)) != nullptr;
169 7074820 : for (MSVehicleDevice* const dev : veh->getDevices()) {
170 3772071 : dev->generateOutput(hasTripinfo ? tripinfoOut : nullptr);
171 : }
172 4017963 : if (tripinfoOut != nullptr && hasTripinfo) {
173 : // close tag after tripinfo (possibly including emissions from another device) have been written
174 479848 : tripinfoOut->closeTag();
175 : }
176 4017963 : if (myKeepTime == 0) {
177 4017950 : deleteVehicle(veh);
178 : } else {
179 13 : deleteKeptVehicle(veh);
180 : }
181 : }
182 : vehs.clear();
183 108861968 : 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 108861968 : }
191 :
192 :
193 : void
194 16 : MSVehicleControl::deleteKeptVehicle(SUMOVehicle* veh) {
195 16 : myEndedVehNo++;
196 16 : MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(new DeleteKeptVehicle(veh), SIMSTEP + myKeepTime);
197 16 : }
198 :
199 : void
200 4168457 : MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) {
201 4168457 : ++myRunningVehNo;
202 4168457 : myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart));
203 4168457 : MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VehicleState::DEPARTED);
204 4168457 : myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor());
205 4168457 : myMaxMinGap = MAX2(myMaxMinGap, v.getVehicleType().getMinGap());
206 4168457 : const double maxDecel = v.getVehicleType().getCarFollowModel().getMaxDecel();
207 4168457 : if ((v.getVClass() & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) {
208 : // only worry about deceleration of road users
209 8119792 : myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
210 8109 : } else if ((v.getVClass() & SVC_RAIL_CLASSES) != 0) {
211 7791 : myMinDecelerationRail = MIN2(myMinDecelerationRail, maxDecel);
212 7791 : if ((v.getEdge()->getPermissions() & SVC_ROAD_MOTOR_CLASSES) != 0) {
213 : // shared rail/road
214 946 : myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
215 : }
216 : }
217 4168457 : }
218 :
219 :
220 : void
221 458 : MSVehicleControl::setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime, double maxSpeedFactor, double minDecel) {
222 458 : myRunningVehNo = runningVehNo;
223 458 : myLoadedVehNo = loadedVehNo;
224 458 : myEndedVehNo = endedVehNo;
225 458 : myTotalDepartureDelay = totalDepartureDelay;
226 458 : myTotalTravelTime = totalTravelTime;
227 458 : myMaxSpeedFactor = maxSpeedFactor;
228 458 : myMinDeceleration = minDecel;
229 458 : }
230 :
231 :
232 : void
233 529 : MSVehicleControl::saveState(OutputDevice& out) {
234 529 : out.openTag(SUMO_TAG_DELAY);
235 529 : out.writeAttr(SUMO_ATTR_NUMBER, myRunningVehNo);
236 529 : out.writeAttr(SUMO_ATTR_BEGIN, myLoadedVehNo);
237 529 : out.writeAttr(SUMO_ATTR_END, myEndedVehNo);
238 529 : out.writeAttr(SUMO_ATTR_DEPART, myTotalDepartureDelay);
239 529 : out.writeAttr(SUMO_ATTR_TIME, myTotalTravelTime);
240 529 : out.writeAttr(SUMO_ATTR_SPEEDFACTOR, myMaxSpeedFactor);
241 529 : out.writeAttr(SUMO_ATTR_DECEL, myMinDeceleration);
242 529 : const SUMOTime loaderTime = MSNet::getInstance()->getLoaderTime();
243 529 : if (loaderTime > 0 && loaderTime != SUMOTime_MAX) {
244 34 : out.writeAttr(SUMO_ATTR_LOADERTIME, MSNet::getInstance()->getLoaderTime());
245 : }
246 1058 : out.closeTag();
247 : // save vehicle types
248 4500 : for (const auto& item : myVTypeDict) {
249 3971 : if (myReplaceableDefaultVTypes.count(item.first) == 0) {
250 1061 : item.second->getParameter().write(out);
251 : }
252 : }
253 711 : 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 4992 : for (const auto& item : myVehicleDict) {
261 4463 : sortedVehs.push_back(item.second);
262 : }
263 529 : std::sort(sortedVehs.begin(), sortedVehs.end(), ComparatorNumericalIdLess());
264 4992 : for (SUMOVehicle* veh : sortedVehs) {
265 4463 : veh->saveState(out);
266 : }
267 529 : }
268 :
269 :
270 : void
271 42049 : MSVehicleControl::clearState(const bool reinit) {
272 366979 : for (const auto& item : myVehicleDict) {
273 324930 : delete item.second;
274 : }
275 : myVehicleDict.clear();
276 : // delete vehicle type distributions
277 42502 : for (const auto& item : myVTypeDistDict) {
278 906 : delete item.second;
279 : }
280 : myVTypeDistDict.clear();
281 : // delete vehicle types
282 345759 : for (const auto& item : myVTypeDict) {
283 303710 : delete item.second;
284 : }
285 : myVTypeDict.clear();
286 42049 : myPendingRemovals.clear(); // could be leftovers from MSVehicleTransfer::checkInsertions (teleport beyond arrival)
287 42049 : if (reinit) {
288 168 : initDefaultTypes();
289 : }
290 42049 : myLoadedVehNo = 0;
291 42049 : myRunningVehNo = 0;
292 42049 : myEndedVehNo = 0;
293 42049 : myDiscarded = 0;
294 42049 : myCollisions = 0;
295 42049 : myTeleportsCollision = 0;
296 42049 : myTeleportsJam = 0;
297 42049 : myTeleportsYield = 0;
298 42049 : myTeleportsWrongLane = 0;
299 42049 : myEmergencyStops = 0;
300 42049 : myEmergencyBrakingCount = 0;
301 42049 : myStoppedVehicles = 0;
302 42049 : myTotalDepartureDelay = 0;
303 42049 : myTotalTravelTime = 0;
304 42049 : }
305 :
306 :
307 : bool
308 5151095 : MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
309 : VehicleDictType::iterator it = myVehicleDict.find(id);
310 5151095 : if (it == myVehicleDict.end()) {
311 : // id not in myVehicleDict.
312 5151095 : myVehicleDict[id] = v;
313 5151095 : handleTriggeredDepart(v, true);
314 5151095 : const SUMOVehicleParameter& pars = v->getParameter();
315 5151095 : if (v->getVClass() != SVC_TAXI && pars.line != "" && pars.repetitionNumber < 0) {
316 1154 : myPTVehicles.push_back(v);
317 : }
318 5151095 : return true;
319 : }
320 : return false;
321 : }
322 :
323 :
324 : void
325 5155592 : MSVehicleControl::handleTriggeredDepart(SUMOVehicle* v, bool add) {
326 5155592 : const SUMOVehicleParameter& pars = v->getParameter();
327 5155592 : if (pars.departProcedure == DepartDefinition::TRIGGERED || pars.departProcedure == DepartDefinition::CONTAINER_TRIGGERED || pars.departProcedure == DepartDefinition::SPLIT) {
328 4278 : const MSEdge* const firstEdge = v->getRoute().getEdges()[pars.departEdge];
329 4278 : if (add) {
330 2204 : if (!MSGlobals::gUseMesoSim) {
331 : // position will be checked against person position later
332 1795 : static_cast<MSVehicle*>(v)->setTentativeLaneAndPosition(nullptr, v->getParameter().departPos);
333 : }
334 2204 : if (firstEdge->isTazConnector()) {
335 78 : for (MSEdge* out : firstEdge->getSuccessors()) {
336 51 : out->addWaiting(v);
337 : }
338 : } else {
339 2177 : firstEdge->addWaiting(v);
340 : }
341 : registerOneWaiting();
342 : } else {
343 2074 : if (firstEdge->isTazConnector()) {
344 14 : for (MSEdge* out : firstEdge->getSuccessors()) {
345 7 : out->removeWaiting(v);
346 : }
347 : } else {
348 2067 : firstEdge->removeWaiting(v);
349 : }
350 : unregisterOneWaiting();
351 : }
352 : }
353 5155592 : }
354 :
355 :
356 : SUMOVehicle*
357 22728236 : MSVehicleControl::getVehicle(const std::string& id) const {
358 : VehicleDictType::const_iterator it = myVehicleDict.find(id);
359 22728236 : if (it == myVehicleDict.end()) {
360 : return nullptr;
361 : }
362 17381974 : return it->second;
363 : }
364 :
365 :
366 : void
367 4931212 : MSVehicleControl::deleteVehicle(SUMOVehicle* veh, bool discard, bool wasKept) {
368 4931212 : if (!wasKept) {
369 4931199 : myEndedVehNo++;
370 4931199 : if (discard) {
371 913249 : myDiscarded++;
372 : }
373 : }
374 4931212 : if (veh != nullptr) {
375 : myVehicleDict.erase(veh->getID());
376 : }
377 4931212 : auto ptVehIt = std::find(myPTVehicles.begin(), myPTVehicles.end(), veh);
378 4931212 : if (ptVehIt != myPTVehicles.end()) {
379 944 : myPTVehicles.erase(ptVehIt);
380 : }
381 4931212 : delete veh;
382 4931212 : }
383 :
384 :
385 : bool
386 63720 : MSVehicleControl::checkVType(const std::string& id) {
387 63720 : if (myReplaceableDefaultVTypes.erase(id) > 0) {
388 10112 : delete myVTypeDict[id];
389 : myVTypeDict.erase(myVTypeDict.find(id));
390 : } else {
391 53608 : if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
392 195 : return false;
393 : }
394 : }
395 : return true;
396 : }
397 :
398 :
399 : bool
400 63267 : MSVehicleControl::addVType(MSVehicleType* vehType) {
401 63267 : if (checkVType(vehType->getID())) {
402 63072 : myVTypeDict[vehType->getID()] = vehType;
403 63072 : return true;
404 : }
405 : return false;
406 : }
407 :
408 :
409 : void
410 1382 : MSVehicleControl::removeVType(const MSVehicleType* vehType) {
411 : assert(vehType != nullptr);
412 : assert(myVTypeDict.find(vehType->getID()) != myVTypeDict.end());
413 : myVTypeDict.erase(vehType->getID());
414 1382 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
415 : myVTypeToDist.erase(vehType->getID());
416 : }
417 1382 : delete vehType;
418 1382 : }
419 :
420 :
421 : bool
422 453 : MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
423 453 : if (checkVType(id)) {
424 453 : myVTypeDistDict[id] = vehTypeDistribution;
425 453 : std::vector<MSVehicleType*> vehTypes = vehTypeDistribution->getVals();
426 1691 : for (auto vehType : vehTypes) {
427 1238 : if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
428 42 : myVTypeToDist[vehType->getID()].insert(id);
429 : } else {
430 3588 : myVTypeToDist[vehType->getID()] = { id };
431 : }
432 : }
433 : return true;
434 453 : }
435 : return false;
436 : }
437 :
438 :
439 : bool
440 46313 : MSVehicleControl::hasVType(const std::string& id) const {
441 46313 : return myVTypeDict.count(id) > 0 || myVTypeDistDict.count(id) > 0;
442 : }
443 :
444 :
445 : bool
446 19565 : MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
447 19565 : return myVTypeDistDict.count(id) > 0;
448 : }
449 :
450 :
451 : MSVehicleType*
452 9842026 : MSVehicleControl::getVType(const std::string& id, SumoRNG* rng, bool readOnly) {
453 : VTypeDictType::iterator it = myVTypeDict.find(id);
454 9842026 : if (it == myVTypeDict.end()) {
455 : VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
456 3898773 : if (it2 == myVTypeDistDict.end()) {
457 : return nullptr;
458 : }
459 84566 : return it2->second->get(rng);
460 : }
461 11861983 : if (!readOnly && myReplaceableDefaultVTypes.erase(id) > 0) {
462 20144 : it->second->check();
463 : }
464 5943253 : 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 2470 : for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
472 2160 : 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 145351 : MSVehicleControl::getVTypeDistributionMembership(const std::string& id) const {
482 : std::map<std::string, std::set<std::string>>::const_iterator it = myVTypeToDist.find(id);
483 145351 : if (it == myVTypeToDist.end()) {
484 60214 : return std::set<std::string>();
485 : }
486 : return it->second;
487 : }
488 :
489 :
490 : const RandomDistributor<MSVehicleType*>*
491 135596 : MSVehicleControl::getVTypeDistribution(const std::string& typeDistID) const {
492 : const auto it = myVTypeDistDict.find(typeDistID);
493 135596 : if (it != myVTypeDistDict.end()) {
494 2192 : 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 28118 : MSVehicleControl::abortWaiting() {
513 30065 : for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
514 1947 : SUMOVehicle* veh = i->second;
515 : std::string waitReason;
516 1947 : if (veh->isStoppedTriggered()) {
517 1873 : const MSStop& stop = veh->getNextStop();
518 1873 : 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 5841 : WRITE_WARNINGF(TL("Vehicle '%' aborted waiting %."), i->first, waitReason);
545 : }
546 28118 : }
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 1391065 : MSVehicleControl::getQuota(double frac, int loaded) const {
585 1391065 : frac = frac < 0 ? myScale : frac;
586 : const int origLoaded = (loaded < 1
587 : // the vehicle in question has already been loaded, hence the '-1'
588 1391065 : ? frac > 1. ? (int)(myLoadedVehNo / frac) : myLoadedVehNo - 1
589 : // given transportable number reflects only previously loaded
590 518517 : : frac > 1. ? (int)(loaded / frac) : loaded);
591 1391065 : return getScalingQuota(frac, origLoaded);
592 : }
593 :
594 :
595 : int
596 552250 : MSVehicleControl::getTeleportCount() const {
597 552250 : return myTeleportsCollision + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
598 : }
599 :
600 :
601 : void
602 4940 : MSVehicleControl::adaptIntermodalRouter(MSTransportableRouter& router) const {
603 5221 : for (const SUMOVehicle* const veh : myPTVehicles) {
604 : // add single vehicles with line attribute which are not part of a flow
605 281 : ConstMSRoutePtr const route = MSRoute::dictionary(veh->getParameter().routeid);
606 281 : 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 13 : MSVehicleControl::DeleteKeptVehicle::execute(SUMOTime /*currentTime*/) {
616 13 : MSNet::getInstance()->getVehicleControl().deleteVehicle(myVehicle, false, true);
617 13 : return 0;
618 : }
619 :
620 : /****************************************************************************/
|