SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_TLS.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // APIs for getting/setting traffic light values via TraCI
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2009-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #ifndef NO_TRACI
35 
36 #include "TraCIConstants.h"
38 #include <microsim/MSLane.h>
39 #include "TraCIServerAPI_TLS.h"
40 
41 #ifdef CHECK_MEMORY_LEAKS
42 #include <foreign/nvwa/debug_new.h>
43 #endif // CHECK_MEMORY_LEAKS
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 bool
51  tcpip::Storage& outputStorage) {
52  // variable & id
53  int variable = inputStorage.readUnsignedByte();
54  std::string id = inputStorage.readString();
55  // check variable
56  if (variable != ID_LIST && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_DEFINITION_RYG
57  && variable != TL_CONTROLLED_LANES && variable != TL_CONTROLLED_LINKS
58  && variable != TL_CURRENT_PHASE && variable != TL_CURRENT_PROGRAM
59  && variable != TL_NEXT_SWITCH && variable != TL_PHASE_DURATION && variable != ID_COUNT) {
60  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable specified", outputStorage);
61  }
62  // begin response building
63  tcpip::Storage tempMsg;
64  // response-code, variableID, objectID
66  tempMsg.writeUnsignedByte(variable);
67  tempMsg.writeString(id);
68  if (variable == ID_LIST) {
69  std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
71  tempMsg.writeStringList(ids);
72  } else if (variable == ID_COUNT) {
73  std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
75  tempMsg.writeInt((int) ids.size());
76  } else {
77  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
78  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Traffic light '" + id + "' is not known", outputStorage);
79  }
81  switch (variable) {
82  case ID_LIST:
83  break;
86  std::string state = vars.getActive()->getCurrentPhaseDef().getState();
87  tempMsg.writeString(state);
88  }
89  break;
91  std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
93  tcpip::Storage tempContent;
94  unsigned int cnt = 0;
95  tempContent.writeUnsignedByte(TYPE_INTEGER);
96  tempContent.writeInt((int) logics.size());
97  ++cnt;
98  for (unsigned int i = 0; i < logics.size(); ++i) {
99  MSTrafficLightLogic* logic = logics[i];
100  tempContent.writeUnsignedByte(TYPE_STRING);
101  tempContent.writeString(logic->getProgramID());
102  ++cnt;
103  // type (always 0 by now)
104  tempContent.writeUnsignedByte(TYPE_INTEGER);
105  tempContent.writeInt(0);
106  ++cnt;
107  // subparameter (always 0 by now)
108  tempContent.writeUnsignedByte(TYPE_COMPOUND);
109  tempContent.writeInt(0);
110  ++cnt;
111  // (current) phase index
112  tempContent.writeUnsignedByte(TYPE_INTEGER);
113  tempContent.writeInt((int) logic->getCurrentPhaseIndex());
114  ++cnt;
115  // phase number
116  unsigned int phaseNo = logic->getPhaseNumber();
117  tempContent.writeUnsignedByte(TYPE_INTEGER);
118  tempContent.writeInt((int) phaseNo);
119  ++cnt;
120  for (unsigned int j = 0; j < phaseNo; ++j) {
121  MSPhaseDefinition phase = logic->getPhase(j);
122  tempContent.writeUnsignedByte(TYPE_INTEGER);
123  tempContent.writeInt(phase.duration);
124  ++cnt;
125  tempContent.writeUnsignedByte(TYPE_INTEGER);
126  tempContent.writeInt(phase.minDuration);
127  ++cnt; // not implemented
128  tempContent.writeUnsignedByte(TYPE_INTEGER);
129  tempContent.writeInt(phase.maxDuration);
130  ++cnt; // not implemented
131  const std::string& state = phase.getState();
132  //unsigned int linkNo = (unsigned int)(vars.getActive()->getLinks().size());
133  tempContent.writeUnsignedByte(TYPE_STRING);
134  tempContent.writeString(state);
135  ++cnt;
136  }
137  }
138  tempMsg.writeInt((int) cnt);
139  tempMsg.writeStorage(tempContent);
140  }
141  break;
142  case TL_CONTROLLED_LANES: {
145  std::vector<std::string> laneIDs;
146  for (MSTrafficLightLogic::LaneVectorVector::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
147  const MSTrafficLightLogic::LaneVector& llanes = (*i);
148  for (MSTrafficLightLogic::LaneVector::const_iterator j = llanes.begin(); j != llanes.end(); ++j) {
149  laneIDs.push_back((*j)->getID());
150  }
151  }
152  tempMsg.writeStringList(laneIDs);
153  }
154  break;
155  case TL_CONTROLLED_LINKS: {
158  //
160  tcpip::Storage tempContent;
161  unsigned int cnt = 0;
162  tempContent.writeUnsignedByte(TYPE_INTEGER);
163  unsigned int no = (unsigned int) lanes.size();
164  tempContent.writeInt((int) no);
165  for (unsigned int i = 0; i < no; ++i) {
166  const MSTrafficLightLogic::LaneVector& llanes = lanes[i];
167  const MSTrafficLightLogic::LinkVector& llinks = links[i];
168  // number of links controlled by this signal (signal i)
169  tempContent.writeUnsignedByte(TYPE_INTEGER);
170  unsigned int no2 = (unsigned int) llanes.size();
171  tempContent.writeInt((int) no2);
172  ++cnt;
173  for (unsigned int j = 0; j < no2; ++j) {
174  MSLink* link = llinks[j];
175  std::vector<std::string> def;
176  // incoming lane
177  def.push_back(llanes[j]->getID());
178  // approached non-internal lane (if any)
179  def.push_back(link->getLane() != 0 ? link->getLane()->getID() : "");
180  // approached "via", internal lane (if any)
181 #ifdef HAVE_INTERNAL_LANES
182  def.push_back(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
183 #else
184  def.push_back("");
185 #endif
186  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
187  tempContent.writeStringList(def);
188  ++cnt;
189  }
190  }
191  tempMsg.writeInt((int) cnt);
192  tempMsg.writeStorage(tempContent);
193  }
194  break;
195  case TL_CURRENT_PHASE:
197  tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseIndex());
198  break;
199  case TL_CURRENT_PROGRAM:
201  tempMsg.writeString(vars.getActive()->getProgramID());
202  break;
203  case TL_PHASE_DURATION:
205  tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseDef().duration);
206  break;
207  case TL_NEXT_SWITCH:
209  tempMsg.writeInt((int) vars.getActive()->getNextSwitchTime());
210  break;
212  }
213  break;
214  default:
215  break;
216  }
217  }
218  server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, "", outputStorage);
219  server.writeResponseWithLength(outputStorage, tempMsg);
220  return true;
221 }
222 
223 
224 bool
226  tcpip::Storage& outputStorage) {
227  std::string warning = ""; // additional description for response
228  // variable
229  int variable = inputStorage.readUnsignedByte();
230  if (variable != TL_PHASE_INDEX && variable != TL_PROGRAM
231  && variable != TL_PHASE_DURATION && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_PROGRAM_RYG) {
232  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable specified", outputStorage);
233  }
234  std::string id = inputStorage.readString();
235  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
236  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Traffic light '" + id + "' is not known", outputStorage);
237  }
240  MSTLLogicControl::TLSLogicVariants& vars = tlsControl.get(id);
241  switch (variable) {
242  case TL_PHASE_INDEX: {
243  int index = 0;
244  if (!server.readTypeCheckingInt(inputStorage, index)) {
245  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index must be given as an integer.", outputStorage);
246  }
247  if (index < 0 || vars.getActive()->getPhaseNumber() <= (unsigned int)index) {
248  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index is not in the allowed range.", outputStorage);
249  }
250  int duration = vars.getActive()->getPhase(index).duration;
251  vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
252  }
253  break;
254  case TL_PROGRAM: {
255  std::string subID;
256  if (!server.readTypeCheckingString(inputStorage, subID)) {
257  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
258  }
259  try {
260  vars.switchTo(tlsControl, subID);
261  } catch (ProcessError& e) {
262  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, e.what(), outputStorage);
263  }
264  }
265  break;
266  case TL_PHASE_DURATION: {
267  int duration = 0;
268  if (!server.readTypeCheckingInt(inputStorage, duration)) {
269  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase duration must be given as an integer.", outputStorage);
270  }
271  int index = vars.getActive()->getCurrentPhaseIndex();
272  vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
273  }
274  break;
276  std::string state;
277  if (!server.readTypeCheckingString(inputStorage, state)) {
278  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
279  }
280  vars.setStateInstantiatingOnline(tlsControl, state);
281  }
282  break;
284  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
285  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
286  }
287  int type = 0, index = 0, phaseNo = 0;
288  //read itemNo
289  inputStorage.readInt();
290  std::string subid;
291  if (!server.readTypeCheckingString(inputStorage, subid)) {
292  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 1. parameter (subid) must be a string.", outputStorage);
293  }
294  if (!server.readTypeCheckingInt(inputStorage, type)) {
295  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 2. parameter (type) must be an int.", outputStorage);
296  }
297  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
298  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 3. parameter (subparams) must be a compound object.", outputStorage);
299  }
300  inputStorage.readInt();
301  if (!server.readTypeCheckingInt(inputStorage, index)) {
302  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4. parameter (index) must be an int.", outputStorage);
303  }
304  if (!server.readTypeCheckingInt(inputStorage, phaseNo)) {
305  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 5. parameter (phase number) must be an int.", outputStorage);
306  }
307  // make sure index and phaseNo are consistent
308  if (index >= phaseNo) {
309  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4/5. parameter (index) must be less than parameter (phase number).", outputStorage);
310  }
311 
312  std::vector<MSPhaseDefinition*> phases;
313  for (int j = 0; j < phaseNo; ++j) {
314  int duration = 0, minDuration = 0, maxDuration = 0;
315  if (!server.readTypeCheckingInt(inputStorage, duration)) {
316  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.1. parameter (duration) must be an int.", outputStorage);
317  }
318  if (!server.readTypeCheckingInt(inputStorage, minDuration)) {
319  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.2. parameter (min duration) must be an int.", outputStorage);
320  }
321  if (!server.readTypeCheckingInt(inputStorage, maxDuration)) {
322  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.3. parameter (max duration) must be an int.", outputStorage);
323  }
324  std::string state;
325  if (!server.readTypeCheckingString(inputStorage, state)) {
326  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.4. parameter (phase) must be a string.", outputStorage);
327  }
328  MSPhaseDefinition* phase = new MSPhaseDefinition(duration, minDuration, maxDuration, state);
329  phases.push_back(phase);
330  }
331  if (vars.getLogic(subid) == 0) {
332  MSTrafficLightLogic* logic = new MSSimpleTrafficLightLogic(tlsControl, id, subid, phases, index, 0, std::map<std::string, std::string>());
333  vars.addLogic(subid, logic, true, true);
334  } else {
335  static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic(subid))->setPhases(phases, index);
336  }
337  }
338  break;
339  default:
340  break;
341  }
342  server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
343  return true;
344 }
345 
346 #endif
347 
348 
349 /****************************************************************************/
350