Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NLTriggerBuilder.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
24// Builds trigger objects for microsim
25/****************************************************************************/
26#include <config.h>
27
28#include <string>
29#include <mesosim/MELoop.h>
33#include <microsim/MSLane.h>
34#include <microsim/MSEdge.h>
35#include <microsim/MSGlobals.h>
52#include <utils/xml/XMLSubSys.h>
53#include "NLHandler.h"
54#include "NLTriggerBuilder.h"
55
56
57// ===========================================================================
58// method definitions
59// ===========================================================================
61 : myHandler(nullptr), myParkingArea(nullptr), myCurrentStop(nullptr) {}
62
63
65
66void
68 myHandler = handler;
69}
70
71
72void
74 WRITE_WARNING(TL("Vaporizers are deprecated. Use rerouters instead."));
75 bool ok = true;
76 // get the id, throw if not given or empty...
77 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
78 if (!ok) {
79 return;
80 }
82 if (e == nullptr) {
83 WRITE_ERRORF(TL("Unknown edge ('%') referenced in a vaporizer."), id);
84 return;
85 }
86 SUMOTime begin = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok);
87 SUMOTime end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok);
88 if (!ok) {
89 return;
90 }
91 if (begin < 0) {
92 WRITE_ERRORF(TL("A vaporization begin time is negative (edge id='%')."), id);
93 return;
94 }
95 if (begin >= end) {
96 WRITE_ERRORF(TL("A vaporization ends before it starts (edge id='%')."), id);
97 return;
98 }
99 if (end >= string2time(OptionsCont::getOptions().getString("begin"))) {
104 }
105}
106
107
108void
110 const std::string& base) {
111 // get the id, throw if not given or empty...
112 bool ok = true;
113 // get the id, throw if not given or empty...
114 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
115 if (!ok) {
116 return;
117 }
118 // get the file name to read further definitions from
119 std::string file = getFileName(attrs, base, true);
120 std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANES, id.c_str(), ok);
121 std::vector<MSLane*> lanes;
122 for (const std::string& laneID : attrs.get<std::vector<std::string> >(SUMO_ATTR_LANES, id.c_str(), ok)) {
123 MSLane* lane = MSLane::dictionary(laneID);
124 if (lane == nullptr) {
125 throw InvalidArgument("The lane '" + laneID + "' to use within MSLaneSpeedTrigger '" + id + "' is not known.");
126 }
127 lanes.push_back(lane);
128 }
129 if (!ok) {
130 throw InvalidArgument("The lanes to use within MSLaneSpeedTrigger '" + id + "' are not known.");
131 }
132 if (lanes.size() == 0) {
133 throw InvalidArgument("No lane defined for MSLaneSpeedTrigger '" + id + "'.");
134 }
135 try {
136 MSLaneSpeedTrigger* trigger = buildLaneSpeedTrigger(net, id, lanes, file);
137 if (file == "") {
139 }
140 } catch (ProcessError& e) {
141 throw InvalidArgument(e.what());
142 }
143}
144
145
146void
148 bool ok = true;
149
150 // get the id, throw if not given or empty...
151 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
152 if (!ok) {
153 throw ProcessError();
154 }
155
156 MSLane* const lane = getLane(attrs, "chargingStation", id);
157 double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
158 double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
159 const double chargingPower = attrs.getOpt<double>(SUMO_ATTR_CHARGINGPOWER, id.c_str(), ok, 22000);
160 const double efficiency = attrs.getOpt<double>(SUMO_ATTR_EFFICIENCY, id.c_str(), ok, 0.95);
161 const bool chargeInTransit = attrs.getOpt<bool>(SUMO_ATTR_CHARGEINTRANSIT, id.c_str(), ok, 0);
162 const SUMOTime chargeDelay = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CHARGEDELAY, id.c_str(), ok, 0);
163 const std::string chargeType = attrs.getOpt<std::string>(SUMO_ATTR_CHARGETYPE, id.c_str(), ok, "normal");
164 const SUMOTime waitingTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_WAITINGTIME, id.c_str(), ok, 900);
165 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
166 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
167 MSParkingArea* parkingArea = getParkingArea(attrs, "parkingArea", id);
168
169 // check charge type
170 if ((chargeType != "normal") && (chargeType != "battery-exchange") && (chargeType != "fuel")) {
171 throw InvalidArgument("The chargeType to use within MSLaneSpeedTrigger '" + id + "' is invalid.");
172 }
173
174 if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
175 throw InvalidArgument("Invalid position for charging station '" + id + "'.");
176 }
177
178 buildChargingStation(net, id, lane, frompos, topos, name, chargingPower, efficiency, chargeInTransit, chargeDelay, chargeType, waitingTime, parkingArea);
179}
180
181
182void
184 bool ok = true;
185
186 // get the id, throw if not given or empty...
187 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
188 if (!ok) {
189 throw ProcessError();
190 }
191
192 /* The following call may either throw InvalidArgument exeption or return NULL:
193 NULL is returned in case when the overhead wire segment should be built over an already
194 ignored internal lane of an intersection, the exeption is thrown in case that
195 the overhead wire segment references a non-existent lane. */
196 MSLane* const lane = getLane(attrs, "overheadWireSegment", id);
197 if (lane == nullptr) {
198 WRITE_MESSAGEF(TL("The overheadWireSegment '%' was not created as it is attached to internal lane. It will be build automatically."), id);
199 return;
200 }
201
202 if (lane->isInternal()) {
203 WRITE_MESSAGEF(TL("The overheadWireSegment '%' not built as it is attached to internal lane. It will be build automatically."), id);
204 return;
205 }
206
207 double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
208 double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
209 const bool voltageSource = attrs.getOpt<bool>(SUMO_ATTR_VOLTAGESOURCE, id.c_str(), ok, false);
210 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
211
212 if (!ok || myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID) {
213 frompos = 0;
214 topos = lane->getLength();
215 WRITE_MESSAGEF(TL("The overheadWireSegment '%' has wrong position. Automatically set from 0 to the length of the lane."), id);
216 //throw InvalidArgument("Invalid position for overheadWireSegment'" + id + "'.");
217 }
218
219 buildOverheadWireSegment(net, id, lane, frompos, topos, voltageSource);
220#ifndef HAVE_EIGEN
223 WRITE_WARNING(TL("Overhead wire solver (Eigen) not compiled in, expect errors in overhead wire simulation"))
224 }
225#endif // !HAVE_EIGEN
226}
227
228void
230 bool ok = true;
231 std::string substationId = attrs.get<std::string>(SUMO_ATTR_SUBSTATIONID, 0, ok);
232 if (!ok) {
233 throw ProcessError();
234 }
235
237 if (substation == nullptr) {
238 throw InvalidArgument("Traction substation '" + substationId + "' refereced by an OverheadWire Section is not known.");
239 } else if (substation->isAnySectionPreviouslyDefined()) {
240 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).");
241 }
242
243 // @todo This may be a relict of older approach to processing the attributes ...
244 std::string segmentStrings = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENTS, substationId.c_str(), ok);
245 if (!ok) {
246 throw InvalidArgument("Segments referenced by Traction substation '" + substationId + "' are not declared .");
247 }
248
249 // process forbidden internal lanes
250 const std::vector<std::string>& forbiddenInnerLanesIDs = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_OVERHEAD_WIRE_FORBIDDEN, substationId.c_str(), ok);
252 for (const std::string& laneID : forbiddenInnerLanesIDs) {
253 MSLane* lane = MSLane::dictionary(laneID);
254 if (lane != nullptr) {
255 substation->addForbiddenLane(lane);
256 } else {
257 throw InvalidArgument("Unknown lane '" + laneID + "' in Traction substation '" + substationId + "'.");
258 }
259 }
260
261 // @todo Check this as well ...
262 // Original version from 2018
263 // std::vector<std::string> segmentIDs;
264 // SUMOSAXAttributes::parseStringVector(segmentStrings, segmentIDs);
265 const std::vector<std::string>& segmentIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_OVERHEAD_WIRE_SEGMENTS, substationId.c_str(), ok);
266 std::vector<MSOverheadWire*> segments;
267
268 // ----------------------------------------------
269 // Add overhead wire segments over internal lanes
270 // ----------------------------------------------
271
272 // Adding internal overhead wire segments (segments on neighboring inner lanes if a connection between two regular lane with overhead wire segment exists)
273 for (const std::string& segmentID : segmentIDs) {
274 const MSLane* connection = nullptr;
276 std::string neigboringOvrhdSegmentID;
277 MSOverheadWire* neigboringOvrhdSegment;
278 MSTractionSubstation* neigboringOvrhdSegmentTractionSubstation;
279 if (ovrhdSegment == nullptr) {
280 throw InvalidArgument("The OverheadWireSegment with id='" + segmentID + "' referenced by OverheadWireSegment for substation '" + substationId + "' was not defined.");
281 }
282
283 MSTractionSubstation* ts = ovrhdSegment->getTractionSubstation();
284 if (!(ts == substation || ts == nullptr)) {
285 std::string tsName = ts->getID();
286 throw InvalidArgument("The OverheadWireSegment '" + segmentID + "' referenced by OverheadWireSegment for substation '" + substationId + "' is already assigned to substation '" + tsName + "'.");
287 }
288 ovrhdSegment->setTractionSubstation(substation);
289
290 const MSLane* lane = &(ovrhdSegment->getLane());
291
292 /* in version before SUMO 1.0.1 the function getOutgoingLanes() returning MSLane* exists,
293 in new version of SUMO the funciton getOutgoingViaLanes() returning MSLane* and MSEdge* pair exists */
294 const std::vector<std::pair<const MSLane*, const MSEdge*> > outgoingLanesAndEdges = lane->getOutgoingViaLanes();
295 std::vector<const MSLane*> neigboringInnerLanes;
296 neigboringInnerLanes.reserve(outgoingLanesAndEdges.size());
297 for (size_t it = 0; it < outgoingLanesAndEdges.size(); ++it) {
298 neigboringInnerLanes.push_back(outgoingLanesAndEdges[it].first);
299 }
300
301 // Check if an outgoing lane has an overhead wire segment. If not, do nothing, otherwise find connnecting internal lanes and
302 // add overhead wire segments over all detected internal lanes
303 for (std::vector<const MSLane*>::iterator it = neigboringInnerLanes.begin(); it != neigboringInnerLanes.end(); ++it) {
304 // If the overhead wire segment is over the outgoing (not internal) lane
305 neigboringOvrhdSegmentID = MSNet::getInstance()->getStoppingPlaceID(*it, NUMERICAL_EPS, SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
306 if (neigboringOvrhdSegmentID != "") {
307 neigboringOvrhdSegment = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(neigboringOvrhdSegmentID, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
308 neigboringOvrhdSegmentTractionSubstation = neigboringOvrhdSegment->getTractionSubstation();
309 } else {
310 neigboringOvrhdSegment = nullptr;
311 neigboringOvrhdSegmentTractionSubstation = nullptr;
312 }
313
314 if (neigboringOvrhdSegmentTractionSubstation == substation && !(*it)->isInternal()) {
315 connection = lane->getInternalFollowingLane(*it);
316 if (connection != nullptr) {
317 //is connection forbidden?
318 if (!(substation->isForbidden(connection) || substation->isForbidden(lane->getInternalFollowingLane(connection)) || substation->isForbidden(connection->getInternalFollowingLane(*it)))) {
319 buildInnerOverheadWireSegments(net, connection, lane->getInternalFollowingLane(connection), connection->getInternalFollowingLane(*it));
320 }
321 }
322 }
323 }
324
325 // Check if an incoming lane has an overhead wire segment. If not, do nothing, otherwise find connnecting internal lanes and
326 // add overhead wire segments over all detected internal lanes
327 neigboringInnerLanes = lane->getNormalIncomingLanes();
328 for (std::vector<const MSLane*>::iterator it = neigboringInnerLanes.begin(); it != neigboringInnerLanes.end(); ++it) {
329 // If the overhead wire segment is over the incoming (not internal) lane
330 neigboringOvrhdSegmentID = MSNet::getInstance()->getStoppingPlaceID(*it, (*it)->getLength() - NUMERICAL_EPS, SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
331 if (neigboringOvrhdSegmentID != "") {
332 neigboringOvrhdSegment = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(neigboringOvrhdSegmentID, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
333 neigboringOvrhdSegmentTractionSubstation = neigboringOvrhdSegment->getTractionSubstation();
334 } else {
335 neigboringOvrhdSegment = nullptr;
336 neigboringOvrhdSegmentTractionSubstation = nullptr;
337 }
338
339 if (neigboringOvrhdSegmentTractionSubstation == substation && !(*it)->isInternal()) {
340 connection = (*it)->getInternalFollowingLane(lane);
341 if (connection != nullptr) {
342 //is connection forbidden?
343 if (!(substation->isForbidden(connection) || substation->isForbidden((*it)->getInternalFollowingLane(connection)) || substation->isForbidden(connection->getInternalFollowingLane(lane)))) {
344 buildInnerOverheadWireSegments(net, connection, (*it)->getInternalFollowingLane(connection), connection->getInternalFollowingLane(lane));
345 }
346 }
347 }
348 }
349 }
350
351
352 // ----- *** adding segments into the electric circuit*** -----
353
354 // setting nullptr for substation (a fragment from old version of adding segments into the circuit)
355 for (const std::string& segmentID : segmentIDs) {
357 ovrhdSegment->setTractionSubstation(nullptr);
358 }
359
360 for (const std::string& segmentID : segmentIDs) {
361 if (segmentID == "") {
362 continue;
363 }
365 substation->addOverheadWireSegmentToCircuit(ovrhdSegment);
366 segments.push_back(ovrhdSegment);
367 }
368
369 // adding overhead wire clamp
370 std::string clampsString = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMPS, nullptr, ok, "");
371 if (clampsString != "" && MSGlobals::gOverheadWireSolver) {
372#ifdef HAVE_EIGEN
373 const std::vector<std::string>& clampIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_OVERHEAD_WIRE_CLAMPS, nullptr, ok);
374 for (const std::string& clampID : clampIDs) {
375 MSTractionSubstation::OverheadWireClamp* clamp = substation->findClamp(clampID);
376 if (clamp != nullptr) {
377 if (clamp->start->getTractionSubstation() == substation && clamp->end->getTractionSubstation() == substation) {
378 substation->addOverheadWireClampToCircuit(clamp->id, clamp->start, clamp->end);
379 buildOverheadWireClamp(net, clamp->id, const_cast<MSLane*>(&clamp->start->getLane()), const_cast<MSLane*>(&clamp->end->getLane()));
380 clamp->usage = true;
381 } else {
382 if (clamp->start->getTractionSubstation() != substation) {
383 WRITE_WARNINGF(TL("A connecting overhead wire start segment '%' defined for overhead wire clamp '%' is not assigned to the traction substation '%'."), clamp->start->getID(), clampID, substationId);
384 } else {
385 WRITE_WARNINGF(TL("A connecting overhead wire end segment '%' defined for overhead wire clamp '%' is not assigned to the traction substation '%'."), clamp->end->getID(), clampID, substationId);
386 }
387 }
388 } else {
389 WRITE_WARNINGF(TL("The overhead wire clamp '%' defined in an overhead wire section was not assigned to the substation '%'. Please define proper <overheadWireClamp .../> in additional files before defining overhead wire section."), clampID, substationId);
390 }
391 }
392#else
393 WRITE_WARNING(TL("Overhead circuit solver requested, but solver support (Eigen) not compiled in."));
394#endif
395 }
396
397 if (segments.size() == 0) {
398 throw InvalidArgument("No segments found for overHeadWireSection '" + substationId + "'.");
400#ifdef HAVE_EIGEN
401 // check that the electric circuit makes sense
402 segments[0]->getCircuit()->checkCircuit(substationId);
403#else
404 WRITE_WARNING(TL("Cannot check circuit, overhead circuit solver support (Eigen) not compiled in."));
405#endif
406 }
407}
408
409void
411 bool ok = true;
412
413 // get the id, throw if not given or empty...
414 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
415 if (!ok) {
416 throw ProcessError();
417 }
418
419 // RICE_TODO Limits are fixed, change them to some predefined constants ...
420 const double voltage = attrs.getOpt<double>(SUMO_ATTR_VOLTAGE, id.c_str(), ok, 600);
421 const double currentLimit = attrs.getOpt<double>(SUMO_ATTR_CURRENTLIMIT, id.c_str(), ok, 400);
422 buildTractionSubstation(net, id, voltage, currentLimit);
423}
424
425void
428#ifdef HAVE_EIGEN
429 bool ok = true;
430 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
431 if (!ok) {
432 throw ProcessError();
433 }
434
435 std::string substationId = attrs.get<std::string>(SUMO_ATTR_SUBSTATIONID, 0, ok);
436 if (!ok) {
437 throw ProcessError();
438 }
440 if (substation == nullptr) {
441 throw InvalidArgument("Traction substation '" + substationId + "' using within an overheadWireClamp '" + id + "' is not known.");
442 }
443
444 std::string overhead_fromItsStart = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMP_START, 0, ok);
445 if (!ok) {
446 throw ProcessError();
447 }
448 MSOverheadWire* ovrhdSegment_fromItsStart = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(overhead_fromItsStart, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
449 if (ovrhdSegment_fromItsStart == nullptr) {
450 throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsStart + "' to use within overheadWireClamp '" + id + "' is not known.");
451 }
452 /*if (ovrhdSegment_fromItsStart->getTractionSubstation() != substation) {
453 throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsStart + "' to use within overheadWireClamp is assign to a different overhead wire section or substation.");
454 }
455 */
456 std::string overhead_fromItsEnd = attrs.get<std::string>(SUMO_ATTR_OVERHEAD_WIRE_CLAMP_END, 0, ok);
457 if (!ok) {
458 throw ProcessError();
459 }
460 MSOverheadWire* ovrhdSegment_fromItsEnd = dynamic_cast<MSOverheadWire*>(MSNet::getInstance()->getStoppingPlace(overhead_fromItsEnd, SUMO_TAG_OVERHEAD_WIRE_SEGMENT));
461 if (ovrhdSegment_fromItsEnd == nullptr) {
462 throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsEnd + "' to use within overheadWireClamp '" + id + "' is not known.");
463 }
464 /*
465 if (ovrhdSegment_fromItsEnd->getTractionSubstation() != substation) {
466 throw InvalidArgument("The overheadWireSegment '" + overhead_fromItsEnd + "' to use within overheadWireClamp is assign to a different overhead wire section or substation.");
467 }
468 */
469 if (substation->findClamp(id) == nullptr) {
470 substation->addClamp(id, ovrhdSegment_fromItsStart, ovrhdSegment_fromItsEnd);
471 } else {
472 WRITE_ERROR("The overhead wire clamp '" + id + "' is probably declared twice.")
473 }
474#else
475 UNUSED_PARAMETER(attrs);
476 WRITE_WARNING(TL("Not building overhead wire clamps, overhead wire solver support (Eigen) not compiled in."));
477#endif
478 } else {
479 WRITE_WARNING(TL("Ignoring overhead wire clamps, they make no sense when overhead wire circuit solver is off."));
480 }
481}
482
483
484void
486 bool ok = true;
487 // get the id, throw if not given or empty...
488 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
489 if (!ok) {
490 throw ProcessError();
491 }
492
493 //get the name, leave blank if not given
494 const std::string ptStopName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
495
496 //get the color, use default if not given
497 // default color, copy from GUIVisualizationStoppingPlaceSettings::busStopColor / containerStopColor
498 RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok, RGBColor::INVISIBLE);
499
500 MSLane* lane = getLane(attrs, toString(element), id);
501 // get the positions
502 double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0.);
503 double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
504 double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, id.c_str(), ok, 90);
505 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
506 if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
507 throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
508 }
509 const std::vector<std::string>& lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, id.c_str(), ok);
510 int defaultCapacity;
511 SumoXMLAttr capacityAttr;
512 if (element != SUMO_TAG_CONTAINER_STOP) {
513 defaultCapacity = MAX2(MSStoppingPlace::getDefaultTransportablesAbreast(topos - frompos, element) * 3, 6);
514 capacityAttr = SUMO_ATTR_PERSON_CAPACITY;
515 } else {
516 defaultCapacity = MSStoppingPlace::getDefaultTransportablesAbreast(topos - frompos, element);
517 capacityAttr = SUMO_ATTR_CONTAINER_CAPACITY;
518 }
519 const int transportableCapacity = attrs.getOpt<int>(capacityAttr, id.c_str(), ok, defaultCapacity);
520 const double parkingLength = attrs.getOpt<double>(SUMO_ATTR_PARKING_LENGTH, id.c_str(), ok, 0);
521 // build the bus stop
522 buildStoppingPlace(net, id, lines, lane, frompos, topos, element, ptStopName, transportableCapacity, parkingLength, color, angle);
523}
524
525
526void
528 if (myCurrentStop == nullptr) {
529 throw InvalidArgument("Could not add access outside a stopping place.");
530 }
531 // get the lane
532 MSLane* lane = getLane(attrs, "access", myCurrentStop->getID());
534 WRITE_WARNINGF(TL("Ignoring invalid access from non-pedestrian lane '%' in busStop '%'."), lane->getID(), myCurrentStop->getID());
535 return;
536 }
537 // get the positions
538 bool ok = true;
539 const std::string accessPos = attrs.getOpt<std::string>(SUMO_ATTR_POSITION, "access", ok);
540 const bool random = accessPos == "random";
542 if (accessPos == "doors") {
544 } else if (accessPos == "carriage") {
546 }
547 double startPos = random || exit != MSStoppingPlace::AccessExit::PLATFORM ? 0. : attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0);
548 double endPos = random || exit != MSStoppingPlace::AccessExit::PLATFORM ? lane->getLength() : startPos;
549 const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
550 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
551 if (!ok || (myHandler->checkStopPos(startPos, endPos, lane->getLength(), 0, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
552 throw InvalidArgument("Invalid position " + attrs.getString(SUMO_ATTR_POSITION) + " for access on lane '" + lane->getID() + "' in stop '" + myCurrentStop->getID() + "'.");
553 }
554 // add bus stop access
555 if (!myCurrentStop->addAccess(lane, startPos, endPos, length, exit)) {
556 throw InvalidArgument("Duplicate access on lane '" + lane->getID() + "' for stop '" + myCurrentStop->getID() + "'");
557 }
558}
559
560
561void
563 bool ok = true;
564 // get the id, throw if not given or empty...
565 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
566 if (!ok) {
567 throw ProcessError();
568 }
569 // get the lane
570 MSLane* lane = getLane(attrs, "parkingArea", id);
571 // get the positions
572 double frompos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
573 double topos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, lane->getLength());
574 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
575 unsigned int capacity = attrs.getOpt<int>(SUMO_ATTR_ROADSIDE_CAPACITY, id.c_str(), ok, 0);
577 bool onRoad = attrs.getOpt<bool>(SUMO_ATTR_ONROAD, id.c_str(), ok, false);
578 double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, 0);
579 double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, id.c_str(), ok, 0);
580 double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, id.c_str(), ok, 0);
581 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok);
582 const std::string departPos = attrs.getOpt<std::string>(SUMO_ATTR_DEPARTPOS, id.c_str(), ok);
583 bool lefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, id.c_str(), ok, false);
584 const std::vector<std::string>& acceptedBadges = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_ACCEPTED_BADGES, id.c_str(), ok);
585
586 if (!ok || (myHandler->checkStopPos(frompos, topos, lane->getLength(), POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
587 throw InvalidArgument("Invalid position for parking area '" + id + "'.");
588 }
589 const std::vector<std::string>& lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, id.c_str(), ok);
590 // build the parking area
591 beginParkingArea(net, id, lines, acceptedBadges, lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos, lefthand);
592}
593
594
595
596void
598 bool ok = true;
599 // Check for open parking area
600 if (myParkingArea == nullptr) {
601 throw ProcessError();
602 }
603 // get the positions
604 double x = attrs.get<double>(SUMO_ATTR_X, "", ok);
605 if (!ok) {
606 throw InvalidArgument("Invalid x position for lot entry.");
607 }
608 double y = attrs.get<double>(SUMO_ATTR_Y, "", ok);
609 if (!ok) {
610 throw InvalidArgument("Invalid y position for lot entry.");
611 }
612 double z = attrs.getOpt<double>(SUMO_ATTR_Z, "", ok, 0.);
613 double width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, "", ok, myParkingArea->getWidth());
614 double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "", ok, myParkingArea->getLength());
615 double angle = attrs.getOpt<double>(SUMO_ATTR_ANGLE, "", ok, myParkingArea->getAngle());
616 double slope = attrs.getOpt<double>(SUMO_ATTR_SLOPE, "", ok, 0.);
617 // add the lot entry
618 addLotEntry(x, y, z, width, length, angle, slope);
619}
620
621
622void
624 const std::string& base) {
625 bool ok = true;
626 // get the id, throw if not given or empty...
627 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
628 if (!ok) {
629 throw ProcessError();
630 }
631 MSLane* lane = nullptr;
632 MSEdge* edge = nullptr;
633 MSJunction* node = nullptr;
634 if (attrs.hasAttribute(SUMO_ATTR_NODE)) {
636 throw InvalidArgument("The node calibrator '" + id + "' cannot define an edge or lane as well.");
637 }
638 const std::string nodeID = attrs.get<std::string>(SUMO_ATTR_NODE, id.c_str(), ok);
639 node = net.getJunctionControl().get(nodeID);
640 if (node == nullptr) {
641 throw InvalidArgument("The node " + nodeID + " to use within the calibrator '" + id + "' is not known.");
642 }
643 } else {
644 if (attrs.hasAttribute(SUMO_ATTR_EDGE)) {
645 const std::string edgeID = attrs.get<std::string>(SUMO_ATTR_EDGE, id.c_str(), ok);
646 edge = MSEdge::dictionary(edgeID);
647 if (edge == nullptr) {
648 throw InvalidArgument("The edge " + edgeID + " to use within the calibrator '" + id + "' is not known.");
649 }
650 if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
651 lane = getLane(attrs, "calibrator", id);
652 if (&lane->getEdge() != edge) {
653 throw InvalidArgument("The edge " + edgeID + " to use within the calibrator '" + id
654 + "' does not match the calibrator lane '" + lane->getID() + ".");
655 }
656 }
657 } else {
658 lane = getLane(attrs, "calibrator", id);
659 edge = &lane->getEdge();
660 }
661 }
662 const double pos = node != nullptr ? 0 : getPosition(attrs, lane, "calibrator", id, edge);
663 const SUMOTime period = attrs.getOptPeriod(id.c_str(), ok, DELTA_T); // !!! no error handling
664 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
665 const std::string file = getFileName(attrs, base, true);
666 const std::string outfile = attrs.getOpt<std::string>(SUMO_ATTR_OUTPUT, id.c_str(), ok, "");
667 const std::string routeProbe = attrs.getOpt<std::string>(SUMO_ATTR_ROUTEPROBE, id.c_str(), ok, "");
668 // differing defaults for backward compatibility, values are dimensionless
669 const double invalidJamThreshold = attrs.getOpt<double>(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, MSGlobals::gUseMesoSim ? 0.8 : 0.5);
670 const bool local = attrs.getOpt<bool>(SUMO_ATTR_LOCAL, id.c_str(), ok, false);
671 MSRouteProbe* probe = nullptr;
672 if (routeProbe != "") {
673 probe = dynamic_cast<MSRouteProbe*>(net.getDetectorControl().getTypedDetectors(SUMO_TAG_ROUTEPROBE).get(routeProbe));
674 if (probe == nullptr) {
675 throw InvalidArgument("The routeProbe '" + routeProbe + "' to use within the calibrator '" + id + "' is not known.");
676 }
677 }
679 if (lane != nullptr && edge->getLanes().size() > 1) {
680 WRITE_WARNING("Meso calibrator '" + id
681 + "' defined for lane '" + lane->getID()
682 + "' will collect data for all lanes of edge '" + edge->getID() + "'.");
683 }
684 METriggeredCalibrator* trigger = buildMECalibrator(id, edge, pos, file, outfile, period, probe, invalidJamThreshold, vTypes);
685 if (file == "") {
687 }
688 } else {
689 MSCalibrator* trigger = buildCalibrator(id, edge, lane, node, pos, file, outfile, period, probe, invalidJamThreshold, vTypes, local);
690 if (file == "") {
692 }
693 }
694}
695
696
697void
699 bool ok = true;
700 // get the id, throw if not given or empty...
701 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
702 if (!ok) {
703 throw ProcessError();
704 }
705 if (MSTriggeredRerouter::getInstances().count(id) > 0) {
706 throw InvalidArgument("Could not build rerouter '" + id + "'; probably declared twice.");
707 }
708 MSEdgeVector edges;
709 for (const std::string& edgeID : attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), ok)) {
710 MSEdge* edge = MSEdge::dictionary(edgeID);
711 if (edge == nullptr) {
712 throw InvalidArgument("The edge '" + edgeID + "' to use within rerouter '" + id + "' is not known.");
713 }
714 edges.push_back(edge);
715 }
716 if (!ok) {
717 throw InvalidArgument("The edge to use within rerouter '" + id + "' is not known.");
718 }
719 if (edges.size() == 0) {
720 throw InvalidArgument("No edges found for rerouter '" + id + "'.");
721 }
722 const double prob = attrs.getOpt<double>(SUMO_ATTR_PROB, id.c_str(), ok, 1);
723 const bool off = attrs.getOpt<bool>(SUMO_ATTR_OFF, id.c_str(), ok, false);
724 const bool optional = attrs.getOpt<bool>(SUMO_ATTR_OPTIONAL, id.c_str(), ok, false);
725 const SUMOTime timeThreshold = TIME2STEPS(attrs.getOpt<double>(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, 0));
726 const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
727 const std::string pos = attrs.getOpt<std::string>(SUMO_ATTR_POSITION, id.c_str(), ok, "");
728 const double radius = attrs.getOpt<double>(SUMO_ATTR_RADIUS, id.c_str(), ok, std::numeric_limits<double>::max());
730 WRITE_WARNINGF(TL("It is strongly advisable to give an explicit position when using radius in the definition of rerouter '%'."), id)
731 }
733 if (pos != "") {
734 const std::vector<std::string> posSplit = StringTokenizer(pos, ",").getVector();
735 if (posSplit.size() == 1) {
736 double lanePos = StringUtils::toDouble(pos);
737 if (lanePos < 0) {
738 lanePos += edges.front()->getLanes()[0]->getLength();
739 }
740 p = edges.front()->getLanes()[0]->geometryPositionAtOffset(lanePos);
741 } else if (posSplit.size() == 2) {
742 p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1]));
743 } else if (posSplit.size() == 3) {
744 p = Position(StringUtils::toDouble(posSplit[0]), StringUtils::toDouble(posSplit[1]), StringUtils::toDouble(posSplit[2]));
745 } else {
746 throw InvalidArgument("Invalid position for rerouter '" + id + "'.");
747 }
748 }
749 if (!ok) {
750 throw InvalidArgument("Could not parse rerouter '" + id + "'.");
751 }
752 MSTriggeredRerouter* trigger = buildRerouter(net, id, edges, prob, off, optional, timeThreshold, vTypes, p, radius);
753 // read in the trigger description
755}
756
757
758// -------------------------
759
760
762NLTriggerBuilder::buildLaneSpeedTrigger(MSNet& /*net*/, const std::string& id,
763 const std::vector<MSLane*>& destLanes,
764 const std::string& file) {
765 return new MSLaneSpeedTrigger(id, destLanes, file);
766}
767
768
771 MSEdge* edge,
772 double pos,
773 const std::string& file,
774 const std::string& outfile,
775 const SUMOTime freq,
776 MSRouteProbe* probe,
777 const double invalidJamThreshold,
778 const std::string& vTypes) {
779 return new METriggeredCalibrator(id, edge, pos, file, outfile, freq,
780 edge == nullptr ? 0. : MSGlobals::gMesoNet->getSegmentForEdge(*edge, pos)->getLength(),
781 probe, invalidJamThreshold, vTypes);
782}
783
784
787 MSEdge* edge,
788 MSLane* lane,
789 MSJunction* node,
790 double pos,
791 const std::string& file,
792 const std::string& outfile,
793 const SUMOTime freq,
794 const MSRouteProbe* probe,
795 const double invalidJamThreshold,
796 const std::string& vTypes,
797 const bool local) {
798 return new MSCalibrator(id, edge, lane, node, pos, file, outfile, freq,
799 edge == nullptr ? 0. : edge->getLength(),
800 probe, invalidJamThreshold, vTypes, local, true);
801}
802
803
806 MSEdgeVector& edges, double prob, bool off, bool optional,
807 SUMOTime timeThreshold, const std::string& vTypes, const Position& pos, const double radius) {
808 return new MSTriggeredRerouter(id, edges, prob, off, optional, timeThreshold, vTypes, pos, radius);
809}
810
811
812void
813NLTriggerBuilder::buildStoppingPlace(MSNet& net, std::string id, std::vector<std::string> lines, MSLane* lane,
814 double frompos, double topos, const SumoXMLTag element, std::string ptStopName,
815 int personCapacity, double parkingLength, RGBColor& color, double angle) {
816 myCurrentStop = new MSStoppingPlace(id, element, lines, *lane, frompos, topos, ptStopName, personCapacity, parkingLength, color, angle);
817 if (!net.addStoppingPlace(element, myCurrentStop)) {
818 delete myCurrentStop;
819 myCurrentStop = nullptr;
820 throw InvalidArgument("Could not build " + toString(element) + " '" + id + "'; probably declared twice.");
821 }
822}
823
824
825void
826NLTriggerBuilder::beginParkingArea(MSNet& net, const std::string& id,
827 const std::vector<std::string>& lines,
828 const std::vector<std::string>& badges,
829 MSLane* lane, double frompos, double topos,
830 unsigned int capacity,
831 double width, double length, double angle, const std::string& name,
832 bool onRoad,
833 const std::string& departPos,
834 bool lefthand) {
835 // Close previous parking area if there are no lots inside
836 MSParkingArea* stop = new MSParkingArea(id, lines, badges, *lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos, lefthand);
837 if (!net.addStoppingPlace(SUMO_TAG_PARKING_AREA, stop)) {
838 delete stop;
839 throw InvalidArgument("Could not build parking area '" + id + "'; probably declared twice.");
840 } else {
841 myParkingArea = stop;
842 }
843}
844
845
846void
847NLTriggerBuilder::addLotEntry(double x, double y, double z,
848 double width, double length,
849 double angle, double slope) {
850 if (myParkingArea != nullptr) {
851 if (!myParkingArea->parkOnRoad()) {
852 myParkingArea->addLotEntry(x, y, z, width, length, angle, slope);
854 } else {
855 throw InvalidArgument("Cannot not add lot entry to on-road parking area.");
856 }
857 } else {
858 throw InvalidArgument("Could not add lot entry outside a parking area.");
859 }
860}
861
862
863void
865 if (myParkingArea != nullptr) {
866 myParkingArea = nullptr;
868 } else {
869 throw InvalidArgument("Could not end a parking area that is not opened.");
870 }
871}
872
873
874void
876 if (myCurrentStop != nullptr) {
878 myCurrentStop = nullptr;
879 } else {
880 throw InvalidArgument("Could not end a stopping place that is not opened.");
881 }
882}
883
884
885void
886NLTriggerBuilder::buildChargingStation(MSNet& net, const std::string& id, MSLane* lane, double frompos, double topos,
887 const std::string& name, double chargingPower, double efficiency, bool chargeInTransit,
888 SUMOTime chargeDelay, std::string chargeType, SUMOTime waitingTime, MSParkingArea* parkingArea) {
889 MSChargingStation* chargingStation = (parkingArea == nullptr) ? new MSChargingStation(id, *lane, frompos, topos, name, chargingPower, efficiency,
890 chargeInTransit, chargeDelay, chargeType, waitingTime) : new MSChargingStation(id, parkingArea, name, chargingPower, efficiency,
891 chargeInTransit, chargeDelay, chargeType, waitingTime);
892 if (!net.addStoppingPlace(SUMO_TAG_CHARGING_STATION, chargingStation)) {
893 delete chargingStation;
894 throw InvalidArgument("Could not build charging station '" + id + "'; probably declared twice.");
895 }
896 myCurrentStop = chargingStation;
897}
898
899
900void
901NLTriggerBuilder::buildOverheadWireSegment(MSNet& net, const std::string& id, MSLane* lane, double frompos, double topos,
902 bool voltageSource) {
903 MSOverheadWire* overheadWireSegment = new MSOverheadWire(id, *lane, frompos, topos, voltageSource);
904 if (!net.addStoppingPlace(SUMO_TAG_OVERHEAD_WIRE_SEGMENT, overheadWireSegment)) {
905 delete overheadWireSegment;
906 throw InvalidArgument("Could not build overheadWireSegment '" + id + "'; probably declared twice.");
907 }
908}
909
910void
911NLTriggerBuilder::buildInnerOverheadWireSegments(MSNet& net, const MSLane* connection, const MSLane* frontConnection, const MSLane* behindConnection) {
912 if (frontConnection == NULL && behindConnection == NULL) {
913 buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
914 } else if (frontConnection != NULL && behindConnection == NULL) {
915 buildOverheadWireSegment(net, "ovrhd_inner_" + frontConnection->getID(), const_cast<MSLane*>(frontConnection), 0, frontConnection->getLength(), false);
916 buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
917 } else if (frontConnection == NULL && behindConnection != NULL) {
918 buildOverheadWireSegment(net, "ovrhd_inner_" + behindConnection->getID(), const_cast<MSLane*>(behindConnection), 0, behindConnection->getLength(), false);
919 buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
920 } else if (frontConnection != NULL && behindConnection != NULL) {
921 buildOverheadWireSegment(net, "ovrhd_inner_" + frontConnection->getID(), const_cast<MSLane*>(frontConnection), 0, frontConnection->getLength(), false);
922 buildOverheadWireSegment(net, "ovrhd_inner_" + behindConnection->getID(), const_cast<MSLane*>(behindConnection), 0, behindConnection->getLength(), false);
923 buildOverheadWireSegment(net, "ovrhd_inner_" + connection->getID(), const_cast<MSLane*>(connection), 0, connection->getLength(), false);
924 }
925}
926
927void
928NLTriggerBuilder::buildTractionSubstation(MSNet& net, std::string id, double voltage, double currentLimit) {
929 MSTractionSubstation* myTractionSubstation = new MSTractionSubstation(id, voltage, currentLimit);
930 if (!net.addTractionSubstation(myTractionSubstation)) {
931 delete myTractionSubstation;
932 throw InvalidArgument("Could not build traction substation '" + id + "'; probably declared twice.");
933 }
934}
935
936void
937NLTriggerBuilder::buildOverheadWireClamp(MSNet& /*net*/, const std::string& /*id*/, MSLane* /*lane_start*/, MSLane* /*lane_end*/) {
938}
939
940std::string
942 const std::string& base,
943 const bool allowEmpty) {
944 // get the file name to read further definitions from
945 bool ok = true;
946 std::string file = attrs.getOpt<std::string>(SUMO_ATTR_FILE, nullptr, ok, "");
947 if (file == "") {
948 if (allowEmpty) {
949 return file;
950 }
951 throw InvalidArgument("No filename given.");
952 }
953 // check whether absolute or relative filenames are given
954 if (!FileHelpers::isAbsolute(file)) {
955 return FileHelpers::getConfigurationRelative(base, file);
956 }
957 return file;
958}
959
960
961MSLane*
963 const std::string& tt,
964 const std::string& tid) {
965 bool ok = true;
966 std::string objectid = attrs.get<std::string>(SUMO_ATTR_LANE, tid.c_str(), ok);
967 MSLane* lane = MSLane::dictionary(objectid);
968 if (lane == nullptr) {
969 // Either a lane that is non-existent/broken, or a lane that is internal and has been ignored.
970 // We assume that internal lane names start with ':'.
971 if (objectid[0] == ':' && !MSGlobals::gUsingInternalLanes) {
972 return nullptr;
973 }
974 // Throw the exception only in case that the lane really does not exist in the network file
975 // or it is broken.
976 throw InvalidArgument("The lane " + objectid + " to use within the " + tt + " '" + tid + "' is not known.");
977 }
978 return lane;
979}
980
981
983NLTriggerBuilder::getParkingArea(const SUMOSAXAttributes& attrs, const std::string& tt, const std::string& tid) {
984 bool ok = true;
985 std::string objectID = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, tid.c_str(), ok);
986 if (!ok || objectID.size() == 0) {
987 return nullptr;
988 }
990 if (pa == nullptr) {
991 // Throw the exception only in case that the lane really does not exist in the network file
992 // or it is broken.
993 throw InvalidArgument("The parkingArea " + objectID + " to use within the " + tt + " '" + tid + "' is not known.");
994 }
995 return pa;
996}
997
998
999double
1001 MSLane* lane,
1002 const std::string& tt, const std::string& tid,
1003 MSEdge* edge) {
1004 assert(lane != nullptr || edge != nullptr);
1005 const double length = lane != nullptr ? lane->getLength() : edge->getLength();
1006 bool ok = true;
1007 double pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
1008 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
1009 if (!ok) {
1010 throw InvalidArgument("Error on parsing a position information.");
1011 }
1012 if (pos < 0) {
1013 pos = length + pos;
1014 }
1015 if (pos > length) {
1016 if (friendlyPos) {
1017 pos = length - (double) 0.1;
1018 } else {
1019 if (lane != nullptr) {
1020 throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the lane's '" + lane->getID() + "' length.");
1021 } else {
1022 throw InvalidArgument("The position of " + tt + " '" + tid + "' lies beyond the edge's '" + edge->getID() + "' length.");
1023 }
1024 }
1025 }
1026 return pos;
1027}
1028
1029
1030void
1036
1037
1042
1043
1044/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:290
#define WRITE_ERRORF(...)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define TIME2STEPS(x)
Definition SUMOTime.h:57
@ 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_NODE
@ SUMO_ATTR_LINES
@ SUMO_ATTR_LANE
@ SUMO_ATTR_ACCEPTED_BADGES
@ SUMO_ATTR_WAITINGTIME
@ SUMO_ATTR_RADIUS
The turning radius at an intersection in m.
@ SUMO_ATTR_FILE
@ SUMO_ATTR_PARKING_AREA
@ 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_CHARGETYPE
Charge type (fuel or electric)
@ SUMO_ATTR_PARKING_LENGTH
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_VOLTAGE
voltage of the traction substation [V]
@ SUMO_ATTR_X
@ SUMO_ATTR_LOCAL
@ 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_LEFTHAND
@ SUMO_ATTR_CHARGEINTRANSIT
Allow/disallow charge in transit in Charging Stations.
@ SUMO_ATTR_CONTAINER_CAPACITY
@ SUMO_ATTR_NAME
@ SUMO_ATTR_SLOPE
@ 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_OPTIONAL
@ 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_OVERHEAD_WIRE_SEGMENTS
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_CHARGEDELAY
Delay in the charge of charging stations (different of waiting time)
T MAX2(T a, T b)
Definition StdDefs.h:86
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.
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition MELoop.cpp:340
double getLength() const
Returns the length of the segment in meters.
Definition MESegment.h:244
Calibrates the flow on a segment to a specified one.
Calibrates the flow on a segment to a specified one.
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:520
double getLength() const
return the length of the edge
Definition MSEdge.h:685
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:1053
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition MSEdge.cpp:513
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition MSGlobals.h:106
static bool gOverheadWireSolver
Definition MSGlobals.h:121
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition MSGlobals.h:112
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition MSGlobals.h:81
The base class for an intersection.
Definition MSJunction.h:58
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double getLength() const
Returns the lane's length.
Definition MSLane.h:611
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:2746
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition MSLane.h:930
const std::vector< std::pair< const MSLane *, const MSEdge * > > getOutgoingViaLanes() const
get the list of outgoing lanes
Definition MSLane.cpp:3317
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition MSLane.cpp:2478
bool isInternal() const
Definition MSLane.cpp:2609
std::vector< const MSLane * > getNormalIncomingLanes() const
get the list of all direct (disregarding internal predecessors) non-internal predecessor lanes of thi...
Definition MSLane.cpp:3327
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
Changes the speed allowed on a set of lanes.
The simulated network and simulation perfomer.
Definition MSNet.h:89
bool addStoppingPlace(const SumoXMLTag category, MSStoppingPlace *stop)
Adds a stopping place.
Definition MSNet.cpp:1387
MSDetectorControl & getDetectorControl()
Returns the detector control.
Definition MSNet.h:447
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:477
bool addTractionSubstation(MSTractionSubstation *substation)
Adds a traction substation.
Definition MSNet.cpp:1393
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:1424
MSJunctionControl & getJunctionControl()
Returns the junctions control.
Definition MSNet.h:467
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition MSNet.cpp:1403
MSTractionSubstation * findTractionSubstation(const std::string &substationId)
find electrical substation by its id
Definition MSNet.cpp:1508
Definition of overhead wire segment.
MSTractionSubstation * getTractionSubstation() const
void setTractionSubstation(MSTractionSubstation *substation)
A lane area vehicles can halt at.
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
void setRoadsideCapacity(int capactity)
overwrite the capacity (caution: will delete ANY previous parking space definitions)
Writes routes of vehicles passing a certain edge.
A lane area vehicles can halt at.
virtual void finishedLoading()
perform extra processing after element has been loaded
const MSLane & getLane() const
Returns the lane this stop is located at.
virtual bool addAccess(MSLane *const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit)
adds an access point to this stop
static int getDefaultTransportablesAbreast(double length, SumoXMLTag element)
Traction substation 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 traffic objects passing an edge.
static const std::map< std::string, MSTriggeredRerouter * > & getInstances()
return all rerouter instances
The XML-Handler for network loading.
Definition NLHandler.h:79
MSParkingArea * getParkingArea(const SUMOSAXAttributes &attrs, const std::string &tt, const std::string &tid)
Returns the parking area defined by attribute "parkingArea".
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.
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 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, double angle)
Builds a stopping place.
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 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, std::string chargeType, SUMOTime waitingTime, MSParkingArea *parkingArea)
Builds a charging station.
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.
void updateParkingAreaDefaultCapacity()
updates the parkingArea default capacity
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.
void parseAndBuildRerouter(MSNet &net, const SUMOSAXAttributes &attrs)
Parses his values and builds a rerouter.
void parseAndBuildOverheadWireSection(MSNet &net, const SUMOSAXAttributes &attrs)
Parses its values and builds an overhead wire section.
virtual void beginParkingArea(MSNet &net, const std::string &id, const std::vector< std::string > &lines, const std::vector< std::string > &badges, 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, bool lefthand)
Begin a parking area.
void setHandler(NLHandler *handler)
Sets the parent handler to use for nested parsing.
virtual ~NLTriggerBuilder()
Destructor.
void buildTractionSubstation(MSNet &net, std::string id, double voltage, double currentLimit)
Builds a traction substation.
virtual METriggeredCalibrator * buildMECalibrator(const std::string &id, 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
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.
virtual MSTriggeredRerouter * buildRerouter(MSNet &net, const std::string &id, MSEdgeVector &edges, double prob, bool off, bool optional, SUMOTime timeThreshold, const std::string &vTypes, const Position &pos, const double radius)
builds an 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 MSCalibrator * buildCalibrator(const std::string &id, MSEdge *edge, MSLane *lane, MSJunction *node, double pos, const std::string &file, const std::string &outfile, const SUMOTime freq, const MSRouteProbe *probe, const double invalidJamThreshold, const std::string &vTypes, const bool local)
builds a microscopic calibrator
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.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:323
static const RGBColor INVISIBLE
Definition RGBColor.h:198
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.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOTime getOptPeriod(const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read the SUMOTime 'period' attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
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.
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
A wrapper for a Command function.
#define UNUSED_PARAMETER(x)