1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2017-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    VehicleType.cpp
11 /// @author  Gregor Laemmel
12 /// @date    04.04.2017
13 /// @version $Id$
14 ///
15 // C++ TraCI client API implementation
16 /****************************************************************************/
17 
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23 
24 #include <microsim/MSNet.h>
25 #include <microsim/MSVehicleControl.h>
26 #include <microsim/MSVehicleType.h>
27 #include <libsumo/TraCIConstants.h>
28 #include <utils/emissions/PollutantsInterface.h>
29 #include <utils/vehicle/SUMOVehicleParserHelper.h>
30 #include "Helper.h"
31 #include "VehicleType.h"
32 
33 
34 namespace libsumo {
35 // ===========================================================================
36 // static member initializations
37 // ===========================================================================
38 SubscriptionResults VehicleType::mySubscriptionResults;
39 ContextSubscriptionResults VehicleType::myContextSubscriptionResults;
40 
41 
42 // ===========================================================================
43 // static member definitions
44 // ===========================================================================
45 std::vector<std::string>
getIDList()46 VehicleType::getIDList() {
47     std::vector<std::string> ids;
48     MSNet::getInstance()->getVehicleControl().insertVTypeIDs(ids);
49     return ids;
50 }
51 
52 
53 int
getIDCount()54 VehicleType::getIDCount() {
55     return (int)getIDList().size();
56 }
57 
58 
59 double
getLength(const std::string & typeID)60 VehicleType::getLength(const std::string& typeID) {
61     return getVType(typeID)->getLength();
62 }
63 
64 
65 double
getMaxSpeed(const std::string & typeID)66 VehicleType::getMaxSpeed(const std::string& typeID) {
67     return getVType(typeID)->getMaxSpeed();
68 }
69 
70 
71 double
getActionStepLength(const std::string & typeID)72 VehicleType::getActionStepLength(const std::string& typeID) {
73     return getVType(typeID)->getActionStepLengthSecs();
74 }
75 
76 
77 double
getSpeedFactor(const std::string & typeID)78 VehicleType::getSpeedFactor(const std::string& typeID) {
79     return getVType(typeID)->getSpeedFactor().getParameter()[0];
80 }
81 
82 
83 double
getSpeedDeviation(const std::string & typeID)84 VehicleType::getSpeedDeviation(const std::string& typeID) {
85     return getVType(typeID)->getSpeedFactor().getParameter()[1];
86 }
87 
88 
89 double
getAccel(const std::string & typeID)90 VehicleType::getAccel(const std::string& typeID) {
91     return getVType(typeID)->getCarFollowModel().getMaxAccel();
92 }
93 
94 
95 double
getDecel(const std::string & typeID)96 VehicleType::getDecel(const std::string& typeID) {
97     return getVType(typeID)->getCarFollowModel().getMaxDecel();
98 }
99 
100 
101 double
getEmergencyDecel(const std::string & typeID)102 VehicleType::getEmergencyDecel(const std::string& typeID) {
103     return getVType(typeID)->getCarFollowModel().getEmergencyDecel();
104 }
105 
106 
107 double
getApparentDecel(const std::string & typeID)108 VehicleType::getApparentDecel(const std::string& typeID) {
109     return getVType(typeID)->getCarFollowModel().getApparentDecel();
110 }
111 
112 
113 double
getImperfection(const std::string & typeID)114 VehicleType::getImperfection(const std::string& typeID) {
115     return getVType(typeID)->getCarFollowModel().getImperfection();
116 }
117 
118 
119 double
getTau(const std::string & typeID)120 VehicleType::getTau(const std::string& typeID) {
121     return getVType(typeID)->getCarFollowModel().getHeadwayTime();
122 }
123 
124 
125 std::string
getVehicleClass(const std::string & typeID)126 VehicleType::getVehicleClass(const std::string& typeID) {
127     return toString(getVType(typeID)->getVehicleClass());
128 }
129 
130 
131 std::string
getEmissionClass(const std::string & typeID)132 VehicleType::getEmissionClass(const std::string& typeID) {
133     return PollutantsInterface::getName(getVType(typeID)->getEmissionClass());
134 }
135 
136 
137 std::string
getShapeClass(const std::string & typeID)138 VehicleType::getShapeClass(const std::string& typeID) {
139     return getVehicleShapeName(getVType(typeID)->getGuiShape());
140 }
141 
142 
143 double
getMinGap(const std::string & typeID)144 VehicleType::getMinGap(const std::string& typeID) {
145     return getVType(typeID)->getMinGap();
146 }
147 
148 
149 double
getWidth(const std::string & typeID)150 VehicleType::getWidth(const std::string& typeID) {
151     return getVType(typeID)->getWidth();
152 }
153 
154 
155 double
getHeight(const std::string & typeID)156 VehicleType::getHeight(const std::string& typeID) {
157     return getVType(typeID)->getHeight();
158 }
159 
160 
161 TraCIColor
getColor(const std::string & typeID)162 VehicleType::getColor(const std::string& typeID) {
163     return Helper::makeTraCIColor(getVType(typeID)->getColor());
164 }
165 
166 
167 double
getMinGapLat(const std::string & typeID)168 VehicleType::getMinGapLat(const std::string& typeID) {
169     return getVType(typeID)->getMinGapLat();
170 }
171 
172 
173 double
getMaxSpeedLat(const std::string & typeID)174 VehicleType::getMaxSpeedLat(const std::string& typeID) {
175     return getVType(typeID)->getMaxSpeedLat();
176 }
177 
178 
179 std::string
getLateralAlignment(const std::string & typeID)180 VehicleType::getLateralAlignment(const std::string& typeID) {
181     return toString(getVType(typeID)->getPreferredLateralAlignment());
182 }
183 
184 
185 std::string
getParameter(const std::string & typeID,const std::string & key)186 VehicleType::getParameter(const std::string& typeID, const std::string& key) {
187     return getVType(typeID)->getParameter().getParameter(key, "");
188 }
189 
190 
191 void
setLength(const std::string & typeID,double length)192 VehicleType::setLength(const std::string& typeID, double length)  {
193     getVType(typeID)->setLength(length);
194 }
195 
196 
197 void
setMaxSpeed(const std::string & typeID,double speed)198 VehicleType::setMaxSpeed(const std::string& typeID, double speed)  {
199     getVType(typeID)->setMaxSpeed(speed);
200 }
201 
202 
203 void
setActionStepLength(const std::string & typeID,double actionStepLength,bool resetActionOffset)204 VehicleType::setActionStepLength(const std::string& typeID, double actionStepLength, bool resetActionOffset)  {
205     getVType(typeID)->setActionStepLength(SUMOVehicleParserHelper::processActionStepLength(actionStepLength), resetActionOffset);
206 }
207 
208 
209 void
setVehicleClass(const std::string & typeID,const std::string & clazz)210 VehicleType::setVehicleClass(const std::string& typeID, const std::string& clazz)  {
211     getVType(typeID)->setVClass(getVehicleClassID(clazz));
212 }
213 
214 
215 void
setSpeedFactor(const std::string & typeID,double factor)216 VehicleType::setSpeedFactor(const std::string& typeID, double factor)  {
217     getVType(typeID)->setSpeedFactor(factor);
218 }
219 
220 
221 void
setSpeedDeviation(const std::string & typeID,double deviation)222 VehicleType::setSpeedDeviation(const std::string& typeID, double deviation)  {
223     getVType(typeID)->setSpeedDeviation(deviation);
224 }
225 
226 
227 void
setEmissionClass(const std::string & typeID,const std::string & clazz)228 VehicleType::setEmissionClass(const std::string& typeID, const std::string& clazz)  {
229     getVType(typeID)->setEmissionClass(PollutantsInterface::getClassByName(clazz));
230 }
231 
232 
233 void
setShapeClass(const std::string & typeID,const std::string & shapeClass)234 VehicleType::setShapeClass(const std::string& typeID, const std::string& shapeClass)  {
235     getVType(typeID)->setShape(getVehicleShapeID(shapeClass));
236 }
237 
238 
239 void
setWidth(const std::string & typeID,double width)240 VehicleType::setWidth(const std::string& typeID, double width)  {
241     getVType(typeID)->setWidth(width);
242 }
243 
244 
245 void
setHeight(const std::string & typeID,double height)246 VehicleType::setHeight(const std::string& typeID, double height)  {
247     getVType(typeID)->setHeight(height);
248 }
249 
250 
251 void
setMinGap(const std::string & typeID,double minGap)252 VehicleType::setMinGap(const std::string& typeID, double minGap)  {
253     getVType(typeID)->setMinGap(minGap);
254 }
255 
256 
257 void
setAccel(const std::string & typeID,double accel)258 VehicleType::setAccel(const std::string& typeID, double accel)  {
259     getVType(typeID)->setAccel(accel);
260 }
261 
262 
263 void
setDecel(const std::string & typeID,double decel)264 VehicleType::setDecel(const std::string& typeID, double decel)  {
265     MSVehicleType* v = getVType(typeID);
266     v->setDecel(decel);
267     // automatically raise emergencyDecel to ensure it is at least as high as decel
268     if (decel > v->getCarFollowModel().getEmergencyDecel()) {
269         if (v->getParameter().cfParameter.count(SUMO_ATTR_EMERGENCYDECEL) > 0) {
270             // notify user only if emergencyDecel was previously specified
271             WRITE_WARNING("Automatically setting emergencyDecel to " + toString(decel) + " for vType '" + typeID + "' to match decel.");
272         }
273         v->setEmergencyDecel(decel);
274     }
275 }
276 
277 
278 void
setEmergencyDecel(const std::string & typeID,double decel)279 VehicleType::setEmergencyDecel(const std::string& typeID, double decel)  {
280     MSVehicleType* v = getVType(typeID);
281     v->setEmergencyDecel(decel);
282     if (decel < v->getCarFollowModel().getMaxDecel()) {
283         WRITE_WARNING("New value of emergencyDecel (" + toString(decel) + ") is lower than decel (" + toString(v->getCarFollowModel().getMaxDecel()) + ")");
284     }
285 }
286 
287 
288 void
setApparentDecel(const std::string & typeID,double decel)289 VehicleType::setApparentDecel(const std::string& typeID, double decel)  {
290     getVType(typeID)->setApparentDecel(decel);
291 }
292 
293 
294 void
setImperfection(const std::string & typeID,double imperfection)295 VehicleType::setImperfection(const std::string& typeID, double imperfection)  {
296     getVType(typeID)->setImperfection(imperfection);
297 }
298 
299 
300 void
setTau(const std::string & typeID,double tau)301 VehicleType::setTau(const std::string& typeID, double tau)  {
302     getVType(typeID)->setTau(tau);
303 }
304 
305 
306 void
setColor(const std::string & typeID,const TraCIColor & c)307 VehicleType::setColor(const std::string& typeID, const TraCIColor& c)  {
308     getVType(typeID)->setColor(Helper::makeRGBColor(c));
309 }
310 
311 
312 void
setMinGapLat(const std::string & typeID,double minGapLat)313 VehicleType::setMinGapLat(const std::string& typeID, double minGapLat)  {
314     getVType(typeID)->setMinGapLat(minGapLat);
315 }
316 
317 
318 void
setMaxSpeedLat(const std::string & typeID,double speed)319 VehicleType::setMaxSpeedLat(const std::string& typeID, double speed)  {
320     getVType(typeID)->setMaxSpeedLat(speed);
321 }
322 
323 
324 void
setLateralAlignment(const std::string & typeID,const std::string & latAlignment)325 VehicleType::setLateralAlignment(const std::string& typeID, const std::string& latAlignment)  {
326     getVType(typeID)->setPreferredLateralAlignment(SUMOXMLDefinitions::LateralAlignments.get(latAlignment));
327 }
328 
329 
330 void
copy(const std::string & origTypeID,const std::string & newTypeID)331 VehicleType::copy(const std::string& origTypeID, const std::string& newTypeID)  {
332     getVType(origTypeID)->duplicateType(newTypeID, true);
333 }
334 
335 
336 void
setParameter(const std::string & typeID,const std::string & name,const std::string & value)337 VehicleType::setParameter(const std::string& typeID, const std::string& name, const std::string& value) {
338     ((SUMOVTypeParameter&)getVType(typeID)->getParameter()).setParameter(name, value);
339 }
340 
341 
LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(VehicleType,VEHICLETYPE)342 LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(VehicleType, VEHICLETYPE)
343 
344 
345 MSVehicleType*
346 VehicleType::getVType(std::string id) {
347     MSVehicleType* t = MSNet::getInstance()->getVehicleControl().getVType(id);
348     if (t == nullptr) {
349         throw TraCIException("Vehicle type '" + id + "' is not known");
350     }
351     return t;
352 }
353 
354 
355 std::shared_ptr<VariableWrapper>
makeWrapper()356 VehicleType::makeWrapper() {
357     return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
358 }
359 
360 
361 bool
handleVariable(const std::string & objID,const int variable,VariableWrapper * wrapper)362 VehicleType::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper) {
363     switch (variable) {
364         case TRACI_ID_LIST:
365             return wrapper->wrapStringList(objID, variable, getIDList());
366         case ID_COUNT:
367             return wrapper->wrapInt(objID, variable, getIDCount());
368         case VAR_LENGTH:
369             return wrapper->wrapDouble(objID, variable, getLength(objID));
370         case VAR_HEIGHT:
371             return wrapper->wrapDouble(objID, variable, getHeight(objID));
372         case VAR_MINGAP:
373             return wrapper->wrapDouble(objID, variable, getMinGap(objID));
374         case VAR_MAXSPEED:
375             return wrapper->wrapDouble(objID, variable, getMaxSpeed(objID));
376         case VAR_ACCEL:
377             return wrapper->wrapDouble(objID, variable, getAccel(objID));
378         case VAR_DECEL:
379             return wrapper->wrapDouble(objID, variable, getDecel(objID));
380         case VAR_EMERGENCY_DECEL:
381             return wrapper->wrapDouble(objID, variable, getEmergencyDecel(objID));
382         case VAR_APPARENT_DECEL:
383             return wrapper->wrapDouble(objID, variable, getApparentDecel(objID));
384         case VAR_ACTIONSTEPLENGTH:
385             return wrapper->wrapDouble(objID, variable, getActionStepLength(objID));
386         case VAR_IMPERFECTION:
387             return wrapper->wrapDouble(objID, variable, getImperfection(objID));
388         case VAR_TAU:
389             return wrapper->wrapDouble(objID, variable, getTau(objID));
390         case VAR_SPEED_FACTOR:
391             return wrapper->wrapDouble(objID, variable, getSpeedFactor(objID));
392         case VAR_SPEED_DEVIATION:
393             return wrapper->wrapDouble(objID, variable, getSpeedDeviation(objID));
394         case VAR_VEHICLECLASS:
395             return wrapper->wrapString(objID, variable, getVehicleClass(objID));
396         case VAR_EMISSIONCLASS:
397             return wrapper->wrapString(objID, variable, getEmissionClass(objID));
398         case VAR_SHAPECLASS:
399             return wrapper->wrapString(objID, variable, getShapeClass(objID));
400         case VAR_WIDTH:
401             return wrapper->wrapDouble(objID, variable, getWidth(objID));
402         case VAR_COLOR:
403             return wrapper->wrapColor(objID, variable, getColor(objID));
404         case VAR_MINGAP_LAT:
405             return wrapper->wrapDouble(objID, variable, getMinGapLat(objID));
406         case VAR_MAXSPEED_LAT:
407             return wrapper->wrapDouble(objID, variable, getMaxSpeedLat(objID));
408         case VAR_LATALIGNMENT:
409             return wrapper->wrapString(objID, variable, getLateralAlignment(objID));
410         default:
411             return false;
412     }
413 }
414 
415 
416 }
417 
418 
419 /****************************************************************************/
420