SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_Edge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // APIs for getting/setting edge values via TraCI
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
14 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #ifndef NO_TRACI
36 
37 #include <utils/common/StdDefs.h>
38 #include <microsim/MSNet.h>
39 #include <microsim/MSEdgeControl.h>
40 #include <microsim/MSEdge.h>
41 #include <microsim/MSLane.h>
42 #include <microsim/MSVehicle.h>
43 #include "TraCIConstants.h"
44 #include "TraCIServerAPI_Edge.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // used namespaces
55 // ===========================================================================
56 using namespace traci;
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
62 bool
64  tcpip::Storage& outputStorage) {
65  // variable & id
66  int variable = inputStorage.readUnsignedByte();
67  std::string id = inputStorage.readString();
68  // check variable
69  if (variable != ID_LIST && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_CURRENT_TRAVELTIME
70  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
71  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
72  && variable != LAST_STEP_VEHICLE_NUMBER && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_OCCUPANCY
73  && variable != LAST_STEP_VEHICLE_HALTING_NUMBER && variable != LAST_STEP_LENGTH
74  && variable != LAST_STEP_VEHICLE_ID_LIST && variable != ID_COUNT) {
75  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Get Edge Variable: unsupported variable specified", outputStorage);
76  return false;
77  }
78  // begin response building
79  tcpip::Storage tempMsg;
80  // response-code, variableID, objectID
82  tempMsg.writeUnsignedByte(variable);
83  tempMsg.writeString(id);
84  // process request
85  if (variable == ID_LIST) {
86  std::vector<std::string> ids;
87  MSEdge::insertIDs(ids);
89  tempMsg.writeStringList(ids);
90  } else if (variable == ID_COUNT) {
91  std::vector<std::string> ids;
92  MSEdge::insertIDs(ids);
94  tempMsg.writeInt((int) ids.size());
95  } else {
96  MSEdge* e = MSEdge::dictionary(id);
97  if (e == 0) {
98  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage);
99  return false;
100  }
101  switch (variable) {
102  case VAR_EDGE_TRAVELTIME: {
103  // time
104  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
105  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage);
106  return false;
107  }
108  SUMOTime time = inputStorage.readInt();
110  SUMOReal value;
111  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, 0, time, value)) {
112  tempMsg.writeDouble(-1);
113  } else {
114  tempMsg.writeDouble(value);
115  }
116  }
117  break;
118  case VAR_EDGE_EFFORT: {
119  // time
120  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
121  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage);
122  return false;
123  }
124  SUMOTime time = inputStorage.readInt();
126  SUMOReal value;
127  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, 0, time, value)) {
128  tempMsg.writeDouble(-1);
129  } else {
130  tempMsg.writeDouble(value);
131  }
132  }
133  break;
136  tempMsg.writeDouble(e->getCurrentTravelTime());
137  break;
139  std::vector<std::string> vehIDs;
140  const std::vector<MSLane*>& lanes = e->getLanes();
141  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
142  const std::deque<MSVehicle*>& vehs = (*i)->getVehiclesSecure();
143  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
144  vehIDs.push_back((*j)->getID());
145  }
146  (*i)->releaseVehicles();
147  }
149  tempMsg.writeStringList(vehIDs);
150  }
151  break;
152  case VAR_CO2EMISSION: {
153  SUMOReal sum = 0;
154  const std::vector<MSLane*>& lanes = e->getLanes();
155  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
156  sum += (*i)->getHBEFA_CO2Emissions();
157  }
159  tempMsg.writeDouble(sum);
160  }
161  break;
162  case VAR_COEMISSION: {
163  SUMOReal sum = 0;
164  const std::vector<MSLane*>& lanes = e->getLanes();
165  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
166  sum += (*i)->getHBEFA_COEmissions();
167  }
169  tempMsg.writeDouble(sum);
170  }
171  break;
172  case VAR_HCEMISSION: {
173  SUMOReal sum = 0;
174  const std::vector<MSLane*>& lanes = e->getLanes();
175  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
176  sum += (*i)->getHBEFA_HCEmissions();
177  }
179  tempMsg.writeDouble(sum);
180  }
181  break;
182  case VAR_PMXEMISSION: {
183  SUMOReal sum = 0;
184  const std::vector<MSLane*>& lanes = e->getLanes();
185  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
186  sum += (*i)->getHBEFA_PMxEmissions();
187  }
189  tempMsg.writeDouble(sum);
190  }
191  break;
192  case VAR_NOXEMISSION: {
193  SUMOReal sum = 0;
194  const std::vector<MSLane*>& lanes = e->getLanes();
195  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
196  sum += (*i)->getHBEFA_NOxEmissions();
197  }
199  tempMsg.writeDouble(sum);
200  }
201  break;
202  case VAR_FUELCONSUMPTION: {
203  SUMOReal sum = 0;
204  const std::vector<MSLane*>& lanes = e->getLanes();
205  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
206  sum += (*i)->getHBEFA_FuelConsumption();
207  }
209  tempMsg.writeDouble(sum);
210  }
211  break;
212  case VAR_NOISEEMISSION: {
213  SUMOReal sum = 0;
214  const std::vector<MSLane*>& lanes = e->getLanes();
215  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
216  sum += (SUMOReal) pow(10., ((*i)->getHarmonoise_NoiseEmissions() / 10.));
217  }
219  if (sum != 0) {
220  tempMsg.writeDouble(HelpersHarmonoise::sum(sum));
221  } else {
222  tempMsg.writeDouble(0);
223  }
224  }
225  break;
227  int sum = 0;
228  const std::vector<MSLane*>& lanes = e->getLanes();
229  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
230  sum += (*i)->getVehicleNumber();
231  }
233  tempMsg.writeInt(sum);
234  }
235  break;
236  case LAST_STEP_MEAN_SPEED: {
237  SUMOReal sum = 0;
238  const std::vector<MSLane*>& lanes = e->getLanes();
239  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
240  sum += (*i)->getMeanSpeed();
241  }
243  tempMsg.writeDouble(sum / (SUMOReal) lanes.size());
244  }
245  break;
246  case LAST_STEP_OCCUPANCY: {
247  SUMOReal sum = 0;
248  const std::vector<MSLane*>& lanes = e->getLanes();
249  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
250  sum += (*i)->getOccupancy();
251  }
253  tempMsg.writeDouble(sum / (SUMOReal) lanes.size());
254  }
255  break;
257  int halting = 0;
258  const std::vector<MSLane*>& lanes = e->getLanes();
259  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
260  const std::deque<MSVehicle*>& vehs = (*i)->getVehiclesSecure();
261  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
262  if ((*j)->getSpeed() < 0.1) {
263  ++halting;
264  }
265  }
266  (*i)->releaseVehicles();
267  }
269  tempMsg.writeInt(halting);
270  }
271  break;
272  case LAST_STEP_LENGTH: {
273  SUMOReal lengthSum = 0;
274  int noVehicles = 0;
275  const std::vector<MSLane*>& lanes = e->getLanes();
276  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
277  const std::deque<MSVehicle*>& vehs = (*i)->getVehiclesSecure();
278  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
279  lengthSum += (*j)->getVehicleType().getLength();
280  }
281  noVehicles += (int) vehs.size();
282  (*i)->releaseVehicles();
283  }
285  if (noVehicles == 0) {
286  tempMsg.writeDouble(0);
287  } else {
288  tempMsg.writeDouble(lengthSum / (SUMOReal) noVehicles);
289  }
290  }
291  break;
292  default:
293  break;
294  }
295  }
296  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_OK, "", outputStorage);
297  server.writeResponseWithLength(outputStorage, tempMsg);
298  return true;
299 }
300 
301 
302 bool
304  tcpip::Storage& outputStorage) {
305  std::string warning = ""; // additional description for response
306  // variable
307  int variable = inputStorage.readUnsignedByte();
308  if (variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_MAXSPEED) {
309  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Change Edge State: unsupported variable specified", outputStorage);
310  return false;
311  }
312  // id
313  std::string id = inputStorage.readString();
314  MSEdge* e = MSEdge::dictionary(id);
315  if (e == 0) {
316  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage);
317  return false;
318  }
319  // process
320  int valueDataType = inputStorage.readUnsignedByte();
321  switch (variable) {
322  case LANE_ALLOWED: {
323  if (inputStorage.readUnsignedByte() != TYPE_STRINGLIST) {
324  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Allowed vehicle classes must be given as a list of strings.", outputStorage);
325  return false;
326  }
327  SVCPermissions permissions = parseVehicleClasses(inputStorage.readStringList());
328  const std::vector<MSLane*>& lanes = e->getLanes();
329  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
330  (*i)->setPermissions(permissions);
331  }
332  e->rebuildAllowedLanes();
333  }
334  break;
335  case LANE_DISALLOWED: {
336  // time
337  if (inputStorage.readUnsignedByte() != TYPE_STRINGLIST) {
338  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Not allowed vehicle classes must be given as a list of strings.", outputStorage);
339  return false;
340  }
341  SVCPermissions permissions = ~parseVehicleClasses(inputStorage.readStringList()); // negation yields allowed
342  const std::vector<MSLane*>& lanes = e->getLanes();
343  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
344  (*i)->setPermissions(permissions);
345  }
346  e->rebuildAllowedLanes();
347  }
348  break;
349  case VAR_EDGE_TRAVELTIME: {
350  if (valueDataType != TYPE_COMPOUND) {
351  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires a compound object.", outputStorage);
352  return false;
353  }
354  int parameterCount = inputStorage.readInt();
355  if (parameterCount == 3) {
356  // begin
357  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
358  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage);
359  return false;
360  }
361  SUMOTime begTime = inputStorage.readInt();
362  // end
363  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
364  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage);
365  return false;
366  }
367  SUMOTime endTime = inputStorage.readInt();
368  // value
369  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
370  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as double", outputStorage);
371  return false;
372  }
373  SUMOReal value = inputStorage.readDouble();
374  // set
375  MSNet::getInstance()->getWeightsStorage().addTravelTime(e, begTime, endTime, value);
376  } else if (parameterCount == 1) {
377  // value
378  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
379  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The variable must be the value given as double", outputStorage);
380  return false;
381  }
382  SUMOReal value = inputStorage.readDouble();
383  // set
385  } else {
386  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires either begin time, end time, and value, or only value as parameter.", outputStorage);
387  return false;
388  }
389  }
390  break;
391  case VAR_EDGE_EFFORT: {
392  if (valueDataType != TYPE_COMPOUND) {
393  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires a compound object.", outputStorage);
394  return false;
395  }
396  int parameterCount = inputStorage.readInt();
397  if (parameterCount == 3) {
398  // begin
399  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
400  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage);
401  return false;
402  }
403  SUMOTime begTime = inputStorage.readInt();
404  // end
405  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
406  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage);
407  return false;
408  }
409  SUMOTime endTime = inputStorage.readInt();
410  // value
411  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
412  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as double", outputStorage);
413  return false;
414  }
415  SUMOReal value = inputStorage.readDouble();
416  // set
417  MSNet::getInstance()->getWeightsStorage().addEffort(e, begTime, endTime, value);
418  } else if (parameterCount == 1) {
419  // value
420  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
421  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The variable must be the value given as double", outputStorage);
422  return false;
423  }
424  SUMOReal value = inputStorage.readDouble();
425  // set
427  } else {
428  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires either begin time, end time, and value, or only value as parameter.", outputStorage);
429  return false;
430  }
431  }
432  break;
433  case VAR_MAXSPEED: {
434  // speed
435  if (valueDataType != TYPE_DOUBLE) {
436  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The speed must be given as a double.", outputStorage);
437  return false;
438  }
439  SUMOReal val = inputStorage.readDouble();
440  const std::vector<MSLane*>& lanes = e->getLanes();
441  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
442  (*i)->setMaxSpeed(val);
443  }
444  }
445  break;
446  default:
447  break;
448  }
449  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage);
450  return true;
451 }
452 
453 
454 bool
455 TraCIServerAPI_Edge::getShape(const std::string& id, PositionVector& shape) {
456  MSEdge* e = MSEdge::dictionary(id);
457  if (e == 0) {
458  return false;
459  }
460  const std::vector<MSLane*>& lanes = e->getLanes();
461  shape.push_back(lanes.front()->getShape());
462  if (lanes.size() > 1) {
463  shape.push_back(lanes.back()->getShape().reverse());
464  }
465  return true;
466 }
467 
468 
469 TraCIRTree*
471  TraCIRTree* t = new TraCIRTree();
472  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
473  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
474  const std::vector<MSLane*>& lanes = (*i)->getLanes();
475  Boundary b;
476  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
477  b.add((*j)->getShape().getBoxBoundary());
478  }
479  t->addObject(*i, b);
480  }
481  return t;
482 }
483 
484 #endif
485 
486 
487 /****************************************************************************/
488