SUMO - Simulation of Urban MObility
TraCIServerAPI_TrafficLight.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2009-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // APIs for getting/setting traffic light values via TraCI
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 <microsim/MSLane.h>
36 #include <microsim/MSEdge.h>
39 #include <libsumo/TrafficLight.h>
40 #include "TraCIConstants.h"
42 
43 
44 // ===========================================================================
45 // method definitions
46 // ===========================================================================
47 bool
49  tcpip::Storage& outputStorage) {
50  // variable & id
51  const int variable = inputStorage.readUnsignedByte();
52  const std::string id = inputStorage.readString();
53  // check variable
54  if (variable != ID_LIST && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_DEFINITION_RYG
55  && variable != TL_CONTROLLED_LANES && variable != TL_CONTROLLED_LINKS
56  && variable != TL_CURRENT_PHASE && variable != TL_CURRENT_PROGRAM
57  && variable != TL_NEXT_SWITCH && variable != TL_PHASE_DURATION && variable != ID_COUNT
58  && variable != VAR_PARAMETER && variable != TL_EXTERNAL_STATE) {
59  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable " + toHex(variable, 2) + " 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  try {
68  switch (variable) {
69  case ID_LIST:
72  break;
73  case ID_COUNT:
76  break;
80  break;
82  std::vector<libsumo::TraCILogic> logics = libsumo::TrafficLight::getCompleteRedYellowGreenDefinition(id);
84  tcpip::Storage tempContent;
85  int cnt = 0;
86  tempContent.writeUnsignedByte(TYPE_INTEGER);
87  tempContent.writeInt((int)logics.size());
88  ++cnt;
89  for (const libsumo::TraCILogic& logic : logics) {
90  tempContent.writeUnsignedByte(TYPE_STRING);
91  tempContent.writeString(logic.subID);
92  ++cnt;
93  // type (always 0 by now)
94  tempContent.writeUnsignedByte(TYPE_INTEGER);
95  tempContent.writeInt(logic.type);
96  ++cnt;
97  // subparameter (always 0 by now)
98  tempContent.writeUnsignedByte(TYPE_COMPOUND);
99  tempContent.writeInt(0);
100  ++cnt;
101  // (current) phase index
102  tempContent.writeUnsignedByte(TYPE_INTEGER);
103  tempContent.writeInt(logic.currentPhaseIndex);
104  ++cnt;
105  // phase number
106  tempContent.writeUnsignedByte(TYPE_INTEGER);
107  tempContent.writeInt((int)logic.phases.size());
108  ++cnt;
109  for (const libsumo::TraCIPhase& phase : logic.phases) {
110  tempContent.writeUnsignedByte(TYPE_INTEGER);
111  tempContent.writeInt((int)phase.duration);
112  ++cnt;
113  tempContent.writeUnsignedByte(TYPE_INTEGER);
114  tempContent.writeInt((int)phase.duration1);
115  ++cnt; // not implemented
116  tempContent.writeUnsignedByte(TYPE_INTEGER);
117  tempContent.writeInt((int)phase.duration2);
118  ++cnt; // not implemented
119  tempContent.writeUnsignedByte(TYPE_STRING);
120  tempContent.writeString(phase.phase);
121  ++cnt;
122  }
123  }
124  tempMsg.writeInt((int)cnt);
125  tempMsg.writeStorage(tempContent);
126  break;
127  }
128  case TL_CONTROLLED_LANES:
131  break;
132  case TL_CONTROLLED_LINKS: {
133  const std::vector<std::vector<libsumo::TraCILink> > links = libsumo::TrafficLight::getControlledLinks(id);
135  tcpip::Storage tempContent;
136  int cnt = 0;
137  tempContent.writeUnsignedByte(TYPE_INTEGER);
138  tempContent.writeInt((int)links.size());
139  for (const std::vector<libsumo::TraCILink>& sublinks : links) {
140  tempContent.writeUnsignedByte(TYPE_INTEGER);
141  tempContent.writeInt((int)sublinks.size());
142  ++cnt;
143  for (const libsumo::TraCILink& link : sublinks) {
144  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
145  tempContent.writeStringList(std::vector<std::string>({ link.from, link.to, link.via }));
146  ++cnt;
147  }
148  }
149  tempMsg.writeInt(cnt);
150  tempMsg.writeStorage(tempContent);
151  break;
152  }
153  case TL_CURRENT_PHASE:
156  break;
157  case TL_CURRENT_PROGRAM:
160  break;
161  case TL_PHASE_DURATION:
164  break;
165  case TL_NEXT_SWITCH:
168  break;
169  case VAR_PARAMETER: {
170  std::string paramName = "";
171  if (!server.readTypeCheckingString(inputStorage, paramName)) {
172  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
173  }
175  tempMsg.writeString(libsumo::TrafficLight::getParameter(id, paramName));
176  break;
177  }
181  break;
182  }
183  case TL_EXTERNAL_STATE: {
184  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
185  throw libsumo::TraCIException("Traffic light '" + id + "' is not known");
186  }
188  const std::string& state = tls->getCurrentPhaseDef().getState();
189  const std::map<std::string, std::string>& params = tls->getMap();
190  int num = 0;
191  for (std::map<std::string, std::string>::const_iterator i = params.begin(); i != params.end(); ++i) {
192  if ("connection:" == (*i).first.substr(0, 11)) {
193  ++num;
194  }
195  }
196 
199  tempMsg.writeInt(num * 2);
200  for (std::map<std::string, std::string>::const_iterator i = params.begin(); i != params.end(); ++i) {
201  if ("connection:" != (*i).first.substr(0, 11)) {
202  continue;
203  }
205  tempMsg.writeString((*i).second); // foreign id
206  std::string connection = (*i).first.substr(11);
207  std::string from, to;
208  const std::string::size_type b = connection.find("->");
209  if (b == std::string::npos) {
210  from = connection;
211  } else {
212  from = connection.substr(0, b);
213  to = connection.substr(b + 2);
214  }
215  bool denotesEdge = from.find("_") == std::string::npos;
216  MSLane* fromLane = 0;
218  MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin();
219  for (; j != lanes.end() && fromLane == 0;) {
220  for (MSTrafficLightLogic::LaneVector::const_iterator k = (*j).begin(); k != (*j).end() && fromLane == 0;) {
221  if (denotesEdge && (*k)->getEdge().getID() == from) {
222  fromLane = *k;
223  } else if (!denotesEdge && (*k)->getID() == from) {
224  fromLane = *k;
225  }
226  if (fromLane == 0) {
227  ++k;
228  }
229  }
230  if (fromLane == 0) {
231  ++j;
232  }
233  }
234  if (fromLane == 0) {
235  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Could not find edge or lane '" + from + "' in traffic light '" + id + "'.", outputStorage);
236  }
237  int pos = (int)std::distance(lanes.begin(), j);
238  tempMsg.writeUnsignedByte(TYPE_UBYTE);
239  tempMsg.writeUnsignedByte(state[pos]); // state
240  }
241  break;
242  }
243  default:
244  break;
245  }
246  } catch (libsumo::TraCIException& e) {
247  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, e.what(), outputStorage);
248  }
249  server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, "", outputStorage);
250  server.writeResponseWithLength(outputStorage, tempMsg);
251  return true;
252 }
253 
254 
255 bool
257  tcpip::Storage& outputStorage) {
258  std::string warning = ""; // additional description for response
259  // variable
260  const int variable = inputStorage.readUnsignedByte();
261  if (variable != TL_PHASE_INDEX && variable != TL_PROGRAM && variable != TL_PHASE_DURATION
262  && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_PROGRAM_RYG
263  && variable != VAR_PARAMETER) {
264  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
265  }
266  const std::string id = inputStorage.readString();
267  try {
268  switch (variable) {
269  case TL_PHASE_INDEX: {
270  int index = 0;
271  if (!server.readTypeCheckingInt(inputStorage, index)) {
272  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index must be given as an integer.", outputStorage);
273  }
275  }
276  break;
277  case TL_PROGRAM: {
278  std::string subID;
279  if (!server.readTypeCheckingString(inputStorage, subID)) {
280  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
281  }
283  }
284  break;
285  case TL_PHASE_DURATION: {
286  int duration = 0;
287  if (!server.readTypeCheckingInt(inputStorage, duration)) {
288  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase duration must be given as an integer.", outputStorage);
289  }
291  }
292  break;
294  std::string state;
295  if (!server.readTypeCheckingString(inputStorage, state)) {
296  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
297  }
299  }
300  break;
302  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
303  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
304  }
305  //read itemNo
306  inputStorage.readInt();
307  libsumo::TraCILogic logic;
308  int numPhases = 0;
309  if (!server.readTypeCheckingString(inputStorage, logic.subID)) {
310  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 1. parameter (subid) must be a string.", outputStorage);
311  }
312  if (!server.readTypeCheckingInt(inputStorage, logic.type)) {
313  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 2. parameter (type) must be an int.", outputStorage);
314  }
315  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
316  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 3. parameter (subparams) must be a compound object.", outputStorage);
317  }
318  inputStorage.readInt();
319  if (!server.readTypeCheckingInt(inputStorage, logic.currentPhaseIndex)) {
320  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4. parameter (index) must be an int.", outputStorage);
321  }
322  if (!server.readTypeCheckingInt(inputStorage, numPhases)) {
323  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 5. parameter (phase number) must be an int.", outputStorage);
324  }
325  for (int j = 0; j < numPhases; ++j) {
326  int duration = 0, minDuration = 0, maxDuration = 0;
327  if (!server.readTypeCheckingInt(inputStorage, duration)) {
328  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.1. parameter (duration) must be an int.", outputStorage);
329  }
330  if (!server.readTypeCheckingInt(inputStorage, minDuration)) {
331  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.2. parameter (min duration) must be an int.", outputStorage);
332  }
333  if (!server.readTypeCheckingInt(inputStorage, maxDuration)) {
334  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.3. parameter (max duration) must be an int.", outputStorage);
335  }
336  std::string state;
337  if (!server.readTypeCheckingString(inputStorage, state)) {
338  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.4. parameter (phase) must be a string.", outputStorage);
339  }
340  logic.phases.emplace_back(libsumo::TraCIPhase(duration, minDuration, maxDuration, state));
341  }
343  }
344  break;
345  case VAR_PARAMETER: {
346  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
347  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
348  }
349  //read itemNo
350  inputStorage.readInt();
351  std::string name;
352  if (!server.readTypeCheckingString(inputStorage, name)) {
353  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
354  }
355  std::string value;
356  if (!server.readTypeCheckingString(inputStorage, value)) {
357  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
358  }
359  libsumo::TrafficLight::setParameter(id, name, value);
360  }
361  break;
362  default:
363  break;
364  }
365  } catch (libsumo::TraCIException& e) {
366  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, e.what(), outputStorage);
367  }
368  server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
369  return true;
370 }
371 
372 #endif
373 
374 
375 /****************************************************************************/
376 
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.
std::string phase
Definition: TraCIDefs.h:114
#define CMD_GET_TL_VARIABLE
#define TYPE_COMPOUND
static std::string getRedYellowGreenState(const std::string &tlsID)
#define TYPE_UBYTE
#define RTYPE_OK
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
static std::vector< std::string > getControlledJunctions(const std::string &tlsID)
static void setParameter(const std::string &tlsID, const std::string &paramName, const std::string &value)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc2: Change Traffic Lights State)
static std::vector< std::string > getIDList()
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:167
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
#define RESPONSE_GET_TL_VARIABLE
virtual void writeUnsignedByte(int)
#define TL_CONTROLLED_JUNCTIONS
static std::vector< std::string > getControlledLanes(const std::string &tlsID)
#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.
std::vector< TraCIPhase > phases
Definition: TraCIDefs.h:128
virtual void writeInt(int)
#define TYPE_STRING
virtual int readUnsignedByte()
#define TL_PHASE_DURATION
static void setRedYellowGreenState(const std::string &tlsID, const std::string &state)
#define TL_CURRENT_PROGRAM
#define CMD_SET_TL_VARIABLE
virtual int readInt()
#define TL_COMPLETE_PROGRAM_RYG
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:379
static void setPhaseDuration(const std::string &tlsID, const SUMOTime phaseDuration)
#define TL_COMPLETE_DEFINITION_RYG
virtual void writeStringList(const std::vector< std::string > &s)
#define TL_EXTERNAL_STATE
static int getIDCount()
virtual std::string readString()
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:69
virtual void writeStorage(tcpip::Storage &store)
#define TL_CONTROLLED_LINKS
static std::vector< TraCILogic > getCompleteRedYellowGreenDefinition(const std::string &tlsID)
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
#define TL_RED_YELLOW_GREEN_STATE
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa2: Get Traffic Lights Variable)
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of lanes that do have the same attribute.
virtual void writeString(const std::string &s)
#define TL_PROGRAM
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:65
const std::map< std::string, std::string > & getMap() const
Returns the inner key/value map.
static SUMOTime getNextSwitch(const std::string &tlsID)
SUMOTime duration2
Definition: TraCIDefs.h:113
static void setPhase(const std::string &tlsID, const int index)
std::string subID
Definition: TraCIDefs.h:125
static SUMOTime getPhaseDuration(const std::string &tlsID)
static void setCompleteRedYellowGreenDefinition(const std::string &tlsID, const TraCILogic &logic)
The parent class for traffic light logics.
static void setProgram(const std::string &tlsID, const std::string &programID)
SUMOTime duration1
Definition: TraCIDefs.h:113
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
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
#define VAR_PARAMETER
static std::string getProgram(const std::string &tlsID)
#define ID_COUNT
MSTrafficLightLogic * getActive() const
static int getPhase(const std::string &tlsID)
static std::string getParameter(const std::string &tlsID, const std::string &paramName)
#define TYPE_INTEGER
#define ID_LIST
#define TL_PHASE_INDEX
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
static std::vector< std::vector< TraCILink > > getControlledLinks(const std::string &tlsID)