Line data Source code
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 : /****************************************************************************/
14 : /// @file SUMOVehicleParameter.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Tue, 31.03.2009
19 : ///
20 : // Structure representing possible vehicle parameter
21 : /****************************************************************************/
22 : #include <config.h>
23 : #include <utils/common/MsgHandler.h>
24 : #include <utils/common/StringTokenizer.h>
25 : #include <utils/common/StringUtils.h>
26 : #include <utils/common/ToString.h>
27 : #include <utils/common/RandHelper.h>
28 : #include <utils/iodevices/OutputDevice.h>
29 : #include <utils/options/OptionsCont.h>
30 :
31 : #include "SUMOVehicleParameter.h"
32 :
33 : // ===========================================================================
34 : // member method definitions
35 : // ===========================================================================
36 :
37 1135768 : SUMOVehicleParameter::SUMOVehicleParameter()
38 2271536 : : tag(SUMO_TAG_NOTHING), vtypeid(DEFAULT_VTYPE_ID), color(RGBColor::DEFAULT_COLOR),
39 1135768 : depart(-1), departProcedure(DepartDefinition::GIVEN),
40 1135768 : departLane(0), departLaneProcedure(DepartLaneDefinition::DEFAULT),
41 1135768 : departPos(0), departPosProcedure(DepartPosDefinition::DEFAULT),
42 1135768 : departPosLat(0), departPosLatProcedure(DepartPosLatDefinition::DEFAULT),
43 1135768 : departSpeed(-1), departSpeedProcedure(DepartSpeedDefinition::DEFAULT),
44 1135768 : departEdge(0), departEdgeProcedure(RouteIndexDefinition::DEFAULT),
45 1135768 : arrivalLane(0), arrivalLaneProcedure(ArrivalLaneDefinition::DEFAULT),
46 1135768 : arrivalPos(0), arrivalPosProcedure(ArrivalPosDefinition::DEFAULT),
47 1135768 : arrivalPosLat(0), arrivalPosLatProcedure(ArrivalPosLatDefinition::DEFAULT),
48 1135768 : arrivalSpeed(-1), arrivalSpeedProcedure(ArrivalSpeedDefinition::DEFAULT),
49 1135768 : arrivalEdge(-1), arrivalEdgeProcedure(RouteIndexDefinition::DEFAULT),
50 1135768 : repetitionNumber(-1),
51 1135768 : repetitionsDone(-1),
52 1135768 : repetitionOffset(-1),
53 1135768 : repetitionTotalOffset(0),
54 1135768 : repetitionProbability(-1),
55 1135768 : poissonRate(0),
56 1135768 : repetitionEnd(-1),
57 1135768 : line(), fromTaz(), toTaz(), personNumber(0), containerNumber(0),
58 1135768 : speedFactor(-1),
59 1135768 : calibratorSpeed(-1),
60 1135768 : insertionChecks((int)InsertionCheck::ALL),
61 1135768 : parametersSet(0)
62 1135768 : { }
63 :
64 :
65 12745774 : SUMOVehicleParameter::~SUMOVehicleParameter() {
66 12745774 : }
67 :
68 :
69 : bool
70 288503 : SUMOVehicleParameter::defaultOptionOverrides(const OptionsCont& oc, const std::string& optionName) const {
71 577006 : return oc.exists(optionName) && oc.isSet(optionName) && oc.getBool("defaults-override");
72 : }
73 :
74 :
75 : void
76 530081 : SUMOVehicleParameter::write(OutputDevice& dev, const OptionsCont& oc, const SumoXMLTag altTag, const std::string& typeID) const {
77 530081 : if (!id.empty()) {
78 : // only used by calibrator flows
79 530081 : dev.openTag(altTag).writeAttr(SUMO_ATTR_ID, id);
80 : }
81 530081 : if (typeID == "") {
82 504946 : if (wasSet(VEHPARS_VTYPE_SET)) {
83 33850 : dev.writeAttr(SUMO_ATTR_TYPE, vtypeid);
84 : }
85 : } else {
86 25135 : dev.writeAttr(SUMO_ATTR_TYPE, typeID);
87 : }
88 : // write depart depending of tag
89 : if (altTag == SUMO_TAG_FLOW
90 530081 : || altTag == SUMO_TAG_PERSONFLOW
91 : || altTag == SUMO_TAG_CONTAINERFLOW
92 : || altTag == GNE_TAG_FLOW_ROUTE
93 : || altTag == GNE_TAG_FLOW_WITHROUTE
94 : || altTag == SUMO_TAG_FLOWSTATE) {
95 2022 : dev.writeAttr(SUMO_ATTR_BEGIN, getDepart());
96 :
97 1011 : if (wasSet(VEHPARS_END_SET)) {
98 2022 : dev.writeAttr(SUMO_ATTR_END, time2string(repetitionEnd));
99 : }
100 1011 : if (wasSet(VEHPARS_NUMBER_SET)) {
101 56 : dev.writeAttr(SUMO_ATTR_NUMBER, repetitionNumber);
102 : }
103 1011 : if (wasSet(VEHPARS_VPH_SET)) {
104 0 : dev.writeAttr(SUMO_ATTR_PERHOUR, 3600 / STEPS2TIME(repetitionOffset));
105 : }
106 : // netedit uses VEHPARS_POISSON_SET
107 1011 : if (wasSet(VEHPARS_PERIOD_SET) || wasSet(VEHPARS_POISSON_SET)) {
108 593 : if (repetitionOffset >= 0 && !wasSet(VEHPARS_POISSON_SET)) {
109 1062 : dev.writeAttr(SUMO_ATTR_PERIOD, StringUtils::adjustDecimalValue(STEPS2TIME(repetitionOffset), 20));
110 : } else {
111 186 : dev.writeAttr(SUMO_ATTR_PERIOD, "exp(" + StringUtils::adjustDecimalValue(poissonRate, 20) + ")");
112 : }
113 : }
114 1011 : if (wasSet(VEHPARS_PROB_SET) && repetitionProbability > 0) {
115 724 : dev.writeAttr(SUMO_ATTR_PROB, StringUtils::adjustDecimalValue(repetitionProbability, 20));
116 : }
117 : } else {
118 1058140 : dev.writeAttr(SUMO_ATTR_DEPART, getDepart());
119 : }
120 : // optional parameter
121 : // departlane
122 633631 : if (wasSet(VEHPARS_DEPARTLANE_SET) && !defaultOptionOverrides(oc, "departlane")) {
123 206940 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, getDepartLane());
124 739605 : } else if (oc.exists("departlane") && oc.isSet("departlane")) {
125 718 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
126 : }
127 : // departpos
128 571064 : if (wasSet(VEHPARS_DEPARTPOS_SET) && !defaultOptionOverrides(oc, "departpos")) {
129 81838 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, getDepartPos());
130 882793 : } else if (oc.exists("departpos") && oc.isSet("departpos")) {
131 676 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
132 : }
133 : // departPosLat
134 530081 : if (wasSet(VEHPARS_DEPARTPOSLAT_SET)) {
135 12 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS_LAT, getDepartPosLat());
136 : }
137 : // departspeed
138 665468 : if (wasSet(VEHPARS_DEPARTSPEED_SET) && !defaultOptionOverrides(oc, "departspeed")) {
139 270646 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, getDepartSpeed());
140 704262 : } else if (oc.exists("departspeed") && oc.isSet("departspeed")) {
141 722 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
142 : }
143 : // departedge
144 530393 : if (wasSet(VEHPARS_DEPARTEDGE_SET) && !defaultOptionOverrides(oc, "departedge")) {
145 624 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, getDepartEdge());
146 529769 : } else if (oc.exists("departedge") && oc.isSet("departedge")) {
147 0 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, oc.getString("departedge"));
148 : }
149 : // arrivallane
150 530409 : if (wasSet(VEHPARS_ARRIVALLANE_SET) && !defaultOptionOverrides(oc, "arrivallane")) {
151 592 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, getArrivalLane());
152 925360 : } else if (oc.exists("arrivallane") && oc.isSet("arrivallane")) {
153 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
154 : }
155 : // arrivalpos
156 534211 : if (wasSet(VEHPARS_ARRIVALPOS_SET) && !defaultOptionOverrides(oc, "arrivalpos")) {
157 8164 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, getArrivalPos());
158 921379 : } else if (oc.exists("arrivalpos") && oc.isSet("arrivalpos")) {
159 692 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
160 : }
161 : // arrivalPosLat
162 530081 : if (wasSet(VEHPARS_ARRIVALPOSLAT_SET)) {
163 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS_LAT, getArrivalPosLat());
164 : }
165 : // arrivalspeed
166 533848 : if (wasSet(VEHPARS_ARRIVALSPEED_SET) && !defaultOptionOverrides(oc, "arrivalspeed")) {
167 7470 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, getArrivalSpeed());
168 921929 : } else if (oc.exists("arrivalspeed") && oc.isSet("arrivalspeed")) {
169 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
170 : }
171 : // arrivalEdge
172 530287 : if (wasSet(VEHPARS_ARRIVALEDGE_SET) && !defaultOptionOverrides(oc, "arrivaledge") && arrivalEdge >= 0) {
173 412 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, getArrivalEdge());
174 529875 : } else if (oc.exists("arrivaledge") && oc.isSet("arrivaledge")) {
175 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, oc.getString("arrivaledge"));
176 : }
177 : // color
178 530081 : if (wasSet(VEHPARS_COLOR_SET)) {
179 7713 : dev.writeAttr(SUMO_ATTR_COLOR, color);
180 : }
181 : // line
182 530081 : if (wasSet(VEHPARS_LINE_SET)) {
183 371 : dev.writeAttr(SUMO_ATTR_LINE, line);
184 : }
185 : // from TAZ
186 530081 : if (wasSet(VEHPARS_FROM_TAZ_SET)) {
187 9594 : dev.writeAttr(SUMO_ATTR_FROM_TAZ, fromTaz);
188 : }
189 : // to TAZ
190 530081 : if (wasSet(VEHPARS_TO_TAZ_SET)) {
191 9594 : dev.writeAttr(SUMO_ATTR_TO_TAZ, toTaz);
192 : }
193 : // person number
194 530081 : if (wasSet(VEHPARS_PERSON_NUMBER_SET)) {
195 0 : dev.writeAttr(SUMO_ATTR_PERSON_NUMBER, personNumber);
196 : }
197 : // container number
198 530081 : if (wasSet(VEHPARS_CONTAINER_NUMBER_SET)) {
199 0 : dev.writeAttr(SUMO_ATTR_CONTAINER_NUMBER, containerNumber);
200 : }
201 : // individual speedFactor
202 530081 : if (wasSet(VEHPARS_SPEEDFACTOR_SET)) {
203 : // might be saving state with custom precision
204 : const int precision = dev.getPrecision();
205 49319 : dev.setPrecision(MAX2(gPrecisionRandom, precision));
206 49319 : dev.writeAttr(SUMO_ATTR_SPEEDFACTOR, speedFactor);
207 49319 : dev.setPrecision(precision);
208 : }
209 : // speed (only used by calibrators)
210 530081 : if (wasSet(VEHPARS_CALIBRATORSPEED_SET)) {
211 0 : dev.writeAttr(SUMO_ATTR_SPEED, calibratorSpeed);
212 : }
213 : // insertionChecks
214 530081 : if (wasSet(VEHPARS_INSERTION_CHECKS_SET) && insertionChecks != (int)InsertionCheck::ALL) {
215 : std::vector<std::string> checks;
216 109 : if (insertionChecks == (int)InsertionCheck::NONE) {
217 204 : checks.push_back(toString(InsertionCheck::NONE));
218 : } else {
219 98 : for (auto it : SUMOXMLDefinitions::InsertionChecks.getValues()) {
220 91 : if (((int)it & insertionChecks) != 0) {
221 126 : checks.push_back(toString(it));
222 : }
223 7 : }
224 : }
225 109 : dev.writeAttr(SUMO_ATTR_INSERTIONCHECKS, checks);
226 109 : }
227 : // parking access rights
228 530081 : if (wasSet(VEHPARS_PARKING_BADGES_SET)) {
229 0 : dev.writeNonEmptyAttr(SUMO_ATTR_PARKING_BADGES, joinToString(parkingBadges, " "));
230 : }
231 530081 : }
232 :
233 :
234 : void
235 29355 : SUMOVehicleParameter::Stop::write(OutputDevice& dev, const bool close, const bool writeTagAndParents) const {
236 29355 : if (writeTagAndParents) {
237 29355 : dev.openTag(SUMO_TAG_STOP);
238 29355 : if (busstop != "") {
239 10601 : dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop);
240 : }
241 29355 : if (containerstop != "") {
242 415 : dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop);
243 : }
244 29355 : if (chargingStation != "") {
245 308 : dev.writeAttr(SUMO_ATTR_CHARGING_STATION, chargingStation);
246 : }
247 29355 : if (parkingarea != "") {
248 8866 : dev.writeAttr(SUMO_ATTR_PARKING_AREA, parkingarea);
249 : }
250 29355 : if ((busstop == "") && (containerstop == "") && (parkingarea == "") && (chargingStation == "")) {
251 9179 : if (lane != "") {
252 7744 : dev.writeAttr(SUMO_ATTR_LANE, lane);
253 : } else {
254 1435 : dev.writeAttr(SUMO_ATTR_EDGE, edge);
255 : }
256 9179 : if ((parametersSet & STOP_START_SET) != 0) {
257 3059 : dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
258 : }
259 9179 : if ((parametersSet & STOP_END_SET) != 0) {
260 6464 : dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
261 : }
262 : }
263 : }
264 29355 : if (index > 0) {
265 312 : dev.writeAttr(SUMO_ATTR_INDEX, index);
266 : }
267 29355 : if ((parametersSet & STOP_POSLAT_SET) != 0 && posLat != INVALID_DOUBLE) {
268 71 : dev.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
269 : }
270 29355 : if ((parametersSet & STOP_ARRIVAL_SET) && (arrival >= 0)) {
271 780 : dev.writeAttr(SUMO_ATTR_ARRIVAL, time2string(arrival));
272 : }
273 29355 : if ((parametersSet & STOP_DURATION_SET) && (duration >= 0)) {
274 32654 : dev.writeAttr(SUMO_ATTR_DURATION, time2string(duration));
275 : }
276 29355 : if ((parametersSet & STOP_UNTIL_SET) && (until >= 0)) {
277 27582 : dev.writeAttr(SUMO_ATTR_UNTIL, time2string(until));
278 : }
279 29355 : if ((parametersSet & STOP_STARTED_SET) && (started >= 0)) {
280 178 : dev.writeAttr(SUMO_ATTR_STARTED, time2string(started));
281 : }
282 29355 : if ((parametersSet & STOP_ENDED_SET) && (ended >= 0)) {
283 218 : dev.writeAttr(SUMO_ATTR_ENDED, time2string(ended));
284 : }
285 29355 : if ((parametersSet & STOP_EXTENSION_SET) && (extension >= 0)) {
286 146 : dev.writeAttr(SUMO_ATTR_EXTENSION, time2string(extension));
287 : }
288 29355 : if ((parametersSet & STOP_TRIGGER_SET) != 0) {
289 287 : const std::vector<std::string> triggers = getTriggers();
290 287 : if (triggers.size() > 0) {
291 279 : dev.writeAttr(SUMO_ATTR_TRIGGERED, triggers);
292 : }
293 287 : }
294 29355 : if ((parametersSet & STOP_PARKING_SET) != 0) {
295 1609 : dev.writeAttr(SUMO_ATTR_PARKING, parking);
296 : }
297 29355 : if ((parametersSet & STOP_EXPECTED_SET) != 0 && awaitedPersons.size() > 0) {
298 51 : dev.writeAttr(SUMO_ATTR_EXPECTED, awaitedPersons);
299 : }
300 29355 : if ((parametersSet & STOP_PERMITTED_SET) != 0 && permitted.size() > 0) {
301 1008 : dev.writeAttr(SUMO_ATTR_PERMITTED, permitted);
302 : }
303 29355 : if ((parametersSet & STOP_EXPECTED_CONTAINERS_SET) != 0 && awaitedContainers.size() > 0) {
304 4 : dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, awaitedContainers);
305 : }
306 29355 : if ((parametersSet & STOP_TRIP_ID_SET) != 0) {
307 55 : dev.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
308 : }
309 29355 : if ((parametersSet & STOP_LINE_SET) != 0) {
310 22 : dev.writeAttr(SUMO_ATTR_LINE, line);
311 : }
312 29355 : if ((parametersSet & STOP_SPLIT_SET) != 0) {
313 21 : dev.writeAttr(SUMO_ATTR_SPLIT, split);
314 : }
315 29355 : if ((parametersSet & STOP_JOIN_SET) != 0) {
316 17 : dev.writeAttr(SUMO_ATTR_JOIN, join);
317 : }
318 29355 : if ((parametersSet & STOP_SPEED_SET) != 0) {
319 168 : dev.writeAttr(SUMO_ATTR_SPEED, speed);
320 : }
321 29355 : if ((parametersSet & STOP_ONDEMAND_SET) != 0) {
322 79 : dev.writeAttr(SUMO_ATTR_ONDEMAND, onDemand);
323 : }
324 29355 : if ((parametersSet & STOP_JUMP_SET) != 0 && jump >= 0) {
325 624 : dev.writeAttr(SUMO_ATTR_JUMP, time2string(jump));
326 : }
327 29355 : if ((parametersSet & STOP_JUMP_UNTIL_SET) != 0 && jumpUntil >= 0) {
328 18 : dev.writeAttr(SUMO_ATTR_JUMP_UNTIL, time2string(jumpUntil));
329 : }
330 29355 : if ((parametersSet & STOP_PRIORITY_SET) != 0 && priority >= 0) {
331 258 : dev.writeAttr(SUMO_ATTR_PRIORITY, priority);
332 : }
333 29355 : if (collision) {
334 700 : dev.writeAttr(SUMO_ATTR_COLLISION, collision);
335 : }
336 : // only write friendly position if is true
337 29355 : if (friendlyPos) {
338 0 : dev.writeAttr(SUMO_ATTR_FRIENDLY_POS, friendlyPos);
339 : }
340 : // only write act type if isn't empty
341 29355 : if (!actType.empty()) {
342 1772 : dev.writeAttr(SUMO_ATTR_ACTTYPE, actType);
343 : }
344 29355 : if (close) {
345 : // the user is closing the stop it is responsible for writing params
346 20784 : writeParams(dev);
347 41568 : dev.closeTag();
348 : }
349 29355 : }
350 :
351 : std::vector<std::string>
352 192 : SUMOVehicleParameter::Stop::getStoppingPlaceIDs() const {
353 : std::vector<std::string> result;
354 192 : if (busstop != "") {
355 96 : result.push_back(busstop);
356 : }
357 192 : if (containerstop != "") {
358 8 : result.push_back(containerstop);
359 : }
360 192 : if (chargingStation != "") {
361 8 : result.push_back(chargingStation);
362 : }
363 192 : if (parkingarea != "") {
364 8 : result.push_back(parkingarea);
365 : }
366 192 : return result;
367 0 : }
368 :
369 : bool
370 682700 : SUMOVehicleParameter::parseDepart(const std::string& val, const std::string& element, const std::string& id,
371 : SUMOTime& depart, DepartDefinition& dd, std::string& error, const std::string& attr) {
372 682700 : if (val == "triggered") {
373 1440 : dd = DepartDefinition::TRIGGERED;
374 681260 : } else if (val == "containerTriggered") {
375 105 : dd = DepartDefinition::CONTAINER_TRIGGERED;
376 681155 : } else if (val == "now") {
377 : // only used via TraCI. depart must be set by the calling code
378 22875 : dd = DepartDefinition::NOW;
379 658280 : } else if (val == "split") {
380 40 : dd = DepartDefinition::SPLIT;
381 658240 : } else if (val == "begin") {
382 11 : dd = DepartDefinition::BEGIN;
383 : } else {
384 : try {
385 658229 : depart = string2time(val);
386 658221 : dd = DepartDefinition::GIVEN;
387 658221 : if (depart < 0) {
388 14 : error = "Negative " + attr + " time in the definition of " + element + " '" + id + "'.";
389 7 : return false;
390 : }
391 8 : } catch (...) {
392 8 : if (id.empty()) {
393 0 : error = "Invalid " + attr + " time for " + element + ". Must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
394 : } else {
395 24 : error = "Invalid " + attr + " time for " + element + " '" + id + "';\n must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
396 : }
397 : return false;
398 8 : }
399 : }
400 : return true;
401 : }
402 :
403 :
404 : bool
405 174896 : SUMOVehicleParameter::parseDepartLane(const std::string& val, const std::string& element, const std::string& id,
406 : int& lane, DepartLaneDefinition& dld, std::string& error) {
407 : bool ok = true;
408 174896 : lane = 0;
409 174896 : dld = DepartLaneDefinition::GIVEN;
410 174896 : if (val == "random") {
411 4139 : dld = DepartLaneDefinition::RANDOM;
412 170757 : } else if (val == "free") {
413 2348 : dld = DepartLaneDefinition::FREE;
414 168409 : } else if (val == "allowed") {
415 131 : dld = DepartLaneDefinition::ALLOWED_FREE;
416 168278 : } else if (val == "best") {
417 94567 : dld = DepartLaneDefinition::BEST_FREE;
418 73711 : } else if (val == "best_prob") {
419 48 : dld = DepartLaneDefinition::BEST_PROB;
420 73663 : } else if (val == "first") {
421 41475 : dld = DepartLaneDefinition::FIRST_ALLOWED;
422 : } else {
423 : try {
424 32188 : lane = StringUtils::toInt(val);
425 32129 : if (lane < 0) {
426 : ok = false;
427 : }
428 59 : } catch (...) {
429 : ok = false;
430 59 : }
431 : }
432 : if (!ok) {
433 59 : if (id.empty()) {
434 0 : error = "Invalid departLane definition for " + element + ". Must be one of (\"random\", \"free\", \"allowed\", \"best\", \"best_prob\", \"first\", or an int>=0)";
435 : } else {
436 177 : error = "Invalid departLane definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", \"allowed\", \"best\", \"best_prob\", \"first\", or an int>=0)";
437 : }
438 : }
439 174896 : return ok;
440 : }
441 :
442 :
443 : bool
444 112917 : SUMOVehicleParameter::parseDepartPos(const std::string& val, const std::string& element, const std::string& id,
445 : double& pos, DepartPosDefinition& dpd, std::string& error) {
446 : bool ok = true;
447 112917 : pos = 0.;
448 112917 : dpd = DepartPosDefinition::GIVEN;
449 112917 : if (val == "random") {
450 3141 : dpd = DepartPosDefinition::RANDOM;
451 109776 : } else if (val == "random_free") {
452 72 : dpd = DepartPosDefinition::RANDOM_FREE;
453 109704 : } else if (val == "random_location") {
454 0 : dpd = DepartPosDefinition::RANDOM_LOCATION;
455 109704 : } else if (val == "free") {
456 417 : dpd = DepartPosDefinition::FREE;
457 109287 : } else if (val == "base") {
458 995 : dpd = DepartPosDefinition::BASE;
459 108292 : } else if (val == "last") {
460 848 : dpd = DepartPosDefinition::LAST;
461 107444 : } else if (val == "splitFront") {
462 5 : dpd = DepartPosDefinition::SPLIT_FRONT;
463 107439 : } else if (val == "stop") {
464 2483 : dpd = DepartPosDefinition::STOP;
465 : } else {
466 : try {
467 104956 : pos = StringUtils::toDouble(val);
468 54 : } catch (...) {
469 : ok = false;
470 54 : }
471 : }
472 : if (!ok) {
473 54 : if (id.empty()) {
474 0 : error = "Invalid departPos definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
475 : } else {
476 162 : error = "Invalid departPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
477 : }
478 : }
479 112917 : return ok;
480 : }
481 :
482 :
483 : bool
484 8954 : SUMOVehicleParameter::parseDepartPosLat(const std::string& val, const std::string& element, const std::string& id,
485 : double& pos, DepartPosLatDefinition& dpd, std::string& error) {
486 : bool ok = true;
487 8954 : pos = 0.;
488 8954 : dpd = DepartPosLatDefinition::GIVEN;
489 8954 : if (val == "random") {
490 6181 : dpd = DepartPosLatDefinition::RANDOM;
491 2773 : } else if (val == "random_free") {
492 441 : dpd = DepartPosLatDefinition::RANDOM_FREE;
493 2332 : } else if (val == "free") {
494 71 : dpd = DepartPosLatDefinition::FREE;
495 2261 : } else if (val == "right") {
496 246 : dpd = DepartPosLatDefinition::RIGHT;
497 2015 : } else if (val == "center") {
498 590 : dpd = DepartPosLatDefinition::CENTER;
499 1425 : } else if (val == "left") {
500 187 : dpd = DepartPosLatDefinition::LEFT;
501 : } else {
502 : try {
503 1238 : pos = StringUtils::toDouble(val);
504 0 : } catch (...) {
505 : ok = false;
506 0 : }
507 : }
508 : if (!ok) {
509 0 : if (id.empty()) {
510 0 : error = "Invalid departPosLat definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
511 : } else {
512 0 : error = "Invalid departPosLat definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
513 : }
514 : }
515 8954 : return ok;
516 : }
517 :
518 :
519 : bool
520 305960 : SUMOVehicleParameter::parseDepartSpeed(const std::string& val, const std::string& element, const std::string& id,
521 : double& speed, DepartSpeedDefinition& dsd, std::string& error) {
522 : bool ok = true;
523 305960 : speed = -1.;
524 305960 : dsd = DepartSpeedDefinition::GIVEN;
525 305960 : if (val == "random") {
526 235 : dsd = DepartSpeedDefinition::RANDOM;
527 305725 : } else if (val == "max") {
528 138407 : dsd = DepartSpeedDefinition::MAX;
529 167318 : } else if (val == "desired") {
530 289 : dsd = DepartSpeedDefinition::DESIRED;
531 167029 : } else if (val == "speedLimit") {
532 556 : dsd = DepartSpeedDefinition::LIMIT;
533 166473 : } else if (val == "last") {
534 37 : dsd = DepartSpeedDefinition::LAST;
535 166436 : } else if (val == "avg") {
536 1204 : dsd = DepartSpeedDefinition::AVG;
537 : } else {
538 : try {
539 165232 : speed = StringUtils::toDouble(val);
540 165178 : if (speed < 0) {
541 : ok = false;
542 : }
543 54 : } catch (...) {
544 : ok = false;
545 54 : }
546 : }
547 : if (!ok) {
548 54 : if (id.empty()) {
549 0 : error = "Invalid departSpeed definition for " + element + ". Must be one of (\"random\", \"max\", or a float>=0)";
550 : } else {
551 162 : error = "Invalid departSpeed definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float>=0)";
552 : }
553 : }
554 305960 : return ok;
555 : }
556 :
557 :
558 : bool
559 352 : SUMOVehicleParameter::parseRouteIndex(const std::string& val, const std::string& element, const std::string& id,
560 : const SumoXMLAttr attr, int& edgeIndex, RouteIndexDefinition& rid, std::string& error) {
561 : bool ok = true;
562 352 : edgeIndex = -1;
563 352 : rid = RouteIndexDefinition::GIVEN;
564 352 : if (val == "random") {
565 63 : rid = RouteIndexDefinition::RANDOM;
566 : } else {
567 : try {
568 289 : edgeIndex = StringUtils::toInt(val);
569 289 : if (edgeIndex < 0) {
570 : ok = false;
571 : }
572 0 : } catch (...) {
573 : ok = false;
574 0 : }
575 : }
576 : if (!ok) {
577 14 : if (id.empty()) {
578 0 : error = "Invalid " + toString(attr) + " definition for " + element + ". Must be one of (\"random\", \"free\", or an int>=0)";
579 : } else {
580 42 : error = "Invalid " + toString(attr) + " definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", or an int>=0)";
581 : }
582 : }
583 352 : return ok;
584 : }
585 :
586 :
587 : bool
588 26193 : SUMOVehicleParameter::parseArrivalLane(const std::string& val, const std::string& element, const std::string& id,
589 : int& lane, ArrivalLaneDefinition& ald, std::string& error) {
590 : bool ok = true;
591 26193 : lane = 0;
592 26193 : ald = ArrivalLaneDefinition::GIVEN;
593 26193 : if (val == "current") {
594 23440 : ald = ArrivalLaneDefinition::CURRENT;
595 2753 : } else if (val == "random") {
596 72 : ald = ArrivalLaneDefinition::RANDOM;
597 2681 : } else if (val == "first") {
598 7 : ald = ArrivalLaneDefinition::FIRST_ALLOWED;
599 : } else {
600 : try {
601 2674 : lane = StringUtils::toInt(val);
602 2620 : if (lane < 0) {
603 : ok = false;
604 : }
605 54 : } catch (...) {
606 : ok = false;
607 54 : }
608 : }
609 : if (!ok) {
610 54 : if (id.empty()) {
611 0 : error = "Invalid arrivalLane definition for " + element + ". Must be one of (\"current\", or an int>=0)";
612 : } else {
613 162 : error = "Invalid arrivalLane definition for " + element + " '" + id + "';\n must be one of (\"current\", or an int>=0)";
614 : }
615 : }
616 26193 : return ok;
617 : }
618 :
619 :
620 : bool
621 63229 : SUMOVehicleParameter::parseArrivalPos(const std::string& val, const std::string& element, const std::string& id,
622 : double& pos, ArrivalPosDefinition& apd, std::string& error) {
623 : bool ok = true;
624 63229 : pos = 0.;
625 63229 : apd = ArrivalPosDefinition::GIVEN;
626 63229 : if (val == "random") {
627 1649 : apd = ArrivalPosDefinition::RANDOM;
628 61580 : } else if (val == "center") {
629 0 : apd = ArrivalPosDefinition::CENTER;
630 61580 : } else if (val == "max") {
631 23001 : apd = ArrivalPosDefinition::MAX;
632 : } else {
633 : try {
634 38579 : pos = StringUtils::toDouble(val);
635 54 : } catch (...) {
636 : ok = false;
637 54 : }
638 : }
639 : if (!ok) {
640 54 : if (id.empty()) {
641 0 : error = "Invalid arrivalPos definition for " + element + ". Must be one of (\"random\", \"max\", or a float)";
642 : } else {
643 162 : error = "Invalid arrivalPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float)";
644 : }
645 : }
646 63229 : return ok;
647 : }
648 :
649 :
650 : bool
651 1052 : SUMOVehicleParameter::parseArrivalPosLat(const std::string& val, const std::string& element, const std::string& id,
652 : double& pos, ArrivalPosLatDefinition& apd, std::string& error) {
653 : bool ok = true;
654 1052 : pos = 0.;
655 1052 : apd = ArrivalPosLatDefinition::GIVEN;
656 1052 : if (val == "right") {
657 490 : apd = ArrivalPosLatDefinition::RIGHT;
658 562 : } else if (val == "center") {
659 9 : apd = ArrivalPosLatDefinition::CENTER;
660 553 : } else if (val == "left") {
661 41 : apd = ArrivalPosLatDefinition::LEFT;
662 : } else {
663 : try {
664 512 : pos = StringUtils::toDouble(val);
665 0 : } catch (...) {
666 : ok = false;
667 0 : }
668 : }
669 : if (!ok) {
670 0 : if (id.empty()) {
671 0 : error = "Invalid arrivalPosLat definition for " + element + ". Must be one of (\"right\", \"center\", \"left\", or a float)";
672 : } else {
673 0 : error = "Invalid arrivalPosLat definition for " + element + " '" + id + "';\n must be one of (\"right\", \"center\", \"left\", or a float)";
674 : }
675 : }
676 1052 : return ok;
677 : }
678 :
679 :
680 : bool
681 26715 : SUMOVehicleParameter::parseArrivalSpeed(const std::string& val, const std::string& element, const std::string& id,
682 : double& speed, ArrivalSpeedDefinition& asd, std::string& error) {
683 : bool ok = true;
684 26715 : speed = -1.;
685 26715 : asd = ArrivalSpeedDefinition::GIVEN;
686 26715 : if (val == "current") {
687 23513 : asd = ArrivalSpeedDefinition::CURRENT;
688 : } else {
689 : try {
690 3202 : speed = StringUtils::toDouble(val);
691 3148 : if (speed < 0) {
692 : ok = false;
693 : }
694 54 : } catch (...) {
695 : ok = false;
696 54 : }
697 : }
698 : if (!ok) {
699 54 : if (id.empty()) {
700 0 : error = "Invalid arrivalSpeed definition for " + element + ". Must be one of (\"current\", or a float>=0)";
701 : } else {
702 162 : error = "Invalid arrivalSpeed definition for " + element + " '" + id + "';\n must be one of (\"current\", or a float>=0)";
703 : }
704 : }
705 26715 : return ok;
706 : }
707 :
708 :
709 : double
710 1396396 : SUMOVehicleParameter::interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string& id, bool silent) {
711 1396396 : if (pos < 0) {
712 28780 : pos = maximumValue + pos;
713 : }
714 1396396 : if (pos > maximumValue && pos != std::numeric_limits<double>::infinity()) {
715 0 : if (!silent) {
716 0 : WRITE_WARNINGF(TL("Invalid % % given for %. Using edge end instead."), toString(attr), toString(pos), id);
717 : }
718 0 : pos = maximumValue;
719 : }
720 1396396 : return pos;
721 : }
722 :
723 :
724 : bool
725 1090 : SUMOVehicleParameter::parsePersonModes(const std::string& modes, const std::string& element, const std::string& id, SVCPermissions& modeSet, std::string& error) {
726 : // separte modes in different strings, and check if modes are valid
727 3452 : for (StringTokenizer st(modes); st.hasNext();) {
728 1272 : const std::string mode = st.next();
729 1272 : if (mode == "car") {
730 480 : modeSet |= SVC_PASSENGER;
731 792 : } else if (mode == "taxi") {
732 174 : modeSet |= SVC_TAXI;
733 618 : } else if (mode == "bicycle") {
734 41 : modeSet |= SVC_BICYCLE;
735 577 : } else if (mode == "public") {
736 577 : modeSet |= SVC_BUS;
737 : } else {
738 0 : if (id.empty()) {
739 0 : error = "Unknown person mode '" + mode + "'. Must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
740 : } else {
741 0 : error = "Unknown person mode '" + mode + "' for " + element + " '" + id + "';\n must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
742 : }
743 : return false;
744 : }
745 1090 : }
746 1090 : return true;
747 : }
748 :
749 :
750 : void
751 38629 : SUMOVehicleParameter::parseStopTriggers(const std::vector<std::string>& triggers, bool expectTrigger, Stop& stop) {
752 38629 : if (triggers.size() == 0 && expectTrigger) {
753 1033 : stop.triggered = true;
754 : }
755 40180 : for (std::string val : triggers) {
756 1551 : if (val == toString(SUMO_TAG_PERSON)) {
757 965 : stop.triggered = true;
758 586 : } else if (val == toString(SUMO_TAG_CONTAINER)) {
759 309 : stop.containerTriggered = true;
760 277 : } else if (val == toString(SUMO_ATTR_JOIN)) {
761 128 : stop.joinTriggered = true;
762 : } else {
763 : try {
764 149 : stop.triggered = StringUtils::toBool(val);
765 0 : } catch (BoolFormatException&) {
766 0 : WRITE_ERROR(TL("Value of stop attribute 'trigger' must be 'person', 'container', 'join' or a boolean"));
767 0 : }
768 : }
769 : }
770 38629 : }
771 :
772 :
773 : ParkingType
774 3533 : SUMOVehicleParameter::parseParkingType(const std::string& value) {
775 3533 : if (value == toString(ParkingType::OPPORTUNISTIC)) {
776 : return ParkingType::OPPORTUNISTIC;
777 : } else {
778 3533 : return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
779 : }
780 : }
781 :
782 :
783 : std::vector<std::string>
784 315 : SUMOVehicleParameter::Stop::getTriggers() const {
785 : std::vector<std::string> triggers;
786 315 : if (triggered) {
787 432 : triggers.push_back(toString(SUMO_TAG_PERSON));
788 : }
789 315 : if (containerTriggered) {
790 110 : triggers.push_back(toString(SUMO_TAG_CONTAINER));
791 : }
792 315 : if (joinTriggered) {
793 64 : triggers.push_back(toString(SUMO_ATTR_JOIN));
794 : }
795 315 : return triggers;
796 0 : }
797 :
798 : int
799 8504 : SUMOVehicleParameter::Stop::getFlags() const {
800 8504 : return (((parking == ParkingType::OFFROAD) ? 1 : 0) +
801 8504 : (triggered ? 2 : 0) +
802 8504 : (containerTriggered ? 4 : 0) +
803 8504 : (busstop != "" ? 8 : 0) +
804 8504 : (containerstop != "" ? 16 : 0) +
805 8504 : (chargingStation != "" ? 32 : 0) +
806 8504 : (parkingarea != "" ? 64 : 0) +
807 8504 : (overheadWireSegment != "" ? 128 : 0));
808 : }
809 :
810 :
811 : std::string
812 530081 : SUMOVehicleParameter::getDepart() const {
813 530081 : if (departProcedure == DepartDefinition::TRIGGERED) {
814 743 : return "triggered";
815 529338 : } else if (departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
816 16 : return "containerTriggered";
817 : // } else if (departProcedure == DepartDefinition::NOW) { // TODO check whether this is useful in XML input (currently TraCI only)
818 : // return "now";
819 529322 : } else if (departProcedure == DepartDefinition::SPLIT) {
820 0 : return "split";
821 529322 : } else if (departProcedure == DepartDefinition::BEGIN) {
822 8 : return "begin";
823 : } else {
824 529314 : return time2string(depart);
825 : }
826 : }
827 :
828 :
829 : std::string
830 103470 : SUMOVehicleParameter::getDepartLane() const {
831 : std::string val;
832 103470 : switch (departLaneProcedure) {
833 15145 : case DepartLaneDefinition::GIVEN:
834 15145 : val = toString(departLane);
835 15145 : break;
836 : case DepartLaneDefinition::RANDOM:
837 : val = "random";
838 : break;
839 : case DepartLaneDefinition::FREE:
840 : val = "free";
841 : break;
842 : case DepartLaneDefinition::ALLOWED_FREE:
843 : val = "allowed";
844 : break;
845 : case DepartLaneDefinition::BEST_FREE:
846 : val = "best";
847 : break;
848 : case DepartLaneDefinition::BEST_PROB:
849 : val = "best_prob";
850 : break;
851 : case DepartLaneDefinition::FIRST_ALLOWED:
852 : val = "first";
853 : break;
854 : case DepartLaneDefinition::DEFAULT:
855 : default:
856 : break;
857 : }
858 103470 : return val;
859 : }
860 :
861 :
862 : std::string
863 40919 : SUMOVehicleParameter::getDepartPos() const {
864 : std::string val;
865 40919 : switch (departPosProcedure) {
866 24737 : case DepartPosDefinition::GIVEN:
867 24737 : val = toString(departPos);
868 24737 : break;
869 13821 : case DepartPosDefinition::GIVEN_VEHROUTE:
870 13821 : val = StringUtils::pruneZeros(toString(departPos, MAX2(gPrecisionRandom, gPrecision)), 2);
871 13821 : break;
872 : case DepartPosDefinition::RANDOM:
873 : val = "random";
874 : break;
875 : case DepartPosDefinition::RANDOM_FREE:
876 : val = "random_free";
877 : break;
878 : case DepartPosDefinition::RANDOM_LOCATION:
879 : val = "random_location";
880 : break;
881 : case DepartPosDefinition::FREE:
882 : val = "free";
883 : break;
884 : case DepartPosDefinition::LAST:
885 : val = "last";
886 : break;
887 : case DepartPosDefinition::BASE:
888 : val = "base";
889 : break;
890 : case DepartPosDefinition::SPLIT_FRONT:
891 : val = "splitFront";
892 : break;
893 : case DepartPosDefinition::STOP:
894 : val = "stop";
895 : break;
896 : case DepartPosDefinition::DEFAULT:
897 : default:
898 : break;
899 : }
900 40919 : return val;
901 : }
902 :
903 :
904 : std::string
905 6 : SUMOVehicleParameter::getDepartPosLat() const {
906 : std::string val;
907 6 : switch (departPosLatProcedure) {
908 0 : case DepartPosLatDefinition::GIVEN:
909 0 : val = toString(departPosLat);
910 0 : break;
911 4 : case DepartPosLatDefinition::GIVEN_VEHROUTE:
912 4 : val = StringUtils::pruneZeros(toString(departPosLat, MAX2(gPrecisionRandom, gPrecision)), 2);
913 4 : break;
914 : case DepartPosLatDefinition::RANDOM:
915 : val = "random";
916 : break;
917 : case DepartPosLatDefinition::RANDOM_FREE:
918 : val = "random_free";
919 : break;
920 : case DepartPosLatDefinition::FREE:
921 : val = "free";
922 : break;
923 : case DepartPosLatDefinition::RIGHT:
924 : val = "right";
925 : break;
926 : case DepartPosLatDefinition::CENTER:
927 : val = "center";
928 : break;
929 : case DepartPosLatDefinition::LEFT:
930 : val = "left";
931 : break;
932 : case DepartPosLatDefinition::DEFAULT:
933 : default:
934 : break;
935 : }
936 6 : return val;
937 : }
938 :
939 :
940 : std::string
941 135323 : SUMOVehicleParameter::getDepartSpeed() const {
942 : std::string val;
943 135323 : switch (departSpeedProcedure) {
944 2458 : case DepartSpeedDefinition::GIVEN:
945 2458 : val = toString(departSpeed);
946 2458 : break;
947 45320 : case DepartSpeedDefinition::GIVEN_VEHROUTE:
948 45320 : val = StringUtils::pruneZeros(toString(departSpeed, MAX2(gPrecisionRandom, gPrecision)), 2);
949 45320 : break;
950 : case DepartSpeedDefinition::RANDOM:
951 : val = "random";
952 : break;
953 : case DepartSpeedDefinition::MAX:
954 : val = "max";
955 : break;
956 : case DepartSpeedDefinition::DESIRED:
957 : val = "desired";
958 : break;
959 : case DepartSpeedDefinition::LIMIT:
960 : val = "speedLimit";
961 : break;
962 : case DepartSpeedDefinition::LAST:
963 : val = "last";
964 : break;
965 : case DepartSpeedDefinition::AVG:
966 : val = "avg";
967 : break;
968 : case DepartSpeedDefinition::DEFAULT:
969 : default:
970 : break;
971 : }
972 135323 : return val;
973 : }
974 :
975 :
976 : std::string
977 312 : SUMOVehicleParameter::getDepartEdge() const {
978 : std::string val;
979 312 : switch (departEdgeProcedure) {
980 312 : case RouteIndexDefinition::GIVEN:
981 312 : val = toString(departEdge);
982 312 : break;
983 : case RouteIndexDefinition::RANDOM:
984 : val = "random";
985 : break;
986 : case RouteIndexDefinition::DEFAULT:
987 : default:
988 : break;
989 : }
990 312 : return val;
991 : }
992 :
993 : std::string
994 206 : SUMOVehicleParameter::getArrivalEdge() const {
995 : std::string val;
996 206 : switch (arrivalEdgeProcedure) {
997 206 : case RouteIndexDefinition::GIVEN:
998 206 : val = toString(arrivalEdge);
999 206 : break;
1000 : case RouteIndexDefinition::RANDOM:
1001 : val = "random";
1002 : break;
1003 : case RouteIndexDefinition::DEFAULT:
1004 : default:
1005 : break;
1006 : }
1007 206 : return val;
1008 : }
1009 :
1010 :
1011 :
1012 :
1013 : std::string
1014 296 : SUMOVehicleParameter::getArrivalLane() const {
1015 : std::string val;
1016 296 : switch (arrivalLaneProcedure) {
1017 160 : case ArrivalLaneDefinition::GIVEN:
1018 160 : val = toString(arrivalLane);
1019 160 : break;
1020 : case ArrivalLaneDefinition::CURRENT:
1021 : val = "current";
1022 : break;
1023 : case ArrivalLaneDefinition::RANDOM:
1024 : val = "random";
1025 : break;
1026 : case ArrivalLaneDefinition::FIRST_ALLOWED:
1027 : val = "first";
1028 : break;
1029 : case ArrivalLaneDefinition::DEFAULT:
1030 : default:
1031 : break;
1032 : }
1033 296 : return val;
1034 : }
1035 :
1036 :
1037 : std::string
1038 4082 : SUMOVehicleParameter::getArrivalPos() const {
1039 : std::string val;
1040 4082 : switch (arrivalPosProcedure) {
1041 3764 : case ArrivalPosDefinition::GIVEN:
1042 3764 : val = toString(arrivalPos);
1043 3764 : break;
1044 : case ArrivalPosDefinition::RANDOM:
1045 : val = "random";
1046 : break;
1047 : case ArrivalPosDefinition::CENTER:
1048 : val = "center";
1049 : break;
1050 : case ArrivalPosDefinition::MAX:
1051 : val = "max";
1052 : break;
1053 : case ArrivalPosDefinition::DEFAULT:
1054 : default:
1055 : break;
1056 : }
1057 4082 : return val;
1058 : }
1059 :
1060 :
1061 : std::string
1062 0 : SUMOVehicleParameter::getArrivalPosLat() const {
1063 : std::string val;
1064 0 : switch (arrivalPosLatProcedure) {
1065 0 : case ArrivalPosLatDefinition::GIVEN:
1066 0 : val = toString(arrivalPosLat);
1067 0 : break;
1068 : case ArrivalPosLatDefinition::RIGHT:
1069 : val = "right";
1070 : break;
1071 : case ArrivalPosLatDefinition::CENTER:
1072 : val = "center";
1073 : break;
1074 : case ArrivalPosLatDefinition::LEFT:
1075 : val = "left";
1076 : break;
1077 : case ArrivalPosLatDefinition::DEFAULT:
1078 : default:
1079 : break;
1080 : }
1081 0 : return val;
1082 : }
1083 :
1084 :
1085 : std::string
1086 3735 : SUMOVehicleParameter::getArrivalSpeed() const {
1087 : std::string val;
1088 3735 : switch (arrivalSpeedProcedure) {
1089 3599 : case ArrivalSpeedDefinition::GIVEN:
1090 3599 : val = toString(arrivalSpeed);
1091 3599 : break;
1092 : case ArrivalSpeedDefinition::CURRENT:
1093 : val = "current";
1094 : break;
1095 : case ArrivalSpeedDefinition::DEFAULT:
1096 : default:
1097 : break;
1098 : }
1099 3735 : return val;
1100 : }
1101 :
1102 :
1103 : void
1104 5243190 : SUMOVehicleParameter::incrementFlow(double scale, SumoRNG* rng) {
1105 5243190 : repetitionsDone++;
1106 : // equidistant or exponential offset (for poisson distributed arrivals)
1107 5243190 : if (repetitionProbability < 0) {
1108 4719217 : if (repetitionOffset >= 0) {
1109 4293514 : repetitionTotalOffset += (SUMOTime)((double)repetitionOffset / scale);
1110 : } else {
1111 : assert(poissonRate > 0);
1112 : // we need to cache this do avoid double generation of the rng in the TIME2STEPS macro
1113 425703 : const double r = RandHelper::randExp(poissonRate, rng);
1114 425703 : repetitionTotalOffset += TIME2STEPS(r / scale);
1115 : }
1116 : }
1117 5243190 : }
1118 :
1119 :
1120 : std::string
1121 0 : SUMOVehicleParameter::getInsertionChecks() const {
1122 0 : if ((insertionChecks == 0) || (insertionChecks == (int)InsertionCheck::ALL)) {
1123 0 : return SUMOXMLDefinitions::InsertionChecks.getString(InsertionCheck::ALL);
1124 : } else {
1125 : std::vector<std::string> insertionChecksStrs;
1126 0 : const auto insertionCheckValues = SUMOXMLDefinitions::InsertionChecks.getValues();
1127 : // iterate over values
1128 0 : for (const auto insertionCheckValue : insertionCheckValues) {
1129 0 : if ((insertionCheckValue != InsertionCheck::ALL) && (insertionChecks & (int)insertionCheckValue) != 0) {
1130 0 : insertionChecksStrs.push_back(SUMOXMLDefinitions::InsertionChecks.getString(insertionCheckValue));
1131 : }
1132 : }
1133 0 : return toString(insertionChecksStrs);
1134 0 : }
1135 : }
1136 :
1137 :
1138 : bool
1139 0 : SUMOVehicleParameter::areInsertionChecksValid(const std::string& value) const {
1140 0 : if (value.empty()) {
1141 : return true;
1142 : } else {
1143 : // split value in substrinsg
1144 0 : StringTokenizer valueStrs(value, " ");
1145 : // iterate over values
1146 0 : while (valueStrs.hasNext()) {
1147 0 : if (!SUMOXMLDefinitions::InsertionChecks.hasString(valueStrs.next())) {
1148 : return false;
1149 : }
1150 : }
1151 : return true;
1152 0 : }
1153 : }
1154 :
1155 :
1156 : int
1157 41420 : SUMOVehicleParameter::parseInsertionChecks(const std::string& value) {
1158 : // first reset insertionChecks
1159 : int result = 0;
1160 41420 : if (value.empty()) {
1161 : return (int)InsertionCheck::ALL;
1162 : } else {
1163 : // split value in substrinsg
1164 124260 : StringTokenizer insertionCheckStrs(value, " ");
1165 85494 : while (insertionCheckStrs.hasNext()) {
1166 44078 : std::string val = insertionCheckStrs.next();
1167 : if (SUMOXMLDefinitions::InsertionChecks.hasString(val)) {
1168 44074 : result |= (int)SUMOXMLDefinitions::InsertionChecks.get(val);
1169 : } else {
1170 16 : throw InvalidArgument("Unknown value '" + val + "' in " + toString(SUMO_ATTR_INSERTIONCHECKS) + ".");
1171 : }
1172 : }
1173 41420 : }
1174 41416 : return result;
1175 : }
1176 :
1177 : /****************************************************************************/
|