Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file 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 1004681 : SUMOVehicleParameter::SUMOVehicleParameter()
38 2009362 : : tag(SUMO_TAG_NOTHING), vtypeid(DEFAULT_VTYPE_ID), color(RGBColor::DEFAULT_COLOR),
39 1004681 : depart(-1), departProcedure(DepartDefinition::GIVEN),
40 1004681 : departLane(0), departLaneProcedure(DepartLaneDefinition::DEFAULT),
41 1004681 : departPos(0), departPosProcedure(DepartPosDefinition::DEFAULT),
42 1004681 : departPosLat(0), departPosLatProcedure(DepartPosLatDefinition::DEFAULT),
43 1004681 : departSpeed(-1), departSpeedProcedure(DepartSpeedDefinition::DEFAULT),
44 1004681 : departEdge(0), departEdgeProcedure(RouteIndexDefinition::DEFAULT),
45 1004681 : arrivalLane(0), arrivalLaneProcedure(ArrivalLaneDefinition::DEFAULT),
46 1004681 : arrivalPos(0), arrivalPosProcedure(ArrivalPosDefinition::DEFAULT),
47 1004681 : arrivalPosLat(0), arrivalPosLatProcedure(ArrivalPosLatDefinition::DEFAULT),
48 1004681 : arrivalSpeed(-1), arrivalSpeedProcedure(ArrivalSpeedDefinition::DEFAULT),
49 1004681 : arrivalEdge(-1), arrivalEdgeProcedure(RouteIndexDefinition::DEFAULT),
50 1004681 : repetitionNumber(-1),
51 1004681 : repetitionsDone(-1),
52 1004681 : repetitionOffset(-1),
53 1004681 : repetitionTotalOffset(0),
54 1004681 : repetitionProbability(-1),
55 1004681 : poissonRate(0),
56 1004681 : repetitionEnd(-1),
57 1004681 : line(), fromTaz(), toTaz(), personNumber(0), containerNumber(0),
58 1004681 : speedFactor(-1),
59 1004681 : calibratorSpeed(-1),
60 1004681 : insertionChecks((int)InsertionCheck::ALL),
61 1004681 : parametersSet(0)
62 1004681 : { }
63 :
64 :
65 11924979 : SUMOVehicleParameter::~SUMOVehicleParameter() {
66 11924979 : }
67 :
68 :
69 : bool
70 281882 : SUMOVehicleParameter::defaultOptionOverrides(const OptionsCont& oc, const std::string& optionName) const {
71 563764 : return oc.exists(optionName) && oc.isSet(optionName) && oc.getBool("defaults-override");
72 : }
73 :
74 :
75 : void
76 385678 : SUMOVehicleParameter::write(OutputDevice& dev, const OptionsCont& oc, const SumoXMLTag altTag, const std::string& typeID) const {
77 385678 : if (!id.empty()) {
78 : // only used by calibrator flows
79 385678 : dev.openTag(altTag).writeAttr(SUMO_ATTR_ID, id);
80 : }
81 385678 : if (typeID == "") {
82 361336 : if (wasSet(VEHPARS_VTYPE_SET)) {
83 32163 : dev.writeAttr(SUMO_ATTR_TYPE, vtypeid);
84 : }
85 : } else {
86 : dev.writeAttr(SUMO_ATTR_TYPE, typeID);
87 : }
88 : // write depart depending of tag
89 : if (altTag == SUMO_TAG_FLOW
90 385678 : || 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 148 : dev.writeAttr(SUMO_ATTR_BEGIN, getDepart());
96 : } else {
97 771208 : dev.writeAttr(SUMO_ATTR_DEPART, getDepart());
98 : }
99 : // optional parameter
100 : // departlane
101 488276 : if (wasSet(VEHPARS_DEPARTLANE_SET) && !defaultOptionOverrides(oc, "departlane")) {
102 205036 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, getDepartLane());
103 470933 : } else if (oc.exists("departlane") && oc.isSet("departlane")) {
104 698 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
105 : }
106 : // departpos
107 424871 : if (wasSet(VEHPARS_DEPARTPOS_SET) && !defaultOptionOverrides(oc, "departpos")) {
108 78258 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, getDepartPos());
109 615308 : } else if (oc.exists("departpos") && oc.isSet("departpos")) {
110 676 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
111 : }
112 : // departPosLat
113 385678 : if (wasSet(VEHPARS_DEPARTPOSLAT_SET)) {
114 12 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS_LAT, getDepartPosLat());
115 : }
116 : // departspeed
117 517368 : if (wasSet(VEHPARS_DEPARTSPEED_SET) && !defaultOptionOverrides(oc, "departspeed")) {
118 263252 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, getDepartSpeed());
119 438207 : } else if (oc.exists("departspeed") && oc.isSet("departspeed")) {
120 702 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
121 : }
122 : // departedge
123 385897 : if (wasSet(VEHPARS_DEPARTEDGE_SET) && !defaultOptionOverrides(oc, "departedge")) {
124 438 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, getDepartEdge());
125 385459 : } else if (oc.exists("departedge") && oc.isSet("departedge")) {
126 0 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, oc.getString("departedge"));
127 : }
128 : // arrivallane
129 386006 : if (wasSet(VEHPARS_ARRIVALLANE_SET) && !defaultOptionOverrides(oc, "arrivallane")) {
130 592 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, getArrivalLane());
131 654957 : } else if (oc.exists("arrivallane") && oc.isSet("arrivallane")) {
132 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
133 : }
134 : // arrivalpos
135 389722 : if (wasSet(VEHPARS_ARRIVALPOS_SET) && !defaultOptionOverrides(oc, "arrivalpos")) {
136 7992 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, getArrivalPos());
137 651102 : } else if (oc.exists("arrivalpos") && oc.isSet("arrivalpos")) {
138 692 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
139 : }
140 : // arrivalPosLat
141 385678 : if (wasSet(VEHPARS_ARRIVALPOSLAT_SET)) {
142 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS_LAT, getArrivalPosLat());
143 : }
144 : // arrivalspeed
145 389445 : if (wasSet(VEHPARS_ARRIVALSPEED_SET) && !defaultOptionOverrides(oc, "arrivalspeed")) {
146 7470 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, getArrivalSpeed());
147 651526 : } else if (oc.exists("arrivalspeed") && oc.isSet("arrivalspeed")) {
148 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
149 : }
150 : // arrivalEdge
151 385881 : if (wasSet(VEHPARS_ARRIVALEDGE_SET) && !defaultOptionOverrides(oc, "arrivaledge") && arrivalEdge >= 0) {
152 406 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, getArrivalEdge());
153 385475 : } else if (oc.exists("arrivaledge") && oc.isSet("arrivaledge")) {
154 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, oc.getString("arrivaledge"));
155 : }
156 : // color
157 385678 : if (wasSet(VEHPARS_COLOR_SET)) {
158 6717 : dev.writeAttr(SUMO_ATTR_COLOR, color);
159 : }
160 : // line
161 385678 : if (wasSet(VEHPARS_LINE_SET)) {
162 353 : dev.writeAttr(SUMO_ATTR_LINE, line);
163 : }
164 : // from TAZ
165 385678 : if (wasSet(VEHPARS_FROM_TAZ_SET)) {
166 5295 : dev.writeAttr(SUMO_ATTR_FROM_TAZ, fromTaz);
167 : }
168 : // to TAZ
169 385678 : if (wasSet(VEHPARS_TO_TAZ_SET)) {
170 5295 : dev.writeAttr(SUMO_ATTR_TO_TAZ, toTaz);
171 : }
172 : // person number
173 385678 : if (wasSet(VEHPARS_PERSON_NUMBER_SET)) {
174 0 : dev.writeAttr(SUMO_ATTR_PERSON_NUMBER, personNumber);
175 : }
176 : // container number
177 385678 : if (wasSet(VEHPARS_CONTAINER_NUMBER_SET)) {
178 0 : dev.writeAttr(SUMO_ATTR_CONTAINER_NUMBER, containerNumber);
179 : }
180 : // individual speedFactor
181 385678 : if (wasSet(VEHPARS_SPEEDFACTOR_SET)) {
182 : // might be saving state with custom precision
183 46966 : const int precision = dev.precision();
184 46966 : dev.setPrecision(MAX2(gPrecisionRandom, precision));
185 46966 : dev.writeAttr(SUMO_ATTR_SPEEDFACTOR, speedFactor);
186 46966 : dev.setPrecision(precision);
187 : }
188 : // speed (only used by calibrators)
189 385678 : if (wasSet(VEHPARS_CALIBRATORSPEED_SET)) {
190 0 : dev.writeAttr(SUMO_ATTR_SPEED, calibratorSpeed);
191 : }
192 : // insertionChecks
193 385678 : if (wasSet(VEHPARS_INSERTION_CHECKS_SET) && insertionChecks != (int)InsertionCheck::ALL) {
194 : std::vector<std::string> checks;
195 26 : if (insertionChecks == (int)InsertionCheck::NONE) {
196 52 : checks.push_back(toString(InsertionCheck::NONE));
197 : } else {
198 0 : for (auto it : SUMOXMLDefinitions::InsertionChecks.getValues()) {
199 0 : if (((int)it & insertionChecks) != 0) {
200 0 : checks.push_back(toString(it));
201 : }
202 0 : }
203 : }
204 : dev.writeAttr(SUMO_ATTR_INSERTIONCHECKS, checks);
205 26 : }
206 : // parking access rights
207 385678 : if (wasSet(VEHPARS_PARKING_BADGES_SET)) {
208 0 : dev.writeNonEmptyAttr(SUMO_ATTR_PARKING_BADGES, joinToString(parkingBadges, " "));
209 : }
210 385678 : }
211 :
212 :
213 : void
214 34288 : SUMOVehicleParameter::Stop::write(OutputDevice& dev, const bool close, const bool writeTagAndParents) const {
215 34288 : if (writeTagAndParents) {
216 34288 : dev.openTag(SUMO_TAG_STOP);
217 34288 : if (busstop != "") {
218 : dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop);
219 : }
220 34288 : if (containerstop != "") {
221 : dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop);
222 : }
223 34288 : if (chargingStation != "") {
224 : dev.writeAttr(SUMO_ATTR_CHARGING_STATION, chargingStation);
225 : }
226 34288 : if (parkingarea != "") {
227 : dev.writeAttr(SUMO_ATTR_PARKING_AREA, parkingarea);
228 : }
229 34288 : if ((busstop == "") && (containerstop == "") && (parkingarea == "") && (chargingStation == "")) {
230 19809 : if (lane != "") {
231 : dev.writeAttr(SUMO_ATTR_LANE, lane);
232 : } else {
233 1221 : dev.writeAttr(SUMO_ATTR_EDGE, edge);
234 : }
235 19809 : if ((parametersSet & STOP_START_SET) != 0) {
236 2836 : dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
237 : }
238 19809 : if ((parametersSet & STOP_END_SET) != 0) {
239 6105 : dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
240 : }
241 : }
242 : }
243 34288 : if (index > 0) {
244 257 : dev.writeAttr(SUMO_ATTR_INDEX, index);
245 : }
246 34288 : if ((parametersSet & STOP_POSLAT_SET) != 0 && posLat != INVALID_DOUBLE) {
247 71 : dev.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
248 : }
249 34288 : if ((parametersSet & STOP_ARRIVAL_SET) && (arrival >= 0)) {
250 758 : dev.writeAttr(SUMO_ATTR_ARRIVAL, time2string(arrival));
251 : }
252 34288 : if ((parametersSet & STOP_DURATION_SET) && (duration >= 0)) {
253 50212 : dev.writeAttr(SUMO_ATTR_DURATION, time2string(duration));
254 : }
255 34288 : if ((parametersSet & STOP_UNTIL_SET) && (until >= 0)) {
256 19392 : dev.writeAttr(SUMO_ATTR_UNTIL, time2string(until));
257 : }
258 34288 : if ((parametersSet & STOP_STARTED_SET) && (started >= 0)) {
259 176 : dev.writeAttr(SUMO_ATTR_STARTED, time2string(started));
260 : }
261 34288 : if ((parametersSet & STOP_ENDED_SET) && (ended >= 0)) {
262 218 : dev.writeAttr(SUMO_ATTR_ENDED, time2string(ended));
263 : }
264 34288 : if ((parametersSet & STOP_EXTENSION_SET) && (extension >= 0)) {
265 146 : dev.writeAttr(SUMO_ATTR_EXTENSION, time2string(extension));
266 : }
267 34288 : if ((parametersSet & STOP_TRIGGER_SET) != 0) {
268 211 : const std::vector<std::string> triggers = getTriggers();
269 211 : if (triggers.size() > 0) {
270 : dev.writeAttr(SUMO_ATTR_TRIGGERED, triggers);
271 : }
272 211 : }
273 34288 : if ((parametersSet & STOP_PARKING_SET) != 0) {
274 550 : dev.writeAttr(SUMO_ATTR_PARKING, parking);
275 : }
276 34288 : if ((parametersSet & STOP_EXPECTED_SET) != 0 && awaitedPersons.size() > 0) {
277 50 : dev.writeAttr(SUMO_ATTR_EXPECTED, awaitedPersons);
278 : }
279 34288 : if ((parametersSet & STOP_PERMITTED_SET) != 0 && permitted.size() > 0) {
280 790 : dev.writeAttr(SUMO_ATTR_PERMITTED, permitted);
281 : }
282 34288 : if ((parametersSet & STOP_EXPECTED_CONTAINERS_SET) != 0 && awaitedContainers.size() > 0) {
283 4 : dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, awaitedContainers);
284 : }
285 34288 : if ((parametersSet & STOP_TRIP_ID_SET) != 0) {
286 55 : dev.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
287 : }
288 34288 : if ((parametersSet & STOP_LINE_SET) != 0) {
289 22 : dev.writeAttr(SUMO_ATTR_LINE, line);
290 : }
291 34288 : if ((parametersSet & STOP_SPLIT_SET) != 0) {
292 21 : dev.writeAttr(SUMO_ATTR_SPLIT, split);
293 : }
294 34288 : if ((parametersSet & STOP_JOIN_SET) != 0) {
295 17 : dev.writeAttr(SUMO_ATTR_JOIN, join);
296 : }
297 34288 : if ((parametersSet & STOP_SPEED_SET) != 0) {
298 157 : dev.writeAttr(SUMO_ATTR_SPEED, speed);
299 : }
300 34288 : if ((parametersSet & STOP_ONDEMAND_SET) != 0) {
301 79 : dev.writeAttr(SUMO_ATTR_ONDEMAND, onDemand);
302 : }
303 34288 : if ((parametersSet & STOP_JUMP_SET) != 0 && jump >= 0) {
304 562 : dev.writeAttr(SUMO_ATTR_JUMP, time2string(jump));
305 : }
306 34288 : if (collision) {
307 633 : dev.writeAttr(SUMO_ATTR_COLLISION, collision);
308 : }
309 : // only write friendly position if is true
310 34288 : if (friendlyPos) {
311 0 : dev.writeAttr(SUMO_ATTR_FRIENDLY_POS, friendlyPos);
312 : }
313 : // only write act type if isn't empty
314 34288 : if (!actType.empty()) {
315 1361 : dev.writeAttr(SUMO_ATTR_ACTTYPE, actType);
316 : }
317 34288 : if (close) {
318 : // the user is closing the stop it is responsible for writing params
319 29178 : writeParams(dev);
320 58356 : dev.closeTag();
321 : }
322 34288 : }
323 :
324 : std::vector<std::string>
325 172 : SUMOVehicleParameter::Stop::getStoppingPlaceIDs() const {
326 : std::vector<std::string> result;
327 172 : if (busstop != "") {
328 76 : result.push_back(busstop);
329 : }
330 172 : if (containerstop != "") {
331 8 : result.push_back(containerstop);
332 : }
333 172 : if (chargingStation != "") {
334 8 : result.push_back(chargingStation);
335 : }
336 172 : if (parkingarea != "") {
337 8 : result.push_back(parkingarea);
338 : }
339 172 : return result;
340 0 : }
341 :
342 : bool
343 519307 : SUMOVehicleParameter::parseDepart(const std::string& val, const std::string& element, const std::string& id,
344 : SUMOTime& depart, DepartDefinition& dd, std::string& error, const std::string& attr) {
345 519307 : if (val == "triggered") {
346 1371 : dd = DepartDefinition::TRIGGERED;
347 517936 : } else if (val == "containerTriggered") {
348 105 : dd = DepartDefinition::CONTAINER_TRIGGERED;
349 517831 : } else if (val == "now") {
350 : // only used via TraCI. depart must be set by the calling code
351 22854 : dd = DepartDefinition::NOW;
352 494977 : } else if (val == "split") {
353 40 : dd = DepartDefinition::SPLIT;
354 494937 : } else if (val == "begin") {
355 11 : dd = DepartDefinition::BEGIN;
356 : } else {
357 : try {
358 494926 : depart = string2time(val);
359 494918 : dd = DepartDefinition::GIVEN;
360 494918 : if (depart < 0) {
361 14 : error = "Negative " + attr + " time in the definition of " + element + " '" + id + "'.";
362 7 : return false;
363 : }
364 8 : } catch (...) {
365 8 : if (id.empty()) {
366 0 : error = "Invalid " + attr + " time for " + element + ". Must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
367 : } else {
368 24 : error = "Invalid " + attr + " time for " + element + " '" + id + "';\n must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
369 : }
370 : return false;
371 8 : }
372 : }
373 : return true;
374 : }
375 :
376 :
377 : bool
378 133340 : SUMOVehicleParameter::parseDepartLane(const std::string& val, const std::string& element, const std::string& id,
379 : int& lane, DepartLaneDefinition& dld, std::string& error) {
380 : bool ok = true;
381 133340 : lane = 0;
382 133340 : dld = DepartLaneDefinition::GIVEN;
383 133340 : if (val == "random") {
384 4080 : dld = DepartLaneDefinition::RANDOM;
385 129260 : } else if (val == "free") {
386 2306 : dld = DepartLaneDefinition::FREE;
387 126954 : } else if (val == "allowed") {
388 131 : dld = DepartLaneDefinition::ALLOWED_FREE;
389 126823 : } else if (val == "best") {
390 94027 : dld = DepartLaneDefinition::BEST_FREE;
391 32796 : } else if (val == "best_prob") {
392 34 : dld = DepartLaneDefinition::BEST_PROB;
393 32762 : } else if (val == "first") {
394 1063 : dld = DepartLaneDefinition::FIRST_ALLOWED;
395 : } else {
396 : try {
397 31699 : lane = StringUtils::toInt(val);
398 31640 : if (lane < 0) {
399 : ok = false;
400 : }
401 59 : } catch (...) {
402 : ok = false;
403 59 : }
404 : }
405 : if (!ok) {
406 59 : if (id.empty()) {
407 0 : error = "Invalid departLane definition for " + element + ". Must be one of (\"random\", \"free\", \"allowed\", \"best\", \"best_prob\", \"first\", or an int>=0)";
408 : } else {
409 177 : error = "Invalid departLane definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", \"allowed\", \"best\", \"best_prob\", \"first\", or an int>=0)";
410 : }
411 : }
412 133340 : return ok;
413 : }
414 :
415 :
416 : bool
417 109921 : SUMOVehicleParameter::parseDepartPos(const std::string& val, const std::string& element, const std::string& id,
418 : double& pos, DepartPosDefinition& dpd, std::string& error) {
419 : bool ok = true;
420 109921 : pos = 0.;
421 109921 : dpd = DepartPosDefinition::GIVEN;
422 109921 : if (val == "random") {
423 2111 : dpd = DepartPosDefinition::RANDOM;
424 107810 : } else if (val == "random_free") {
425 72 : dpd = DepartPosDefinition::RANDOM_FREE;
426 107738 : } else if (val == "random_location") {
427 0 : dpd = DepartPosDefinition::RANDOM_LOCATION;
428 107738 : } else if (val == "free") {
429 375 : dpd = DepartPosDefinition::FREE;
430 107363 : } else if (val == "base") {
431 973 : dpd = DepartPosDefinition::BASE;
432 106390 : } else if (val == "last") {
433 773 : dpd = DepartPosDefinition::LAST;
434 105617 : } else if (val == "splitFront") {
435 5 : dpd = DepartPosDefinition::SPLIT_FRONT;
436 105612 : } else if (val == "stop") {
437 1832 : dpd = DepartPosDefinition::STOP;
438 : } else {
439 : try {
440 103780 : pos = StringUtils::toDouble(val);
441 54 : } catch (...) {
442 : ok = false;
443 54 : }
444 : }
445 : if (!ok) {
446 54 : if (id.empty()) {
447 0 : error = "Invalid departPos definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
448 : } else {
449 162 : error = "Invalid departPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
450 : }
451 : }
452 109921 : return ok;
453 : }
454 :
455 :
456 : bool
457 8967 : SUMOVehicleParameter::parseDepartPosLat(const std::string& val, const std::string& element, const std::string& id,
458 : double& pos, DepartPosLatDefinition& dpd, std::string& error) {
459 : bool ok = true;
460 8967 : pos = 0.;
461 8967 : dpd = DepartPosLatDefinition::GIVEN;
462 8967 : if (val == "random") {
463 6181 : dpd = DepartPosLatDefinition::RANDOM;
464 2786 : } else if (val == "random_free") {
465 450 : dpd = DepartPosLatDefinition::RANDOM_FREE;
466 2336 : } else if (val == "free") {
467 71 : dpd = DepartPosLatDefinition::FREE;
468 2265 : } else if (val == "right") {
469 246 : dpd = DepartPosLatDefinition::RIGHT;
470 2019 : } else if (val == "center") {
471 589 : dpd = DepartPosLatDefinition::CENTER;
472 1430 : } else if (val == "left") {
473 187 : dpd = DepartPosLatDefinition::LEFT;
474 : } else {
475 : try {
476 1243 : pos = StringUtils::toDouble(val);
477 0 : } catch (...) {
478 : ok = false;
479 0 : }
480 : }
481 : if (!ok) {
482 0 : if (id.empty()) {
483 0 : error = "Invalid departPosLat definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
484 : } else {
485 0 : error = "Invalid departPosLat definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
486 : }
487 : }
488 8967 : return ok;
489 : }
490 :
491 :
492 : bool
493 263964 : SUMOVehicleParameter::parseDepartSpeed(const std::string& val, const std::string& element, const std::string& id,
494 : double& speed, DepartSpeedDefinition& dsd, std::string& error) {
495 : bool ok = true;
496 263964 : speed = -1.;
497 263964 : dsd = DepartSpeedDefinition::GIVEN;
498 263964 : if (val == "random") {
499 229 : dsd = DepartSpeedDefinition::RANDOM;
500 263735 : } else if (val == "max") {
501 137621 : dsd = DepartSpeedDefinition::MAX;
502 126114 : } else if (val == "desired") {
503 191 : dsd = DepartSpeedDefinition::DESIRED;
504 125923 : } else if (val == "speedLimit") {
505 489 : dsd = DepartSpeedDefinition::LIMIT;
506 125434 : } else if (val == "last") {
507 37 : dsd = DepartSpeedDefinition::LAST;
508 125397 : } else if (val == "avg") {
509 692 : dsd = DepartSpeedDefinition::AVG;
510 : } else {
511 : try {
512 124705 : speed = StringUtils::toDouble(val);
513 124651 : if (speed < 0) {
514 : ok = false;
515 : }
516 54 : } catch (...) {
517 : ok = false;
518 54 : }
519 : }
520 : if (!ok) {
521 54 : if (id.empty()) {
522 0 : error = "Invalid departSpeed definition for " + element + ". Must be one of (\"random\", \"max\", or a float>=0)";
523 : } else {
524 162 : error = "Invalid departSpeed definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float>=0)";
525 : }
526 : }
527 263964 : return ok;
528 : }
529 :
530 :
531 : bool
532 232 : SUMOVehicleParameter::parseRouteIndex(const std::string& val, const std::string& element, const std::string& id,
533 : const SumoXMLAttr attr, int& edgeIndex, RouteIndexDefinition& rid, std::string& error) {
534 : bool ok = true;
535 232 : edgeIndex = -1;
536 232 : rid = RouteIndexDefinition::GIVEN;
537 232 : if (val == "random") {
538 63 : rid = RouteIndexDefinition::RANDOM;
539 : } else {
540 : try {
541 169 : edgeIndex = StringUtils::toInt(val);
542 169 : if (edgeIndex < 0) {
543 : ok = false;
544 : }
545 0 : } catch (...) {
546 : ok = false;
547 0 : }
548 : }
549 : if (!ok) {
550 14 : if (id.empty()) {
551 0 : error = "Invalid " + toString(attr) + " definition for " + element + ". Must be one of (\"random\", \"free\", or an int>=0)";
552 : } else {
553 42 : error = "Invalid " + toString(attr) + " definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", or an int>=0)";
554 : }
555 : }
556 232 : return ok;
557 : }
558 :
559 :
560 : bool
561 26080 : SUMOVehicleParameter::parseArrivalLane(const std::string& val, const std::string& element, const std::string& id,
562 : int& lane, ArrivalLaneDefinition& ald, std::string& error) {
563 : bool ok = true;
564 26080 : lane = 0;
565 26080 : ald = ArrivalLaneDefinition::GIVEN;
566 26080 : if (val == "current") {
567 23428 : ald = ArrivalLaneDefinition::CURRENT;
568 2652 : } else if (val == "random") {
569 67 : ald = ArrivalLaneDefinition::RANDOM;
570 2585 : } else if (val == "first") {
571 7 : ald = ArrivalLaneDefinition::FIRST_ALLOWED;
572 : } else {
573 : try {
574 2578 : lane = StringUtils::toInt(val);
575 2524 : if (lane < 0) {
576 : ok = false;
577 : }
578 54 : } catch (...) {
579 : ok = false;
580 54 : }
581 : }
582 : if (!ok) {
583 54 : if (id.empty()) {
584 0 : error = "Invalid arrivalLane definition for " + element + ". Must be one of (\"current\", or an int>=0)";
585 : } else {
586 162 : error = "Invalid arrivalLane definition for " + element + " '" + id + "';\n must be one of (\"current\", or an int>=0)";
587 : }
588 : }
589 26080 : return ok;
590 : }
591 :
592 :
593 : bool
594 62745 : SUMOVehicleParameter::parseArrivalPos(const std::string& val, const std::string& element, const std::string& id,
595 : double& pos, ArrivalPosDefinition& apd, std::string& error) {
596 : bool ok = true;
597 62745 : pos = 0.;
598 62745 : apd = ArrivalPosDefinition::GIVEN;
599 62745 : if (val == "random") {
600 1448 : apd = ArrivalPosDefinition::RANDOM;
601 61297 : } else if (val == "center") {
602 0 : apd = ArrivalPosDefinition::CENTER;
603 61297 : } else if (val == "max") {
604 22980 : apd = ArrivalPosDefinition::MAX;
605 : } else {
606 : try {
607 38317 : pos = StringUtils::toDouble(val);
608 54 : } catch (...) {
609 : ok = false;
610 54 : }
611 : }
612 : if (!ok) {
613 54 : if (id.empty()) {
614 0 : error = "Invalid arrivalPos definition for " + element + ". Must be one of (\"random\", \"max\", or a float)";
615 : } else {
616 162 : error = "Invalid arrivalPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float)";
617 : }
618 : }
619 62745 : return ok;
620 : }
621 :
622 :
623 : bool
624 1065 : SUMOVehicleParameter::parseArrivalPosLat(const std::string& val, const std::string& element, const std::string& id,
625 : double& pos, ArrivalPosLatDefinition& apd, std::string& error) {
626 : bool ok = true;
627 1065 : pos = 0.;
628 1065 : apd = ArrivalPosLatDefinition::GIVEN;
629 1065 : if (val == "right") {
630 499 : apd = ArrivalPosLatDefinition::RIGHT;
631 566 : } else if (val == "center") {
632 9 : apd = ArrivalPosLatDefinition::CENTER;
633 557 : } else if (val == "left") {
634 39 : apd = ArrivalPosLatDefinition::LEFT;
635 : } else {
636 : try {
637 518 : pos = StringUtils::toDouble(val);
638 0 : } catch (...) {
639 : ok = false;
640 0 : }
641 : }
642 : if (!ok) {
643 0 : if (id.empty()) {
644 0 : error = "Invalid arrivalPosLat definition for " + element + ". Must be one of (\"right\", \"center\", \"left\", or a float)";
645 : } else {
646 0 : error = "Invalid arrivalPosLat definition for " + element + " '" + id + "';\n must be one of (\"right\", \"center\", \"left\", or a float)";
647 : }
648 : }
649 1065 : return ok;
650 : }
651 :
652 :
653 : bool
654 26710 : SUMOVehicleParameter::parseArrivalSpeed(const std::string& val, const std::string& element, const std::string& id,
655 : double& speed, ArrivalSpeedDefinition& asd, std::string& error) {
656 : bool ok = true;
657 26710 : speed = -1.;
658 26710 : asd = ArrivalSpeedDefinition::GIVEN;
659 26710 : if (val == "current") {
660 23501 : asd = ArrivalSpeedDefinition::CURRENT;
661 : } else {
662 : try {
663 3209 : speed = StringUtils::toDouble(val);
664 3155 : if (speed < 0) {
665 : ok = false;
666 : }
667 54 : } catch (...) {
668 : ok = false;
669 54 : }
670 : }
671 : if (!ok) {
672 54 : if (id.empty()) {
673 0 : error = "Invalid arrivalSpeed definition for " + element + ". Must be one of (\"current\", or a float>=0)";
674 : } else {
675 162 : error = "Invalid arrivalSpeed definition for " + element + " '" + id + "';\n must be one of (\"current\", or a float>=0)";
676 : }
677 : }
678 26710 : return ok;
679 : }
680 :
681 :
682 : double
683 1466457 : SUMOVehicleParameter::interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string& id, bool silent) {
684 1466457 : if (pos < 0) {
685 28746 : pos = maximumValue + pos;
686 : }
687 1466457 : if (pos > maximumValue && pos != std::numeric_limits<double>::infinity()) {
688 3 : if (!silent) {
689 9 : WRITE_WARNINGF(TL("Invalid % % given for %. Using edge end instead."), toString(attr), toString(pos), id);
690 : }
691 3 : pos = maximumValue;
692 : }
693 1466457 : return pos;
694 : }
695 :
696 :
697 : bool
698 980 : SUMOVehicleParameter::parsePersonModes(const std::string& modes, const std::string& element, const std::string& id, SVCPermissions& modeSet, std::string& error) {
699 : // separte modes in different strings, and check if modes are valid
700 3090 : for (StringTokenizer st(modes); st.hasNext();) {
701 1130 : const std::string mode = st.next();
702 1130 : if (mode == "car") {
703 442 : modeSet |= SVC_PASSENGER;
704 688 : } else if (mode == "taxi") {
705 135 : modeSet |= SVC_TAXI;
706 553 : } else if (mode == "bicycle") {
707 41 : modeSet |= SVC_BICYCLE;
708 512 : } else if (mode == "public") {
709 512 : modeSet |= SVC_BUS;
710 : } else {
711 0 : if (id.empty()) {
712 0 : error = "Unknown person mode '" + mode + "'. Must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
713 : } else {
714 0 : error = "Unknown person mode '" + mode + "' for " + element + " '" + id + "';\n must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
715 : }
716 : return false;
717 : }
718 980 : }
719 980 : return true;
720 : }
721 :
722 :
723 : void
724 44254 : SUMOVehicleParameter::parseStopTriggers(const std::vector<std::string>& triggers, bool expectTrigger, Stop& stop) {
725 44254 : if (triggers.size() == 0 && expectTrigger) {
726 1145 : stop.triggered = true;
727 : }
728 45546 : for (std::string val : triggers) {
729 1292 : if (val == toString(SUMO_TAG_PERSON)) {
730 776 : stop.triggered = true;
731 516 : } else if (val == toString(SUMO_TAG_CONTAINER)) {
732 267 : stop.containerTriggered = true;
733 249 : } else if (val == toString(SUMO_ATTR_JOIN)) {
734 116 : stop.joinTriggered = true;
735 : } else {
736 : try {
737 133 : stop.triggered = StringUtils::toBool(val);
738 0 : } catch (BoolFormatException&) {
739 0 : WRITE_ERROR(TL("Value of stop attribute 'trigger' must be 'person', 'container', 'join' or a boolean"));
740 0 : }
741 : }
742 : }
743 44254 : }
744 :
745 :
746 : ParkingType
747 3119 : SUMOVehicleParameter::parseParkingType(const std::string& value) {
748 3119 : if (value == toString(ParkingType::OPPORTUNISTIC)) {
749 : return ParkingType::OPPORTUNISTIC;
750 : } else {
751 3119 : return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
752 : }
753 : }
754 :
755 :
756 : std::vector<std::string>
757 240 : SUMOVehicleParameter::Stop::getTriggers() const {
758 : std::vector<std::string> triggers;
759 240 : if (triggered) {
760 330 : triggers.push_back(toString(SUMO_TAG_PERSON));
761 : }
762 240 : if (containerTriggered) {
763 60 : triggers.push_back(toString(SUMO_TAG_CONTAINER));
764 : }
765 240 : if (joinTriggered) {
766 64 : triggers.push_back(toString(SUMO_ATTR_JOIN));
767 : }
768 240 : return triggers;
769 0 : }
770 :
771 : int
772 8821 : SUMOVehicleParameter::Stop::getFlags() const {
773 8821 : return (((parking == ParkingType::OFFROAD) ? 1 : 0) +
774 8821 : (triggered ? 2 : 0) +
775 8821 : (containerTriggered ? 4 : 0) +
776 8821 : (busstop != "" ? 8 : 0) +
777 8821 : (containerstop != "" ? 16 : 0) +
778 8821 : (chargingStation != "" ? 32 : 0) +
779 8821 : (parkingarea != "" ? 64 : 0) +
780 8821 : (overheadWireSegment != "" ? 128 : 0));
781 : }
782 :
783 :
784 : std::string
785 385678 : SUMOVehicleParameter::getDepart() const {
786 385678 : if (departProcedure == DepartDefinition::TRIGGERED) {
787 703 : return "triggered";
788 384975 : } else if (departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
789 16 : return "containerTriggered";
790 : // } else if (departProcedure == DepartDefinition::NOW) { // TODO check whether this is useful in XML input (currently TraCI only)
791 : // return "now";
792 384959 : } else if (departProcedure == DepartDefinition::SPLIT) {
793 0 : return "split";
794 384959 : } else if (departProcedure == DepartDefinition::BEGIN) {
795 8 : return "begin";
796 : } else {
797 384951 : return time2string(depart);
798 : }
799 : }
800 :
801 :
802 : std::string
803 102518 : SUMOVehicleParameter::getDepartLane() const {
804 : std::string val;
805 102518 : switch (departLaneProcedure) {
806 14972 : case DepartLaneDefinition::GIVEN:
807 14972 : val = toString(departLane);
808 14972 : break;
809 : case DepartLaneDefinition::RANDOM:
810 : val = "random";
811 : break;
812 : case DepartLaneDefinition::FREE:
813 : val = "free";
814 : break;
815 : case DepartLaneDefinition::ALLOWED_FREE:
816 : val = "allowed";
817 : break;
818 : case DepartLaneDefinition::BEST_FREE:
819 : val = "best";
820 : break;
821 : case DepartLaneDefinition::BEST_PROB:
822 : val = "best_prob";
823 : break;
824 : case DepartLaneDefinition::FIRST_ALLOWED:
825 : val = "first";
826 : break;
827 : case DepartLaneDefinition::DEFAULT:
828 : default:
829 : break;
830 : }
831 102518 : return val;
832 : }
833 :
834 :
835 : std::string
836 39129 : SUMOVehicleParameter::getDepartPos() const {
837 : std::string val;
838 39129 : switch (departPosProcedure) {
839 24455 : case DepartPosDefinition::GIVEN:
840 24455 : val = toString(departPos);
841 24455 : break;
842 13629 : case DepartPosDefinition::GIVEN_VEHROUTE:
843 13629 : val = StringUtils::pruneZeros(toString(departPos, MAX2(gPrecisionRandom, gPrecision)), 2);
844 13629 : break;
845 : case DepartPosDefinition::RANDOM:
846 : val = "random";
847 : break;
848 : case DepartPosDefinition::RANDOM_FREE:
849 : val = "random_free";
850 : break;
851 : case DepartPosDefinition::RANDOM_LOCATION:
852 : val = "random_location";
853 : break;
854 : case DepartPosDefinition::FREE:
855 : val = "free";
856 : break;
857 : case DepartPosDefinition::LAST:
858 : val = "last";
859 : break;
860 : case DepartPosDefinition::BASE:
861 : val = "base";
862 : break;
863 : case DepartPosDefinition::SPLIT_FRONT:
864 : val = "splitFront";
865 : break;
866 : case DepartPosDefinition::STOP:
867 : val = "stop";
868 : break;
869 : case DepartPosDefinition::DEFAULT:
870 : default:
871 : break;
872 : }
873 39129 : return val;
874 : }
875 :
876 :
877 : std::string
878 6 : SUMOVehicleParameter::getDepartPosLat() const {
879 : std::string val;
880 6 : switch (departPosLatProcedure) {
881 0 : case DepartPosLatDefinition::GIVEN:
882 0 : val = toString(departPosLat);
883 0 : break;
884 4 : case DepartPosLatDefinition::GIVEN_VEHROUTE:
885 4 : val = StringUtils::pruneZeros(toString(departPosLat, MAX2(gPrecisionRandom, gPrecision)), 2);
886 4 : break;
887 : case DepartPosLatDefinition::RANDOM:
888 : val = "random";
889 : break;
890 : case DepartPosLatDefinition::RANDOM_FREE:
891 : val = "random_free";
892 : break;
893 : case DepartPosLatDefinition::FREE:
894 : val = "free";
895 : break;
896 : case DepartPosLatDefinition::RIGHT:
897 : val = "right";
898 : break;
899 : case DepartPosLatDefinition::CENTER:
900 : val = "center";
901 : break;
902 : case DepartPosLatDefinition::LEFT:
903 : val = "left";
904 : break;
905 : case DepartPosLatDefinition::DEFAULT:
906 : default:
907 : break;
908 : }
909 6 : return val;
910 : }
911 :
912 :
913 : std::string
914 131626 : SUMOVehicleParameter::getDepartSpeed() const {
915 : std::string val;
916 131626 : switch (departSpeedProcedure) {
917 2402 : case DepartSpeedDefinition::GIVEN:
918 2402 : val = toString(departSpeed);
919 2402 : break;
920 43000 : case DepartSpeedDefinition::GIVEN_VEHROUTE:
921 43000 : val = StringUtils::pruneZeros(toString(departSpeed, MAX2(gPrecisionRandom, gPrecision)), 2);
922 43000 : break;
923 : case DepartSpeedDefinition::RANDOM:
924 : val = "random";
925 : break;
926 : case DepartSpeedDefinition::MAX:
927 : val = "max";
928 : break;
929 : case DepartSpeedDefinition::DESIRED:
930 : val = "desired";
931 : break;
932 : case DepartSpeedDefinition::LIMIT:
933 : val = "speedLimit";
934 : break;
935 : case DepartSpeedDefinition::LAST:
936 : val = "last";
937 : break;
938 : case DepartSpeedDefinition::AVG:
939 : val = "avg";
940 : break;
941 : case DepartSpeedDefinition::DEFAULT:
942 : default:
943 : break;
944 : }
945 131626 : return val;
946 : }
947 :
948 :
949 : std::string
950 219 : SUMOVehicleParameter::getDepartEdge() const {
951 : std::string val;
952 219 : switch (departEdgeProcedure) {
953 219 : case RouteIndexDefinition::GIVEN:
954 219 : val = toString(departEdge);
955 219 : break;
956 : case RouteIndexDefinition::RANDOM:
957 : val = "random";
958 : break;
959 : case RouteIndexDefinition::DEFAULT:
960 : default:
961 : break;
962 : }
963 219 : return val;
964 : }
965 :
966 : std::string
967 203 : SUMOVehicleParameter::getArrivalEdge() const {
968 : std::string val;
969 203 : switch (arrivalEdgeProcedure) {
970 203 : case RouteIndexDefinition::GIVEN:
971 203 : val = toString(arrivalEdge);
972 203 : break;
973 : case RouteIndexDefinition::RANDOM:
974 : val = "random";
975 : break;
976 : case RouteIndexDefinition::DEFAULT:
977 : default:
978 : break;
979 : }
980 203 : return val;
981 : }
982 :
983 :
984 :
985 :
986 : std::string
987 296 : SUMOVehicleParameter::getArrivalLane() const {
988 : std::string val;
989 296 : switch (arrivalLaneProcedure) {
990 160 : case ArrivalLaneDefinition::GIVEN:
991 160 : val = toString(arrivalLane);
992 160 : break;
993 : case ArrivalLaneDefinition::CURRENT:
994 : val = "current";
995 : break;
996 : case ArrivalLaneDefinition::RANDOM:
997 : val = "random";
998 : break;
999 : case ArrivalLaneDefinition::FIRST_ALLOWED:
1000 : val = "first";
1001 : break;
1002 : case ArrivalLaneDefinition::DEFAULT:
1003 : default:
1004 : break;
1005 : }
1006 296 : return val;
1007 : }
1008 :
1009 :
1010 : std::string
1011 3996 : SUMOVehicleParameter::getArrivalPos() const {
1012 : std::string val;
1013 3996 : switch (arrivalPosProcedure) {
1014 3724 : case ArrivalPosDefinition::GIVEN:
1015 3724 : val = toString(arrivalPos);
1016 3724 : break;
1017 : case ArrivalPosDefinition::RANDOM:
1018 : val = "random";
1019 : break;
1020 : case ArrivalPosDefinition::CENTER:
1021 : val = "center";
1022 : break;
1023 : case ArrivalPosDefinition::MAX:
1024 : val = "max";
1025 : break;
1026 : case ArrivalPosDefinition::DEFAULT:
1027 : default:
1028 : break;
1029 : }
1030 3996 : return val;
1031 : }
1032 :
1033 :
1034 : std::string
1035 0 : SUMOVehicleParameter::getArrivalPosLat() const {
1036 : std::string val;
1037 0 : switch (arrivalPosLatProcedure) {
1038 0 : case ArrivalPosLatDefinition::GIVEN:
1039 0 : val = toString(arrivalPosLat);
1040 0 : break;
1041 : case ArrivalPosLatDefinition::RIGHT:
1042 : val = "right";
1043 : break;
1044 : case ArrivalPosLatDefinition::CENTER:
1045 : val = "center";
1046 : break;
1047 : case ArrivalPosLatDefinition::LEFT:
1048 : val = "left";
1049 : break;
1050 : case ArrivalPosLatDefinition::DEFAULT:
1051 : default:
1052 : break;
1053 : }
1054 0 : return val;
1055 : }
1056 :
1057 :
1058 : std::string
1059 3735 : SUMOVehicleParameter::getArrivalSpeed() const {
1060 : std::string val;
1061 3735 : switch (arrivalSpeedProcedure) {
1062 3599 : case ArrivalSpeedDefinition::GIVEN:
1063 3599 : val = toString(arrivalSpeed);
1064 3599 : break;
1065 : case ArrivalSpeedDefinition::CURRENT:
1066 : val = "current";
1067 : break;
1068 : case ArrivalSpeedDefinition::DEFAULT:
1069 : default:
1070 : break;
1071 : }
1072 3735 : return val;
1073 : }
1074 :
1075 :
1076 : void
1077 5081528 : SUMOVehicleParameter::incrementFlow(double scale, SumoRNG* rng) {
1078 5081528 : repetitionsDone++;
1079 : // equidistant or exponential offset (for poisson distributed arrivals)
1080 5081528 : if (repetitionProbability < 0) {
1081 4590624 : if (repetitionOffset >= 0) {
1082 4207710 : repetitionTotalOffset += (SUMOTime)((double)repetitionOffset / scale);
1083 : } else {
1084 : assert(poissonRate > 0);
1085 : // we need to cache this do avoid double generation of the rng in the TIME2STEPS macro
1086 382914 : const double r = RandHelper::randExp(poissonRate, rng);
1087 382914 : repetitionTotalOffset += TIME2STEPS(r / scale);
1088 : }
1089 : }
1090 5081528 : }
1091 :
1092 :
1093 : std::string
1094 0 : SUMOVehicleParameter::getInsertionChecks() const {
1095 0 : if ((insertionChecks == 0) || (insertionChecks == (int)InsertionCheck::ALL)) {
1096 0 : return SUMOXMLDefinitions::InsertionChecks.getString(InsertionCheck::ALL);
1097 : } else {
1098 : std::vector<std::string> insertionChecksStrs;
1099 0 : const auto insertionCheckValues = SUMOXMLDefinitions::InsertionChecks.getValues();
1100 : // iterate over values
1101 0 : for (const auto insertionCheckValue : insertionCheckValues) {
1102 0 : if ((insertionCheckValue != InsertionCheck::ALL) && (insertionChecks & (int)insertionCheckValue) != 0) {
1103 0 : insertionChecksStrs.push_back(SUMOXMLDefinitions::InsertionChecks.getString(insertionCheckValue));
1104 : }
1105 : }
1106 0 : return toString(insertionChecksStrs);
1107 0 : }
1108 : }
1109 :
1110 :
1111 : bool
1112 0 : SUMOVehicleParameter::areInsertionChecksValid(const std::string& value) const {
1113 0 : if (value.empty()) {
1114 : return true;
1115 : } else {
1116 : // split value in substrinsg
1117 0 : StringTokenizer valueStrs(value, " ");
1118 : // iterate over values
1119 0 : while (valueStrs.hasNext()) {
1120 0 : if (!SUMOXMLDefinitions::InsertionChecks.hasString(valueStrs.next())) {
1121 : return false;
1122 : }
1123 : }
1124 : return true;
1125 0 : }
1126 : }
1127 :
1128 :
1129 : int
1130 44268 : SUMOVehicleParameter::parseInsertionChecks(const std::string& value) {
1131 : // first reset insertionChecks
1132 : int result = 0;
1133 44268 : if (value.empty()) {
1134 : return (int)InsertionCheck::ALL;
1135 : } else {
1136 : // split value in substrinsg
1137 132804 : StringTokenizer insertionCheckStrs(value, " ");
1138 91425 : while (insertionCheckStrs.hasNext()) {
1139 47161 : std::string val = insertionCheckStrs.next();
1140 : if (SUMOXMLDefinitions::InsertionChecks.hasString(val)) {
1141 47157 : result |= (int)SUMOXMLDefinitions::InsertionChecks.get(val);
1142 : } else {
1143 12 : throw InvalidArgument("Unknown value '" + val + "' in " + toString(SUMO_ATTR_INSERTIONCHECKS) + ".");
1144 : }
1145 : }
1146 44268 : }
1147 44264 : return result;
1148 : }
1149 :
1150 : /****************************************************************************/
|