Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2017-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 VehicleType.cpp
15 : /// @author Gregor Laemmel
16 : /// @date 04.04.2017
17 : ///
18 : // C++ TraCI client API implementation
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <microsim/MSNet.h>
23 : #include <microsim/MSVehicleControl.h>
24 : #include <microsim/MSVehicleType.h>
25 : #include <libsumo/TraCIConstants.h>
26 : #include <utils/emissions/PollutantsInterface.h>
27 : #include <utils/vehicle/SUMOVehicleParserHelper.h>
28 : #include "Helper.h"
29 : #include "VehicleType.h"
30 :
31 :
32 : namespace libsumo {
33 : // ===========================================================================
34 : // static member initializations
35 : // ===========================================================================
36 : SubscriptionResults VehicleType::mySubscriptionResults;
37 : ContextSubscriptionResults VehicleType::myContextSubscriptionResults;
38 :
39 :
40 : // ===========================================================================
41 : // static member definitions
42 : // ===========================================================================
43 : std::vector<std::string>
44 249 : VehicleType::getIDList() {
45 : std::vector<std::string> ids;
46 249 : MSNet::getInstance()->getVehicleControl().insertVTypeIDs(ids);
47 247 : return ids;
48 2 : }
49 :
50 :
51 : int
52 14 : VehicleType::getIDCount() {
53 14 : return (int)getIDList().size();
54 : }
55 :
56 :
57 : double
58 465 : VehicleType::getLength(const std::string& typeID) {
59 930 : return getVType(typeID)->getLength();
60 : }
61 :
62 :
63 : double
64 104 : VehicleType::getMaxSpeed(const std::string& typeID) {
65 208 : return getVType(typeID)->getMaxSpeed();
66 : }
67 :
68 :
69 : double
70 89 : VehicleType::getActionStepLength(const std::string& typeID) {
71 178 : return getVType(typeID)->getActionStepLengthSecs();
72 : }
73 :
74 :
75 : double
76 154 : VehicleType::getSpeedFactor(const std::string& typeID) {
77 154 : return getVType(typeID)->getSpeedFactor().getParameter()[0];
78 : }
79 :
80 :
81 : double
82 67 : VehicleType::getSpeedDeviation(const std::string& typeID) {
83 73 : return getVType(typeID)->getSpeedFactor().getParameter()[1];
84 : }
85 :
86 :
87 : double
88 1307 : VehicleType::getAccel(const std::string& typeID) {
89 2612 : return getVType(typeID)->getCarFollowModel().getMaxAccel();
90 : }
91 :
92 :
93 : double
94 1066 : VehicleType::getDecel(const std::string& typeID) {
95 2132 : return getVType(typeID)->getCarFollowModel().getMaxDecel();
96 : }
97 :
98 :
99 : double
100 894 : VehicleType::getEmergencyDecel(const std::string& typeID) {
101 1788 : return getVType(typeID)->getCarFollowModel().getEmergencyDecel();
102 : }
103 :
104 :
105 : double
106 90 : VehicleType::getApparentDecel(const std::string& typeID) {
107 180 : return getVType(typeID)->getCarFollowModel().getApparentDecel();
108 : }
109 :
110 :
111 : double
112 105 : VehicleType::getImperfection(const std::string& typeID) {
113 210 : return getVType(typeID)->getCarFollowModel().getImperfection();
114 : }
115 :
116 :
117 : double
118 522 : VehicleType::getTau(const std::string& typeID) {
119 1044 : return getVType(typeID)->getCarFollowModel().getHeadwayTime();
120 : }
121 :
122 :
123 : std::string
124 776 : VehicleType::getVehicleClass(const std::string& typeID) {
125 1170 : return toString(getVType(typeID)->getVehicleClass());
126 : }
127 :
128 :
129 : std::string
130 165 : VehicleType::getEmissionClass(const std::string& typeID) {
131 330 : return PollutantsInterface::getName(getVType(typeID)->getEmissionClass());
132 : }
133 :
134 :
135 : std::string
136 72 : VehicleType::getShapeClass(const std::string& typeID) {
137 144 : return getVehicleShapeName(getVType(typeID)->getGuiShape());
138 : }
139 :
140 :
141 : double
142 704 : VehicleType::getMinGap(const std::string& typeID) {
143 1408 : return getVType(typeID)->getMinGap();
144 : }
145 :
146 :
147 : double
148 98 : VehicleType::getWidth(const std::string& typeID) {
149 196 : return getVType(typeID)->getWidth();
150 : }
151 :
152 :
153 : double
154 63 : VehicleType::getHeight(const std::string& typeID) {
155 126 : return getVType(typeID)->getHeight();
156 : }
157 :
158 :
159 : TraCIColor
160 14 : VehicleType::getColor(const std::string& typeID) {
161 28 : return Helper::makeTraCIColor(getVType(typeID)->getColor());
162 : }
163 :
164 :
165 : double
166 13 : VehicleType::getMinGapLat(const std::string& typeID) {
167 26 : return getVType(typeID)->getMinGapLat();
168 : }
169 :
170 :
171 : double
172 68 : VehicleType::getMaxSpeedLat(const std::string& typeID) {
173 136 : return getVType(typeID)->getMaxSpeedLat();
174 : }
175 :
176 :
177 : std::string
178 68 : VehicleType::getLateralAlignment(const std::string& typeID) {
179 74 : if (getVType(typeID)->getPreferredLateralAlignment() != LatAlignmentDefinition::GIVEN) {
180 136 : return toString(getVType(typeID)->getPreferredLateralAlignment());
181 : } else {
182 0 : return toString(getVType(typeID)->getPreferredLateralAlignmentOffset());
183 : }
184 : }
185 :
186 :
187 : std::string
188 132 : VehicleType::getParameter(const std::string& typeID, const std::string& key) {
189 264 : if (StringUtils::startsWith(key, "junctionModel.")) {
190 12 : const std::string attrName = key.substr(14);
191 12 : if (!SUMOXMLDefinitions::Attrs.hasString(attrName)) {
192 0 : throw TraCIException("Invalid junctionModel parameter '" + key + "' for type '" + typeID + "'");
193 : }
194 12 : SumoXMLAttr attr = (SumoXMLAttr)SUMOXMLDefinitions::Attrs.get(attrName);
195 : if (SUMOVTypeParameter::AllowedJMAttrs.count(attr) == 0) {
196 0 : throw TraCIException("Invalid junctionModel parameter '" + key + "' for type '" + typeID + "'");
197 : }
198 24 : if (getVType(typeID)->getParameter().jmParameter.count(attr) != 0) {
199 12 : return getVType(typeID)->getParameter().jmParameter.find(attr)->second;
200 : } else {
201 6 : return "";
202 : }
203 : } else {
204 240 : return getVType(typeID)->getParameter().getParameter(key, "");
205 : }
206 : }
207 :
208 56 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(VehicleType)
209 :
210 : int
211 7 : VehicleType::getPersonCapacity(const std::string& typeID) {
212 14 : return getVType(typeID)->getPersonCapacity();
213 : }
214 :
215 : double
216 6 : VehicleType::getScale(const std::string& typeID) {
217 6 : return getVType(typeID)->getParameter().scale;
218 : }
219 :
220 : double
221 43 : VehicleType::getBoardingDuration(const std::string& typeID) {
222 43 : return STEPS2TIME(getVType(typeID)->getBoardingDuration(true));
223 : }
224 :
225 : double
226 12 : VehicleType::getImpatience(const std::string& typeID) {
227 24 : return getVType(typeID)->getImpatience();
228 : }
229 :
230 : void
231 103 : VehicleType::setLength(const std::string& typeID, double length) {
232 103 : getVType(typeID)->setLength(length);
233 103 : }
234 :
235 :
236 : void
237 44 : VehicleType::setMaxSpeed(const std::string& typeID, double speed) {
238 44 : getVType(typeID)->setMaxSpeed(speed);
239 44 : }
240 :
241 :
242 : void
243 16 : VehicleType::setActionStepLength(const std::string& typeID, double actionStepLength, bool resetActionOffset) {
244 16 : getVType(typeID)->setActionStepLength(SUMOVehicleParserHelper::processActionStepLength(actionStepLength), resetActionOffset);
245 16 : }
246 :
247 :
248 : void
249 13 : VehicleType::setBoardingDuration(const std::string& typeID, double boardingDuration) {
250 13 : getVType(typeID)->setBoardingDuration(TIME2STEPS(boardingDuration), true);
251 13 : }
252 :
253 :
254 : void
255 6 : VehicleType::setImpatience(const std::string& typeID, double impatience) {
256 6 : getVType(typeID)->setImpatience(impatience);
257 6 : }
258 :
259 :
260 : void
261 17 : VehicleType::setVehicleClass(const std::string& typeID, const std::string& clazz) {
262 17 : getVType(typeID)->setVClass(getVehicleClassID(clazz));
263 17 : }
264 :
265 :
266 : void
267 11 : VehicleType::setSpeedFactor(const std::string& typeID, double factor) {
268 11 : getVType(typeID)->setSpeedFactor(factor);
269 11 : }
270 :
271 :
272 : void
273 6 : VehicleType::setSpeedDeviation(const std::string& typeID, double deviation) {
274 6 : getVType(typeID)->setSpeedDeviation(deviation);
275 6 : }
276 :
277 :
278 : void
279 22 : VehicleType::setEmissionClass(const std::string& typeID, const std::string& clazz) {
280 22 : getVType(typeID)->setEmissionClass(PollutantsInterface::getClassByName(clazz));
281 22 : }
282 :
283 :
284 : void
285 15 : VehicleType::setShapeClass(const std::string& typeID, const std::string& shapeClass) {
286 15 : getVType(typeID)->setShape(getVehicleShapeID(shapeClass));
287 15 : }
288 :
289 :
290 : void
291 29 : VehicleType::setWidth(const std::string& typeID, double width) {
292 29 : getVType(typeID)->setWidth(width);
293 29 : }
294 :
295 :
296 : void
297 19 : VehicleType::setHeight(const std::string& typeID, double height) {
298 19 : getVType(typeID)->setHeight(height);
299 19 : }
300 :
301 :
302 : void
303 28 : VehicleType::setMinGap(const std::string& typeID, double minGap) {
304 28 : getVType(typeID)->setMinGap(minGap);
305 28 : }
306 :
307 :
308 : void
309 38 : VehicleType::setAccel(const std::string& typeID, double accel) {
310 38 : getVType(typeID)->setAccel(accel);
311 38 : }
312 :
313 :
314 : void
315 28 : VehicleType::setDecel(const std::string& typeID, double decel) {
316 28 : MSVehicleType* v = getVType(typeID);
317 28 : v->setDecel(decel);
318 : // automatically raise emergencyDecel to ensure it is at least as high as decel
319 28 : if (decel > v->getCarFollowModel().getEmergencyDecel()) {
320 : if (v->getParameter().cfParameter.count(SUMO_ATTR_EMERGENCYDECEL) > 0) {
321 : // notify user only if emergencyDecel was previously specified
322 44 : WRITE_WARNINGF(TL("Automatically setting emergencyDecel to % for vType '%' to match decel."), toString(decel), typeID);
323 : }
324 12 : v->setEmergencyDecel(decel);
325 : }
326 28 : }
327 :
328 :
329 : void
330 39 : VehicleType::setEmergencyDecel(const std::string& typeID, double decel) {
331 39 : MSVehicleType* v = getVType(typeID);
332 39 : v->setEmergencyDecel(decel);
333 39 : if (decel < v->getCarFollowModel().getMaxDecel()) {
334 22 : WRITE_WARNINGF(TL("New value of emergencyDecel (%) is lower than decel (%)"), toString(decel), toString(v->getCarFollowModel().getMaxDecel()));
335 : }
336 39 : }
337 :
338 :
339 : void
340 23 : VehicleType::setApparentDecel(const std::string& typeID, double decel) {
341 23 : getVType(typeID)->setApparentDecel(decel);
342 23 : }
343 :
344 :
345 : void
346 32 : VehicleType::setImperfection(const std::string& typeID, double imperfection) {
347 32 : getVType(typeID)->setImperfection(imperfection);
348 32 : }
349 :
350 :
351 : void
352 23 : VehicleType::setTau(const std::string& typeID, double tau) {
353 23 : getVType(typeID)->setTau(tau);
354 23 : }
355 :
356 :
357 : void
358 6 : VehicleType::setColor(const std::string& typeID, const TraCIColor& c) {
359 6 : getVType(typeID)->setColor(Helper::makeRGBColor(c));
360 6 : }
361 :
362 :
363 : void
364 7 : VehicleType::setMinGapLat(const std::string& typeID, double minGapLat) {
365 7 : getVType(typeID)->setMinGapLat(minGapLat);
366 7 : }
367 :
368 :
369 : void
370 14 : VehicleType::setMaxSpeedLat(const std::string& typeID, double speed) {
371 14 : getVType(typeID)->setMaxSpeedLat(speed);
372 14 : }
373 :
374 :
375 : void
376 14 : VehicleType::setLateralAlignment(const std::string& typeID, const std::string& latAlignment) {
377 : double lao;
378 : LatAlignmentDefinition lad;
379 14 : if (SUMOVTypeParameter::parseLatAlignment(latAlignment, lao, lad)) {
380 14 : getVType(typeID)->setPreferredLateralAlignment(lad, lao);
381 : } else {
382 0 : throw TraCIException("Unknown value '" + latAlignment + "' when setting latAlignment for vType '" + typeID + "';\n must be one of (\"right\", \"center\", \"arbitrary\", \"nice\", \"compact\", \"left\" or a float)");
383 : }
384 14 : }
385 :
386 : void
387 6 : VehicleType::setScale(const std::string& typeID, double value) {
388 6 : getVType(typeID)->setScale(value);
389 6 : }
390 :
391 : void
392 7 : VehicleType::copy(const std::string& origTypeID, const std::string& newTypeID) {
393 7 : getVType(origTypeID)->duplicateType(newTypeID, true);
394 7 : }
395 :
396 :
397 : void
398 96 : VehicleType::setParameter(const std::string& typeID, const std::string& name, const std::string& value) {
399 192 : if (StringUtils::startsWith(name, "junctionModel.")) {
400 24 : const std::string attrName = name.substr(14);
401 24 : if (!SUMOXMLDefinitions::Attrs.hasString(attrName)) {
402 12 : throw TraCIException("Invalid junctionModel parameter '" + name + "' for type '" + typeID + "'");
403 : }
404 18 : SumoXMLAttr attr = (SumoXMLAttr)SUMOXMLDefinitions::Attrs.get(attrName);
405 : if (SUMOVTypeParameter::AllowedJMAttrs.count(attr) == 0) {
406 12 : throw TraCIException("Invalid junctionModel parameter '" + name + "' for type '" + typeID + "'");
407 : }
408 : try {
409 12 : StringUtils::toDouble(value); // check number format
410 12 : ((SUMOVTypeParameter&)getVType(typeID)->getParameter()).jmParameter[attr] = value;
411 6 : } catch (NumberFormatException&) {
412 12 : throw TraCIException("Invalid junctionModel parameter value '" + value + "' for type '" + typeID + " (should be numeric)'");
413 6 : }
414 : } else {
415 144 : ((SUMOVTypeParameter&)getVType(typeID)->getParameter()).setParameter(name, value);
416 : }
417 78 : }
418 :
419 :
420 172 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(VehicleType, VEHICLETYPE)
421 :
422 :
423 : MSVehicleType*
424 7822 : VehicleType::getVType(std::string id) {
425 7822 : MSVehicleType* t = MSNet::getInstance()->getVehicleControl().getVType(id);
426 7822 : if (t == nullptr) {
427 4 : throw TraCIException("Vehicle type '" + id + "' is not known");
428 : }
429 7820 : return t;
430 : }
431 :
432 :
433 : std::shared_ptr<VariableWrapper>
434 267 : VehicleType::makeWrapper() {
435 267 : return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
436 : }
437 :
438 :
439 : bool
440 5057 : VehicleType::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
441 5057 : return handleVariableWithID(objID, objID, variable, wrapper, paramData);
442 : }
443 :
444 :
445 : bool
446 32299 : VehicleType::handleVariableWithID(const std::string& objID, const std::string& typeID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
447 32299 : switch (variable) {
448 160 : case TRACI_ID_LIST:
449 160 : return wrapper->wrapStringList(objID, variable, getIDList());
450 10 : case ID_COUNT:
451 10 : return wrapper->wrapInt(objID, variable, getIDCount());
452 347 : case VAR_LENGTH:
453 347 : return wrapper->wrapDouble(objID, variable, getLength(typeID));
454 61 : case VAR_HEIGHT:
455 61 : return wrapper->wrapDouble(objID, variable, getHeight(typeID));
456 562 : case VAR_MINGAP:
457 562 : return wrapper->wrapDouble(objID, variable, getMinGap(typeID));
458 94 : case VAR_MAXSPEED:
459 94 : return wrapper->wrapDouble(objID, variable, getMaxSpeed(typeID));
460 1297 : case VAR_ACCEL:
461 1297 : return wrapper->wrapDouble(objID, variable, getAccel(typeID));
462 924 : case VAR_DECEL:
463 924 : return wrapper->wrapDouble(objID, variable, getDecel(typeID));
464 640 : case VAR_EMERGENCY_DECEL:
465 640 : return wrapper->wrapDouble(objID, variable, getEmergencyDecel(typeID));
466 84 : case VAR_APPARENT_DECEL:
467 84 : return wrapper->wrapDouble(objID, variable, getApparentDecel(typeID));
468 83 : case VAR_ACTIONSTEPLENGTH:
469 83 : return wrapper->wrapDouble(objID, variable, getActionStepLength(typeID));
470 97 : case VAR_IMPERFECTION:
471 97 : return wrapper->wrapDouble(objID, variable, getImperfection(typeID));
472 380 : case VAR_TAU:
473 380 : return wrapper->wrapDouble(objID, variable, getTau(typeID));
474 101 : case VAR_SPEED_FACTOR:
475 101 : return wrapper->wrapDouble(objID, variable, getSpeedFactor(typeID));
476 63 : case VAR_SPEED_DEVIATION:
477 63 : return wrapper->wrapDouble(objID, variable, getSpeedDeviation(typeID));
478 559 : case VAR_VEHICLECLASS:
479 1118 : return wrapper->wrapString(objID, variable, getVehicleClass(typeID));
480 161 : case VAR_EMISSIONCLASS:
481 322 : return wrapper->wrapString(objID, variable, getEmissionClass(typeID));
482 68 : case VAR_SHAPECLASS:
483 136 : return wrapper->wrapString(objID, variable, getShapeClass(typeID));
484 92 : case VAR_WIDTH:
485 92 : return wrapper->wrapDouble(objID, variable, getWidth(typeID));
486 10 : case VAR_COLOR:
487 10 : return wrapper->wrapColor(objID, variable, getColor(typeID));
488 9 : case VAR_MINGAP_LAT:
489 9 : return wrapper->wrapDouble(objID, variable, getMinGapLat(typeID));
490 64 : case VAR_MAXSPEED_LAT:
491 64 : return wrapper->wrapDouble(objID, variable, getMaxSpeedLat(typeID));
492 64 : case VAR_LATALIGNMENT:
493 128 : return wrapper->wrapString(objID, variable, getLateralAlignment(typeID));
494 5 : case VAR_PERSON_CAPACITY:
495 5 : return wrapper->wrapInt(objID, variable, getPersonCapacity(typeID));
496 39 : case VAR_BOARDING_DURATION:
497 39 : return wrapper->wrapDouble(objID, variable, getBoardingDuration(typeID));
498 8 : case VAR_IMPATIENCE:
499 8 : return wrapper->wrapDouble(objID, variable, getImpatience(typeID));
500 4 : case VAR_SCALE:
501 4 : return wrapper->wrapDouble(objID, variable, getScale(typeID));
502 76 : case libsumo::VAR_PARAMETER:
503 76 : paramData->readUnsignedByte();
504 160 : return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
505 24 : case libsumo::VAR_PARAMETER_WITH_KEY:
506 24 : paramData->readUnsignedByte();
507 24 : return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
508 : default:
509 : return false;
510 : }
511 : }
512 :
513 : }
514 :
515 :
516 : /****************************************************************************/
|