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-2018 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 /****************************************************************************/
18 // APIs for getting/setting traffic light values via TraCI
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <microsim/MSLane.h>
28 #include <microsim/MSEdge.h>
31 #include <libsumo/TrafficLight.h>
32 #include "TraCIConstants.h"
34 
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 bool
41  tcpip::Storage& outputStorage) {
42  const int variable = inputStorage.readUnsignedByte();
43  const std::string id = inputStorage.readString();
44  server.initWrapper(RESPONSE_GET_TL_VARIABLE, variable, id);
45  try {
46  if (!libsumo::TrafficLight::handleVariable(id, variable, &server)) {
47  switch (variable) {
49  std::vector<libsumo::TraCILogic> logics = libsumo::TrafficLight::getCompleteRedYellowGreenDefinition(id);
51  tcpip::Storage tempContent;
52  int cnt = 0;
53  tempContent.writeUnsignedByte(TYPE_INTEGER);
54  tempContent.writeInt((int)logics.size());
55  ++cnt;
56  for (const libsumo::TraCILogic& logic : logics) {
57  tempContent.writeUnsignedByte(TYPE_STRING);
58  tempContent.writeString(logic.subID);
59  ++cnt;
60  // type (always 0 by now)
61  tempContent.writeUnsignedByte(TYPE_INTEGER);
62  tempContent.writeInt(logic.type);
63  ++cnt;
64  // subparameter (always 0 by now)
65  tempContent.writeUnsignedByte(TYPE_COMPOUND);
66  tempContent.writeInt(0);
67  ++cnt;
68  // (current) phase index
69  tempContent.writeUnsignedByte(TYPE_INTEGER);
70  tempContent.writeInt(logic.currentPhaseIndex);
71  ++cnt;
72  // phase number
73  tempContent.writeUnsignedByte(TYPE_INTEGER);
74  tempContent.writeInt((int)logic.phases.size());
75  ++cnt;
76  for (const libsumo::TraCIPhase& phase : logic.phases) {
77  tempContent.writeUnsignedByte(TYPE_DOUBLE);
78  tempContent.writeDouble(phase.duration);
79  ++cnt;
80  tempContent.writeUnsignedByte(TYPE_DOUBLE);
81  tempContent.writeDouble(phase.duration1);
82  ++cnt; // not implemented
83  tempContent.writeUnsignedByte(TYPE_DOUBLE);
84  tempContent.writeDouble(phase.duration2);
85  ++cnt; // not implemented
86  tempContent.writeUnsignedByte(TYPE_STRING);
87  tempContent.writeString(phase.phase);
88  ++cnt;
89  }
90  }
91  server.getWrapperStorage().writeInt((int)cnt);
92  server.getWrapperStorage().writeStorage(tempContent);
93  break;
94  }
95  case TL_CONTROLLED_LINKS: {
96  const std::vector<std::vector<libsumo::TraCILink> > links = libsumo::TrafficLight::getControlledLinks(id);
98  tcpip::Storage tempContent;
99  int cnt = 0;
100  tempContent.writeUnsignedByte(TYPE_INTEGER);
101  tempContent.writeInt((int)links.size());
102  for (const std::vector<libsumo::TraCILink>& sublinks : links) {
103  tempContent.writeUnsignedByte(TYPE_INTEGER);
104  tempContent.writeInt((int)sublinks.size());
105  ++cnt;
106  for (const libsumo::TraCILink& link : sublinks) {
107  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
108  tempContent.writeStringList(std::vector<std::string>({ link.fromLane, link.toLane, link.viaLane }));
109  ++cnt;
110  }
111  }
112  server.getWrapperStorage().writeInt(cnt);
113  server.getWrapperStorage().writeStorage(tempContent);
114  break;
115  }
116  case VAR_PARAMETER: {
117  std::string paramName = "";
118  if (!server.readTypeCheckingString(inputStorage, paramName)) {
119  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
120  }
123  break;
124  }
125  case TL_EXTERNAL_STATE: {
126  if (!MSNet::getInstance()->getTLSControl().knows(id)) {
127  throw libsumo::TraCIException("Traffic light '" + id + "' is not known");
128  }
130  const std::string& state = tls->getCurrentPhaseDef().getState();
131  const std::map<std::string, std::string>& params = tls->getParametersMap();
132  int num = 0;
133  for (std::map<std::string, std::string>::const_iterator i = params.begin(); i != params.end(); ++i) {
134  if ("connection:" == (*i).first.substr(0, 11)) {
135  ++num;
136  }
137  }
138 
141  server.getWrapperStorage().writeInt(num * 2);
142  for (std::map<std::string, std::string>::const_iterator i = params.begin(); i != params.end(); ++i) {
143  if ("connection:" != (*i).first.substr(0, 11)) {
144  continue;
145  }
147  server.getWrapperStorage().writeString((*i).second); // foreign id
148  std::string connection = (*i).first.substr(11);
149  std::string from, to;
150  const std::string::size_type b = connection.find("->");
151  if (b == std::string::npos) {
152  from = connection;
153  } else {
154  from = connection.substr(0, b);
155  to = connection.substr(b + 2);
156  }
157  bool denotesEdge = from.find("_") == std::string::npos;
158  MSLane* fromLane = 0;
160  MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin();
161  for (; j != lanes.end() && fromLane == 0;) {
162  for (MSTrafficLightLogic::LaneVector::const_iterator k = (*j).begin(); k != (*j).end() && fromLane == 0;) {
163  if (denotesEdge && (*k)->getEdge().getID() == from) {
164  fromLane = *k;
165  } else if (!denotesEdge && (*k)->getID() == from) {
166  fromLane = *k;
167  }
168  if (fromLane == 0) {
169  ++k;
170  }
171  }
172  if (fromLane == 0) {
173  ++j;
174  }
175  }
176  if (fromLane == 0) {
177  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Could not find edge or lane '" + from + "' in traffic light '" + id + "'.", outputStorage);
178  }
179  int pos = (int)std::distance(lanes.begin(), j);
181  server.getWrapperStorage().writeUnsignedByte(state[pos]); // state
182  }
183  break;
184  }
185  default:
186  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
187  }
188  }
189  } catch (libsumo::TraCIException& e) {
190  return server.writeErrorStatusCmd(CMD_GET_TL_VARIABLE, e.what(), outputStorage);
191  }
192  server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, "", outputStorage);
193  server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
194  return true;
195 }
196 
197 
198 bool
200  tcpip::Storage& outputStorage) {
201  std::string warning = ""; // additional description for response
202  // variable
203  const int variable = inputStorage.readUnsignedByte();
204  if (variable != TL_PHASE_INDEX && variable != TL_PROGRAM && variable != TL_PHASE_DURATION
205  && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_PROGRAM_RYG
206  && variable != VAR_PARAMETER) {
207  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
208  }
209  const std::string id = inputStorage.readString();
210  try {
211  switch (variable) {
212  case TL_PHASE_INDEX: {
213  int index = 0;
214  if (!server.readTypeCheckingInt(inputStorage, index)) {
215  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase index must be given as an integer.", outputStorage);
216  }
218  }
219  break;
220  case TL_PROGRAM: {
221  std::string subID;
222  if (!server.readTypeCheckingString(inputStorage, subID)) {
223  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
224  }
226  }
227  break;
228  case TL_PHASE_DURATION: {
229  double duration = 0.;
230  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
231  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase duration must be given as a double.", outputStorage);
232  }
234  }
235  break;
237  std::string state;
238  if (!server.readTypeCheckingString(inputStorage, state)) {
239  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
240  }
242  }
243  break;
245  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
246  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
247  }
248  //read itemNo
249  inputStorage.readInt();
250  libsumo::TraCILogic logic;
251  int numPhases = 0;
252  if (!server.readTypeCheckingString(inputStorage, logic.subID)) {
253  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 1. parameter (subid) must be a string.", outputStorage);
254  }
255  if (!server.readTypeCheckingInt(inputStorage, logic.type)) {
256  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 2. parameter (type) must be an int.", outputStorage);
257  }
258  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
259  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 3. parameter (subparams) must be a compound object.", outputStorage);
260  }
261  inputStorage.readInt();
262  if (!server.readTypeCheckingInt(inputStorage, logic.currentPhaseIndex)) {
263  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 4. parameter (index) must be an int.", outputStorage);
264  }
265  if (!server.readTypeCheckingInt(inputStorage, numPhases)) {
266  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 5. parameter (phase number) must be an int.", outputStorage);
267  }
268  for (int j = 0; j < numPhases; ++j) {
269  double duration = 0., minDuration = 0., maxDuration = 0.;
270  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
271  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.1. parameter (duration) must be a double.", outputStorage);
272  }
273  if (!server.readTypeCheckingDouble(inputStorage, minDuration)) {
274  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.2. parameter (min duration) must be a double.", outputStorage);
275  }
276  if (!server.readTypeCheckingDouble(inputStorage, maxDuration)) {
277  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.3. parameter (max duration) must be a double.", outputStorage);
278  }
279  std::string state;
280  if (!server.readTypeCheckingString(inputStorage, state)) {
281  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "set program: 6.4. parameter (phase) must be a string.", outputStorage);
282  }
283  logic.phases.emplace_back(libsumo::TraCIPhase(duration, minDuration, maxDuration, state));
284  }
286  }
287  break;
288  case VAR_PARAMETER: {
289  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
290  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
291  }
292  //read itemNo
293  inputStorage.readInt();
294  std::string name;
295  if (!server.readTypeCheckingString(inputStorage, name)) {
296  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
297  }
298  std::string value;
299  if (!server.readTypeCheckingString(inputStorage, value)) {
300  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
301  }
302  libsumo::TrafficLight::setParameter(id, name, value);
303  }
304  break;
305  default:
306  break;
307  }
308  } catch (libsumo::TraCIException& e) {
309  return server.writeErrorStatusCmd(CMD_SET_TL_VARIABLE, e.what(), outputStorage);
310  }
311  server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
312  return true;
313 }
314 
315 
316 /****************************************************************************/
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
const std::string & getState() const
Returns the state within this phase.
std::string phase
Definition: TraCIDefs.h:211
#define CMD_GET_TL_VARIABLE
#define TYPE_COMPOUND
static void setPhaseDuration(const std::string &tlsID, const double phaseDuration)
#define TYPE_UBYTE
#define RTYPE_OK
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
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)
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:160
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
#define RESPONSE_GET_TL_VARIABLE
static bool handleVariable(const std::string &objID, const int variable, VariableWrapper *wrapper)
virtual void writeUnsignedByte(int)
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:225
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 CMD_SET_TL_VARIABLE
virtual int readInt()
#define TL_COMPLETE_PROGRAM_RYG
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:382
#define TL_COMPLETE_DEFINITION_RYG
virtual void writeStringList(const std::vector< std::string > &s)
#define TL_EXTERNAL_STATE
tcpip::Storage & getWrapperStorage()
virtual std::string readString()
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:62
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
#define TYPE_DOUBLE
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:59
static void setPhase(const std::string &tlsID, const int index)
std::string subID
Definition: TraCIDefs.h:222
virtual void writeDouble(double)
static void setCompleteRedYellowGreenDefinition(const std::string &tlsID, const TraCILogic &logic)
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
The parent class for traffic light logics.
static void setProgram(const std::string &tlsID, const std::string &programID)
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
void initWrapper(const int domainID, const int variable, const std::string &objID)
#define VAR_PARAMETER
MSTrafficLightLogic * getActive() const
static std::string getParameter(const std::string &tlsID, const std::string &paramName)
#define TYPE_INTEGER
#define TL_PHASE_INDEX
Representation of a lane in the micro simulation.
Definition: MSLane.h:71
static std::vector< std::vector< TraCILink > > getControlledLinks(const std::string &tlsID)