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