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