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