Eclipse SUMO - Simulation of Urban MObility
libsumo/Simulation.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2017-2022 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 /****************************************************************************/
19 // C++ TraCI client API implementation
20 /****************************************************************************/
21 #include <config.h>
22 #ifdef HAVE_VERSION_H
23 #include <version.h>
24 #endif
27 #include <utils/common/StdDefs.h>
35 #include <utils/xml/XMLSubSys.h>
36 #include <microsim/MSNet.h>
37 #include <microsim/MSEdgeControl.h>
39 #include <microsim/MSEdge.h>
40 #include <microsim/MSLane.h>
41 #include <microsim/MSVehicle.h>
47 #include <microsim/MSParkingArea.h>
51 #include <mesosim/MELoop.h>
52 #include <mesosim/MESegment.h>
53 #include <netload/NLBuilder.h>
54 #include <libsumo/TraCIConstants.h>
55 #include "Simulation.h"
56 #include <libsumo/TraCIDefs.h>
57 
58 
59 namespace libsumo {
60 // ===========================================================================
61 // static member initializations
62 // ===========================================================================
63 SubscriptionResults Simulation::mySubscriptionResults;
64 ContextSubscriptionResults Simulation::myContextSubscriptionResults;
65 
66 
67 // ===========================================================================
68 // static member definitions
69 // ===========================================================================
70 std::pair<int, std::string>
71 Simulation::start(const std::vector<std::string>& cmd, int /* port */, int /* numRetries */, const std::string& /* label */, const bool /* verbose */,
72  const std::string& /* traceFile */, bool /* traceGetters */, void* /* _stdout */) {
73  load(std::vector<std::string>(cmd.begin() + 1, cmd.end()));
74  return getVersion();
75 }
76 
77 
78 void
79 Simulation::load(const std::vector<std::string>& args) {
80  close("Libsumo issued load command.");
81  try {
82  gSimulation = true;
84  OptionsIO::setArgs(args);
85  if (NLBuilder::init(true) != nullptr) {
86  const SUMOTime begin = string2time(OptionsCont::getOptions().getString("begin"));
87  MSNet::getInstance()->setCurrentTimeStep(begin); // needed for state loading
88  WRITE_MESSAGE("Simulation started via Libsumo with time: " + time2string(begin));
89  }
90  } catch (ProcessError& e) {
91  throw TraCIException(e.what());
92  }
93 }
94 
95 
96 bool
97 Simulation::isLoaded() {
98  return MSNet::hasInstance();
99 }
100 
101 
102 void
103 Simulation::step(const double time) {
106  const SUMOTime t = TIME2STEPS(time);
107  if (t == 0) {
109  } else {
110  while (MSNet::getInstance()->getCurrentTimeStep() < t) {
112  }
113  }
115 }
116 
117 
118 void
119 Simulation::close(const std::string& reason) {
121  if (MSNet::hasInstance()) {
122  MSNet::getInstance()->closeSimulation(0, reason);
123  delete MSNet::getInstance();
126  }
127 }
128 
129 
130 void
131 Simulation::subscribe(const std::vector<int>& varIDs, double begin, double end, const libsumo::TraCIResults& params) {
132  libsumo::Helper::subscribe(CMD_SUBSCRIBE_SIM_VARIABLE, "", varIDs, begin, end, params);
133 }
134 
135 
136 const TraCIResults
137 Simulation::getSubscriptionResults() {
138  return mySubscriptionResults[""];
139 }
140 
141 
143 
144 
145 std::pair<int, std::string>
146 Simulation::getVersion() {
147  return std::make_pair(libsumo::TRACI_VERSION, "SUMO " VERSION_STRING);
148 }
149 
150 
151 int
152 Simulation::getCurrentTime() {
153  return (int)MSNet::getInstance()->getCurrentTimeStep();
154 }
155 
156 
157 double
158 Simulation::getTime() {
159  return SIMTIME;
160 }
161 
162 double
163 Simulation::getEndTime() {
164  return STEPS2TIME(string2time(OptionsCont::getOptions().getString("end")));
165 }
166 
167 
168 int
169 Simulation::getLoadedNumber() {
171 }
172 
173 
174 std::vector<std::string>
175 Simulation::getLoadedIDList() {
177 }
178 
179 
180 int
181 Simulation::getDepartedNumber() {
183 }
184 
185 
186 std::vector<std::string>
187 Simulation::getDepartedIDList() {
189 }
190 
191 
192 int
193 Simulation::getArrivedNumber() {
195 }
196 
197 
198 std::vector<std::string>
199 Simulation::getArrivedIDList() {
201 }
202 
203 
204 int
205 Simulation::getParkingStartingVehiclesNumber() {
207 }
208 
209 
210 std::vector<std::string>
211 Simulation::getParkingStartingVehiclesIDList() {
213 }
214 
215 
216 int
217 Simulation::getParkingEndingVehiclesNumber() {
219 }
220 
221 
222 std::vector<std::string>
223 Simulation::getParkingEndingVehiclesIDList() {
225 }
226 
227 
228 int
229 Simulation::getStopStartingVehiclesNumber() {
231 }
232 
233 
234 std::vector<std::string>
235 Simulation::getStopStartingVehiclesIDList() {
237 }
238 
239 
240 int
241 Simulation::getStopEndingVehiclesNumber() {
243 }
244 
245 
246 std::vector<std::string>
247 Simulation::getStopEndingVehiclesIDList() {
249 }
250 
251 
252 int
253 Simulation::getCollidingVehiclesNumber() {
255 }
256 
257 
258 std::vector<std::string>
259 Simulation::getCollidingVehiclesIDList() {
261 }
262 
263 
264 int
265 Simulation::getEmergencyStoppingVehiclesNumber() {
267 }
268 
269 
270 std::vector<std::string>
271 Simulation::getEmergencyStoppingVehiclesIDList() {
273 }
274 
275 
276 int
277 Simulation::getStartingTeleportNumber() {
279 }
280 
281 
282 std::vector<std::string>
283 Simulation::getStartingTeleportIDList() {
285 }
286 
287 
288 int
289 Simulation::getEndingTeleportNumber() {
291 }
292 
293 
294 std::vector<std::string>
295 Simulation::getEndingTeleportIDList() {
297 }
298 
299 int
300 Simulation::getDepartedPersonNumber() {
302 }
303 
304 
305 std::vector<std::string>
306 Simulation::getDepartedPersonIDList() {
308 }
309 
310 
311 int
312 Simulation::getArrivedPersonNumber() {
314 }
315 
316 
317 std::vector<std::string>
318 Simulation::getArrivedPersonIDList() {
320 }
321 
322 std::vector<std::string>
323 Simulation::getBusStopIDList() {
324  std::vector<std::string> result;
325  for (const auto& pair : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP)) {
326  result.push_back(pair.first);
327  }
328  return result;
329 }
330 
331 int
332 Simulation::getBusStopWaiting(const std::string& stopID) {
334  if (s == nullptr) {
335  throw TraCIException("Unknown bus stop '" + stopID + "'.");
336  }
337  return s->getTransportableNumber();
338 }
339 
340 std::vector<std::string>
341 Simulation::getBusStopWaitingIDList(const std::string& stopID) {
343  if (s == nullptr) {
344  throw TraCIException("Unknown bus stop '" + stopID + "'.");
345  }
346  std::vector<std::string> result;
347  for (const MSTransportable* t : s->getTransportables()) {
348  result.push_back(t->getID());
349  }
350  return result;
351 }
352 
353 
354 std::vector<std::string>
355 Simulation::getPendingVehicles() {
356  std::vector<std::string> result;
357  for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
358  result.push_back(veh->getID());
359  }
360  return result;
361 }
362 
363 
364 std::vector<libsumo::TraCICollision>
365 Simulation::getCollisions() {
366  std::vector<libsumo::TraCICollision> result;
367  for (auto item : MSNet::getInstance()->getCollisions()) {
368  for (const MSNet::Collision& c : item.second) {
370  c2.collider = item.first;
371  c2.victim = c.victim;
372  c2.colliderType = c.colliderType;
373  c2.victimType = c.victimType;
375  c2.victimSpeed = c.victimSpeed;
376  c2.type = c.type;
377  c2.lane = c.lane->getID();
378  c2.pos = c.pos;
379  result.push_back(c2);
380  }
381  }
382  return result;
383 }
384 
385 double
386 Simulation::getDeltaT() {
387  return TS;
388 }
389 
390 
391 TraCIPositionVector
392 Simulation::getNetBoundary() {
394  TraCIPositionVector tb;
395  TraCIPosition minV;
396  TraCIPosition maxV;
397  minV.x = b.xmin();
398  maxV.x = b.xmax();
399  minV.y = b.ymin();
400  maxV.y = b.ymax();
401  minV.z = b.zmin();
402  maxV.z = b.zmax();
403  tb.value.push_back(minV);
404  tb.value.push_back(maxV);
405  return tb;
406 }
407 
408 
409 int
410 Simulation::getMinExpectedNumber() {
411  MSNet* net = MSNet::getInstance();
414  + (net->hasPersons() ? net->getPersonControl().getActiveCount() : 0)
415  + (net->hasContainers() ? net->getContainerControl().getActiveCount() : 0));
416 }
417 
418 
419 TraCIPosition
420 Simulation::convert2D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
421  Position result = Helper::getLaneChecking(edgeID, laneIndex, pos)->geometryPositionAtOffset(pos);
422  if (toGeo) {
424  }
425  result.setz(0.);
426  return Helper::makeTraCIPosition(result);
427 }
428 
429 
430 TraCIPosition
431 Simulation::convert3D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
432  Position result = Helper::getLaneChecking(edgeID, laneIndex, pos)->geometryPositionAtOffset(pos);
433  if (toGeo) {
435  }
436  return Helper::makeTraCIPosition(result, true);
437 }
438 
439 
440 TraCIRoadPosition
441 Simulation::convertRoad(double x, double y, bool isGeo, const std::string& vClass) {
442  Position pos(x, y);
443  if (isGeo) {
445  }
446  if (!SumoVehicleClassStrings.hasString(vClass)) {
447  throw TraCIException("Unknown vehicle class '" + vClass + "'.");
448  }
449  const SUMOVehicleClass vc = SumoVehicleClassStrings.get(vClass);
450  std::pair<MSLane*, double> roadPos = libsumo::Helper::convertCartesianToRoadMap(pos, vc);
451  if (roadPos.first == nullptr) {
452  throw TraCIException("Cannot convert position to road.");
453  }
454  TraCIRoadPosition result;
455  result.edgeID = roadPos.first->getEdge().getID();
456  result.laneIndex = roadPos.first->getIndex();
457  result.pos = roadPos.second;
458  return result;
459 }
460 
461 
462 TraCIPosition
463 Simulation::convertGeo(double x, double y, bool fromGeo) {
464  Position pos(x, y);
465  if (fromGeo) {
467  } else {
469  }
470  return Helper::makeTraCIPosition(pos);
471 }
472 
473 
474 double
475 Simulation::getDistance2D(double x1, double y1, double x2, double y2, bool isGeo, bool isDriving) {
476  Position pos1(x1, y1);
477  Position pos2(x2, y2);
478  if (isGeo) {
481  }
482  if (isDriving) {
483  std::pair<const MSLane*, double> roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
484  std::pair<const MSLane*, double> roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
485  return Helper::getDrivingDistance(roadPos1, roadPos2);
486  } else {
487  return pos1.distanceTo(pos2);
488  }
489 }
490 
491 
492 double
493 Simulation::getDistanceRoad(const std::string& edgeID1, double pos1, const std::string& edgeID2, double pos2, bool isDriving) {
494  std::pair<const MSLane*, double> roadPos1 = std::make_pair(libsumo::Helper::getLaneChecking(edgeID1, 0, pos1), pos1);
495  std::pair<const MSLane*, double> roadPos2 = std::make_pair(libsumo::Helper::getLaneChecking(edgeID2, 0, pos2), pos2);
496  if (isDriving) {
497  return Helper::getDrivingDistance(roadPos1, roadPos2);
498  } else {
499  const Position p1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);
500  const Position p2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);
501  return p1.distanceTo(p2);
502  }
503 }
504 
505 
506 TraCIStage
507 Simulation::findRoute(const std::string& from, const std::string& to, const std::string& typeID, const double depart, const int routingMode) {
508  TraCIStage result(STAGE_DRIVING);
509  const MSEdge* const fromEdge = MSEdge::dictionary(from);
510  if (fromEdge == nullptr) {
511  throw TraCIException("Unknown from edge '" + from + "'.");
512  }
513  const MSEdge* const toEdge = MSEdge::dictionary(to);
514  if (toEdge == nullptr) {
515  throw TraCIException("Unknown to edge '" + from + "'.");
516  }
517  SUMOVehicle* vehicle = nullptr;
518  MSVehicleType* type = MSNet::getInstance()->getVehicleControl().getVType(typeID == "" ? DEFAULT_VTYPE_ID : typeID);
519  if (type == nullptr) {
520  throw TraCIException("The vehicle type '" + typeID + "' is not known.");
521  }
523  pars->id = "simulation.findRoute";
524  try {
525  const MSRoute* const routeDummy = new MSRoute("", ConstMSEdgeVector({ fromEdge }), true, nullptr, std::vector<SUMOVehicleParameter::Stop>());
526  vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(pars, routeDummy, type, false);
527  std::string msg;
528  if (!vehicle->hasValidRouteStart(msg)) {
530  throw TraCIException("Invalid departure edge for vehicle type '" + type->getID() + "' (" + msg + ")");
531  }
532  // we need to fix the speed factor here for deterministic results
533  vehicle->setChosenSpeedFactor(type->getSpeedFactor().getParameter()[0]);
534  } catch (ProcessError& e) {
535  throw TraCIException("Invalid departure edge for vehicle type '" + type->getID() + "' (" + e.what() + ")");
536  }
537  ConstMSEdgeVector edges;
538  const SUMOTime dep = depart < 0 ? MSNet::getInstance()->getCurrentTimeStep() : TIME2STEPS(depart);
540  router.compute(fromEdge, toEdge, vehicle, dep, edges);
541  for (const MSEdge* e : edges) {
542  result.edges.push_back(e->getID());
543  }
544  result.travelTime = result.cost = router.recomputeCosts(edges, vehicle, dep, &result.length);
545  if (vehicle != nullptr) {
547  }
548  return result;
549 }
550 
551 
552 std::vector<TraCIStage>
553 Simulation::findIntermodalRoute(const std::string& from, const std::string& to,
554  const std::string& modes, double depart, const int routingMode, double speed, double walkFactor,
555  double departPos, double arrivalPos, const double departPosLat,
556  const std::string& pType, const std::string& vType, const std::string& destStop) {
557  UNUSED_PARAMETER(departPosLat);
558  std::vector<TraCIStage> result;
559  const MSEdge* const fromEdge = MSEdge::dictionary(from);
560  if (fromEdge == nullptr) {
561  throw TraCIException("Unknown from edge '" + from + "'.");
562  }
563  const MSEdge* const toEdge = MSEdge::dictionary(to);
564  if (toEdge == nullptr) {
565  throw TraCIException("Unknown to edge '" + to + "'.");
566  }
568  SVCPermissions modeSet = 0;
569  std::vector<SUMOVehicleParameter*> pars;
570  if (vType != "") {
571  pars.push_back(new SUMOVehicleParameter());
572  pars.back()->vtypeid = vType;
573  pars.back()->id = vType;
574  modeSet |= SVC_PASSENGER;
575  }
576  for (StringTokenizer st(modes); st.hasNext();) {
577  const std::string mode = st.next();
578  if (mode == toString(PersonMode::CAR)) {
579  pars.push_back(new SUMOVehicleParameter());
580  pars.back()->vtypeid = DEFAULT_VTYPE_ID;
581  pars.back()->id = mode;
582  modeSet |= SVC_PASSENGER;
583  } else if (mode == toString(PersonMode::BICYCLE)) {
584  pars.push_back(new SUMOVehicleParameter());
585  pars.back()->vtypeid = DEFAULT_BIKETYPE_ID;
586  pars.back()->id = mode;
587  modeSet |= SVC_BICYCLE;
588  } else if (mode == toString(PersonMode::TAXI)) {
589  pars.push_back(new SUMOVehicleParameter());
590  pars.back()->vtypeid = DEFAULT_TAXITYPE_ID;
591  pars.back()->id = mode;
592  modeSet |= SVC_TAXI;
593  } else if (mode == toString(PersonMode::PUBLIC)) {
594  pars.push_back(nullptr);
595  modeSet |= SVC_BUS;
596  } else if (mode == toString(PersonMode::WALK)) {
597  // do nothing
598  } else {
599  throw TraCIException("Unknown person mode '" + mode + "'.");
600  }
601  }
602  if (pars.empty()) {
603  pars.push_back(nullptr);
604  }
605  // interpret default arguments
606  const MSVehicleType* pedType = vehControl.hasVType(pType) ? vehControl.getVType(pType) : vehControl.getVType(DEFAULT_PEDTYPE_ID);
607  SUMOTime departStep = TIME2STEPS(depart);
608  if (depart < 0) {
609  departStep = MSNet::getInstance()->getCurrentTimeStep();
610  }
611  if (speed < 0) {
612  speed = pedType->getMaxSpeed();
613  }
614  if (walkFactor < 0) {
615  walkFactor = OptionsCont::getOptions().getFloat("persontrip.walkfactor");
616  }
617  const double externalFactor = StringUtils::toDouble(pedType->getParameter().getParameter("externalEffortFactor", "100"));
618  if (departPos < 0) {
619  departPos += fromEdge->getLength();
620  }
621  if (arrivalPos == INVALID_DOUBLE_VALUE) {
622  arrivalPos = toEdge->getLength() / 2;
623  } else if (arrivalPos < 0) {
624  arrivalPos += toEdge->getLength();
625  }
626  if (departPos < 0 || departPos >= fromEdge->getLength()) {
627  throw TraCIException("Invalid depart position " + toString(departPos) + " for edge '" + to + "'.");
628  }
629  if (arrivalPos < 0 || arrivalPos >= toEdge->getLength()) {
630  throw TraCIException("Invalid arrival position " + toString(arrivalPos) + " for edge '" + to + "'.");
631  }
632  double minCost = std::numeric_limits<double>::max();
634  for (SUMOVehicleParameter* vehPar : pars) {
635  std::vector<TraCIStage> resultCand;
636  SUMOVehicle* vehicle = nullptr;
637  if (vehPar != nullptr) {
638  MSVehicleType* type = MSNet::getInstance()->getVehicleControl().getVType(vehPar->vtypeid);
639  if (type == nullptr) {
640  throw TraCIException("Unknown vehicle type '" + vehPar->vtypeid + "'.");
641  }
642  if (type->getVehicleClass() != SVC_IGNORING && (fromEdge->getPermissions() & type->getVehicleClass()) == 0) {
643  WRITE_WARNING("Ignoring vehicle type '" + type->getID() + "' when performing intermodal routing because it is not allowed on the start edge '" + from + "'.");
644  } else {
645  const MSRoute* const routeDummy = new MSRoute(vehPar->id, ConstMSEdgeVector({ fromEdge }), true, nullptr, std::vector<SUMOVehicleParameter::Stop>());
646  vehicle = vehControl.buildVehicle(vehPar, routeDummy, type, !MSGlobals::gCheckRoutes);
647  // we need to fix the speed factor here for deterministic results
648  vehicle->setChosenSpeedFactor(type->getSpeedFactor().getParameter()[0]);
649  }
650  }
651  std::vector<MSNet::MSIntermodalRouter::TripItem> items;
652  if (router.compute(fromEdge, toEdge, departPos, "", arrivalPos, destStop,
653  speed * walkFactor, vehicle, modeSet, departStep, items, externalFactor)) {
654  double cost = 0;
655  for (std::vector<MSNet::MSIntermodalRouter::TripItem>::iterator it = items.begin(); it != items.end(); ++it) {
656  if (!it->edges.empty()) {
657  resultCand.push_back(TraCIStage((it->line == "" ? STAGE_WALKING : STAGE_DRIVING), it->vType, it->line, it->destStop));
658  for (const MSEdge* e : it->edges) {
659  resultCand.back().edges.push_back(e->getID());
660  }
661  resultCand.back().travelTime = it->traveltime;
662  resultCand.back().cost = it->cost;
663  resultCand.back().length = it->length;
664  resultCand.back().intended = it->intended;
665  resultCand.back().depart = it->depart;
666  resultCand.back().departPos = it->departPos;
667  resultCand.back().arrivalPos = it->arrivalPos;
668  resultCand.back().description = it->description;
669  }
670  cost += it->cost;
671  }
672  if (cost < minCost) {
673  minCost = cost;
674  result = resultCand;
675  }
676  }
677  if (vehicle != nullptr) {
678  vehControl.deleteVehicle(vehicle, true);
679  }
680  }
681  return result;
682 }
683 
684 
685 std::string
686 Simulation::getParameter(const std::string& objectID, const std::string& key) {
687  if (StringUtils::startsWith(key, "chargingStation.")) {
688  const std::string attrName = key.substr(16);
690  if (cs == nullptr) {
691  throw TraCIException("Invalid chargingStation '" + objectID + "'");
692  }
693  if (attrName == toString(SUMO_ATTR_TOTALENERGYCHARGED)) {
694  return toString(cs->getTotalCharged());
695  } else if (attrName == toString(SUMO_ATTR_NAME)) {
696  return toString(cs->getMyName());
697  } else if (attrName == "lane") {
698  return cs->getLane().getID();
699  } else if (cs->knowsParameter(attrName)) {
700  return cs->getParameter(attrName);
701  } else {
702  throw TraCIException("Invalid chargingStation parameter '" + attrName + "'");
703  }
704  } else if (StringUtils::startsWith(key, "overheadWire.")) {
705  const std::string attrName = key.substr(16);
707  if (cs == 0) {
708  throw TraCIException("Invalid overhead wire '" + objectID + "'");
709  }
710  if (attrName == toString(SUMO_ATTR_TOTALENERGYCHARGED)) {
711  return toString(cs->getTotalCharged());
712  } else if (attrName == toString(SUMO_ATTR_NAME)) {
713  return toString(cs->getMyName());
714  } else {
715  throw TraCIException("Invalid overhead wire parameter '" + attrName + "'");
716  }
717  } else if (StringUtils::startsWith(key, "net.")) {
718  const std::string attrName = key.substr(4);
720  if (attrName == toString(SUMO_ATTR_NET_OFFSET)) {
721  return toString(GeoConvHelper::getFinal().getOffsetBase());
722  } else {
723  throw TraCIException("Invalid net parameter '" + attrName + "'");
724  }
725  } else if (StringUtils::startsWith(key, "parkingArea.")) {
726  const std::string attrName = key.substr(12);
728  if (pa == nullptr) {
729  throw TraCIException("Invalid parkingArea '" + objectID + "'");
730  }
731  if (attrName == "capacity") {
732  return toString(pa->getCapacity());
733  } else if (attrName == "occupancy") {
735  } else if (attrName == toString(SUMO_ATTR_NAME)) {
736  return toString(pa->getMyName());
737  } else if (attrName == "lane") {
738  return pa->getLane().getID();
739  } else if (pa->knowsParameter(attrName)) {
740  return pa->getParameter(attrName);
741  } else {
742  throw TraCIException("Invalid parkingArea parameter '" + attrName + "'");
743  }
744  } else if (StringUtils::startsWith(key, "busStop.")) {
745  const std::string attrName = key.substr(8);
747  if (bs == nullptr) {
748  throw TraCIException("Invalid busStop '" + objectID + "'");
749  }
750  if (attrName == toString(SUMO_ATTR_NAME)) {
751  return toString(bs->getMyName());
752  } else if (attrName == "lane") {
753  return bs->getLane().getID();
754  } else if (bs->knowsParameter(attrName)) {
755  return bs->getParameter(attrName);
756  } else {
757  throw TraCIException("Invalid busStop parameter '" + attrName + "'");
758  }
759  } else if (objectID == "") {
760  return MSNet::getInstance()->getParameter(key, "");
761  } else {
762  throw TraCIException("Simulation parameter '" + key + "' is not supported for object id '" + objectID + "'. Use empty id for generic network parameters");
763  }
764 }
765 
767 
768 void
769 Simulation::setParameter(const std::string& objectID, const std::string& param, const std::string& value) {
770  if (objectID == "") {
771  MSNet::getInstance()->setParameter(param, value);
772  } else {
773  throw TraCIException("Setting simulation parameter '" + param + "' is not supported for object id '" + objectID + "'. Use empty id for generic network parameters");
774  }
775 }
776 
777 void
778 Simulation::clearPending(const std::string& routeID) {
780 }
781 
782 
783 void
784 Simulation::saveState(const std::string& fileName) {
785  MSStateHandler::saveState(fileName, MSNet::getInstance()->getCurrentTimeStep());
786 }
787 
788 double
789 Simulation::loadState(const std::string& fileName) {
790  long before = PROGRESS_BEGIN_TIME_MESSAGE("Loading state from '" + fileName + "'");
791  // XXX reset transportable state
792  // load time only
793  const SUMOTime newTime = MSStateHandler::MSStateTimeHandler::getTime(fileName);
794  // clean up state
795  MSNet::getInstance()->clearState(newTime);
796  // load state
797  MSStateHandler h(fileName, 0);
798  XMLSubSys::runParser(h, fileName);
799  if (MsgHandler::getErrorInstance()->wasInformed()) {
800  throw TraCIException("Loading state from '" + fileName + "' failed.");
801  }
805  PROGRESS_TIME_MESSAGE(before);
807  return STEPS2TIME(newTime);
808 }
809 
810 void
811 Simulation::writeMessage(const std::string& msg) {
812  WRITE_MESSAGE(msg);
813 }
814 
815 
816 std::shared_ptr<VariableWrapper>
817 Simulation::makeWrapper() {
818  return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
819 }
820 
821 
822 bool
823 Simulation::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
824  switch (variable) {
825  case VAR_TIME:
826  return wrapper->wrapDouble(objID, variable, getTime());
827  case VAR_TIME_STEP:
828  return wrapper->wrapInt(objID, variable, (int)getCurrentTime());
829  case VAR_END:
830  return wrapper->wrapDouble(objID, variable, getEndTime());
832  return wrapper->wrapInt(objID, variable, getLoadedNumber());
834  return wrapper->wrapStringList(objID, variable, getLoadedIDList());
836  return wrapper->wrapInt(objID, variable, getDepartedNumber());
838  return wrapper->wrapStringList(objID, variable, getDepartedIDList());
840  return wrapper->wrapInt(objID, variable, getStartingTeleportNumber());
842  return wrapper->wrapStringList(objID, variable, getStartingTeleportIDList());
844  return wrapper->wrapInt(objID, variable, getEndingTeleportNumber());
846  return wrapper->wrapStringList(objID, variable, getEndingTeleportIDList());
848  return wrapper->wrapInt(objID, variable, getArrivedNumber());
850  return wrapper->wrapStringList(objID, variable, getArrivedIDList());
852  return wrapper->wrapInt(objID, variable, getParkingStartingVehiclesNumber());
854  return wrapper->wrapStringList(objID, variable, getParkingStartingVehiclesIDList());
856  return wrapper->wrapInt(objID, variable, getParkingEndingVehiclesNumber());
858  return wrapper->wrapStringList(objID, variable, getParkingEndingVehiclesIDList());
860  return wrapper->wrapInt(objID, variable, getStopStartingVehiclesNumber());
862  return wrapper->wrapStringList(objID, variable, getStopStartingVehiclesIDList());
864  return wrapper->wrapInt(objID, variable, getStopEndingVehiclesNumber());
866  return wrapper->wrapStringList(objID, variable, getStopEndingVehiclesIDList());
868  return wrapper->wrapInt(objID, variable, getCollidingVehiclesNumber());
870  return wrapper->wrapStringList(objID, variable, getCollidingVehiclesIDList());
872  return wrapper->wrapInt(objID, variable, getEmergencyStoppingVehiclesNumber());
874  return wrapper->wrapStringList(objID, variable, getEmergencyStoppingVehiclesIDList());
876  return wrapper->wrapInt(objID, variable, getDepartedPersonNumber());
878  return wrapper->wrapStringList(objID, variable, getDepartedPersonIDList());
880  return wrapper->wrapInt(objID, variable, getArrivedPersonNumber());
882  return wrapper->wrapStringList(objID, variable, getArrivedPersonIDList());
883  case VAR_DELTA_T:
884  return wrapper->wrapDouble(objID, variable, getDeltaT());
886  return wrapper->wrapInt(objID, variable, getMinExpectedNumber());
888  return wrapper->wrapStringList(objID, variable, getBusStopIDList());
890  return wrapper->wrapInt(objID, variable, getBusStopWaiting(objID));
892  return wrapper->wrapStringList(objID, variable, getBusStopWaitingIDList(objID));
894  return wrapper->wrapStringList(objID, variable, getPendingVehicles());
896  paramData->readUnsignedByte();
897  return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
899  paramData->readUnsignedByte();
900  return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
901  default:
902  return false;
903  }
904 }
905 }
906 
907 
908 /****************************************************************************/
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:282
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
Definition: MsgHandler.h:285
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:286
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define TS
Definition: SUMOTime.h:40
#define SIMTIME
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
const std::string DEFAULT_TAXITYPE_ID
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const std::string DEFAULT_BIKETYPE_ID
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_ATTR_NET_OFFSET
@ SUMO_ATTR_TOTALENERGYCHARGED
@ SUMO_ATTR_NAME
bool gSimulation
Definition: StdDefs.cpp:28
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOMAIN)
Definition: TraCIDefs.h:69
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition: TraCIDefs.h:115
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:129
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:117
double zmin() const
Returns minimum z-coordinate.
Definition: Boundary.cpp:141
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:135
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:123
double zmax() const
Returns maximum z-coordinate.
Definition: Boundary.cpp:147
std::vector< double > & getParameter()
Returns the parameters of this distribution.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
const Position getOffsetBase() const
Returns the network base.
const Boundary & getConvBoundary() const
Returns the converted boundary.
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
bool compute(const E *from, const E *to, const double departPos, const std::string &originStopID, const double arrivalPos, const std::string &stopID, const double speed, const V *const vehicle, const SVCPermissions modeSet, const SUMOTime msTime, std::vector< TripItem > &into, const double externalFactor=0.)
Builds the route between the given edges using the minimum effort at the given time The definition of...
C++ TraCI client API implementation.
Definition: Simulation.h:33
double getTotalCharged() const
A road/street connecting two junctions.
Definition: MSEdge.h:77
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:605
double getLength() const
return the length of the edge
Definition: MSEdge.h:641
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:885
static bool gCheckRoutes
Definition: MSGlobals.h:82
void clearPendingVehicles(const std::string &route)
clears out all pending vehicles from a route, "" for all routes
int getPendingFlowCount() const
Returns the number of flows that are still active.
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:505
The simulated network and simulation perfomer.
Definition: MSNet.h:88
MSIntermodalRouter & getIntermodalRouter(const int rngIndex, const int routingMode=0, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:1390
@ ENDING_PARKING
The vehicle ends to park.
@ STARTING_STOP
The vehicles starts to stop.
@ BUILT
The vehicle was built, but has not yet departed.
@ STARTING_PARKING
The vehicles starts to park.
@ STARTING_TELEPORT
The vehicle started to teleport.
@ ENDING_STOP
The vehicle ends to stop.
@ ENDING_TELEPORT
The vehicle ended being teleported.
@ ARRIVED
The vehicle arrived at his destination (is deleted)
@ DEPARTED
The vehicle has departed (was inserted into the network)
@ COLLISION
The vehicle is involved in a collision.
@ EMERGENCYSTOP
The vehicle had to brake harder than permitted.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:1068
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:1352
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:376
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:318
static bool hasInstance()
Returns whether the network was already constructed.
Definition: MSNet.h:154
void closeSimulation(SUMOTime start, const std::string &reason="")
Closes the simulation (all files, connections, etc.)
Definition: MSNet.cpp:545
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:1250
void simulationStep()
Performs a single simulation step.
Definition: MSNet.cpp:583
virtual void updateGUI() const
update view after simulation.loadState
Definition: MSNet.h:588
void setCurrentTimeStep(const SUMOTime step)
Sets the current simulation step (used by state loading)
Definition: MSNet.h:326
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:409
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:429
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:393
@ PERSON_DEPARTED
The transportable person has departed (was inserted into the network)
@ PERSON_ARRIVED
The transportable person arrived at his destination (is deleted)
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1059
void clearState(const SUMOTime step)
Resets events when quick-loading state.
Definition: MSNet.cpp:824
Definition of overhead wire segment.
double getTotalCharged() const
A lane area vehicles can halt at.
Definition: MSParkingArea.h:58
int getCapacity() const
Returns the area capacity.
int getOccupancyIncludingBlocked() const
Returns the area occupancy.
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
static SUMOTime getTime(const std::string &fileName)
parse time from state file
Parser and output filter for routes and vehicles state saving and loading.
static void saveState(const std::string &file, SUMOTime step)
Saves the current state.
A lane area vehicles can halt at.
std::vector< const MSTransportable * > getTransportables() const
Returns the tranportables waiting on this stop.
int getTransportableNumber() const
Returns the number of transportables waiting on this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
const std::string & getMyName() const
int getActiveCount()
return the number of active transportable objects
The class responsible for building and deletion of vehicles.
bool hasVType(const std::string &id) const
Asks for existence of a vehicle type.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
int getActiveVehicleCount() const
Returns the number of build vehicles that have not been removed or need to wait for a passenger or a ...
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
The car-following model and parameter.
Definition: MSVehicleType.h:62
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:90
const SUMOVTypeParameter & getParameter() const
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
static MSNet * init(const bool isLibsumo=false)
Definition: NLBuilder.cpp:270
const std::string & getID() const
Returns the id.
Definition: Named.h:74
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:58
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:242
void setz(double z)
set position z
Definition: Position.h:80
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
virtual void setChosenSpeedFactor(const double factor)=0
virtual bool hasValidRouteStart(std::string &msg)=0
checks wether the vehicle can depart on the first edge
Structure representing possible vehicle parameter.
std::string id
The vehicle's id.
bool hasNext()
returns the information whether further substrings exist
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static void close()
Closes all of an applications subsystems.
static void close()
Closes the xml-subsystem.
Definition: XMLSubSys.cpp:120
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:54
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:149
static double getDrivingDistance(std::pair< const MSLane *, double > &roadPos1, std::pair< const MSLane *, double > &roadPos2)
Definition: Helper.cpp:453
static TraCIPosition makeTraCIPosition(const Position &position, const bool includeZ=false)
Definition: Helper.cpp:378
static void subscribe(const int commandId, const std::string &id, const std::vector< int > &variables, const double beginTime, const double endTime, const libsumo::TraCIResults &params, const int contextDomain=0, const double range=0.)
Definition: Helper.cpp:142
static const std::vector< std::string > & getTransportableStateChanges(const MSNet::TransportableState state)
Definition: Helper.cpp:719
static void clearVehicleStates()
Definition: Helper.cpp:703
static void clearSubscriptions()
Definition: Helper.cpp:233
static void clearTransportableStates()
Definition: Helper.cpp:725
static std::pair< MSLane *, double > convertCartesianToRoadMap(const Position &pos, const SUMOVehicleClass vClass)
Definition: Helper.cpp:421
static const std::vector< std::string > & getVehicleStateChanges(const MSNet::VehicleState state)
Definition: Helper.cpp:697
static void handleSubscriptions(const SUMOTime t)
Definition: Helper.cpp:183
static const MSLane * getLaneChecking(const std::string &edgeID, int laneIndex, double pos)
Definition: Helper.cpp:404
virtual std::string readString()
Definition: storage.cpp:180
virtual int readUnsignedByte()
Definition: storage.cpp:155
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int VAR_MIN_EXPECTED_VEHICLES
TRACI_CONST int VAR_STOP_ENDING_VEHICLES_IDS
TRACI_CONST int CMD_SUBSCRIBE_SIM_VARIABLE
TRACI_CONST int VAR_ARRIVED_VEHICLES_NUMBER
TRACI_CONST int VAR_STOP_STARTING_VEHICLES_NUMBER
TRACI_CONST int VAR_DEPARTED_VEHICLES_NUMBER
TRACI_CONST int VAR_COLLIDING_VEHICLES_NUMBER
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition: TraCIDefs.h:279
TRACI_CONST int VAR_PARKING_ENDING_VEHICLES_IDS
TRACI_CONST int VAR_PARKING_STARTING_VEHICLES_IDS
TRACI_CONST int VAR_DEPARTED_PERSONS_NUMBER
TRACI_CONST int VAR_END
TRACI_CONST int VAR_ARRIVED_PERSONS_IDS
TRACI_CONST int ROUTING_MODE_AGGREGATED
TRACI_CONST int VAR_TIME
TRACI_CONST int VAR_PENDING_VEHICLES
TRACI_CONST int VAR_BUS_STOP_ID_LIST
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition: TraCIDefs.h:278
TRACI_CONST int TRACI_VERSION
TRACI_CONST int VAR_EMERGENCYSTOPPING_VEHICLES_IDS
TRACI_CONST int VAR_BUS_STOP_WAITING_IDS
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int VAR_DEPARTED_VEHICLES_IDS
TRACI_CONST int VAR_TELEPORT_ENDING_VEHICLES_NUMBER
TRACI_CONST int VAR_PARKING_ENDING_VEHICLES_NUMBER
TRACI_CONST int VAR_LOADED_VEHICLES_IDS
TRACI_CONST int VAR_DELTA_T
TRACI_CONST int STAGE_WALKING
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_DEPARTED_PERSONS_IDS
TRACI_CONST int VAR_ARRIVED_PERSONS_NUMBER
TRACI_CONST int VAR_STOP_STARTING_VEHICLES_IDS
TRACI_CONST int VAR_STOP_ENDING_VEHICLES_NUMBER
TRACI_CONST int VAR_LOADED_VEHICLES_NUMBER
TRACI_CONST int VAR_TELEPORT_ENDING_VEHICLES_IDS
TRACI_CONST int VAR_COLLIDING_VEHICLES_IDS
TRACI_CONST int VAR_TELEPORT_STARTING_VEHICLES_NUMBER
TRACI_CONST int VAR_TELEPORT_STARTING_VEHICLES_IDS
TRACI_CONST int VAR_BUS_STOP_WAITING
TRACI_CONST int VAR_TIME_STEP
TRACI_CONST int VAR_ARRIVED_VEHICLES_IDS
TRACI_CONST int STAGE_DRIVING
TRACI_CONST int VAR_PARKING_STARTING_VEHICLES_NUMBER
TRACI_CONST int VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER
std::map< int, std::shared_ptr< libsumo::TraCIResult > > TraCIResults
{variable->value}
Definition: TraCIDefs.h:276
collision tracking
Definition: MSNet.h:116
double victimSpeed
Definition: MSNet.h:121
const MSLane * lane
Definition: MSNet.h:123
std::string victimType
Definition: MSNet.h:119
double pos
Definition: MSNet.h:124
std::string type
Definition: MSNet.h:122
std::string colliderType
Definition: MSNet.h:118
std::string victim
Definition: MSNet.h:117
double colliderSpeed
Definition: MSNet.h:120
std::string lane
The lane where the collision happended.
Definition: TraCIDefs.h:584
std::string type
The type of collision.
Definition: TraCIDefs.h:582
std::string collider
The ids of the participating vehicles and persons.
Definition: TraCIDefs.h:575
std::string victimType
Definition: TraCIDefs.h:578
double pos
The position of the collision along the lane.
Definition: TraCIDefs.h:586
std::string colliderType
Definition: TraCIDefs.h:577