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 1169188 : SUMOVehicleParameter::SUMOVehicleParameter()
38 2338376 : : tag(SUMO_TAG_NOTHING), vtypeid(DEFAULT_VTYPE_ID), color(RGBColor::DEFAULT_COLOR),
39 1169188 : depart(-1), departProcedure(DepartDefinition::GIVEN),
40 1169188 : departLane(0), departLaneProcedure(DepartLaneDefinition::DEFAULT),
41 1169188 : departPos(0), departPosProcedure(DepartPosDefinition::DEFAULT),
42 1169188 : departPosLat(0), departPosLatProcedure(DepartPosLatDefinition::DEFAULT),
43 1169188 : departSpeed(-1), departSpeedProcedure(DepartSpeedDefinition::DEFAULT),
44 1169188 : departEdge(0), departEdgeProcedure(RouteIndexDefinition::DEFAULT),
45 1169188 : arrivalLane(0), arrivalLaneProcedure(ArrivalLaneDefinition::DEFAULT),
46 1169188 : arrivalPos(0), arrivalPosProcedure(ArrivalPosDefinition::DEFAULT),
47 1169188 : arrivalPosLat(0), arrivalPosLatProcedure(ArrivalPosLatDefinition::DEFAULT),
48 1169188 : arrivalSpeed(-1), arrivalSpeedProcedure(ArrivalSpeedDefinition::DEFAULT),
49 1169188 : arrivalEdge(-1), arrivalEdgeProcedure(RouteIndexDefinition::DEFAULT),
50 1169188 : repetitionNumber(-1),
51 1169188 : repetitionsDone(-1),
52 1169188 : repetitionOffset(-1),
53 1169188 : repetitionTotalOffset(0),
54 1169188 : repetitionProbability(-1),
55 1169188 : poissonRate(0),
56 1169188 : repetitionEnd(-1),
57 1169188 : line(), fromTaz(), toTaz(), personNumber(0), containerNumber(0),
58 1169188 : speedFactor(-1),
59 1169188 : calibratorSpeed(-1),
60 1169188 : insertionChecks((int)InsertionCheck::ALL),
61 1169188 : parametersSet(0)
62 1169188 : { }
63 :
64 :
65 12881241 : SUMOVehicleParameter::~SUMOVehicleParameter() {
66 12881241 : }
67 :
68 :
69 : bool
70 287945 : SUMOVehicleParameter::defaultOptionOverrides(const OptionsCont& oc, const std::string& optionName) const {
71 575890 : return oc.exists(optionName) && oc.isSet(optionName) && oc.getBool("defaults-override");
72 : }
73 :
74 :
75 : void
76 530088 : SUMOVehicleParameter::write(OutputDevice& dev, const OptionsCont& oc, const SumoXMLTag altTag, const std::string& typeID) const {
77 530088 : if (!id.empty()) {
78 : // only used by calibrator flows
79 530088 : dev.openTag(altTag).writeAttr(SUMO_ATTR_ID, id);
80 : }
81 530088 : if (typeID == "") {
82 504980 : if (wasSet(VEHPARS_VTYPE_SET)) {
83 34267 : dev.writeAttr(SUMO_ATTR_TYPE, vtypeid);
84 : }
85 : } else {
86 25108 : dev.writeAttr(SUMO_ATTR_TYPE, typeID);
87 : }
88 : // write depart depending of tag
89 : if (altTag == SUMO_TAG_FLOW
90 530088 : || 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 1058154 : dev.writeAttr(SUMO_ATTR_DEPART, getDepart());
119 : }
120 : // optional parameter
121 : // departlane
122 633357 : if (wasSet(VEHPARS_DEPARTLANE_SET) && !defaultOptionOverrides(oc, "departlane")) {
123 206378 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, getDepartLane());
124 740230 : } else if (oc.exists("departlane") && oc.isSet("departlane")) {
125 718 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
126 : }
127 : // departpos
128 571080 : if (wasSet(VEHPARS_DEPARTPOS_SET) && !defaultOptionOverrides(oc, "departpos")) {
129 81856 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, getDepartPos());
130 883128 : } else if (oc.exists("departpos") && oc.isSet("departpos")) {
131 676 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
132 : }
133 : // departPosLat
134 530088 : if (wasSet(VEHPARS_DEPARTPOSLAT_SET)) {
135 12 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS_LAT, getDepartPosLat());
136 : }
137 : // departspeed
138 665189 : if (wasSet(VEHPARS_DEPARTSPEED_SET) && !defaultOptionOverrides(oc, "departspeed")) {
139 270074 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, getDepartSpeed());
140 704892 : } else if (oc.exists("departspeed") && oc.isSet("departspeed")) {
141 722 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
142 : }
143 : // departedge
144 530400 : if (wasSet(VEHPARS_DEPARTEDGE_SET) && !defaultOptionOverrides(oc, "departedge")) {
145 624 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, getDepartEdge());
146 529776 : } else if (oc.exists("departedge") && oc.isSet("departedge")) {
147 0 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, oc.getString("departedge"));
148 : }
149 : // arrivallane
150 530416 : if (wasSet(VEHPARS_ARRIVALLANE_SET) && !defaultOptionOverrides(oc, "arrivallane")) {
151 592 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, getArrivalLane());
152 925704 : } else if (oc.exists("arrivallane") && oc.isSet("arrivallane")) {
153 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
154 : }
155 : // arrivalpos
156 534218 : if (wasSet(VEHPARS_ARRIVALPOS_SET) && !defaultOptionOverrides(oc, "arrivalpos")) {
157 8164 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, getArrivalPos());
158 921723 : } else if (oc.exists("arrivalpos") && oc.isSet("arrivalpos")) {
159 692 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
160 : }
161 : // arrivalPosLat
162 530088 : if (wasSet(VEHPARS_ARRIVALPOSLAT_SET)) {
163 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS_LAT, getArrivalPosLat());
164 : }
165 : // arrivalspeed
166 533855 : if (wasSet(VEHPARS_ARRIVALSPEED_SET) && !defaultOptionOverrides(oc, "arrivalspeed")) {
167 7470 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, getArrivalSpeed());
168 922273 : } else if (oc.exists("arrivalspeed") && oc.isSet("arrivalspeed")) {
169 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
170 : }
171 : // arrivalEdge
172 530294 : if (wasSet(VEHPARS_ARRIVALEDGE_SET) && !defaultOptionOverrides(oc, "arrivaledge") && arrivalEdge >= 0) {
173 412 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, getArrivalEdge());
174 529882 : } else if (oc.exists("arrivaledge") && oc.isSet("arrivaledge")) {
175 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, oc.getString("arrivaledge"));
176 : }
177 : // color
178 530088 : if (wasSet(VEHPARS_COLOR_SET)) {
179 7713 : dev.writeAttr(SUMO_ATTR_COLOR, color);
180 : }
181 : // line
182 530088 : if (wasSet(VEHPARS_LINE_SET)) {
183 371 : dev.writeAttr(SUMO_ATTR_LINE, line);
184 : }
185 : // from TAZ
186 530088 : if (wasSet(VEHPARS_FROM_TAZ_SET)) {
187 9594 : dev.writeAttr(SUMO_ATTR_FROM_TAZ, fromTaz);
188 : }
189 : // to TAZ
190 530088 : if (wasSet(VEHPARS_TO_TAZ_SET)) {
191 9594 : dev.writeAttr(SUMO_ATTR_TO_TAZ, toTaz);
192 : }
193 : // person number
194 530088 : if (wasSet(VEHPARS_PERSON_NUMBER_SET)) {
195 0 : dev.writeAttr(SUMO_ATTR_PERSON_NUMBER, personNumber);
196 : }
197 : // container number
198 530088 : if (wasSet(VEHPARS_CONTAINER_NUMBER_SET)) {
199 0 : dev.writeAttr(SUMO_ATTR_CONTAINER_NUMBER, containerNumber);
200 : }
201 : // individual speedFactor
202 530088 : if (wasSet(VEHPARS_SPEEDFACTOR_SET)) {
203 : // might be saving state with custom precision
204 : const int precision = dev.getPrecision();
205 49033 : dev.setPrecision(MAX2(gPrecisionRandom, precision));
206 49033 : dev.writeAttr(SUMO_ATTR_SPEEDFACTOR, speedFactor);
207 49033 : dev.setPrecision(precision);
208 : }
209 : // speed (only used by calibrators)
210 530088 : if (wasSet(VEHPARS_CALIBRATORSPEED_SET)) {
211 0 : dev.writeAttr(SUMO_ATTR_SPEED, calibratorSpeed);
212 : }
213 : // insertionChecks
214 530088 : 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 530088 : if (wasSet(VEHPARS_PARKING_BADGES_SET)) {
229 0 : dev.writeNonEmptyAttr(SUMO_ATTR_PARKING_BADGES, joinToString(parkingBadges, " "));
230 : }
231 530088 : }
232 :
233 :
234 : void
235 29119 : SUMOVehicleParameter::Stop::write(OutputDevice& dev, const bool close, const bool writeTagAndParents) const {
236 29119 : if (writeTagAndParents) {
237 29119 : dev.openTag(SUMO_TAG_STOP);
238 29119 : if (busstop != "") {
239 10403 : dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop);
240 : }
241 29119 : if (containerstop != "") {
242 415 : dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop);
243 : }
244 29119 : if (chargingStation != "") {
245 302 : dev.writeAttr(SUMO_ATTR_CHARGING_STATION, chargingStation);
246 : }
247 29119 : if (parkingarea != "") {
248 8897 : dev.writeAttr(SUMO_ATTR_PARKING_AREA, parkingarea);
249 : }
250 29119 : if ((busstop == "") && (containerstop == "") && (parkingarea == "") && (chargingStation == "")) {
251 9112 : if (lane != "") {
252 7700 : dev.writeAttr(SUMO_ATTR_LANE, lane);
253 : } else {
254 1412 : dev.writeAttr(SUMO_ATTR_EDGE, edge);
255 : }
256 9112 : if ((parametersSet & STOP_START_SET) != 0) {
257 3007 : dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
258 : }
259 9112 : if ((parametersSet & STOP_END_SET) != 0) {
260 6391 : dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
261 : }
262 : }
263 : }
264 29119 : if (index > 0) {
265 297 : dev.writeAttr(SUMO_ATTR_INDEX, index);
266 : }
267 29119 : if ((parametersSet & STOP_POSLAT_SET) != 0 && posLat != INVALID_DOUBLE) {
268 71 : dev.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
269 : }
270 29119 : if ((parametersSet & STOP_ARRIVAL_SET) && (arrival >= 0)) {
271 792 : dev.writeAttr(SUMO_ATTR_ARRIVAL, time2string(arrival));
272 : }
273 29119 : if ((parametersSet & STOP_DURATION_SET) && (duration >= 0)) {
274 32104 : dev.writeAttr(SUMO_ATTR_DURATION, time2string(duration));
275 : }
276 29119 : if ((parametersSet & STOP_UNTIL_SET) && (until >= 0)) {
277 27644 : dev.writeAttr(SUMO_ATTR_UNTIL, time2string(until));
278 : }
279 29119 : if ((parametersSet & STOP_STARTED_SET) && (started >= 0)) {
280 178 : dev.writeAttr(SUMO_ATTR_STARTED, time2string(started));
281 : }
282 29119 : if ((parametersSet & STOP_ENDED_SET) && (ended >= 0)) {
283 218 : dev.writeAttr(SUMO_ATTR_ENDED, time2string(ended));
284 : }
285 29119 : if ((parametersSet & STOP_EXTENSION_SET) && (extension >= 0)) {
286 146 : dev.writeAttr(SUMO_ATTR_EXTENSION, time2string(extension));
287 : }
288 29119 : if ((parametersSet & STOP_TRIGGER_SET) != 0) {
289 285 : const std::vector<std::string> triggers = getTriggers();
290 285 : if (triggers.size() > 0) {
291 277 : dev.writeAttr(SUMO_ATTR_TRIGGERED, triggers);
292 : }
293 285 : }
294 29119 : if ((parametersSet & STOP_PARKING_SET) != 0) {
295 1608 : dev.writeAttr(SUMO_ATTR_PARKING, parking);
296 : }
297 29119 : if ((parametersSet & STOP_EXPECTED_SET) != 0 && awaitedPersons.size() > 0) {
298 51 : dev.writeAttr(SUMO_ATTR_EXPECTED, awaitedPersons);
299 : }
300 29119 : if ((parametersSet & STOP_PERMITTED_SET) != 0 && permitted.size() > 0) {
301 1008 : dev.writeAttr(SUMO_ATTR_PERMITTED, permitted);
302 : }
303 29119 : if ((parametersSet & STOP_EXPECTED_CONTAINERS_SET) != 0 && awaitedContainers.size() > 0) {
304 4 : dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, awaitedContainers);
305 : }
306 29119 : if ((parametersSet & STOP_TRIP_ID_SET) != 0) {
307 55 : dev.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
308 : }
309 29119 : if ((parametersSet & STOP_LINE_SET) != 0) {
310 22 : dev.writeAttr(SUMO_ATTR_LINE, line);
311 : }
312 29119 : if ((parametersSet & STOP_SPLIT_SET) != 0) {
313 21 : dev.writeAttr(SUMO_ATTR_SPLIT, split);
314 : }
315 29119 : if ((parametersSet & STOP_JOIN_SET) != 0) {
316 17 : dev.writeAttr(SUMO_ATTR_JOIN, join);
317 : }
318 29119 : if ((parametersSet & STOP_SPEED_SET) != 0) {
319 164 : dev.writeAttr(SUMO_ATTR_SPEED, speed);
320 : }
321 29119 : if ((parametersSet & STOP_ONDEMAND_SET) != 0) {
322 79 : dev.writeAttr(SUMO_ATTR_ONDEMAND, onDemand);
323 : }
324 29119 : if ((parametersSet & STOP_JUMP_SET) != 0 && jump >= 0) {
325 624 : dev.writeAttr(SUMO_ATTR_JUMP, time2string(jump));
326 : }
327 29119 : if ((parametersSet & STOP_JUMP_UNTIL_SET) != 0 && jumpUntil >= 0) {
328 18 : dev.writeAttr(SUMO_ATTR_JUMP_UNTIL, time2string(jumpUntil));
329 : }
330 29119 : if ((parametersSet & STOP_PRIORITY_SET) != 0 && priority >= 0) {
331 42 : dev.writeAttr(SUMO_ATTR_PRIORITY, priority);
332 : }
333 29119 : if (collision) {
334 665 : dev.writeAttr(SUMO_ATTR_COLLISION, collision);
335 : }
336 : // only write friendly position if is true
337 29119 : if (friendlyPos) {
338 0 : dev.writeAttr(SUMO_ATTR_FRIENDLY_POS, friendlyPos);
339 : }
340 : // only write act type if isn't empty
341 29119 : if (!actType.empty()) {
342 1771 : dev.writeAttr(SUMO_ATTR_ACTTYPE, actType);
343 : }
344 29119 : if (close) {
345 : // the user is closing the stop it is responsible for writing params
346 20502 : writeParams(dev);
347 41004 : dev.closeTag();
348 : }
349 29119 : }
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 682577 : 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 682577 : if (val == "triggered") {
373 1443 : dd = DepartDefinition::TRIGGERED;
374 681134 : } else if (val == "containerTriggered") {
375 105 : dd = DepartDefinition::CONTAINER_TRIGGERED;
376 681029 : } else if (val == "now") {
377 : // only used via TraCI. depart must be set by the calling code
378 22875 : dd = DepartDefinition::NOW;
379 658154 : } else if (val == "split") {
380 40 : dd = DepartDefinition::SPLIT;
381 658114 : } else if (val == "begin") {
382 11 : dd = DepartDefinition::BEGIN;
383 : } else {
384 : try {
385 658103 : depart = string2time(val);
386 658095 : dd = DepartDefinition::GIVEN;
387 658095 : 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 173511 : 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 173511 : lane = 0;
409 173511 : dld = DepartLaneDefinition::GIVEN;
410 173511 : if (val == "random") {
411 4146 : dld = DepartLaneDefinition::RANDOM;
412 169365 : } else if (val == "free") {
413 2354 : dld = DepartLaneDefinition::FREE;
414 167011 : } else if (val == "allowed") {
415 131 : dld = DepartLaneDefinition::ALLOWED_FREE;
416 166880 : } else if (val == "best") {
417 94568 : dld = DepartLaneDefinition::BEST_FREE;
418 72312 : } else if (val == "best_prob") {
419 48 : dld = DepartLaneDefinition::BEST_PROB;
420 72264 : } else if (val == "first") {
421 40088 : dld = DepartLaneDefinition::FIRST_ALLOWED;
422 : } else {
423 : try {
424 32176 : lane = StringUtils::toInt(val);
425 32117 : 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 173511 : return ok;
440 : }
441 :
442 :
443 : bool
444 112877 : 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 112877 : pos = 0.;
448 112877 : dpd = DepartPosDefinition::GIVEN;
449 112877 : if (val == "random") {
450 3149 : dpd = DepartPosDefinition::RANDOM;
451 109728 : } else if (val == "random_free") {
452 72 : dpd = DepartPosDefinition::RANDOM_FREE;
453 109656 : } else if (val == "random_location") {
454 0 : dpd = DepartPosDefinition::RANDOM_LOCATION;
455 109656 : } else if (val == "free") {
456 417 : dpd = DepartPosDefinition::FREE;
457 109239 : } else if (val == "base") {
458 995 : dpd = DepartPosDefinition::BASE;
459 108244 : } else if (val == "last") {
460 848 : dpd = DepartPosDefinition::LAST;
461 107396 : } else if (val == "splitFront") {
462 5 : dpd = DepartPosDefinition::SPLIT_FRONT;
463 107391 : } else if (val == "stop") {
464 2484 : dpd = DepartPosDefinition::STOP;
465 : } else {
466 : try {
467 104907 : 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 112877 : return ok;
480 : }
481 :
482 :
483 : bool
484 8965 : 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 8965 : pos = 0.;
488 8965 : dpd = DepartPosLatDefinition::GIVEN;
489 8965 : if (val == "random") {
490 6181 : dpd = DepartPosLatDefinition::RANDOM;
491 2784 : } else if (val == "random_free") {
492 449 : dpd = DepartPosLatDefinition::RANDOM_FREE;
493 2335 : } else if (val == "free") {
494 71 : dpd = DepartPosLatDefinition::FREE;
495 2264 : } else if (val == "right") {
496 246 : dpd = DepartPosLatDefinition::RIGHT;
497 2018 : } else if (val == "center") {
498 589 : dpd = DepartPosLatDefinition::CENTER;
499 1429 : } else if (val == "left") {
500 187 : dpd = DepartPosLatDefinition::LEFT;
501 : } else {
502 : try {
503 1242 : 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 8965 : return ok;
516 : }
517 :
518 :
519 : bool
520 304542 : 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 304542 : speed = -1.;
524 304542 : dsd = DepartSpeedDefinition::GIVEN;
525 304542 : if (val == "random") {
526 234 : dsd = DepartSpeedDefinition::RANDOM;
527 304308 : } else if (val == "max") {
528 138395 : dsd = DepartSpeedDefinition::MAX;
529 165913 : } else if (val == "desired") {
530 289 : dsd = DepartSpeedDefinition::DESIRED;
531 165624 : } else if (val == "speedLimit") {
532 564 : dsd = DepartSpeedDefinition::LIMIT;
533 165060 : } else if (val == "last") {
534 37 : dsd = DepartSpeedDefinition::LAST;
535 165023 : } else if (val == "avg") {
536 1175 : dsd = DepartSpeedDefinition::AVG;
537 : } else {
538 : try {
539 163848 : speed = StringUtils::toDouble(val);
540 163794 : 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 304542 : 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 26202 : 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 26202 : lane = 0;
592 26202 : ald = ArrivalLaneDefinition::GIVEN;
593 26202 : if (val == "current") {
594 23448 : ald = ArrivalLaneDefinition::CURRENT;
595 2754 : } else if (val == "random") {
596 72 : ald = ArrivalLaneDefinition::RANDOM;
597 2682 : } else if (val == "first") {
598 7 : ald = ArrivalLaneDefinition::FIRST_ALLOWED;
599 : } else {
600 : try {
601 2675 : lane = StringUtils::toInt(val);
602 2621 : 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 26202 : return ok;
617 : }
618 :
619 :
620 : bool
621 63215 : 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 63215 : pos = 0.;
625 63215 : apd = ArrivalPosDefinition::GIVEN;
626 63215 : if (val == "random") {
627 1650 : apd = ArrivalPosDefinition::RANDOM;
628 61565 : } else if (val == "center") {
629 0 : apd = ArrivalPosDefinition::CENTER;
630 61565 : } else if (val == "max") {
631 23001 : apd = ArrivalPosDefinition::MAX;
632 : } else {
633 : try {
634 38564 : 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 63215 : return ok;
647 : }
648 :
649 :
650 : bool
651 1069 : 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 1069 : pos = 0.;
655 1069 : apd = ArrivalPosLatDefinition::GIVEN;
656 1069 : if (val == "right") {
657 498 : apd = ArrivalPosLatDefinition::RIGHT;
658 571 : } else if (val == "center") {
659 9 : apd = ArrivalPosLatDefinition::CENTER;
660 562 : } else if (val == "left") {
661 41 : apd = ArrivalPosLatDefinition::LEFT;
662 : } else {
663 : try {
664 521 : 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 1069 : return ok;
677 : }
678 :
679 :
680 : bool
681 26732 : 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 26732 : speed = -1.;
685 26732 : asd = ArrivalSpeedDefinition::GIVEN;
686 26732 : if (val == "current") {
687 23521 : asd = ArrivalSpeedDefinition::CURRENT;
688 : } else {
689 : try {
690 3211 : speed = StringUtils::toDouble(val);
691 3157 : 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 26732 : return ok;
706 : }
707 :
708 :
709 : double
710 1478489 : SUMOVehicleParameter::interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string& id, bool silent) {
711 1478489 : if (pos < 0) {
712 28768 : pos = maximumValue + pos;
713 : }
714 1478489 : 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 1478489 : return pos;
721 : }
722 :
723 :
724 : bool
725 1070 : 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 3392 : for (StringTokenizer st(modes); st.hasNext();) {
728 1252 : const std::string mode = st.next();
729 1252 : if (mode == "car") {
730 471 : modeSet |= SVC_PASSENGER;
731 781 : } else if (mode == "taxi") {
732 168 : modeSet |= SVC_TAXI;
733 613 : } else if (mode == "bicycle") {
734 41 : modeSet |= SVC_BICYCLE;
735 572 : } else if (mode == "public") {
736 572 : 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 1070 : }
746 1070 : return true;
747 : }
748 :
749 :
750 : void
751 39266 : SUMOVehicleParameter::parseStopTriggers(const std::vector<std::string>& triggers, bool expectTrigger, Stop& stop) {
752 39266 : if (triggers.size() == 0 && expectTrigger) {
753 1031 : stop.triggered = true;
754 : }
755 40804 : for (std::string val : triggers) {
756 1538 : if (val == toString(SUMO_TAG_PERSON)) {
757 958 : stop.triggered = true;
758 580 : } else if (val == toString(SUMO_TAG_CONTAINER)) {
759 303 : 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 39266 : }
771 :
772 :
773 : ParkingType
774 3528 : SUMOVehicleParameter::parseParkingType(const std::string& value) {
775 3528 : if (value == toString(ParkingType::OPPORTUNISTIC)) {
776 : return ParkingType::OPPORTUNISTIC;
777 : } else {
778 3528 : return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
779 : }
780 : }
781 :
782 :
783 : std::vector<std::string>
784 313 : SUMOVehicleParameter::Stop::getTriggers() const {
785 : std::vector<std::string> triggers;
786 313 : if (triggered) {
787 428 : triggers.push_back(toString(SUMO_TAG_PERSON));
788 : }
789 313 : if (containerTriggered) {
790 110 : triggers.push_back(toString(SUMO_TAG_CONTAINER));
791 : }
792 313 : if (joinTriggered) {
793 64 : triggers.push_back(toString(SUMO_ATTR_JOIN));
794 : }
795 313 : return triggers;
796 0 : }
797 :
798 : int
799 9532 : SUMOVehicleParameter::Stop::getFlags() const {
800 9532 : return (((parking == ParkingType::OFFROAD) ? 1 : 0) +
801 9532 : (triggered ? 2 : 0) +
802 9532 : (containerTriggered ? 4 : 0) +
803 9532 : (busstop != "" ? 8 : 0) +
804 9532 : (containerstop != "" ? 16 : 0) +
805 9532 : (chargingStation != "" ? 32 : 0) +
806 9532 : (parkingarea != "" ? 64 : 0) +
807 9532 : (overheadWireSegment != "" ? 128 : 0));
808 : }
809 :
810 :
811 : std::string
812 530088 : SUMOVehicleParameter::getDepart() const {
813 530088 : if (departProcedure == DepartDefinition::TRIGGERED) {
814 743 : return "triggered";
815 529345 : } 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 529329 : } else if (departProcedure == DepartDefinition::SPLIT) {
820 0 : return "split";
821 529329 : } else if (departProcedure == DepartDefinition::BEGIN) {
822 8 : return "begin";
823 : } else {
824 529321 : return time2string(depart);
825 : }
826 : }
827 :
828 :
829 : std::string
830 103189 : SUMOVehicleParameter::getDepartLane() const {
831 : std::string val;
832 103189 : switch (departLaneProcedure) {
833 14864 : case DepartLaneDefinition::GIVEN:
834 14864 : val = toString(departLane);
835 14864 : 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 103189 : return val;
859 : }
860 :
861 :
862 : std::string
863 40928 : SUMOVehicleParameter::getDepartPos() const {
864 : std::string val;
865 40928 : switch (departPosProcedure) {
866 24738 : case DepartPosDefinition::GIVEN:
867 24738 : val = toString(departPos);
868 24738 : break;
869 13826 : case DepartPosDefinition::GIVEN_VEHROUTE:
870 13826 : val = StringUtils::pruneZeros(toString(departPos, MAX2(gPrecisionRandom, gPrecision)), 2);
871 13826 : 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 40928 : 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 135037 : SUMOVehicleParameter::getDepartSpeed() const {
942 : std::string val;
943 135037 : switch (departSpeedProcedure) {
944 2458 : case DepartSpeedDefinition::GIVEN:
945 2458 : val = toString(departSpeed);
946 2458 : break;
947 45034 : case DepartSpeedDefinition::GIVEN_VEHROUTE:
948 45034 : val = StringUtils::pruneZeros(toString(departSpeed, MAX2(gPrecisionRandom, gPrecision)), 2);
949 45034 : 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 135037 : 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 5311461 : SUMOVehicleParameter::incrementFlow(double scale, SumoRNG* rng) {
1105 5311461 : repetitionsDone++;
1106 : // equidistant or exponential offset (for poisson distributed arrivals)
1107 5311461 : if (repetitionProbability < 0) {
1108 4787365 : if (repetitionOffset >= 0) {
1109 4370320 : 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 417045 : const double r = RandHelper::randExp(poissonRate, rng);
1114 417045 : repetitionTotalOffset += TIME2STEPS(r / scale);
1115 : }
1116 : }
1117 5311461 : }
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 40034 : SUMOVehicleParameter::parseInsertionChecks(const std::string& value) {
1158 : // first reset insertionChecks
1159 : int result = 0;
1160 40034 : if (value.empty()) {
1161 : return (int)InsertionCheck::ALL;
1162 : } else {
1163 : // split value in substrinsg
1164 120102 : StringTokenizer insertionCheckStrs(value, " ");
1165 82724 : while (insertionCheckStrs.hasNext()) {
1166 42694 : std::string val = insertionCheckStrs.next();
1167 : if (SUMOXMLDefinitions::InsertionChecks.hasString(val)) {
1168 42690 : result |= (int)SUMOXMLDefinitions::InsertionChecks.get(val);
1169 : } else {
1170 16 : throw InvalidArgument("Unknown value '" + val + "' in " + toString(SUMO_ATTR_INSERTIONCHECKS) + ".");
1171 : }
1172 : }
1173 40034 : }
1174 40030 : return result;
1175 : }
1176 :
1177 : /****************************************************************************/
|