Eclipse SUMO - Simulation of Urban MObility
NLTriggerBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-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 /****************************************************************************/
24 // Builds trigger objects for microsim
25 /****************************************************************************/
26 #include <config.h>
27 
28 #include <string>
30 #include <microsim/MSLane.h>
31 #include <microsim/MSEdge.h>
32 #include <microsim/MSGlobals.h>
33 #include <microsim/MSParkingArea.h>
46 #include <utils/common/RGBColor.h>
48 #include "NLHandler.h"
49 #include "NLTriggerBuilder.h"
51 #include <utils/xml/XMLSubSys.h>
52 
53 
54 #include <mesosim/MELoop.h>
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
62  : myHandler(nullptr), myParkingArea(nullptr), myCurrentStop(nullptr) {}
63 
64 
66 
67 void
69  myHandler = handler;
70 }
71 
72 
73 void
75  WRITE_WARNING("Vaporizers are deprecated. Use rerouters instead.");
76  bool ok = true;
77  // get the id, throw if not given or empty...
78  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
79  if (!ok) {
80  return;
81  }
82  MSEdge* e = MSEdge::dictionary(id);
83  if (e == nullptr) {
84  WRITE_ERROR("Unknown edge ('" + id + "') referenced in a vaporizer.");
85  return;
86  }
87  SUMOTime begin = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok);
88  SUMOTime end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok);
89  if (!ok) {
90  return;
91  }
92  if (begin < 0) {
93  WRITE_ERROR("A vaporization begin time is negative (edge id='" + id + "').");
94  return;
95  }
96  if (begin >= end) {
97  WRITE_ERROR("A vaporization ends before it starts (edge id='" + id + "').");
98  return;
99  }
100  if (end >= string2time(OptionsCont::getOptions().getString("begin"))) {
105  }
106 }
107 
108 
109 
110 void
112  const std::string& base) {
113  // get the id, throw if not given or empty...
114  bool ok = true;
115  // get the id, throw if not given or empty...
116  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
117  if (!ok) {
118  return;
119  }
120  // get the file name to read further definitions from
121  std::string file = getFileName(attrs, base, true);
122  std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANES, id.c_str(), ok);
123  std::vector<MSLane*> lanes;
124  for (const std::string& laneID : attrs.get<std::vector<std::string> >(SUMO_ATTR_LANES, id.c_str(), ok)) {
125  MSLane* lane = MSLane::dictionary(laneID);
126  if (lane == nullptr) {
127  throw InvalidArgument("The lane '" + laneID + "' to use within MSLaneSpeedTrigger '" + id + "' is not known.");
128  }
129  lanes.push_back(lane);
130  }
131  if (!ok) {
132  throw InvalidArgument("The lanes to use within MSLaneSpeedTrigger '" + id + "' are not known.");
133  }
134  if (lanes.size() == 0) {
135  throw InvalidArgument("No lane defined for MSLaneSpeedTrigger '" + id + "'.");
136  }
137  try {
138  MSLaneSpeedTrigger* trigger = buildLaneSpeedTrigger(net, id, lanes, file);
139  if (file == "") {
141  }
142  } catch (ProcessError& e) {
143  throw InvalidArgument(e.what());
144  }
145 }
146 
147 void
149  bool ok = true;
150 
151  // get the id, throw if not given or empty...
152  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
153  if (!ok) {
154  throw ProcessError();
155  }
156 
157  MSLane* const lane = getLane(attrs, "chargingStation", id);
158  double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
159  double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
160  const double chargingPower = attrs.getOpt<double>(SUMO_ATTR_CHARGINGPOWER, id.c_str(), ok, 0);
161  const double efficiency = attrs.getOpt<double>(SUMO_ATTR_EFFICIENCY, id.c_str(), ok, 0.95);
162  const bool chargeInTransit = attrs.getOpt<bool>(SUMO_ATTR_CHARGEINTRANSIT, id.c_str(), ok, 0);
163  const SUMOTime chargeDelay = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CHARGEDELAY, id.c_str(), ok, 0);
164  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
165  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
166 
167  if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
168  throw InvalidArgument("Invalid position for charging station '" + id + "'.");
169  }
170 
171  buildChargingStation(net, id, lane, frompos, topos, name, chargingPower, efficiency, chargeInTransit, chargeDelay);
172 }
173 
174 void
176  bool ok = true;
177 
178  // get the id, throw if not given or empty...
179  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
180  if (!ok) {
181  throw ProcessError();
182  }
183 
184  /* The following call may either throw InvalidArgument exeption or return NULL:
185  NULL is returned in case when the overhead wire segment should be built over an already
186  ignored internal lane of an intersection, the exeption is thrown in case that
187  the overhead wire segment references a non-existent lane. */
188  MSLane* const lane = getLane(attrs, "overheadWireSegment", id);
189  if (lane == nullptr) {
190  WRITE_MESSAGE("The overheadWireSegment '" + id + "' was not created as it is attached to internal lane. It will be build automatically.");
191  return;
192  }
193 
194  if (lane->isInternal()) {
195  WRITE_MESSAGE("The overheadWireSegment '" + id + "' not built as it is attached to internal lane. It will be build automatically.");
196  return;
197  }
198 
199  double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
200  double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
201  const bool voltageSource = attrs.getOpt<bool>(SUMO_ATTR_VOLTAGESOURCE, id.c_str(), ok, false);
202  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
203 
204  if (!ok || myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID) {
205  frompos = 0;
206  topos = lane->getLength();
207  WRITE_MESSAGE("The overheadWireSegment '" + id + "' has wrong position. Automatically set from 0 to the length of the lane.");
208  //throw InvalidArgument("Invalid position for overheadWireSegment'" + id + "'.");
209  }
210 
211  buildOverheadWireSegment(net, id, lane, frompos, topos, voltageSource);
212 #ifndef HAVE_EIGEN
214  myHaveWarnedAboutEigen = true;
215  WRITE_WARNING("Overhead wire solver (Eigen) not compiled in, expect errors in overhead wire simulation")
216  }
217 #endif // !HAVE_EIGEN
218 }
219 
220 void
222  bool ok = true;
223  std::string substationId = attrs.get<std::string>(SUMO_ATTR_SUBSTATIONID, 0, ok);
224  if (!ok) {
225  throw ProcessError();
226  }
227 
228  MSTractionSubstation* substation = MSNet::getInstance()->findTractionSubstation(substationId);
229  if (substation == nullptr) {
230  throw InvalidArgument("Traction substation '" + substationId + "' refereced by an OverheadWire Section is not known.");
231  } else if (substation->isAnySectionPreviouslyDefined()) {
232  throw InvalidArgument("Traction substation '" + substationId + "' refereced by an OverheadWire Section is probably referenced twice (a known limitation of the actual version of overhead wire simulation).");
233  }
234 
235  // @todo This may be a relict of older approach to processing the attributes ...
236  std::string segmentStrings = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SECTION, substationId.c_str(), ok);
237  if (!ok) {
238  throw InvalidArgument("Segments referenced by Traction Substation '" + substationId + "' are not declared .");
239  }
240 
241  // process forbidden internal lanes
243  std::string forbiddenInnerLanesStrings = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_FORBIDDEN, 0, ok, "");
244  if (forbiddenInnerLanesStrings != "") {
245  std::vector<std::string> forbiddenInnerLanesIDs = attrs.getStringVector(SUMO_ATTR_OVERHEAD_WIRE_FORBIDDEN);
247  for (std::vector<std::string>::iterator i = forbiddenInnerLanesIDs.begin(); i != forbiddenInnerLanesIDs.end(); ++i) {
248  MSLane* lane = MSLane::dictionary(*i);
249  if (lane != nullptr) {
250  substation->addForbiddenLane(lane);
251  }
252  }
253  }
254 
255 
256  // @todo Check this as well ...
257  // Original version from 2018
258  // std::vector<std::string> segmentIDs;
259  // SUMOSAXAttributes::parseStringVector(segmentStrings, segmentIDs);
260  std::vector<std::string> segmentIDs = attrs.getStringVector(SUMO_ATTR_OVERHEAD_WIRE_SECTION);
261  std::vector<MSOverheadWire*> segments;
262 
263  // ----------------------------------------------
264  // Add overhead wire segments over internal lanes
265  // ----------------------------------------------
266 
267  // Adding internal overhead wire segments (segments on neighboring inner lanes if a connection between two regular lane with overhead wire segment exists)
268  for (std::vector<std::string>::iterator it_segment = segmentIDs.begin(); it_segment != segmentIDs.end(); ++it_segment) {
269 
270  const MSLane* connection = nullptr;
272  std::string neigboringOvrhdSegmentID;
273  MSOverheadWire* neigboringOvrhdSegment;
274  MSTractionSubstation* neigboringOvrhdSegmentTractionSubstation;
275  if (ovrhdSegment == nullptr) {
276  throw InvalidArgument("The OverheadWireSegment with id='" + (*it_segment) + "' referenced by OverheadWireSgment for substation '" + substationId + "' was not defined.");
277  }
278 
279  MSTractionSubstation* ts = ovrhdSegment->getTractionSubstation();
280  if (!(ts == substation || ts == nullptr)) {
281  std::string tsName = ts->getID();
282  throw InvalidArgument("The OverheadWireSegment '" + (*it_segment) + "' referenced by OverheadWireSgment for substation '" + substationId + "' is already assigned to substation '" + tsName + "'.");
283  }
284  ovrhdSegment->setTractionSubstation(substation);
285 
286  const MSLane* lane = &(ovrhdSegment->getLane());
287 
288  /* in version before SUMO 1.0.1 the function getOutgoingLanes() returning MSLane* exists,
289  in new version of SUMO the funciton getOutgoingViaLanes() returning MSLane* and MSEdge* pair exists */
290  const std::vector<std::pair<const MSLane*, const MSEdge*> > outgoingLanesAndEdges = lane->getOutgoingViaLanes();
291  std::vector<const MSLane*> neigboringInnerLanes;
292  neigboringInnerLanes.reserve(outgoingLanesAndEdges.size());
293  for (size_t it = 0; it < outgoingLanesAndEdges.size(); ++it) {
294  neigboringInnerLanes.push_back(outgoingLanesAndEdges[it].first);
295  }
296 
297  // Check if an outgoing lane has an overhead wire segment. If not, do nothing, otherwise find connnecting internal lanes and
298  // add overhead wire segments over all detected internal lanes
299  for (std::vector<const MSLane*>::iterator it = neigboringInnerLanes.begin(); it != neigboringInnerLanes.end(); ++it) {
300  // If the overhead wire segment is over the outgoing (not internal) lane
301  neigboringOvrhdSegmentID = MSNet::getInstance()->getStoppingPlaceID(*it, NUMERICAL_EPS, SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
302  if (neigboringOvrhdSegmentID != "") {
303  neigboringOvrhdSegment = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(neigboringOvrhdSegmentID, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
304  neigboringOvrhdSegmentTractionSubstation = neigboringOvrhdSegment->getTractionSubstation();
305  } else {
306  neigboringOvrhdSegment = nullptr;
307  neigboringOvrhdSegmentTractionSubstation = nullptr;
308  }
309 
310  if (neigboringOvrhdSegmentTractionSubstation == substation && !(*it)->isInternal()) {
311  connection = lane->getInternalFollowingLane(*it);
312  if (connection != nullptr) {
313  //is connection forbidden?
314  if (!(substation->isForbidden(connection) || substation->isForbidden(lane->getInternalFollowingLane(connection)) || substation->isForbidden(connection->getInternalFollowingLane(*it)))) {
315  buildInnerOverheadWireSegments(net, connection, lane->getInternalFollowingLane(connection), connection->getInternalFollowingLane(*it));
316  }
317  }
318  }
319  }
320 
321  // Check if an incoming lane has an overhead wire segment. If not, do nothing, otherwise find connnecting internal lanes and
322  // add overhead wire segments over all detected internal lanes
323  neigboringInnerLanes = lane->getNormalIncomingLanes();
324  for (std::vector<const MSLane*>::iterator it = neigboringInnerLanes.begin(); it != neigboringInnerLanes.end(); ++it) {
325  // If the overhead wire segment is over the incoming (not internal) lane
326  neigboringOvrhdSegmentID = MSNet::getInstance()->getStoppingPlaceID(*it, (*it)->getLength() - NUMERICAL_EPS, SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
327  if (neigboringOvrhdSegmentID != "") {
328  neigboringOvrhdSegment = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(neigboringOvrhdSegmentID, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
329  neigboringOvrhdSegmentTractionSubstation = neigboringOvrhdSegment->getTractionSubstation();
330  } else {
331  neigboringOvrhdSegment = nullptr;
332  neigboringOvrhdSegmentTractionSubstation = nullptr;
333  }
334 
335  if (neigboringOvrhdSegmentTractionSubstation == substation && !(*it)->isInternal()) {
336  connection = (*it)->getInternalFollowingLane(lane);
337  if (connection != nullptr) {
338  //is connection forbidden?
339  if (!(substation->isForbidden(connection) || substation->isForbidden((*it)->getInternalFollowingLane(connection)) || substation->isForbidden(connection->getInternalFollowingLane(lane)))) {
340  buildInnerOverheadWireSegments(net, connection, (*it)->getInternalFollowingLane(connection), connection->getInternalFollowingLane(lane));
341  }
342  }
343  }
344  }
345  }
346 
347 
348  // ----- *** adding segments into the electric circuit*** -----
349 
350  // setting nullptr for substation (a fragment from old version of adding segments into the circuit)
351  for (std::vector<std::string>::iterator it_segment = segmentIDs.begin(); it_segment != segmentIDs.end(); ++it_segment) {
353  ovrhdSegment->setTractionSubstation(nullptr);
354  }
355 
356  for (std::vector<std::string>::iterator it_segment = segmentIDs.begin(); it_segment != segmentIDs.end(); ++it_segment) {
357  if (*it_segment == "") {
358  continue;
359  }
361  substation->addOverheadWireSegmentToCircuit(ovrhdSegment);
362  segments.push_back(ovrhdSegment);
363  }
364 
365  // adding overhead wire clamp
366  std::string clampsString = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMPS, 0, ok, "");
367  if (clampsString != "" && MSGlobals::gOverheadWireSolver) {
368 #ifdef HAVE_EIGEN
369  std::vector<std::string> clampIDs = attrs.getStringVector(SUMO_ATTR_OVERHEAD_WIRE_CLAMPS);
371  for (std::vector<std::string>::iterator it_clamp = clampIDs.begin(); it_clamp != clampIDs.end(); ++it_clamp) {
372  clamp = substation->findClamp(*it_clamp);
373  if (clamp != nullptr) {
374  if (clamp->start->getTractionSubstation() == substation && clamp->end->getTractionSubstation() == substation) {
375  substation->addOverheadWireClampToCircuit(clamp->id, clamp->start, clamp->end);
376  buildOverheadWireClamp(net, clamp->id, const_cast<MSLane*>(&clamp->start->getLane()), const_cast<MSLane*>(&clamp->end->getLane()));
377  clamp->usage = true;
378  } else {
379  if (clamp->start->getTractionSubstation() != substation) {
380  WRITE_WARNING("A connecting overhead wire start segment '" + clamp->start->getID() + "' defined for overhead wire clamp '" + (*it_clamp) + "' is not assigned to the traction substation '" + substationId + "'.");
381  } else {
382  WRITE_WARNING("A connecting overhead wire end segment '" + clamp->end->getID() + "' defined for overhead wire clamp '" + (*it_clamp) + "' is not assigned to the traction substation '" + substationId + "'.");
383  }
384  }
385  } else {
386  WRITE_WARNING("The overhead wire clamp '" + (*it_clamp) + "' defined in an overhead wire section was not assigned to the substation '" + substationId + "'. Please define proper <overheadWireClamp .../> in additional files before defining overhead wire section.");
387  }
388  }
389 #else
390  WRITE_WARNING("Overhead circuit solver requested, but solver support (Eigen) not compiled in.");
391 #endif
392  }
393 
394  if (segments.size() == 0) {
395  throw InvalidArgument("No segments found for overHeadWireSection '" + substationId + "'.");
396  } else if (MSGlobals::gOverheadWireSolver) {
397 #ifdef HAVE_EIGEN
398  // check that the electric circuit makes sense
399  segments[0]->getCircuit()->checkCircuit(substationId);
400 #else
401  WRITE_WARNING("Cannot check circuit, overhead circuit solver support (Eigen) not compiled in.");
402 #endif
403  }
404 }
405 
406 void
408  bool ok = true;
409 
410  // get the id, throw if not given or empty...
411  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
412  if (!ok) {
413  throw ProcessError();
414  }
415 
416  // RICE_TODO Limits are fixed, change them to some predefined constants ...
417  const double voltage = attrs.getOpt<double>(SUMO_ATTR_VOLTAGE, id.c_str(), ok, 600);
418  const double currentLimit = attrs.getOpt<double>(SUMO_ATTR_CURRENTLIMIT, id.c_str(), ok, 400);
419  buildTractionSubstation(net, id, voltage, currentLimit);
420 }
421 
422 void
425 #ifdef HAVE_EIGEN
426  bool ok = true;
427  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
428  if (!ok) {
429  throw ProcessError();
430  }
431 
432  std::string substationId = attrs.get<std::string>(SUMO_ATTR_SUBSTATIONID, 0, ok);
433  if (!ok) {
434  throw ProcessError();
435  }
436  MSTractionSubstation* substation = MSNet::getInstance()->findTractionSubstation(substationId);
437  if (substation == nullptr) {
438  throw InvalidArgument("Traction substation '" + substationId + "' using within an overheadWireClamp '" + id + "' is not known.");
439  }
440 
441  std::string overhead_fromItsStart = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMP_START, 0, ok);
442  if (!ok) {
443  throw ProcessError();
444  }
445  MSOverheadWire* ovrhdSegment_fromItsStart = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(overhead_fromItsStart, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
446  if (ovrhdSegment_fromItsStart == nullptr) {
447  throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsStart + "' to use within overheadWireClamp '" + id + "' is not known.");
448  }
449  /*if (ovrhdSegment_fromItsStart->getTractionSubstation() != substation) {
450  throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsStart + "' to use within overheadWireClamp is assign to a different overhead wire section or substation.");
451  }
452  */
453  std::string overhead_fromItsEnd = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMP_END, 0, ok);
454  if (!ok) {
455  throw ProcessError();
456  }
457  MSOverheadWire* ovrhdSegment_fromItsEnd = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(overhead_fromItsEnd, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
458  if (ovrhdSegment_fromItsEnd == nullptr) {
459  throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsEnd + "' to use within overheadWireClamp '" + id + "' is not known.");
460  }
461  /*
462  if (ovrhdSegment_fromItsEnd->getTractionSubstation() != substation) {
463  throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsEnd + "' to use within overheadWireClamp is assign to a different overhead wire section or substation.");
464  }
465  */
466  if (substation->findClamp(id) == nullptr) {
467  substation->addClamp(id, ovrhdSegment_fromItsStart, ovrhdSegment_fromItsEnd);
468  } else {
469  WRITE_ERROR("The overhead wire clamp '" + id + "' is probably declared twice.")
470  }
471 #else
472  UNUSED_PARAMETER(attrs);
473  WRITE_WARNING("Not building overhead wire clamps, overhead wire solver support (Eigen) not compiled in.");
474 #endif
475  } else {
476  WRITE_WARNING("Ignoring overhead wire clamps, they make no sense when overhead wire circuit solver is off.");
477  }
478 }
479 
480 
481 void
483  bool ok = true;
484  // get the id, throw if not given or empty...
485  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
486  if (!ok) {
487  throw ProcessError();
488  }
489 
490  //get the name, leave blank if not given
491  const std::string ptStopName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
492 
493  //get the color, use default if not given
494  // default color, copy from GUIVisualizationStoppingPlaceSettings::busStopColor / containerStopColor
495  RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor::INVISIBLE);
496 
497  MSLane* lane = getLane(attrs, toString(element), id);
498  // get the positions
499  double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
500  double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
501  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
502  if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
503  throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
504  }
505  const std::vector<std::string>& lines = attrs.getOptStringVector(SUMO_ATTR_LINES, id.c_str(), ok, false);
506  int defaultCapacity;
507  SumoXMLAttr capacityAttr;
508  if (element != SUMO_TAG_CONTAINER_STOP) {
509  defaultCapacity = MAX2(MSStoppingPlace::getTransportablesAbreast(topos - frompos, element) * 3, 6);
510  capacityAttr = SUMO_ATTR_PERSON_CAPACITY;
511  } else {
512  defaultCapacity = MSStoppingPlace::getTransportablesAbreast(topos - frompos, element);
513  capacityAttr = SUMO_ATTR_CONTAINER_CAPACITY;
514  }
515  const int transportableCapacity = attrs.getOpt<int>(capacityAttr, id.c_str(), ok, defaultCapacity);
516  const double parkingLength = attrs.getOpt<double>(SUMO_ATTR_PARKING_LENGTH, id.c_str(), ok, 0);
517  // build the bus stop
518  buildStoppingPlace(net, id, lines, lane, frompos, topos, element, ptStopName, transportableCapacity, parkingLength, color);
519 }
520 
521 
522 void
524  if (myCurrentStop == nullptr) {
525  throw InvalidArgument("Could not add access outside a stopping place.");
526  }
527  // get the lane
528  MSLane* lane = getLane(attrs, "access", myCurrentStop->getID());
529  if (!lane->allowsVehicleClass(SVC_PEDESTRIAN)) {
530  WRITE_WARNING("Ignoring invalid access from non-pedestrian lane '" + lane->getID() + "' in busStop '" + myCurrentStop->getID() + "'.");
531  return;
532  }
533  // get the positions
534  bool ok = true;
535  double pos = attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0);
536  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
537  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
538  if (!ok || (myHandler->checkStopPos(pos, pos, lane->getLength(), 0, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
539  throw InvalidArgument("Invalid position " + toString(pos) + " for access on lane '" + lane->getID() + "' in stop '" + myCurrentStop->getID() + "'.");
540  }
541  // add bus stop access
542  if (!myCurrentStop->addAccess(lane, pos, length)) {
543  throw InvalidArgument("Duplicate access on lane '" + lane->getID() + "' for stop '" + myCurrentStop->getID() + "'");
544  }
545 }
546 
547 
548 void
550  bool ok = true;
551  // get the id, throw if not given or empty...
552  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
553  if (!ok) {
554  throw ProcessError();
555  }
556  // get the lane
557  MSLane* lane = getLane(attrs, "parkingArea", id);
558  // get the positions
559  double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
560  double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
561  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
562  unsigned int capacity = attrs.getOpt<int>(SUMO_ATTR_ROADSIDE_CAPACITY, id.c_str(), ok, 0);
563  bool onRoad = attrs.getOpt<bool>(SUMO_ATTR_ONROAD, id.c_str(), ok, false);
564  double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, 0);
565  double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
566  double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, id.c_str(), ok, 0);
567  const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
568  const std::string departPos = attrs.getOpt<std::string>(SUMO_ATTR_DEPARTPOS, id.c_str(), ok, "");
569  if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
570  throw InvalidArgument("Invalid position for parking area '" + id + "'.");
571  }
572  const std::vector<std::string>& lines = attrs.getOptStringVector(SUMO_ATTR_LINES, id.c_str(), ok, false);
573  // build the parking area
574  beginParkingArea(net, id, lines, lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos);
575 }
576 
577 
578 
579 void
581  bool ok = true;
582  // Check for open parking area
583  if (myParkingArea == nullptr) {
584  throw ProcessError();
585  }
586  // get the positions
587  double x = attrs.get<double>(SUMO_ATTR_X, "", ok);
588  if (!ok) {
589  throw InvalidArgument("Invalid x position for lot entry.");
590  }
591  double y = attrs.get<double>(SUMO_ATTR_Y, "", ok);
592  if (!ok) {
593  throw InvalidArgument("Invalid y position for lot entry.");
594  }
595  double z = attrs.getOpt<double>(SUMO_ATTR_Z, "", ok, 0.);
596  double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, "", ok, myParkingArea->getWidth());
597  double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "", ok, myParkingArea->getLength());
598  double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, "", ok, myParkingArea->getAngle());
599  double slope = attrs.getOpt<double>(SUMO_ATTR_SLOPE, "", ok, 0.);
600  // add the lot entry
601  addLotEntry(x, y, z, width, length, angle, slope);
602 }
603 
604 
605 void
607  const std::string& base) {
608  bool ok = true;
609  // get the id, throw if not given or empty...
610  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
611  if (!ok) {
612  throw ProcessError();
613  }
614  MSLane* lane = nullptr;
615  MSEdge* edge = nullptr;
616  // get the file name to read further definitions from
617  if (attrs.hasAttribute(SUMO_ATTR_EDGE)) {
618  std::string edgeID = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
619  edge = MSEdge::dictionary(edgeID);
620  if (edge == nullptr) {
621  throw InvalidArgument("The edge " + edgeID + " to use within the calibrator '" + id + "' is not known.");
622  }
623  if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
624  lane = getLane(attrs, "calibrator", id);
625  if (&lane->getEdge() != edge) {
626  throw InvalidArgument("The edge " + edgeID + " to use within the calibrator '" + id
627  + "' does not match the calibrator lane '" + lane->getID() + ".");
628  }
629  }
630  } else {
631  lane = getLane(attrs, "calibrator", id);
632  edge = &lane->getEdge();
633  }
634  const double pos = getPosition(attrs, lane, "calibrator", id, edge);
635  const SUMOTime freq = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, DELTA_T); // !!! no error handling
636  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
637  std::string file = getFileName(attrs, base, true);
638  std::string outfile = attrs.getOpt<std::string>(SUMO_ATTR_OUTPUT, id.c_str(), ok, "");
639  std::string routeProbe = attrs.getOpt<std::string>(SUMO_ATTR_ROUTEPROBE, id.c_str(), ok, "");
640  // differing defaults for backward compatibility, values are dimensionless
641  double invalidJamThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, MSGlobals::gUseMesoSim ? 0.8 : 0.5);
642  MSRouteProbe* probe = nullptr;
643  if (routeProbe != "") {
644  probe = dynamic_cast<MSRouteProbe*>(net.getDetectorControl().getTypedDetectors(SUMO_TAG_ROUTEPROBE).get(routeProbe));
645  if (probe == nullptr) {
646  throw InvalidArgument("The routeProbe '" + routeProbe + "' to use within the calibrator '" + id + "' is not known.");
647  }
648  }
650  if (lane != nullptr && edge->getLanes().size() > 1) {
651  WRITE_WARNING("Meso calibrator '" + id
652  + "' defined for lane '" + lane->getID()
653  + "' will collect data for all lanes of edge '" + edge->getID() + "'.");
654  }
655  METriggeredCalibrator* trigger = buildMECalibrator(net, id, edge, pos, file, outfile, freq, probe, invalidJamThreshold, vTypes);
656  if (file == "") {
658  }
659  } else {
660  MSCalibrator* trigger = buildCalibrator(net, id, edge, lane, pos, file, outfile, freq, probe, invalidJamThreshold, vTypes);
661  if (file == "") {
663  }
664  }
665 }
666 
667 
668 void
670  const std::string& base) {
671  bool ok = true;
672  // get the id, throw if not given or empty...
673  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
674  if (!ok) {
675  throw ProcessError();
676  }
677  // get the file name to read further definitions from
678  std::string file = getFileName(attrs, base, true);
679  MSEdgeVector edges;
680  for (const std::string& edgeID : attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok)) {
681  MSEdge* edge = MSEdge::dictionary(edgeID);
682  if (edge == nullptr) {
683  throw InvalidArgument("The edge '" + edgeID + "' to use within MSTriggeredRerouter '" + id + "' is not known.");
684  }
685  edges.push_back(edge);
686  }
687  if (!ok) {
688  throw InvalidArgument("The edge to use within MSTriggeredRerouter '" + id + "' is not known.");
689  }
690  if (edges.size() == 0) {
691  throw InvalidArgument("No edges found for MSTriggeredRerouter '" + id + "'.");
692  }
693  double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, id.c_str(), ok, 1);
694  bool off = attrs.getOpt<bool>(SUMO_ATTR_OFF, id.c_str(), ok, false);
695  SUMOTime timeThreshold = TIME2STEPS(attrs.getOpt<double>(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, 0));
696  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
697  if (!ok) {
698  throw InvalidArgument("Could not parse MSTriggeredRerouter '" + id + "'.");
699  }
700  MSTriggeredRerouter* trigger = buildRerouter(net, id, edges, prob, file, off, timeThreshold, vTypes);
701  // read in the trigger description
702  if (file == "") {
704  } else if (!XMLSubSys::runParser(*trigger, file)) {
705  throw ProcessError();
706  }
707 }
708 
709 
710 // -------------------------
711 
712 
714 NLTriggerBuilder::buildLaneSpeedTrigger(MSNet& /*net*/, const std::string& id,
715  const std::vector<MSLane*>& destLanes,
716  const std::string& file) {
717  return new MSLaneSpeedTrigger(id, destLanes, file);
718 }
719 
720 
722 NLTriggerBuilder::buildMECalibrator(MSNet& /*net*/, const std::string& id,
723  const MSEdge* edge,
724  double pos,
725  const std::string& file,
726  const std::string& outfile,
727  const SUMOTime freq,
728  MSRouteProbe* probe,
729  const double invalidJamThreshold,
730  const std::string& vTypes) {
731  return new METriggeredCalibrator(id, edge, pos, file, outfile, freq, MSGlobals::gMesoNet->getSegmentForEdge(*edge, pos)->getLength(), probe, invalidJamThreshold, vTypes);
732 }
733 
734 
736 NLTriggerBuilder::buildCalibrator(MSNet& /*net*/, const std::string& id,
737  MSEdge* edge,
738  MSLane* lane,
739  double pos,
740  const std::string& file,
741  const std::string& outfile,
742  const SUMOTime freq,
743  const MSRouteProbe* probe,
744  const double invalidJamThreshold,
745  const std::string& vTypes) {
746  return new MSCalibrator(id, edge, lane, pos, file, outfile, freq, edge->getLength(), probe, invalidJamThreshold, vTypes);
747 }
748 
749 
751 NLTriggerBuilder::buildRerouter(MSNet&, const std::string& id,
752  MSEdgeVector& edges,
753  double prob, const std::string& file, bool off,
754  SUMOTime timeThreshold,
755  const std::string& vTypes) {
756  return new MSTriggeredRerouter(id, edges, prob, file, off, timeThreshold, vTypes);
757 }
758 
759 
760 void
761 NLTriggerBuilder::buildStoppingPlace(MSNet& net, std::string id, std::vector<std::string> lines, MSLane* lane,
762  double frompos, double topos, const SumoXMLTag element, std::string ptStopName,
763  int personCapacity, double parkingLength, RGBColor& color) {
764  myCurrentStop = new MSStoppingPlace(id, element, lines, *lane, frompos, topos, ptStopName, personCapacity, parkingLength, color);
765  if (!net.addStoppingPlace(element, myCurrentStop)) {
766  delete myCurrentStop;
767  myCurrentStop = nullptr;
768  throw InvalidArgument("Could not build " + toString(element) + " '" + id + "'; probably declared twice.");
769  }
770 }
771 
772 
773 void
774 NLTriggerBuilder::beginParkingArea(MSNet& net, const std::string& id,
775  const std::vector<std::string>& lines,
776  MSLane* lane, double frompos, double topos,
777  unsigned int capacity,
778  double width, double length, double angle, const std::string& name,
779  bool onRoad,
780  const std::string& departPos) {
781  // Close previous parking area if there are not lots inside
782  MSParkingArea* stop = new MSParkingArea(id, lines, *lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos);
783  if (!net.addStoppingPlace(SUMO_TAG_PARKING_AREA, stop)) {
784  delete stop;
785  throw InvalidArgument("Could not build parking area '" + id + "'; probably declared twice.");
786  } else {
787  myParkingArea = stop;
788  }
789 }
790 
791 
792 void
793 NLTriggerBuilder::addLotEntry(double x, double y, double z,
794  double width, double length,
795  double angle, double slope) {
796  if (myParkingArea != nullptr) {
797  if (!myParkingArea->parkOnRoad()) {
798  myParkingArea->addLotEntry(x, y, z, width, length, angle, slope);
799  } else {
800  throw InvalidArgument("Cannot not add lot entry to on-road parking area.");
801  }
802  } else {
803  throw InvalidArgument("Could not add lot entry outside a parking area.");
804  }
805 }
806 
807 
808 void
810  if (myParkingArea != nullptr) {
811  myParkingArea = nullptr;
812  } else {
813  throw InvalidArgument("Could not end a parking area that is not opened.");
814  }
815 }
816 
817 
818 void
820  if (myCurrentStop != nullptr) {
821  myCurrentStop = nullptr;
822  } else {
823  throw InvalidArgument("Could not end a stopping place that is not opened.");
824  }
825 }
826 
827 
828 void
829 NLTriggerBuilder::buildChargingStation(MSNet& net, const std::string& id, MSLane* lane, double frompos, double topos, const std::string& name,
830  double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay) {
831  MSChargingStation* chargingStation = new MSChargingStation(id, *lane, frompos, topos, name, chargingPower, efficiency, chargeInTransit, chargeDelay);
832  if (!net.addStoppingPlace(SUMO_TAG_CHARGING_STATION, chargingStation)) {
833  delete chargingStation;
834  throw InvalidArgument("Could not build charging station '" + id + "'; probably declared twice.");
835  }
836  myCurrentStop = chargingStation;
837 }
838 
839 void
840 NLTriggerBuilder::buildOverheadWireSegment(MSNet& net, const std::string& id, MSLane* lane, double frompos, double topos,
841  bool voltageSource) {
842  MSOverheadWire* overheadWireSegment = new MSOverheadWire(id, *lane, frompos, topos, voltageSource);
843  if (!net.addStoppingPlace(SUMO_TAG_OVERHEAD_WIRE_SEGMENT, overheadWireSegment)) {
844  delete overheadWireSegment;
845  throw InvalidArgument("Could not build overheadWireSegment '" + id + "'; probably declared twice.");
846  }
847 }
848 
849 void
850 NLTriggerBuilder::buildInnerOverheadWireSegments(MSNet& net, const MSLane* connection, const MSLane* frontConnection, const MSLane* behindConnection) {
851  if (frontConnection == NULL && behindConnection == NULL) {
852  buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
853  } else if (frontConnection != NULL && behindConnection == NULL) {
854  buildOverheadWireSegment(net, "ovrhd_inner_" + frontConnection->getID(), const_cast<MSLane*>(frontConnection), 0, frontConnection->getLength(), false);
855  buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
856  } else if (frontConnection == NULL && behindConnection != NULL) {
857  buildOverheadWireSegment(net, "ovrhd_inner_" + behindConnection->getID(), const_cast<MSLane*>(behindConnection), 0, behindConnection->getLength(), false);
858  buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
859  } else if (frontConnection != NULL && behindConnection != NULL) {
860  buildOverheadWireSegment(net, "ovrhd_inner_" + frontConnection->getID(), const_cast<MSLane*>(frontConnection), 0, frontConnection->getLength(), false);
861  buildOverheadWireSegment(net, "ovrhd_inner_" + behindConnection->getID(), const_cast<MSLane*>(behindConnection), 0, behindConnection->getLength(), false);
862  buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
863  }
864 }
865 
866 void
867 NLTriggerBuilder::buildTractionSubstation(MSNet& net, std::string id, double voltage, double currentLimit) {
868  MSTractionSubstation* myTractionSubstation = new MSTractionSubstation(id, voltage, currentLimit);
869  if (!net.addTractionSubstation(myTractionSubstation)) {
870  delete myTractionSubstation;
871  throw InvalidArgument("Could not build traction substation '" + id + "'; probably declared twice.");
872  }
873 }
874 
875 void
876 NLTriggerBuilder::buildOverheadWireClamp(MSNet& /*net*/, const std::string& /*id*/, MSLane* /*lane_start*/, MSLane* /*lane_end*/) {
877 }
878 
879 std::string
881  const std::string& base,
882  const bool allowEmpty) {
883  // get the file name to read further definitions from
884  bool ok = true;
885  std::string file = attrs.getOpt<std::string>(SUMO_ATTR_FILE, nullptr, ok, "");
886  if (file == "") {
887  if (allowEmpty) {
888  return file;
889  }
890  throw InvalidArgument("No filename given.");
891  }
892  // check whether absolute or relative filenames are given
893  if (!FileHelpers::isAbsolute(file)) {
894  return FileHelpers::getConfigurationRelative(base, file);
895  }
896  return file;
897 }
898 
899 
900 MSLane*
902  const std::string& tt,
903  const std::string& tid) {
904  bool ok = true;
905  std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANE, tid.c_str(), ok);
906  MSLane* lane = MSLane::dictionary(objectid);
907  if (lane == nullptr) {
908  // Either a lane that is non-existent/broken, or a lane that is internal and has been ignored.
909  // We assume that internal lane names start with ':'.
910  if (objectid[0] == ':' && !MSGlobals::gUsingInternalLanes) {
911  return nullptr;
912  }
913  // Throw the exception only in case that the lane really does not exist in the network file
914  // or it is broken.
915  throw InvalidArgument("The lane " + objectid + " to use within the " + tt + " '" + tid + "' is not known.");
916  }
917  return lane;
918 }
919 
920 
921 double
923  MSLane* lane,
924  const std::string& tt, const std::string& tid,
925  MSEdge* edge) {
926  assert(lane != 0 || edge != 0);
927  const double length = lane != nullptr ? lane->getLength() : edge->getLength();
928  bool ok = true;
929  double pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
930  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
931  if (!ok) {
932  throw InvalidArgument("Error on parsing a position information.");
933  }
934  if (pos < 0) {
935  pos = length + pos;
936  }
937  if (pos > length) {
938  if (friendlyPos) {
939  pos = length - (double) 0.1;
940  } else {
941  if (lane != nullptr) {
942  throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the lane's '" + lane->getID() + "' length.");
943  } else {
944  throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the edges's '" + edge->getID() + "' length.");
945  }
946  }
947  }
948  return pos;
949 }
950 
953  return myParkingArea == nullptr ? myCurrentStop : myParkingArea;
954 }
955 
956 
957 /****************************************************************************/
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:282
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
@ SVC_PEDESTRIAN
pedestrian
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_REROUTER
A rerouter.
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_VSS
A variable speed sign.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_LINES
@ SUMO_ATTR_LANE
@ SUMO_ATTR_OVERHEAD_WIRE_SECTION
@ SUMO_ATTR_FILE
@ SUMO_ATTR_Y
@ SUMO_ATTR_SUBSTATIONID
id of a traction substation substation
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_PARKING_LENGTH
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_VOLTAGE
voltage of the traction substation [V]
@ SUMO_ATTR_X
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_OFF
@ SUMO_ATTR_ROUTEPROBE
@ SUMO_ATTR_OVERHEAD_WIRE_FORBIDDEN
forbidden lanes for overhead wire segment
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_OVERHEAD_WIRE_CLAMP_END
id of the overhead wire segment, to the end of which the overhead wire clamp is connected
@ SUMO_ATTR_LANES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_CHARGEINTRANSIT
Allow/disallow charge in transit in Charging Stations.
@ SUMO_ATTR_CONTAINER_CAPACITY
@ SUMO_ATTR_NAME
@ SUMO_ATTR_SLOPE
@ SUMO_ATTR_FREQUENCY
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_OVERHEAD_WIRE_CLAMPS
overhead wire clamps for overhead wire segment
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ROADSIDE_CAPACITY
@ SUMO_ATTR_CURRENTLIMIT
current limit of the traction substation [A]
@ SUMO_ATTR_OUTPUT
@ SUMO_ATTR_CHARGINGPOWER
@ SUMO_ATTR_PROB
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_ONROAD
@ SUMO_ATTR_OVERHEAD_WIRE_CLAMP_START
id of the overhead wire segment, to the start of which the overhead wire clamp is connected
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_EFFICIENCY
Eficiency of the charge in Charging Stations.
@ SUMO_ATTR_ID
@ SUMO_ATTR_VOLTAGESOURCE
a voltage source on the overhead wire segment [bool]
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_CHARGEDELAY
Delay in the charge of charging stations.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
Base (microsim) event class.
Definition: Command.h:50
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
void registerParent(const int tag, GenericSAXHandler *handler)
Assigning a parent handler which is enabled when the specified tag is closed.
Calibrates the flow on a segment to a specified one.
Calibrates the flow on a segment to a specified one.
Definition: MSCalibrator.h:48
const NamedObjectCont< MSDetectorFileOutput * > & getTypedDetectors(SumoXMLTag type) const
Returns the list of detectors of the given type.
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:447
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
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:440
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition: MSGlobals.h:94
static bool gOverheadWireSolver
Definition: MSGlobals.h:109
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:100
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:72
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
double getLength() const
Returns the lane's length.
Definition: MSLane.h:541
const MSLane * getInternalFollowingLane(const MSLane *const) const
returns the internal lane leading to the given lane or nullptr, if there is none
Definition: MSLane.cpp:2226
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:814
const std::vector< std::pair< const MSLane *, const MSEdge * > > getOutgoingViaLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2739
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1991
bool isInternal() const
Definition: MSLane.cpp:2122
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:674
std::vector< const MSLane * > getNormalIncomingLanes() const
get the list of all direct (disregarding internal predecessors) non-internal predecessor lanes of thi...
Definition: MSLane.cpp:2749
Changes the speed allowed on a set of lanes.
The simulated network and simulation perfomer.
Definition: MSNet.h:88
bool addStoppingPlace(const SumoXMLTag category, MSStoppingPlace *stop)
Adds a stopping place.
Definition: MSNet.cpp:1234
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
MSDetectorControl & getDetectorControl()
Returns the detector control.
Definition: MSNet.h:439
bool addTractionSubstation(MSTractionSubstation *substation)
Adds a traction substation.
Definition: MSNet.cpp:1240
std::string getStoppingPlaceID(const MSLane *lane, const double pos, const SumoXMLTag category) const
Returns the stop of the given category close to the given position.
Definition: MSNet.cpp:1259
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:1250
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:469
MSTractionSubstation * findTractionSubstation(const std::string &substationId)
find electrical substation by its id
Definition: MSNet.cpp:1330
Definition of overhead wire segment.
MSTractionSubstation * getTractionSubstation() const
void setTractionSubstation(MSTractionSubstation *substation)
A lane area vehicles can halt at.
Definition: MSParkingArea.h:58
double getAngle() const
Returns the lot rectangle angle.
double getLength() const
Returns the lot rectangle length.
virtual void addLotEntry(double x, double y, double z, double width, double length, double angle, double slope)
Add a lot entry to parking area.
double getWidth() const
Returns the lot rectangle width.
bool parkOnRoad() const
whether vehicles park on the road
Writes routes of vehicles passing a certain edge.
Definition: MSRouteProbe.h:58
A lane area vehicles can halt at.
int getTransportablesAbreast() const
virtual bool addAccess(MSLane *lane, const double pos, double length)
adds an access point to this stop
const MSLane & getLane() const
Returns the lane this stop is located at.
Traction substaction powering one or more overhead wire sections.
void addOverheadWireClampToCircuit(const std::string id, MSOverheadWire *startSegment, MSOverheadWire *endSegment)
void addClamp(const std::string &id, MSOverheadWire *startPos, MSOverheadWire *endPos)
bool isForbidden(const MSLane *lane)
void addOverheadWireSegmentToCircuit(MSOverheadWire *newOverheadWireSegment)
OverheadWireClamp * findClamp(std::string id)
Find an overhead wire clamp by its ID.
void addForbiddenLane(MSLane *lane)
Reroutes vehicles passing an edge.
The XML-Handler for network loading.
Definition: NLHandler.h:79
NLTriggerBuilder()
Constructor.
virtual void buildOverheadWireClamp(MSNet &net, const std::string &id, MSLane *lane_start, MSLane *lane_end)
MSParkingArea * myParkingArea
definition of the currently parsed parking area
void parseAndBuildTractionSubstation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds a traction substation.
virtual void beginParkingArea(MSNet &net, const std::string &id, const std::vector< std::string > &lines, MSLane *lane, double frompos, double topos, unsigned int capacity, double width, double length, double angle, const std::string &name, bool onRoad, const std::string &departPos)
Begin a parking area.
void addAccess(MSNet &net, const SUMOSAXAttributes &attrs)
Parses the values and adds an access point to the currently parsed stopping place.
void parseAndBuildOverheadWireSegment(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire segment.
void parseAndBuildCalibrator(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a mesoscopic or microscopic calibrator.
double getPosition(const SUMOSAXAttributes &attrs, MSLane *lane, const std::string &tt, const std::string &tid, MSEdge *edge=0)
returns the position on the lane checking it
void buildInnerOverheadWireSegments(MSNet &net, const MSLane *connection, const MSLane *frontConnection, const MSLane *behindConnection)
Builds an overhead wire inner segments.
virtual MSLaneSpeedTrigger * buildLaneSpeedTrigger(MSNet &net, const std::string &id, const std::vector< MSLane * > &destLanes, const std::string &file)
Builds a lane speed trigger.
virtual void endParkingArea()
End a parking area.
void parseAndBuildLaneSpeedTrigger(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a lane speed trigger.
void parseAndAddLotEntry(const SUMOSAXAttributes &attrs)
Parses his values and adds a lot entry to current parking area.
NLHandler * myHandler
The parent handler to set for subhandlers.
MSLane * getLane(const SUMOSAXAttributes &attrs, const std::string &tt, const std::string &tid)
Returns the lane defined by attribute "lane".
void buildVaporizer(const SUMOSAXAttributes &attrs)
Builds a vaporization.
virtual MSTriggeredRerouter * buildRerouter(MSNet &net, const std::string &id, MSEdgeVector &edges, double prob, const std::string &file, bool off, SUMOTime timeThreshold, const std::string &vTypes)
builds an rerouter
void parseAndBuildOverheadWireSection(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire section.
void setHandler(NLHandler *handler)
Sets the parent handler to use for nested parsing.
virtual MSCalibrator * buildCalibrator(MSNet &net, const std::string &id, MSEdge *edge, MSLane *lane, double pos, const std::string &file, const std::string &outfile, const SUMOTime freq, const MSRouteProbe *probe, const double invalidJamThreshold, const std::string &vTypes)
builds a microscopic calibrator
virtual ~NLTriggerBuilder()
Destructor.
void buildTractionSubstation(MSNet &net, std::string id, double voltage, double currentLimit)
Builds a traction substation.
void addLotEntry(double x, double y, double z, double width, double length, double angle, double slope)
Add a lot entry to current parking area.
void parseAndBuildChargingStation(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a charging station.
void parseAndBuildOverheadWireClamp(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire clamp.
void parseAndBuildRerouter(MSNet &net, const SUMOSAXAttributes &attrs, const std::string &base)
Parses his values and builds a rerouter.
virtual void endStoppingPlace()
End a stopping place.
virtual void buildOverheadWireSegment(MSNet &net, const std::string &id, MSLane *lane, double frompos, double topos, bool voltageSource)
Builds an overhead wire segment.
MSStoppingPlace * myCurrentStop
The currently parsed stop to add access points to.
MSStoppingPlace * getCurrentStop()
virtual METriggeredCalibrator * buildMECalibrator(MSNet &net, const std::string &id, const MSEdge *edge, double pos, const std::string &file, const std::string &outfile, const SUMOTime freq, MSRouteProbe *probe, const double invalidJamThreshold, const std::string &vTypes)
builds a mesoscopic calibrator
virtual void buildStoppingPlace(MSNet &net, std::string id, std::vector< std::string > lines, MSLane *lane, double frompos, double topos, const SumoXMLTag element, std::string string, int personCapacity, double parkingLength, RGBColor &color)
Builds a stopping place.
virtual void buildChargingStation(MSNet &net, const std::string &id, MSLane *lane, double frompos, double topos, const std::string &name, double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay)
Builds a charging station.
void parseAndBuildStoppingPlace(MSNet &net, const SUMOSAXAttributes &attrs, const SumoXMLTag element)
Parses the values and builds a stopping places for busses, trains or container vehicles.
void parseAndBeginParkingArea(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a parking area.
std::string getFileName(const SUMOSAXAttributes &attrs, const std::string &base, const bool allowEmpty=false)
Helper method to obtain the filename.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
T get(const std::string &id) const
Retrieves an item.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static const RGBColor INVISIBLE
Definition: RGBColor.h:195
static StopPos checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
const std::vector< std::string > getOptStringVector(int attr, const char *objectid, bool &ok, bool report=true) const
convenience function to avoid the default argument and the template stuff at getOpt<>
const std::vector< std::string > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
A wrapper for a Command function.
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