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 Edge.cpp
11 /// @author Gregor Laemmel
12 /// @date 15.09.2017
13 /// @version $Id$
14 ///
15 // C++ TraCI client API implementation
16 /****************************************************************************/
17
18 #include <iterator>
19 #include <microsim/MSEdge.h>
20 #include <microsim/MSLane.h>
21 #include <microsim/MSEdgeWeightsStorage.h>
22 #include <microsim/MSTransportable.h>
23 #include <microsim/MSVehicle.h>
24 #include <libsumo/TraCIDefs.h>
25 #include <libsumo/TraCIConstants.h>
26 #include <utils/emissions/HelpersHarmonoise.h>
27 #include "Edge.h"
28
29
30 namespace libsumo {
31 // ===========================================================================
32 // static member initializations
33 // ===========================================================================
34 SubscriptionResults Edge::mySubscriptionResults;
35 ContextSubscriptionResults Edge::myContextSubscriptionResults;
36
37
38 // ===========================================================================
39 // static member definitions
40 // ===========================================================================
41 std::vector<std::string>
getIDList()42 Edge::getIDList() {
43 std::vector<std::string> ids;
44 MSEdge::insertIDs(ids);
45 return ids;
46 }
47
48
49 int
getIDCount()50 Edge::getIDCount() {
51 return (int)getIDList().size();
52 }
53
54
55 double
getAdaptedTraveltime(const std::string & id,double time)56 Edge::getAdaptedTraveltime(const std::string& id, double time) {
57 const MSEdge* e = getEdge(id);
58 double value;
59 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
60 return -1.;
61 }
62 return value;
63 }
64
65
66 double
getEffort(const std::string & id,double time)67 Edge::getEffort(const std::string& id, double time) {
68 const MSEdge* e = getEdge(id);
69 double value;
70 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
71 return -1.;
72 }
73 return value;
74 }
75
76
77 double
getTraveltime(const std::string & id)78 Edge::getTraveltime(const std::string& id) {
79 return getEdge(id)->getCurrentTravelTime();
80 }
81
82
83 MSEdge*
getEdge(const std::string & id)84 Edge::getEdge(const std::string& id) {
85 MSEdge* e = MSEdge::dictionary(id);
86 if (e == nullptr) {
87 throw TraCIException("Edge '" + id + "' is not known");
88 }
89 return e;
90 }
91
92
93 double
getWaitingTime(const std::string & id)94 Edge::getWaitingTime(const std::string& id) {
95 double wtime = 0;
96 for (MSLane* lane : getEdge(id)->getLanes()) {
97 wtime += lane->getWaitingSeconds();
98 }
99 return wtime;
100 }
101
102
103 const std::vector<std::string>
getLastStepPersonIDs(const std::string & id)104 Edge::getLastStepPersonIDs(const std::string& id) {
105 std::vector<std::string> personIDs;
106 std::vector<MSTransportable*> persons = getEdge(id)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true);
107 personIDs.reserve(persons.size());
108 for (MSTransportable* p : persons) {
109 personIDs.push_back(p->getID());
110 }
111 return personIDs;
112 }
113
114
115 const std::vector<std::string>
getLastStepVehicleIDs(const std::string & id)116 Edge::getLastStepVehicleIDs(const std::string& id) {
117 std::vector<std::string> vehIDs;
118 for (MSLane* lane : getEdge(id)->getLanes()) {
119 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
120 for (auto veh : vehs) {
121 vehIDs.push_back(veh->getID());
122 }
123 lane->releaseVehicles();
124 }
125 return vehIDs;
126 }
127
128
129 double
getCO2Emission(const std::string & id)130 Edge::getCO2Emission(const std::string& id) {
131 double sum = 0;
132 for (MSLane* lane : getEdge(id)->getLanes()) {
133 sum += lane->getCO2Emissions();
134 }
135 return sum;
136 }
137
138
139 double
getCOEmission(const std::string & id)140 Edge::getCOEmission(const std::string& id) {
141 double sum = 0;
142 for (MSLane* lane : getEdge(id)->getLanes()) {
143 sum += lane->getCOEmissions();
144 }
145 return sum;
146 }
147
148
149 double
getHCEmission(const std::string & id)150 Edge::getHCEmission(const std::string& id) {
151 double sum = 0;
152 for (MSLane* lane : getEdge(id)->getLanes()) {
153 sum += lane->getHCEmissions();
154 }
155 return sum;
156 }
157
158
159 double
getPMxEmission(const std::string & id)160 Edge::getPMxEmission(const std::string& id) {
161 double sum = 0;
162 for (MSLane* lane : getEdge(id)->getLanes()) {
163 sum += lane->getPMxEmissions();
164 }
165 return sum;
166 }
167
168
169 double
getNOxEmission(const std::string & id)170 Edge::getNOxEmission(const std::string& id) {
171 double sum = 0;
172 for (MSLane* lane : getEdge(id)->getLanes()) {
173 sum += lane->getNOxEmissions();
174 }
175 return sum;
176 }
177
178
179 double
getFuelConsumption(const std::string & id)180 Edge::getFuelConsumption(const std::string& id) {
181 double sum = 0;
182 for (MSLane* lane : getEdge(id)->getLanes()) {
183 sum += lane->getFuelConsumption();
184 }
185 return sum;
186 }
187
188
189 double
getNoiseEmission(const std::string & id)190 Edge::getNoiseEmission(const std::string& id) {
191 double sum = 0;
192 for (MSLane* lane : getEdge(id)->getLanes()) {
193 sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.));
194 }
195 if (sum != 0) {
196 return HelpersHarmonoise::sum(sum);
197 }
198 return sum;
199 }
200
201
202 double
getElectricityConsumption(const std::string & id)203 Edge::getElectricityConsumption(const std::string& id) {
204 double sum = 0;
205 for (MSLane* lane : getEdge(id)->getLanes()) {
206 sum += lane->getElectricityConsumption();
207 }
208 return sum;
209 }
210
211
212 int
getLastStepVehicleNumber(const std::string & id)213 Edge::getLastStepVehicleNumber(const std::string& id) {
214 int sum = 0;
215 for (MSLane* lane : getEdge(id)->getLanes()) {
216 sum += lane->getVehicleNumber();
217 }
218 return sum;
219 }
220
221
222 double
getLastStepMeanSpeed(const std::string & id)223 Edge::getLastStepMeanSpeed(const std::string& id) {
224 return getEdge(id)->getMeanSpeed();
225 }
226
227
228 double
getLastStepOccupancy(const std::string & id)229 Edge::getLastStepOccupancy(const std::string& id) {
230 double sum = 0;
231 const std::vector<MSLane*>& lanes = getEdge(id)->getLanes();
232 for (auto lane : lanes) {
233 sum += lane->getNettoOccupancy();
234 }
235 return sum / (double)lanes.size();
236 }
237
238
239 int
getLastStepHaltingNumber(const std::string & id)240 Edge::getLastStepHaltingNumber(const std::string& id) {
241 int halting = 0;
242 for (MSLane* lane : getEdge(id)->getLanes()) {
243 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
244 for (auto veh : vehs) {
245 if (veh->getSpeed() < SUMO_const_haltingSpeed) {
246 ++halting;
247 }
248 }
249 lane->releaseVehicles();
250 }
251 return halting;
252 }
253
254
255 double
getLastStepLength(const std::string & id)256 Edge::getLastStepLength(const std::string& id) {
257 double lengthSum = 0;
258 int noVehicles = 0;
259 for (MSLane* lane : getEdge(id)->getLanes()) {
260 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
261 for (auto veh : vehs) {
262 lengthSum += veh->getVehicleType().getLength();
263 }
264 noVehicles += (int)vehs.size();
265 lane->releaseVehicles();
266 }
267 if (noVehicles == 0) {
268 return 0;
269 }
270 return lengthSum / (double)noVehicles;
271 }
272
273
274 int
getLaneNumber(const std::string & id)275 Edge::getLaneNumber(const std::string& id) {
276 return (int)getEdge(id)->getLanes().size();
277 }
278
279
280 std::string
getStreetName(const std::string & id)281 Edge::getStreetName(const std::string& id) {
282 return getEdge(id)->getStreetName();
283 }
284
285
286 std::string
getParameter(const std::string & id,const std::string & paramName)287 Edge::getParameter(const std::string& id, const std::string& paramName) {
288 return getEdge(id)->getParameter(paramName, "");
289 }
290
291
292 void
setAllowedVehicleClasses(const std::string & id,std::vector<std::string> classes)293 Edge::setAllowedVehicleClasses(const std::string& id, std::vector<std::string> classes) {
294 SVCPermissions permissions = parseVehicleClasses(classes);
295 setAllowedSVCPermissions(id, permissions);
296 }
297
298
299 void
setDisallowedVehicleClasses(const std::string & id,std::vector<std::string> classes)300 Edge::setDisallowedVehicleClasses(const std::string& id, std::vector<std::string> classes) {
301 SVCPermissions permissions = invertPermissions(parseVehicleClasses(classes));
302 setAllowedSVCPermissions(id, permissions);
303 }
304
305
306 void
setAllowedSVCPermissions(const std::string & id,int permissions)307 Edge::setAllowedSVCPermissions(const std::string& id, int permissions) {
308 MSEdge* e = getEdge(id);
309 for (MSLane* lane : e->getLanes()) {
310 lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT);
311 }
312 e->rebuildAllowedLanes();
313 for (MSEdge* const pred : e->getPredecessors()) {
314 pred->rebuildAllowedTargets();
315 }
316 }
317
318
319 void
adaptTraveltime(const std::string & id,double value,double begTime,double endTime)320 Edge::adaptTraveltime(const std::string& id, double value, double begTime, double endTime) {
321 MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(id), begTime, endTime, value);
322 }
323
324
325 void
setEffort(const std::string & id,double value,double begTime,double endTime)326 Edge::setEffort(const std::string& id, double value, double begTime, double endTime) {
327 MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(id), begTime, endTime, value);
328 }
329
330
331 void
setMaxSpeed(const std::string & id,double value)332 Edge::setMaxSpeed(const std::string& id, double value) {
333 for (MSLane* lane : getEdge(id)->getLanes()) {
334 lane->setMaxSpeed(value);
335 }
336 }
337
338
339 void
setParameter(const std::string & id,const std::string & name,const std::string & value)340 Edge::setParameter(const std::string& id, const std::string& name, const std::string& value) {
341 getEdge(id)->setParameter(name, value);
342 }
343
344
LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Edge,EDGE)345 LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Edge, EDGE)
346
347
348 void
349 Edge::storeShape(const std::string& id, PositionVector& shape) {
350 const MSEdge* const e = getEdge(id);
351 const std::vector<MSLane*>& lanes = e->getLanes();
352 shape = lanes.front()->getShape();
353 if (lanes.size() > 1) {
354 copy(lanes.back()->getShape().begin(), lanes.back()->getShape().end(), back_inserter(shape));
355 }
356 }
357
358
359 std::shared_ptr<VariableWrapper>
makeWrapper()360 Edge::makeWrapper() {
361 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
362 }
363
364
365 bool
handleVariable(const std::string & objID,const int variable,VariableWrapper * wrapper)366 Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper) {
367 switch (variable) {
368 case TRACI_ID_LIST:
369 return wrapper->wrapStringList(objID, variable, getIDList());
370 case ID_COUNT:
371 return wrapper->wrapInt(objID, variable, getIDCount());
372 case VAR_CURRENT_TRAVELTIME:
373 return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
374 case VAR_WAITING_TIME:
375 return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
376 case LAST_STEP_PERSON_ID_LIST:
377 return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID));
378 case LAST_STEP_VEHICLE_ID_LIST:
379 return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
380 case VAR_CO2EMISSION:
381 return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
382 case VAR_COEMISSION:
383 return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
384 case VAR_HCEMISSION:
385 return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
386 case VAR_PMXEMISSION:
387 return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
388 case VAR_NOXEMISSION:
389 return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
390 case VAR_FUELCONSUMPTION:
391 return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
392 case VAR_NOISEEMISSION:
393 return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
394 case VAR_ELECTRICITYCONSUMPTION:
395 return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
396 case LAST_STEP_VEHICLE_NUMBER:
397 return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
398 case LAST_STEP_MEAN_SPEED:
399 return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
400 case LAST_STEP_OCCUPANCY:
401 return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
402 case LAST_STEP_VEHICLE_HALTING_NUMBER:
403 return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
404 case LAST_STEP_LENGTH:
405 return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
406 case VAR_LANE_INDEX:
407 return wrapper->wrapInt(objID, variable, getLaneNumber(objID));
408 case VAR_NAME:
409 return wrapper->wrapString(objID, variable, getStreetName(objID));
410 default:
411 return false;
412 }
413 }
414
415
416 }
417
418
419 /****************************************************************************/
420