Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2017-2025 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 Simulation.cpp
15 : /// @author Laura Bieker-Walz
16 : /// @author Robert Hilbrich
17 : /// @author Mirko Barthauer
18 : /// @date 15.09.2017
19 : ///
20 : // C++ TraCI client API implementation
21 : /****************************************************************************/
22 : #include <config.h>
23 : #ifdef HAVE_VERSION_H
24 : #include <version.h>
25 : #endif
26 : #include <utils/options/OptionsCont.h>
27 : #include <utils/common/MsgHandler.h>
28 : #include <utils/common/StdDefs.h>
29 : #include <utils/common/StringTokenizer.h>
30 : #include <utils/common/StringUtils.h>
31 : #include <utils/common/SystemFrame.h>
32 : #include <utils/geom/GeoConvHelper.h>
33 : #include <utils/options/OptionsIO.h>
34 : #include <utils/router/IntermodalRouter.h>
35 : #include <utils/router/PedestrianRouter.h>
36 : #include <utils/xml/XMLSubSys.h>
37 : #include <microsim/MSNet.h>
38 : #include <microsim/MSEdgeControl.h>
39 : #include <microsim/MSInsertionControl.h>
40 : #include <microsim/MSEdge.h>
41 : #include <microsim/MSLane.h>
42 : #include <microsim/MSVehicle.h>
43 : #include <microsim/MSVehicleControl.h>
44 : #include <microsim/MSVehicleTransfer.h>
45 : #include <microsim/transportables/MSTransportableControl.h>
46 : #include <microsim/MSStateHandler.h>
47 : #include <microsim/MSStoppingPlace.h>
48 : #include <microsim/MSParkingArea.h>
49 : #include <microsim/devices/MSRoutingEngine.h>
50 : #include <microsim/devices/MSDevice_Taxi.h>
51 : #include <microsim/trigger/MSChargingStation.h>
52 : #include <microsim/trigger/MSOverheadWire.h>
53 : #include <microsim/devices/MSDevice_Tripinfo.h>
54 : #include <mesosim/MELoop.h>
55 : #include <mesosim/MESegment.h>
56 : #include <netload/NLBuilder.h>
57 : #include <libsumo/Helper.h>
58 : #include <libsumo/StorageHelper.h>
59 : #include <libsumo/TraCIConstants.h>
60 : #ifdef HAVE_LIBSUMOGUI
61 : #include "GUI.h"
62 : #endif
63 : #include "Simulation.h"
64 : #include <libsumo/TraCIDefs.h>
65 :
66 :
67 : namespace libsumo {
68 : // ===========================================================================
69 : // static member initializations
70 : // ===========================================================================
71 : SubscriptionResults Simulation::mySubscriptionResults;
72 : ContextSubscriptionResults Simulation::myContextSubscriptionResults;
73 : #ifdef HAVE_FOX
74 : FXMutex Simulation::myStepMutex;
75 : #endif
76 :
77 :
78 : // ===========================================================================
79 : // static member definitions
80 : // ===========================================================================
81 : std::pair<int, std::string>
82 2 : Simulation::init(int /* port */, int /* numRetries */, const std::string& /* host */, const std::string& /* label */, FILE* const /* pipe */) {
83 4 : throw TraCIException("Multi client support (including connection switching) is not implemented in libsumo.");
84 : }
85 :
86 :
87 : std::pair<int, std::string>
88 1111 : Simulation::start(const std::vector<std::string>& cmd, int /* port */, int /* numRetries */, const std::string& /* label */, const bool /* verbose */,
89 : const std::string& /* traceFile */, bool /* traceGetters */, void* /* _stdout */) {
90 : #ifdef HAVE_LIBSUMOGUI
91 1111 : if (GUI::start(cmd)) {
92 521 : return getVersion();
93 : }
94 : #endif
95 590 : load(std::vector<std::string>(cmd.begin() + 1, cmd.end()));
96 590 : return getVersion();
97 : }
98 :
99 :
100 : bool
101 0 : Simulation::isLibsumo() {
102 0 : return true;
103 : }
104 :
105 :
106 : void
107 0 : Simulation::switchConnection(const std::string& /* label */) {
108 0 : throw TraCIException("Multi client support (including connection switching) is not implemented in libsumo.");
109 : }
110 :
111 :
112 : const std::string&
113 0 : Simulation::getLabel() {
114 0 : throw TraCIException("Multi client support (including connection switching) is not implemented in libsumo.");
115 : }
116 :
117 :
118 : void
119 1 : Simulation::setOrder(int /* order */) {
120 2 : throw TraCIException("Multi client support (including connection switching) is not implemented in libsumo.");
121 : }
122 :
123 :
124 : void
125 597 : Simulation::load(const std::vector<std::string>& args) {
126 : #ifdef HAVE_LIBSUMOGUI
127 597 : if (GUI::load(args)) {
128 : return;
129 : }
130 : #endif
131 595 : close("Libsumo issued load command.");
132 : try {
133 1190 : OptionsCont::getOptions().setApplicationName("libsumo", "Eclipse SUMO libsumo " VERSION_STRING);
134 595 : gSimulation = true;
135 595 : XMLSubSys::init();
136 595 : OptionsIO::setArgs(args);
137 595 : if (NLBuilder::init(true) != nullptr) {
138 593 : const SUMOTime begin = string2time(OptionsCont::getOptions().getString("begin"));
139 593 : MSNet::getInstance()->setCurrentTimeStep(begin); // needed for state loading
140 1186 : WRITE_MESSAGEF(TL("Simulation version % started via libsumo with time: %."), VERSION_STRING, time2string(begin));
141 : }
142 0 : } catch (ProcessError& e) {
143 0 : throw TraCIException(e.what());
144 0 : }
145 0 : }
146 :
147 :
148 : bool
149 2 : Simulation::hasGUI() {
150 : #ifdef HAVE_LIBSUMOGUI
151 2 : return GUI::hasInstance();
152 : #else
153 0 : return false;
154 : #endif
155 : }
156 :
157 :
158 : bool
159 8 : Simulation::isLoaded() {
160 8 : return MSNet::hasInstance();
161 : }
162 :
163 :
164 : void
165 185710 : Simulation::step(const double time) {
166 : #ifdef HAVE_FOX
167 : FXMutexLock lock(myStepMutex);
168 : #endif
169 185710 : Helper::clearStateChanges();
170 185710 : const SUMOTime t = TIME2STEPS(time);
171 : #ifdef HAVE_LIBSUMOGUI
172 185710 : if (!GUI::step(t)) {
173 : #endif
174 103183 : if (t == 0) {
175 103016 : MSNet::getInstance()->simulationStep();
176 : } else {
177 1859 : while (SIMSTEP < t) {
178 1692 : MSNet::getInstance()->simulationStep();
179 : }
180 : }
181 : #ifdef HAVE_LIBSUMOGUI
182 : }
183 : #endif
184 185710 : Helper::handleSubscriptions(SIMSTEP);
185 185710 : }
186 :
187 :
188 : void
189 4 : Simulation::executeMove() {
190 4 : MSNet::getInstance()->simulationStep(true);
191 4 : }
192 :
193 :
194 : void
195 1681 : Simulation::close(const std::string& reason) {
196 1681 : Helper::clearSubscriptions();
197 0 : if (
198 : #ifdef HAVE_LIBSUMOGUI
199 1681 : !GUI::close(reason) &&
200 : #endif
201 : MSNet::hasInstance()) {
202 592 : MSNet::getInstance()->closeSimulation(0, reason);
203 592 : delete MSNet::getInstance();
204 592 : SystemFrame::close();
205 : }
206 1680 : }
207 :
208 :
209 : void
210 54 : Simulation::subscribe(const std::vector<int>& varIDs, double begin, double end, const libsumo::TraCIResults& parameters) {
211 54 : libsumo::Helper::subscribe(CMD_SUBSCRIBE_SIM_VARIABLE, "", varIDs, begin, end, parameters);
212 42 : }
213 :
214 :
215 : const TraCIResults
216 58 : Simulation::getSubscriptionResults() {
217 116 : return mySubscriptionResults[""];
218 : }
219 :
220 :
221 383 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Simulation, SIM)
222 :
223 :
224 : std::pair<int, std::string>
225 1113 : Simulation::getVersion() {
226 1113 : return std::make_pair(libsumo::TRACI_VERSION, "SUMO " VERSION_STRING);
227 : }
228 :
229 :
230 : std::string
231 14 : Simulation::getOption(const std::string& option) {
232 14 : OptionsCont& oc = OptionsCont::getOptions();
233 14 : if (!oc.exists(option)) {
234 0 : throw TraCIException("The option " + option + " is unknown.");
235 : }
236 14 : return oc.getValueString(option);
237 : }
238 :
239 :
240 : int
241 14 : Simulation::getCurrentTime() {
242 14 : return (int)MSNet::getInstance()->getCurrentTimeStep();
243 : }
244 :
245 :
246 : double
247 296500 : Simulation::getTime() {
248 296500 : return SIMTIME;
249 : }
250 :
251 : double
252 14 : Simulation::getEndTime() {
253 28 : return STEPS2TIME(string2time(OptionsCont::getOptions().getString("end")));
254 : }
255 :
256 :
257 : int
258 10 : Simulation::getLoadedNumber() {
259 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::BUILT).size();
260 : }
261 :
262 :
263 : std::vector<std::string>
264 50 : Simulation::getLoadedIDList() {
265 50 : return Helper::getVehicleStateChanges(MSNet::VehicleState::BUILT);
266 : }
267 :
268 :
269 : int
270 1362 : Simulation::getDepartedNumber() {
271 1362 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::DEPARTED).size();
272 : }
273 :
274 :
275 : std::vector<std::string>
276 6052 : Simulation::getDepartedIDList() {
277 6052 : return Helper::getVehicleStateChanges(MSNet::VehicleState::DEPARTED);
278 : }
279 :
280 :
281 : int
282 346 : Simulation::getArrivedNumber() {
283 346 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::ARRIVED).size();
284 : }
285 :
286 :
287 : std::vector<std::string>
288 6032 : Simulation::getArrivedIDList() {
289 6032 : return Helper::getVehicleStateChanges(MSNet::VehicleState::ARRIVED);
290 : }
291 :
292 :
293 : int
294 10 : Simulation::getParkingStartingVehiclesNumber() {
295 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_PARKING).size();
296 : }
297 :
298 :
299 : std::vector<std::string>
300 10 : Simulation::getParkingStartingVehiclesIDList() {
301 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_PARKING);
302 : }
303 :
304 :
305 : int
306 10 : Simulation::getParkingEndingVehiclesNumber() {
307 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_PARKING).size();
308 : }
309 :
310 :
311 : std::vector<std::string>
312 10 : Simulation::getParkingEndingVehiclesIDList() {
313 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_PARKING);
314 : }
315 :
316 :
317 : int
318 10 : Simulation::getStopStartingVehiclesNumber() {
319 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_STOP).size();
320 : }
321 :
322 :
323 : std::vector<std::string>
324 10 : Simulation::getStopStartingVehiclesIDList() {
325 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_STOP);
326 : }
327 :
328 :
329 : int
330 10 : Simulation::getStopEndingVehiclesNumber() {
331 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_STOP).size();
332 : }
333 :
334 :
335 : std::vector<std::string>
336 10 : Simulation::getStopEndingVehiclesIDList() {
337 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_STOP);
338 : }
339 :
340 :
341 : int
342 35 : Simulation::getCollidingVehiclesNumber() {
343 35 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::COLLISION).size();
344 : }
345 :
346 :
347 : std::vector<std::string>
348 10 : Simulation::getCollidingVehiclesIDList() {
349 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::COLLISION);
350 : }
351 :
352 :
353 : int
354 34 : Simulation::getEmergencyStoppingVehiclesNumber() {
355 34 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::EMERGENCYSTOP).size();
356 : }
357 :
358 :
359 : std::vector<std::string>
360 10 : Simulation::getEmergencyStoppingVehiclesIDList() {
361 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::EMERGENCYSTOP);
362 : }
363 :
364 :
365 : int
366 10 : Simulation::getStartingTeleportNumber() {
367 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_TELEPORT).size();
368 : }
369 :
370 :
371 : std::vector<std::string>
372 10 : Simulation::getStartingTeleportIDList() {
373 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::STARTING_TELEPORT);
374 : }
375 :
376 :
377 : int
378 10 : Simulation::getEndingTeleportNumber() {
379 10 : return (int)Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_TELEPORT).size();
380 : }
381 :
382 :
383 : std::vector<std::string>
384 10 : Simulation::getEndingTeleportIDList() {
385 10 : return Helper::getVehicleStateChanges(MSNet::VehicleState::ENDING_TELEPORT);
386 : }
387 :
388 : int
389 8 : Simulation::getDepartedPersonNumber() {
390 8 : return (int)Helper::getTransportableStateChanges(MSNet::TransportableState::PERSON_DEPARTED).size();
391 : }
392 :
393 :
394 : std::vector<std::string>
395 8 : Simulation::getDepartedPersonIDList() {
396 8 : return Helper::getTransportableStateChanges(MSNet::TransportableState::PERSON_DEPARTED);
397 : }
398 :
399 :
400 : int
401 8 : Simulation::getArrivedPersonNumber() {
402 8 : return (int)Helper::getTransportableStateChanges(MSNet::TransportableState::PERSON_ARRIVED).size();
403 : }
404 :
405 :
406 : std::vector<std::string>
407 8 : Simulation::getArrivedPersonIDList() {
408 8 : return Helper::getTransportableStateChanges(MSNet::TransportableState::PERSON_ARRIVED);
409 : }
410 :
411 : std::vector<std::string>
412 13 : Simulation::getBusStopIDList() {
413 : std::vector<std::string> result;
414 26 : for (const auto& pair : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP)) {
415 13 : result.push_back(pair.first);
416 : }
417 13 : return result;
418 0 : }
419 :
420 : int
421 15 : Simulation::getBusStopWaiting(const std::string& stopID) {
422 15 : MSStoppingPlace* s = MSNet::getInstance()->getStoppingPlace(stopID, SUMO_TAG_BUS_STOP);
423 15 : if (s == nullptr) {
424 18 : throw TraCIException("Unknown bus stop '" + stopID + "'.");
425 : }
426 6 : return s->getTransportableNumber();
427 : }
428 :
429 : std::vector<std::string>
430 160 : Simulation::getBusStopWaitingIDList(const std::string& stopID) {
431 160 : MSStoppingPlace* s = MSNet::getInstance()->getStoppingPlace(stopID, SUMO_TAG_BUS_STOP);
432 160 : if (s == nullptr) {
433 8 : throw TraCIException("Unknown bus stop '" + stopID + "'.");
434 : }
435 : std::vector<std::string> result;
436 212 : for (const MSTransportable* t : s->getTransportables()) {
437 56 : result.push_back(t->getID());
438 156 : }
439 156 : return result;
440 0 : }
441 :
442 :
443 : std::vector<std::string>
444 38 : Simulation::getPendingVehicles() {
445 : std::vector<std::string> result;
446 43 : for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
447 5 : result.push_back(veh->getID());
448 : }
449 38 : return result;
450 0 : }
451 :
452 :
453 : std::vector<libsumo::TraCICollision>
454 346 : Simulation::getCollisions() {
455 : std::vector<libsumo::TraCICollision> result;
456 371 : for (auto item : MSNet::getInstance()->getCollisions()) {
457 50 : for (const MSNet::Collision& c : item.second) {
458 : libsumo::TraCICollision c2;
459 : c2.collider = item.first;
460 25 : c2.victim = c.victim;
461 25 : c2.colliderType = c.colliderType;
462 25 : c2.victimType = c.victimType;
463 25 : c2.colliderSpeed = c.colliderSpeed;
464 25 : c2.victimSpeed = c.victimSpeed;
465 25 : c2.type = c.type;
466 25 : c2.lane = c.lane->getID();
467 25 : c2.pos = c.pos;
468 25 : result.push_back(c2);
469 25 : }
470 : }
471 346 : return result;
472 0 : }
473 :
474 : double
475 13 : Simulation::getScale() {
476 13 : return MSNet::getInstance()->getVehicleControl().getScale();
477 : }
478 :
479 : double
480 148 : Simulation::getDeltaT() {
481 148 : return TS;
482 : }
483 :
484 :
485 : TraCIPositionVector
486 11 : Simulation::getNetBoundary() {
487 11 : Boundary b = GeoConvHelper::getFinal().getConvBoundary();
488 : TraCIPositionVector tb;
489 11 : TraCIPosition minV;
490 11 : TraCIPosition maxV;
491 11 : minV.x = b.xmin();
492 11 : maxV.x = b.xmax();
493 11 : minV.y = b.ymin();
494 11 : maxV.y = b.ymax();
495 11 : minV.z = b.zmin();
496 11 : maxV.z = b.zmax();
497 11 : tb.value.push_back(minV);
498 11 : tb.value.push_back(maxV);
499 11 : return tb;
500 : }
501 :
502 :
503 : int
504 7732230 : Simulation::getMinExpectedNumber() {
505 7732230 : MSNet* net = MSNet::getInstance();
506 : return (net->getVehicleControl().getActiveVehicleCount()
507 7732229 : + net->getInsertionControl().getPendingFlowCount()
508 7732229 : + (net->hasPersons() ? net->getPersonControl().getActiveCount() : 0)
509 7732229 : + (net->hasContainers() ? net->getContainerControl().getActiveCount() : 0)
510 7732229 : + (MSDevice_Taxi::hasServableReservations() ? 1 : 0));
511 : }
512 :
513 :
514 : TraCIPosition
515 89 : Simulation::convert2D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
516 89 : Position result = Helper::getLaneChecking(edgeID, laneIndex, pos)->geometryPositionAtOffset(pos);
517 89 : if (toGeo) {
518 2 : GeoConvHelper::getFinal().cartesian2geo(result);
519 : }
520 : result.setz(0.);
521 89 : return Helper::makeTraCIPosition(result);
522 : }
523 :
524 :
525 : TraCIPosition
526 4 : Simulation::convert3D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
527 4 : Position result = Helper::getLaneChecking(edgeID, laneIndex, pos)->geometryPositionAtOffset(pos);
528 4 : if (toGeo) {
529 2 : GeoConvHelper::getFinal().cartesian2geo(result);
530 : }
531 4 : return Helper::makeTraCIPosition(result, true);
532 : }
533 :
534 :
535 : TraCIRoadPosition
536 52 : Simulation::convertRoad(double x, double y, bool isGeo, const std::string& vClass) {
537 : Position pos(x, y);
538 52 : if (isGeo) {
539 6 : GeoConvHelper::getFinal().x2cartesian_const(pos);
540 : }
541 52 : if (!SumoVehicleClassStrings.hasString(vClass)) {
542 0 : throw TraCIException("Unknown vehicle class '" + vClass + "'.");
543 : }
544 52 : const SUMOVehicleClass vc = SumoVehicleClassStrings.get(vClass);
545 52 : std::pair<MSLane*, double> roadPos = libsumo::Helper::convertCartesianToRoadMap(pos, vc);
546 52 : if (roadPos.first == nullptr) {
547 0 : throw TraCIException("Cannot convert position to road.");
548 : }
549 104 : TraCIRoadPosition result;
550 : result.edgeID = roadPos.first->getEdge().getID();
551 52 : result.laneIndex = roadPos.first->getIndex();
552 52 : result.pos = roadPos.second;
553 52 : return result;
554 : }
555 :
556 :
557 : TraCIPosition
558 10 : Simulation::convertGeo(double x, double y, bool fromGeo) {
559 : Position pos(x, y);
560 10 : if (fromGeo) {
561 2 : GeoConvHelper::getFinal().x2cartesian_const(pos);
562 : } else {
563 8 : GeoConvHelper::getFinal().cartesian2geo(pos);
564 : }
565 10 : return Helper::makeTraCIPosition(pos);
566 : }
567 :
568 :
569 : double
570 74 : Simulation::getDistance2D(double x1, double y1, double x2, double y2, bool isGeo, bool isDriving) {
571 : Position pos1(x1, y1);
572 : Position pos2(x2, y2);
573 74 : if (isGeo) {
574 2 : GeoConvHelper::getFinal().x2cartesian_const(pos1);
575 2 : GeoConvHelper::getFinal().x2cartesian_const(pos2);
576 : }
577 74 : if (isDriving) {
578 70 : std::pair<const MSLane*, double> roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
579 70 : std::pair<const MSLane*, double> roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
580 70 : return Helper::getDrivingDistance(roadPos1, roadPos2);
581 : } else {
582 4 : return pos1.distanceTo(pos2);
583 : }
584 : }
585 :
586 :
587 : double
588 88 : Simulation::getDistanceRoad(const std::string& edgeID1, double pos1, const std::string& edgeID2, double pos2, bool isDriving) {
589 88 : std::pair<const MSLane*, double> roadPos1 = std::make_pair(libsumo::Helper::getLaneChecking(edgeID1, 0, pos1), pos1);
590 88 : std::pair<const MSLane*, double> roadPos2 = std::make_pair(libsumo::Helper::getLaneChecking(edgeID2, 0, pos2), pos2);
591 88 : if (isDriving) {
592 18 : return Helper::getDrivingDistance(roadPos1, roadPos2);
593 : } else {
594 70 : const Position p1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);
595 70 : const Position p2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);
596 70 : return p1.distanceTo(p2);
597 : }
598 : }
599 :
600 :
601 : TraCIStage
602 5437 : Simulation::findRoute(const std::string& from, const std::string& to, const std::string& typeID,
603 : double depart, int routingMode, double departPos, double arrivalPos) {
604 10874 : TraCIStage result(STAGE_DRIVING);
605 5437 : const MSEdge* const fromEdge = MSEdge::dictionary(from);
606 5437 : if (fromEdge == nullptr) {
607 10 : throw TraCIException("Unknown from edge '" + from + "'.");
608 : }
609 5432 : const MSEdge* const toEdge = MSEdge::dictionary(to);
610 5432 : if (toEdge == nullptr) {
611 0 : throw TraCIException("Unknown to edge '" + to + "'.");
612 : }
613 : MSBaseVehicle* vehicle = nullptr;
614 10818 : MSVehicleType* type = MSNet::getInstance()->getVehicleControl().getVType(typeID == "" ? DEFAULT_VTYPE_ID : typeID);
615 5432 : if (type == nullptr) {
616 0 : throw TraCIException("The vehicle type '" + typeID + "' is not known.");
617 : }
618 5432 : SUMOVehicleParameter* pars = new SUMOVehicleParameter();
619 5432 : pars->id = "simulation.findRoute";
620 : try {
621 10864 : ConstMSRoutePtr const routeDummy = std::make_shared<MSRoute>("", ConstMSEdgeVector({ fromEdge }), false, nullptr, StopParVector());
622 10869 : vehicle = dynamic_cast<MSBaseVehicle*>(MSNet::getInstance()->getVehicleControl().buildVehicle(pars, routeDummy, type, false));
623 : std::string msg;
624 5432 : if (!vehicle->hasValidRouteStart(msg)) {
625 5 : MSNet::getInstance()->getVehicleControl().deleteVehicle(vehicle, true);
626 5 : MSNet::getInstance()->getVehicleControl().discountRoutingVehicle();
627 10 : throw TraCIException("Invalid departure edge for vehicle type '" + type->getID() + "' (" + msg + ")");
628 : }
629 : // we need to fix the speed factor here for deterministic results
630 5427 : vehicle->setChosenSpeedFactor(type->getSpeedFactor().getParameter(0));
631 : vehicle->setRoutingMode(routingMode);
632 5 : } catch (ProcessError& e) {
633 0 : throw TraCIException("Invalid departure edge for vehicle type '" + type->getID() + "' (" + e.what() + ")");
634 0 : }
635 5427 : if (abs(departPos) > fromEdge->getLength()) {
636 0 : throw TraCIException("Invalid departPos " + toString(departPos) + " on edge '" + fromEdge->getID() + " (length " + toString(fromEdge->getLength()) + ")");
637 : }
638 5427 : if (departPos < 0) {
639 5 : departPos += fromEdge->getLength();
640 : }
641 5427 : if (arrivalPos == INVALID_DOUBLE_VALUE) {
642 5412 : arrivalPos = toEdge->getLength();
643 : }
644 5427 : if (abs(arrivalPos) > toEdge->getLength()) {
645 0 : throw TraCIException("Invalid arrivalPos " + toString(arrivalPos) + " on edge '" + toEdge->getID() + " (length " + toString(toEdge->getLength()) + ")");
646 : }
647 5427 : if (arrivalPos < 0) {
648 5 : arrivalPos += toEdge->getLength();
649 : }
650 : ConstMSEdgeVector edges;
651 5427 : const SUMOTime dep = depart < 0 ? MSNet::getInstance()->getCurrentTimeStep() : TIME2STEPS(depart);
652 10849 : SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = routingMode == ROUTING_MODE_AGGREGATED ? MSRoutingEngine::getRouterTT(0, vehicle->getVClass()) : MSNet::getInstance()->getRouterTT(0);
653 5427 : router.compute(fromEdge, departPos, toEdge, arrivalPos, vehicle, dep, edges);
654 28665 : for (const MSEdge* e : edges) {
655 23238 : result.edges.push_back(e->getID());
656 : }
657 5427 : result.travelTime = result.cost = router.recomputeCostsPos(edges, vehicle, departPos, arrivalPos, dep, &result.length);
658 5427 : result.arrivalPos = arrivalPos;
659 5427 : result.departPos = departPos;
660 : if (vehicle != nullptr) {
661 5427 : MSNet::getInstance()->getVehicleControl().deleteVehicle(vehicle, true);
662 5427 : MSNet::getInstance()->getVehicleControl().discountRoutingVehicle();
663 : }
664 5427 : return result;
665 5437 : }
666 :
667 :
668 : std::vector<TraCIStage>
669 327 : Simulation::findIntermodalRoute(const std::string& from, const std::string& to,
670 : const std::string& modes, double depart, const int routingMode, double speed, double walkFactor,
671 : double departPos, double arrivalPos, const double departPosLat,
672 : const std::string& pType, const std::string& vType, const std::string& destStop) {
673 : UNUSED_PARAMETER(departPosLat);
674 : std::vector<TraCIStage> result;
675 327 : const MSEdge* const fromEdge = MSEdge::dictionary(from);
676 327 : if (fromEdge == nullptr) {
677 10 : throw TraCIException("Unknown from edge '" + from + "'.");
678 : }
679 322 : const MSEdge* const toEdge = MSEdge::dictionary(to);
680 322 : if (toEdge == nullptr) {
681 0 : throw TraCIException("Unknown to edge '" + to + "'.");
682 : }
683 322 : MSVehicleControl& vehControl = MSNet::getInstance()->getVehicleControl();
684 : SVCPermissions modeSet = 0;
685 : std::vector<SUMOVehicleParameter*> pars;
686 322 : if (vType != "") {
687 149 : pars.push_back(new SUMOVehicleParameter());
688 149 : pars.back()->vtypeid = vType;
689 149 : pars.back()->id = vType;
690 : modeSet |= SVC_PASSENGER;
691 : }
692 1020 : for (StringTokenizer st(modes); st.hasNext();) {
693 376 : const std::string mode = st.next();
694 376 : if (mode == toString(PersonMode::CAR)) {
695 70 : pars.push_back(new SUMOVehicleParameter());
696 70 : pars.back()->vtypeid = DEFAULT_VTYPE_ID;
697 70 : pars.back()->id = mode;
698 70 : modeSet |= SVC_PASSENGER;
699 306 : } else if (mode == toString(PersonMode::BICYCLE)) {
700 80 : pars.push_back(new SUMOVehicleParameter());
701 80 : pars.back()->vtypeid = DEFAULT_BIKETYPE_ID;
702 80 : pars.back()->id = mode;
703 80 : modeSet |= SVC_BICYCLE;
704 226 : } else if (mode == toString(PersonMode::TAXI)) {
705 16 : pars.push_back(new SUMOVehicleParameter());
706 16 : pars.back()->vtypeid = DEFAULT_TAXITYPE_ID;
707 16 : pars.back()->id = mode;
708 16 : pars.back()->line = mode;
709 16 : modeSet |= SVC_TAXI;
710 210 : } else if (mode == toString(PersonMode::PUBLIC)) {
711 210 : pars.push_back(nullptr);
712 210 : modeSet |= SVC_BUS;
713 0 : } else if (mode == toString(PersonMode::WALK)) {
714 : // do nothing
715 : } else {
716 0 : throw TraCIException("Unknown person mode '" + mode + "'.");
717 : }
718 322 : }
719 322 : if (pars.empty()) {
720 36 : pars.push_back(nullptr);
721 : }
722 : // interpret default arguments
723 322 : const MSVehicleType* pedType = vehControl.hasVType(pType) ? vehControl.getVType(pType) : vehControl.getVType(DEFAULT_PEDTYPE_ID);
724 322 : SUMOTime departStep = TIME2STEPS(depart);
725 322 : if (depart < 0) {
726 318 : departStep = MSNet::getInstance()->getCurrentTimeStep();
727 : }
728 322 : if (speed < 0) {
729 : speed = MIN2(pedType->getMaxSpeed(), pedType->getDesiredMaxSpeed());
730 : }
731 322 : if (walkFactor < 0) {
732 636 : walkFactor = OptionsCont::getOptions().getFloat("persontrip.walkfactor");
733 : }
734 644 : const double externalFactor = StringUtils::toDouble(pedType->getParameter().getParameter("externalEffortFactor", "100"));
735 322 : if (departPos < 0) {
736 0 : departPos += fromEdge->getLength();
737 : }
738 322 : if (arrivalPos == INVALID_DOUBLE_VALUE) {
739 45 : arrivalPos = toEdge->getLength() / 2;
740 277 : } else if (arrivalPos < 0) {
741 0 : arrivalPos += toEdge->getLength();
742 : }
743 322 : if (departPos < 0 || departPos >= fromEdge->getLength()) {
744 10 : throw TraCIException("Invalid depart position " + toString(departPos) + " for edge '" + from + "'.");
745 : }
746 317 : if (arrivalPos < 0 || arrivalPos >= toEdge->getLength()) {
747 0 : throw TraCIException("Invalid arrival position " + toString(arrivalPos) + " for edge '" + to + "'.");
748 : }
749 : double minCost = std::numeric_limits<double>::max();
750 634 : MSTransportableRouter& router = MSNet::getInstance()->getIntermodalRouter(0, routingMode);
751 873 : for (SUMOVehicleParameter* vehPar : pars) {
752 : std::vector<TraCIStage> resultCand;
753 : SUMOVehicle* vehicle = nullptr;
754 556 : if (vehPar != nullptr) {
755 315 : MSVehicleType* type = MSNet::getInstance()->getVehicleControl().getVType(vehPar->vtypeid);
756 315 : const bool isTaxi = type != nullptr && type->getID() == DEFAULT_TAXITYPE_ID && vehPar->line == "taxi";
757 : if (type == nullptr) {
758 0 : throw TraCIException("Unknown vehicle type '" + vehPar->vtypeid + "'.");
759 : }
760 315 : if (type->getVehicleClass() != SVC_IGNORING && (fromEdge->getPermissions() & type->getVehicleClass()) == 0 && !isTaxi) {
761 30 : WRITE_WARNINGF(TL("Ignoring vehicle type '%' when performing intermodal routing because it is not allowed on the start edge '%'."), type->getID(), from);
762 : } else {
763 305 : ConstMSRoutePtr const routeDummy = std::make_shared<MSRoute>(vehPar->id, ConstMSEdgeVector({ fromEdge }), false, nullptr, StopParVector());
764 305 : vehicle = vehControl.buildVehicle(vehPar, routeDummy, type, !MSGlobals::gCheckRoutes);
765 : // we need to fix the speed factor here for deterministic results
766 305 : vehicle->setChosenSpeedFactor(type->getSpeedFactor().getParameter(0));
767 : }
768 : }
769 : std::vector<MSTransportableRouter::TripItem> items;
770 1112 : if (router.compute(fromEdge, toEdge, departPos, "", arrivalPos, destStop,
771 : speed * walkFactor, vehicle, pedType->getParameter(), modeSet, departStep, items, externalFactor)) {
772 : double cost = 0;
773 1859 : for (std::vector<MSTransportableRouter::TripItem>::iterator it = items.begin(); it != items.end(); ++it) {
774 1303 : if (!it->edges.empty()) {
775 3227 : resultCand.push_back(TraCIStage((it->line == "" ? STAGE_WALKING : STAGE_DRIVING), it->vType, it->line, it->destStop));
776 3811 : for (const MSEdge* e : it->edges) {
777 2508 : resultCand.back().edges.push_back(e->getID());
778 : }
779 1303 : resultCand.back().travelTime = it->traveltime;
780 1303 : resultCand.back().cost = it->cost;
781 1303 : resultCand.back().length = it->length;
782 1303 : resultCand.back().intended = it->intended;
783 1303 : resultCand.back().depart = it->depart;
784 1303 : resultCand.back().departPos = it->departPos;
785 1303 : resultCand.back().arrivalPos = it->arrivalPos;
786 1303 : resultCand.back().description = it->description;
787 : }
788 1303 : cost += it->cost;
789 : }
790 556 : if (cost < minCost) {
791 : minCost = cost;
792 341 : result = resultCand;
793 : }
794 : }
795 556 : if (vehicle != nullptr) {
796 305 : vehControl.deleteVehicle(vehicle, true);
797 : vehControl.discountRoutingVehicle();
798 : }
799 556 : }
800 317 : return result;
801 332 : }
802 :
803 :
804 : std::string
805 2730 : Simulation::getParameter(const std::string& objectID, const std::string& key) {
806 5460 : if (StringUtils::startsWith(key, "chargingStation.")) {
807 30 : const std::string attrName = key.substr(16);
808 30 : MSChargingStation* cs = static_cast<MSChargingStation*>(MSNet::getInstance()->getStoppingPlace(objectID, SUMO_TAG_CHARGING_STATION));
809 30 : if (cs == nullptr) {
810 10 : throw TraCIException("Invalid chargingStation '" + objectID + "'");
811 : }
812 25 : if (attrName == toString(SUMO_ATTR_TOTALENERGYCHARGED)) {
813 5 : return toString(cs->getTotalCharged());
814 20 : } else if (attrName == toString(SUMO_ATTR_NAME)) {
815 5 : return toString(cs->getMyName());
816 15 : } else if (attrName == "lane") {
817 5 : return cs->getLane().getID();
818 10 : } else if (cs->hasParameter(attrName)) {
819 20 : return cs->getParameter(attrName);
820 : } else {
821 10 : throw TraCIException("Invalid chargingStation parameter '" + attrName + "'");
822 : }
823 5400 : } else if (StringUtils::startsWith(key, "overheadWire.")) {
824 0 : const std::string attrName = key.substr(16);
825 0 : MSOverheadWire* cs = static_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(objectID, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
826 0 : if (cs == 0) {
827 0 : throw TraCIException("Invalid overhead wire '" + objectID + "'");
828 : }
829 0 : if (attrName == toString(SUMO_ATTR_TOTALENERGYCHARGED)) {
830 0 : return toString(cs->getTotalCharged());
831 0 : } else if (attrName == toString(SUMO_ATTR_NAME)) {
832 0 : return toString(cs->getMyName());
833 : } else {
834 0 : throw TraCIException("Invalid overhead wire parameter '" + attrName + "'");
835 : }
836 5400 : } else if (StringUtils::startsWith(key, "net.")) {
837 0 : const std::string attrName = key.substr(4);
838 0 : if (attrName == toString(SUMO_ATTR_NET_OFFSET)) {
839 0 : return toString(GeoConvHelper::getFinal().getOffsetBase());
840 : } else {
841 0 : throw TraCIException("Invalid net parameter '" + attrName + "'");
842 : }
843 5400 : } else if (StringUtils::startsWith(key, "stats.")) {
844 85 : if (objectID != "") {
845 0 : throw TraCIException("Simulation parameter '" + key + "' is not supported for object id '" + objectID + "'. Use empty id for stats");
846 : }
847 85 : const std::string attrName = key.substr(6);
848 85 : const MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
849 85 : const MSTransportableControl* pc = MSNet::getInstance()->hasPersons() ? &MSNet::getInstance()->getPersonControl() : nullptr;
850 85 : if (attrName == "vehicles.loaded") {
851 5 : return toString(vc.getLoadedVehicleNo());
852 80 : } else if (attrName == "vehicles.inserted") {
853 5 : return toString(vc.getDepartedVehicleNo());
854 75 : } else if (attrName == "vehicles.running") {
855 5 : return toString(vc.getRunningVehicleNo());
856 70 : } else if (attrName == "vehicles.waiting") {
857 5 : return toString(MSNet::getInstance()->getInsertionControl().getWaitingVehicleNo());
858 65 : } else if (attrName == "teleports.total") {
859 5 : return toString(vc.getTeleportCount());
860 60 : } else if (attrName == "teleports.jam") {
861 5 : return toString(vc.getTeleportsJam());
862 55 : } else if (attrName == "teleports.yield") {
863 5 : return toString(vc.getTeleportsYield());
864 50 : } else if (attrName == "teleports.wrongLane") {
865 5 : return toString(vc.getTeleportsWrongLane());
866 45 : } else if (attrName == "safety.collisions") {
867 5 : return toString(vc.getCollisionCount());
868 40 : } else if (attrName == "safety.emergencyStops") {
869 5 : return toString(vc.getEmergencyStops());
870 35 : } else if (attrName == "safety.emergencyBraking") {
871 5 : return toString(vc.getEmergencyBrakingCount());
872 30 : } else if (attrName == "persons.loaded") {
873 10 : return toString(pc != nullptr ? pc->getLoadedNumber() : 0);
874 25 : } else if (attrName == "persons.running") {
875 10 : return toString(pc != nullptr ? pc->getRunningNumber() : 0);
876 20 : } else if (attrName == "persons.jammed") {
877 10 : return toString(pc != nullptr ? pc->getJammedNumber() : 0);
878 15 : } else if (attrName == "personTeleports.total") {
879 10 : return toString(pc != nullptr ? pc->getTeleportCount() : 0);
880 10 : } else if (attrName == "personTeleports.abortWait") {
881 10 : return toString(pc != nullptr ? pc->getTeleportsAbortWait() : 0);
882 5 : } else if (attrName == "personTeleports.wrongDest") {
883 10 : return toString(pc != nullptr ? pc->getTeleportsWrongDest() : 0);
884 : } else {
885 0 : throw TraCIException("Invalid stats parameter '" + attrName + "'");
886 : }
887 5230 : } else if (StringUtils::startsWith(key, "parkingArea.")) {
888 26 : const std::string attrName = key.substr(12);
889 26 : MSParkingArea* pa = static_cast<MSParkingArea*>(MSNet::getInstance()->getStoppingPlace(objectID, SUMO_TAG_PARKING_AREA));
890 26 : if (pa == nullptr) {
891 0 : throw TraCIException("Invalid parkingArea '" + objectID + "'");
892 : }
893 26 : if (attrName == "capacity") {
894 6 : return toString(pa->getCapacity());
895 20 : } else if (attrName == "occupancy") {
896 5 : return toString(pa->getOccupancyIncludingBlocked());
897 15 : } else if (attrName == toString(SUMO_ATTR_NAME)) {
898 5 : return toString(pa->getMyName());
899 10 : } else if (attrName == "lane") {
900 5 : return pa->getLane().getID();
901 5 : } else if (pa->hasParameter(attrName)) {
902 10 : return pa->getParameter(attrName);
903 : } else {
904 0 : throw TraCIException("Invalid parkingArea parameter '" + attrName + "'");
905 : }
906 5178 : } else if (StringUtils::startsWith(key, "busStop.")) {
907 15 : const std::string attrName = key.substr(8);
908 15 : MSStoppingPlace* bs = static_cast<MSStoppingPlace*>(MSNet::getInstance()->getStoppingPlace(objectID, SUMO_TAG_BUS_STOP));
909 15 : if (bs == nullptr) {
910 0 : throw TraCIException("Invalid busStop '" + objectID + "'");
911 : }
912 15 : if (attrName == toString(SUMO_ATTR_NAME)) {
913 5 : return toString(bs->getMyName());
914 10 : } else if (attrName == "lane") {
915 5 : return bs->getLane().getID();
916 5 : } else if (bs->hasParameter(attrName)) {
917 10 : return bs->getParameter(attrName);
918 : } else {
919 0 : throw TraCIException("Invalid busStop parameter '" + attrName + "'");
920 : }
921 5148 : } else if (StringUtils::startsWith(key, "device.tripinfo.")) {
922 2548 : if (objectID != "") {
923 0 : throw TraCIException("Simulation parameter '" + key + "' is not supported for object id '" + objectID
924 0 : + "'. Use empty id for global device parameers or vehicle domain for vehicle specific parameters");
925 : }
926 2548 : const std::string attrName = key.substr(16);
927 2548 : return MSDevice_Tripinfo::getGlobalParameter(attrName);
928 26 : } else if (objectID == "") {
929 42 : return MSNet::getInstance()->getParameter(key, "");
930 : } else {
931 10 : throw TraCIException("Simulation parameter '" + key + "' is not supported for object id '" + objectID + "'. Use empty id for generic network parameters");
932 : }
933 : }
934 :
935 16 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(Simulation)
936 :
937 : void
938 10 : Simulation::setParameter(const std::string& objectID, const std::string& key, const std::string& value) {
939 10 : if (objectID == "") {
940 5 : MSNet::getInstance()->setParameter(key, value);
941 : } else {
942 10 : throw TraCIException("Setting simulation parameter '" + key + "' is not supported for object id '" + objectID + "'. Use empty id for generic network parameters");
943 : }
944 5 : }
945 :
946 : void
947 5 : Simulation::setScale(double value) {
948 5 : MSNet::getInstance()->getVehicleControl().setScale(value);
949 5 : }
950 :
951 : void
952 6 : Simulation::clearPending(const std::string& routeID) {
953 6 : MSNet::getInstance()->getInsertionControl().clearPendingVehicles(routeID);
954 6 : }
955 :
956 :
957 : void
958 81 : Simulation::saveState(const std::string& fileName) {
959 81 : MSStateHandler::saveState(fileName, MSNet::getInstance()->getCurrentTimeStep());
960 81 : }
961 :
962 : double
963 196 : Simulation::loadState(const std::string& fileName) {
964 588 : long before = PROGRESS_BEGIN_TIME_MESSAGE("Loading state from '" + fileName + "'");
965 : try {
966 196 : const SUMOTime newTime = MSNet::getInstance()->loadState(fileName, false);
967 186 : Helper::clearStateChanges();
968 186 : Helper::clearSubscriptions();
969 186 : PROGRESS_TIME_MESSAGE(before);
970 186 : return STEPS2TIME(newTime);
971 10 : } catch (const IOError& e) {
972 10 : throw TraCIException("Loading state from '" + fileName + "' failed. " + e.what());
973 10 : } catch (const ProcessError& e) {
974 10 : throw TraCIException("Loading state from '" + fileName + "' failed, check whether SUMO versions match. " + e.what());
975 5 : }
976 : }
977 :
978 : void
979 6 : Simulation::writeMessage(const std::string& msg) {
980 6 : WRITE_MESSAGE(msg);
981 6 : }
982 :
983 :
984 : void
985 2290 : Simulation::storeShape(PositionVector& shape) {
986 4580 : shape = GeoConvHelper::getFinal().getConvBoundary().getShape(true);
987 2290 : }
988 :
989 :
990 : std::shared_ptr<VariableWrapper>
991 271 : Simulation::makeWrapper() {
992 271 : return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
993 : }
994 :
995 :
996 : bool
997 7822207 : Simulation::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
998 7822207 : switch (variable) {
999 178694 : case VAR_TIME:
1000 178694 : return wrapper->wrapDouble(objID, variable, getTime());
1001 14 : case VAR_TIME_STEP:
1002 14 : return wrapper->wrapInt(objID, variable, (int)getCurrentTime());
1003 12 : case VAR_END:
1004 12 : return wrapper->wrapDouble(objID, variable, getEndTime());
1005 2 : case VAR_LOADED_VEHICLES_NUMBER:
1006 2 : return wrapper->wrapInt(objID, variable, getLoadedNumber());
1007 42 : case VAR_LOADED_VEHICLES_IDS:
1008 42 : return wrapper->wrapStringList(objID, variable, getLoadedIDList());
1009 2 : case VAR_DEPARTED_VEHICLES_NUMBER:
1010 2 : return wrapper->wrapInt(objID, variable, getDepartedNumber());
1011 64 : case VAR_DEPARTED_VEHICLES_IDS:
1012 64 : return wrapper->wrapStringList(objID, variable, getDepartedIDList());
1013 2 : case VAR_TELEPORT_STARTING_VEHICLES_NUMBER:
1014 2 : return wrapper->wrapInt(objID, variable, getStartingTeleportNumber());
1015 2 : case VAR_TELEPORT_STARTING_VEHICLES_IDS:
1016 2 : return wrapper->wrapStringList(objID, variable, getStartingTeleportIDList());
1017 2 : case VAR_TELEPORT_ENDING_VEHICLES_NUMBER:
1018 2 : return wrapper->wrapInt(objID, variable, getEndingTeleportNumber());
1019 2 : case VAR_TELEPORT_ENDING_VEHICLES_IDS:
1020 2 : return wrapper->wrapStringList(objID, variable, getEndingTeleportIDList());
1021 2 : case VAR_ARRIVED_VEHICLES_NUMBER:
1022 2 : return wrapper->wrapInt(objID, variable, getArrivedNumber());
1023 2 : case VAR_ARRIVED_VEHICLES_IDS:
1024 2 : return wrapper->wrapStringList(objID, variable, getArrivedIDList());
1025 2 : case VAR_PARKING_STARTING_VEHICLES_NUMBER:
1026 2 : return wrapper->wrapInt(objID, variable, getParkingStartingVehiclesNumber());
1027 2 : case VAR_PARKING_STARTING_VEHICLES_IDS:
1028 2 : return wrapper->wrapStringList(objID, variable, getParkingStartingVehiclesIDList());
1029 2 : case VAR_PARKING_ENDING_VEHICLES_NUMBER:
1030 2 : return wrapper->wrapInt(objID, variable, getParkingEndingVehiclesNumber());
1031 2 : case VAR_PARKING_ENDING_VEHICLES_IDS:
1032 2 : return wrapper->wrapStringList(objID, variable, getParkingEndingVehiclesIDList());
1033 2 : case VAR_STOP_STARTING_VEHICLES_NUMBER:
1034 2 : return wrapper->wrapInt(objID, variable, getStopStartingVehiclesNumber());
1035 2 : case VAR_STOP_STARTING_VEHICLES_IDS:
1036 2 : return wrapper->wrapStringList(objID, variable, getStopStartingVehiclesIDList());
1037 2 : case VAR_STOP_ENDING_VEHICLES_NUMBER:
1038 2 : return wrapper->wrapInt(objID, variable, getStopEndingVehiclesNumber());
1039 2 : case VAR_STOP_ENDING_VEHICLES_IDS:
1040 2 : return wrapper->wrapStringList(objID, variable, getStopEndingVehiclesIDList());
1041 3 : case VAR_COLLIDING_VEHICLES_NUMBER:
1042 3 : return wrapper->wrapInt(objID, variable, getCollidingVehiclesNumber());
1043 2 : case VAR_COLLIDING_VEHICLES_IDS:
1044 2 : return wrapper->wrapStringList(objID, variable, getCollidingVehiclesIDList());
1045 2 : case VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:
1046 2 : return wrapper->wrapInt(objID, variable, getEmergencyStoppingVehiclesNumber());
1047 2 : case VAR_EMERGENCYSTOPPING_VEHICLES_IDS:
1048 2 : return wrapper->wrapStringList(objID, variable, getEmergencyStoppingVehiclesIDList());
1049 2 : case VAR_DEPARTED_PERSONS_NUMBER:
1050 2 : return wrapper->wrapInt(objID, variable, getDepartedPersonNumber());
1051 2 : case VAR_DEPARTED_PERSONS_IDS:
1052 2 : return wrapper->wrapStringList(objID, variable, getDepartedPersonIDList());
1053 2 : case VAR_ARRIVED_PERSONS_NUMBER:
1054 2 : return wrapper->wrapInt(objID, variable, getArrivedPersonNumber());
1055 2 : case VAR_ARRIVED_PERSONS_IDS:
1056 2 : return wrapper->wrapStringList(objID, variable, getArrivedPersonIDList());
1057 11 : case VAR_SCALE:
1058 11 : return wrapper->wrapDouble(objID, variable, getScale());
1059 86 : case VAR_DELTA_T:
1060 86 : return wrapper->wrapDouble(objID, variable, getDeltaT());
1061 12 : case VAR_OPTION:
1062 24 : return wrapper->wrapString(objID, variable, getOption(objID));
1063 7641176 : case VAR_MIN_EXPECTED_VEHICLES:
1064 7641176 : return wrapper->wrapInt(objID, variable, getMinExpectedNumber());
1065 11 : case VAR_BUS_STOP_ID_LIST:
1066 11 : return wrapper->wrapStringList(objID, variable, getBusStopIDList());
1067 11 : case VAR_BUS_STOP_WAITING:
1068 11 : return wrapper->wrapInt(objID, variable, getBusStopWaiting(objID));
1069 98 : case VAR_BUS_STOP_WAITING_IDS:
1070 98 : return wrapper->wrapStringList(objID, variable, getBusStopWaitingIDList(objID));
1071 26 : case VAR_PENDING_VEHICLES:
1072 26 : return wrapper->wrapStringList(objID, variable, getPendingVehicles());
1073 1876 : case VAR_PARAMETER:
1074 3743 : return wrapper->wrapString(objID, variable, getParameter(objID, StoHelp::readTypedString(*paramData)));
1075 8 : case VAR_PARAMETER_WITH_KEY:
1076 16 : return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, StoHelp::readTypedString(*paramData)));
1077 : default:
1078 : return false;
1079 : }
1080 : }
1081 : }
1082 :
1083 :
1084 : /****************************************************************************/
|