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 /****************************************************************************/
9 // APIs for getting/setting traffic light values via TraCI
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #ifndef NO_TRACI
34 
35 #include "TraCIConstants.h"
37 #include <microsim/MSLane.h>
38 #include "TraCIServerAPI_TLS.h"
39 
40 #ifdef CHECK_MEMORY_LEAKS
41 #include <foreign/nvwa/debug_new.h>
42 #endif // CHECK_MEMORY_LEAKS
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
48 bool
50  tcpip::Storage& outputStorage) {
51  // variable & id
52  int variable = inputStorage.readUnsignedByte();
53  std::string id = inputStorage.readString();
54  // check variable
55  if (variable != ID_LIST && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_DEFINITION_RYG
56  && variable != TL_CONTROLLED_LANES && variable != TL_CONTROLLED_LINKS
57  && variable != TL_CURRENT_PHASE && variable != TL_CURRENT_PROGRAM
58  && variable != TL_NEXT_SWITCH && variable != TL_PHASE_DURATION && variable != ID_COUNT) {
59  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable specified", outputStorage);
60  }
61  // begin response building
62  tcpip::Storage tempMsg;
63  // response-code, variableID, objectID
65  tempMsg.writeUnsignedByte(variable);
66  tempMsg.writeString(id);
67  if (variable == ID_LIST) {
68  std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
70  tempMsg.writeStringList(ids);
71  } else if (variable == ID_COUNT) {
72  std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
74  tempMsg.writeInt((int) ids.size());
75  } else {
76  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
77  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Traffic light '" + id + "' is not known", outputStorage);
78  }
80  switch (variable) {
81  case ID_LIST:
82  break;
85  std::string state = vars.getActive()->getCurrentPhaseDef().getState();
86  tempMsg.writeString(state);
87  }
88  break;
90  std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
92  tcpip::Storage tempContent;
93  unsigned int cnt = 0;
94  tempContent.writeUnsignedByte(TYPE_INTEGER);
95  tempContent.writeInt((int) logics.size());
96  ++cnt;
97  for (unsigned int i = 0; i < logics.size(); ++i) {
98  MSTrafficLightLogic* logic = logics[i];
99  tempContent.writeUnsignedByte(TYPE_STRING);
100  tempContent.writeString(logic->getProgramID());
101  ++cnt;
102  // type (always 0 by now)
103  tempContent.writeUnsignedByte(TYPE_INTEGER);
104  tempContent.writeInt(0);
105  ++cnt;
106  // subparameter (always 0 by now)
107  tempContent.writeUnsignedByte(TYPE_COMPOUND);
108  tempContent.writeInt(0);
109  ++cnt;
110  // (current) phase index
111  tempContent.writeUnsignedByte(TYPE_INTEGER);
112  tempContent.writeInt((int) logic->getCurrentPhaseIndex());
113  ++cnt;
114  // phase number
115  unsigned int phaseNo = logic->getPhaseNumber();
116  tempContent.writeUnsignedByte(TYPE_INTEGER);
117  tempContent.writeInt((int) phaseNo);
118  ++cnt;
119  for (unsigned int j = 0; j < phaseNo; ++j) {
120  MSPhaseDefinition phase = logic->getPhase(j);
121  tempContent.writeUnsignedByte(TYPE_INTEGER);
122  tempContent.writeInt(phase.duration);
123  ++cnt;
124  tempContent.writeUnsignedByte(TYPE_INTEGER);
125  tempContent.writeInt(phase.minDuration);
126  ++cnt; // not implemented
127  tempContent.writeUnsignedByte(TYPE_INTEGER);
128  tempContent.writeInt(phase.maxDuration);
129  ++cnt; // not implemented
130  const std::string& state = phase.getState();
131  //unsigned int linkNo = (unsigned int)(vars.getActive()->getLinks().size());
132  tempContent.writeUnsignedByte(TYPE_STRING);
133  tempContent.writeString(state);
134  ++cnt;
135  }
136  }
137  tempMsg.writeInt((int) cnt);
138  tempMsg.writeStorage(tempContent);
139  }
140  break;
141  case TL_CONTROLLED_LANES: {
144  std::vector<std::string> laneIDs;
145  for (MSTrafficLightLogic::LaneVectorVector::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
146  const MSTrafficLightLogic::LaneVector& llanes = (*i);
147  for (MSTrafficLightLogic::LaneVector::const_iterator j = llanes.begin(); j != llanes.end(); ++j) {
148  laneIDs.push_back((*j)->getID());
149  }
150  }
151  tempMsg.writeStringList(laneIDs);
152  }
153  break;
154  case TL_CONTROLLED_LINKS: {
157  //
159  tcpip::Storage tempContent;
160  unsigned int cnt = 0;
161  tempContent.writeUnsignedByte(TYPE_INTEGER);
162  unsigned int no = (unsigned int) lanes.size();
163  tempContent.writeInt((int) no);
164  for (unsigned int i = 0; i < no; ++i) {
165  const MSTrafficLightLogic::LaneVector& llanes = lanes[i];
166  const MSTrafficLightLogic::LinkVector& llinks = links[i];
167  // number of links controlled by this signal (signal i)
168  tempContent.writeUnsignedByte(TYPE_INTEGER);
169  unsigned int no2 = (unsigned int) llanes.size();
170  tempContent.writeInt((int) no2);
171  ++cnt;
172  for (unsigned int j = 0; j < no2; ++j) {
173  MSLink* link = llinks[j];
174  std::vector<std::string> def;
175  // incoming lane
176  def.push_back(llanes[j]->getID());
177  // approached non-internal lane (if any)
178  def.push_back(link->getLane() != 0 ? link->getLane()->getID() : "");
179  // approached "via", internal lane (if any)
180 #ifdef HAVE_INTERNAL_LANES
181  def.push_back(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
182 #else
183  def.push_back("");
184 #endif
185  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
186  tempContent.writeStringList(def);
187  ++cnt;
188  }
189  }
190  tempMsg.writeInt((int) cnt);
191  tempMsg.writeStorage(tempContent);
192  }
193  break;
194  case TL_CURRENT_PHASE:
196  tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseIndex());
197  break;
198  case TL_CURRENT_PROGRAM:
200  tempMsg.writeString(vars.getActive()->getProgramID());
201  break;
202  case TL_PHASE_DURATION:
204  tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseDef().duration);
205  break;
206  case TL_NEXT_SWITCH:
208  tempMsg.writeInt((int) vars.getActive()->getNextSwitchTime());
209  break;
211  }
212  break;
213  default:
214  break;
215  }
216  }
217  server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, "", outputStorage);
218  server.writeResponseWithLength(outputStorage, tempMsg);
219  return true;
220 }
221 
222 
223 bool
225  tcpip::Storage& outputStorage) {
226  std::string warning = ""; // additional description for response
227  // variable
228  int variable = inputStorage.readUnsignedByte();
229  if (variable != TL_PHASE_INDEX && variable != TL_PROGRAM
230  && variable != TL_PHASE_DURATION && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_PROGRAM_RYG) {
231  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable specified", outputStorage);
232  }
233  std::string id = inputStorage.readString();
234  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
235  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Traffic light '" + id + "' is not known", outputStorage);
236  }
239  MSTLLogicControl::TLSLogicVariants& vars = tlsControl.get(id);
240  switch (variable) {
241  case TL_PHASE_INDEX: {
242  int index = 0;
243  if (!server.readTypeCheckingInt(inputStorage, index)) {
244  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index must be given as an integer.", outputStorage);
245  }
246  if (index < 0 || vars.getActive()->getPhaseNumber() <= (unsigned int)index) {
247  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index is not in the allowed range.", outputStorage);
248  }
249  int duration = vars.getActive()->getPhase(index).duration;
250  vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
251  }
252  break;
253  case TL_PROGRAM: {
254  std::string subID;
255  if (!server.readTypeCheckingString(inputStorage, subID)) {
256  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
257  }
258  try {
259  vars.switchTo(tlsControl, subID);
260  } catch (ProcessError& e) {
261  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, e.what(), outputStorage);
262  }
263  }
264  break;
265  case TL_PHASE_DURATION: {
266  int duration = 0;
267  if (!server.readTypeCheckingInt(inputStorage, duration)) {
268  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase duration must be given as an integer.", outputStorage);
269  }
270  int index = vars.getActive()->getCurrentPhaseIndex();
271  vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
272  }
273  break;
275  std::string state;
276  if (!server.readTypeCheckingString(inputStorage, state)) {
277  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
278  }
279  vars.setStateInstantiatingOnline(tlsControl, state);
280  }
281  break;
283  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
284  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
285  }
286  int type = 0, index = 0, phaseNo = 0;
287  //read itemNo
288  inputStorage.readInt();
289  std::string subid;
290  if (!server.readTypeCheckingString(inputStorage, subid)) {
291  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 1. parameter (subid) must be a string.", outputStorage);
292  }
293  if (!server.readTypeCheckingInt(inputStorage, type)) {
294  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 2. parameter (type) must be an int.", outputStorage);
295  }
296  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
297  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 3. parameter (subparams) must be a compound object.", outputStorage);
298  }
299  inputStorage.readInt();
300  if (!server.readTypeCheckingInt(inputStorage, index)) {
301  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4. parameter (index) must be an int.", outputStorage);
302  }
303  if (!server.readTypeCheckingInt(inputStorage, phaseNo)) {
304  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 5. parameter (phase number) must be an int.", outputStorage);
305  }
306  // make sure index and phaseNo are consistent
307  if (index >= phaseNo) {
308  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4/5. parameter (index) must be less than parameter (phase number).", outputStorage);
309  }
310 
311  std::vector<MSPhaseDefinition*> phases;
312  for (int j = 0; j < phaseNo; ++j) {
313  int duration = 0, minDuration = 0, maxDuration = 0;
314  if (!server.readTypeCheckingInt(inputStorage, duration)) {
315  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.1. parameter (duration) must be an int.", outputStorage);
316  }
317  if (!server.readTypeCheckingInt(inputStorage, minDuration)) {
318  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.2. parameter (min duration) must be an int.", outputStorage);
319  }
320  if (!server.readTypeCheckingInt(inputStorage, maxDuration)) {
321  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.3. parameter (max duration) must be an int.", outputStorage);
322  }
323  std::string state;
324  if (!server.readTypeCheckingString(inputStorage, state)) {
325  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.4. parameter (phase) must be a string.", outputStorage);
326  }
327  MSPhaseDefinition* phase = new MSPhaseDefinition(duration, minDuration, maxDuration, state);
328  phases.push_back(phase);
329  }
330  if (vars.getLogic(subid) == 0) {
331  MSTrafficLightLogic* logic = new MSSimpleTrafficLightLogic(tlsControl, id, subid, phases, index, 0, std::map<std::string, std::string>());
332  vars.addLogic(subid, logic, true, true);
333  } else {
334  static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic(subid))->setPhases(phases, index);
335  }
336  }
337  break;
338  default:
339  break;
340  }
341  server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
342  return true;
343 }
344 
345 #endif
346 
347 
348 /****************************************************************************/
349 
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
#define TL_NEXT_SWITCH
const std::string & getState() const
Returns the state within this phase.
#define CMD_GET_TL_VARIABLE
virtual unsigned int getCurrentPhaseIndex() const =0
Returns the current index within the program.
Storage for all programs of a single tls.
#define TYPE_COMPOUND
#define RTYPE_OK
virtual const MSPhaseDefinition & getPhase(unsigned int givenstep) const =0
Returns the definition of the phase from the given position within the plan.
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:154
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
std::vector< std::string > getAllTLIds() const
#define RESPONSE_GET_TL_VARIABLE
virtual void writeUnsignedByte(int)
#define TL_CONTROLLED_JUNCTIONS
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:210
#define TL_CURRENT_PHASE
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
MSTrafficLightLogic * getLogic(const std::string &programID) const
virtual void writeInt(int)
A fixed traffic light logic.
#define TYPE_STRING
virtual int readUnsignedByte()
#define TL_PHASE_DURATION
#define TL_CURRENT_PROGRAM
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, unsigned int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
#define CMD_SET_TL_VARIABLE
A class that stores and controls tls and switching of their programs.
std::vector< MSTrafficLightLogic * > getAllLogics() const
const std::string & getID() const
Returns the id.
Definition: Named.h:60
SUMOTime duration
The duration of the phase.
bool addLogic(const std::string &programID, MSTrafficLightLogic *logic, bool netWasLoaded, bool isNewDefault=true)
Adds a logic (program)
std::vector< LinkVector > LinkVectorVector
Definition of a list that holds lists of links that do have the same attribute.
MSTrafficLightLogic * getActive() const
virtual int readInt()
#define TL_COMPLETE_PROGRAM_RYG
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:314
#define TL_COMPLETE_DEFINITION_RYG
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
virtual void writeStringList(const std::vector< std::string > &s)
virtual std::string readString()
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
void setStateInstantiatingOnline(MSTLLogicControl &tlc, const std::string &state)
bool knows(const std::string &id) const
Returns the information whether the named tls is stored.
virtual void writeStorage(tcpip::Storage &store)
#define TL_CONTROLLED_LINKS
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
#define TL_RED_YELLOW_GREEN_STATE
std::vector< MSLink * > LinkVector
Definition of the list of links that participate in this tl-light.
const LaneVectorVector & getLanes() const
Returns the list of lists of all lanes controlled by this tls.
void switchTo(MSTLLogicControl &tlc, const std::string &programID)
std::vector< MSLane * > LaneVector
Definition of the list of links that participate in this tl-light.
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of links that do have the same attribute.
virtual void writeString(const std::string &s)
SUMOTime maxDuration
The maximum duration of the phase.
#define TL_PROGRAM
virtual unsigned int getPhaseNumber() const =0
Returns the number of phases.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
SUMOTime minDuration
The minimum duration of the phase.
The parent class for traffic light logics.
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc2: Change Traffic Lights State)
const std::string & getProgramID() const
Returns this tl-logic's id.
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
#define TL_CONTROLLED_LANES
#define ID_COUNT
#define TYPE_INTEGER
#define ID_LIST
#define TL_PHASE_INDEX
The definition of a single phase of a tls logic.
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa2: Get Traffic Lights Variable)