Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/traci-server/TraCIServerAPI_TrafficLight.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2009-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file TraCIServerAPI_TrafficLight.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Laura Bieker
17
/// @author Michael Behrisch
18
/// @author Jakob Erdmann
19
/// @date 07.05.2009
20
///
21
// APIs for getting/setting traffic light values via TraCI
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <microsim/MSLane.h>
26
#include <microsim/MSEdge.h>
27
#include <microsim/traffic_lights/MSTLLogicControl.h>
28
#include <microsim/traffic_lights/MSSimpleTrafficLightLogic.h>
29
#include <libsumo/TraCIConstants.h>
30
#include <libsumo/StorageHelper.h>
31
#include <libsumo/TrafficLight.h>
32
#include "TraCIServerAPI_TrafficLight.h"
33
34
35
// ===========================================================================
36
// method definitions
37
// ===========================================================================
38
bool
39
TraCIServerAPI_TrafficLight::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
40
tcpip::Storage& outputStorage) {
41
const int variable = inputStorage.readUnsignedByte();
42
const std::string id = inputStorage.readString();
43
server.initWrapper(libsumo::RESPONSE_GET_TL_VARIABLE, variable, id);
44
try {
45
if (!libsumo::TrafficLight::handleVariable(id, variable, &server, &inputStorage)) {
46
switch (variable) {
47
case libsumo::TL_CONSTRAINT_SWAP: {
48
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
49
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for swapping constraints.", outputStorage);
50
}
51
//read itemNo
52
inputStorage.readInt();
53
std::string tripId;
54
if (!server.readTypeCheckingString(inputStorage, tripId)) {
55
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
56
}
57
std::string foeSignal;
58
if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
59
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foeSignal id must be given as a string.", outputStorage);
60
}
61
std::string foeId;
62
if (!server.readTypeCheckingString(inputStorage, foeId)) {
63
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
64
}
65
server.wrapSignalConstraintVector(id, variable, libsumo::TrafficLight::swapConstraints(id, tripId, foeSignal, foeId));
66
break;
67
}
68
default:
69
return server.writeErrorStatusCmd(libsumo::CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
70
}
71
}
72
} catch (libsumo::TraCIException& e) {
73
return server.writeErrorStatusCmd(libsumo::CMD_GET_TL_VARIABLE, e.what(), outputStorage);
74
}
75
server.writeStatusCmd(libsumo::CMD_GET_TL_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);
76
server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
77
return true;
78
}
79
80
81
bool
82
TraCIServerAPI_TrafficLight::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
83
tcpip::Storage& outputStorage) {
84
std::string warning = ""; // additional description for response
85
// variable
86
const int variable = inputStorage.readUnsignedByte();
87
if (variable != libsumo::TL_PHASE_INDEX && variable != libsumo::TL_PROGRAM && variable != libsumo::TL_PHASE_DURATION
88
&& variable != libsumo::TL_RED_YELLOW_GREEN_STATE && variable != libsumo::TL_COMPLETE_PROGRAM_RYG
89
&& variable != libsumo::VAR_NAME
90
&& variable != libsumo::TL_CONSTRAINT_REMOVE
91
&& variable != libsumo::TL_CONSTRAINT_UPDATE
92
&& variable != libsumo::TL_CONSTRAINT_ADD
93
&& variable != libsumo::VAR_PARAMETER) {
94
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
95
}
96
const std::string id = inputStorage.readString();
97
try {
98
switch (variable) {
99
case libsumo::TL_PHASE_INDEX: {
100
libsumo::TrafficLight::setPhase(id, StoHelp::readTypedInt(inputStorage, "The phase index must be given as an integer."));
101
}
102
break;
103
case libsumo::VAR_NAME: {
104
std::string name;
105
if (!server.readTypeCheckingString(inputStorage, name)) {
106
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase name must be given as a string.", outputStorage);
107
}
108
libsumo::TrafficLight::setPhaseName(id, name);
109
}
110
break;
111
case libsumo::TL_PROGRAM: {
112
std::string subID;
113
if (!server.readTypeCheckingString(inputStorage, subID)) {
114
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
115
}
116
libsumo::TrafficLight::setProgram(id, subID);
117
}
118
break;
119
case libsumo::TL_PHASE_DURATION: {
120
double duration = 0.;
121
if (!server.readTypeCheckingDouble(inputStorage, duration)) {
122
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase duration must be given as a double.", outputStorage);
123
}
124
libsumo::TrafficLight::setPhaseDuration(id, duration);
125
}
126
break;
127
case libsumo::TL_RED_YELLOW_GREEN_STATE: {
128
std::string state;
129
if (!server.readTypeCheckingString(inputStorage, state)) {
130
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
131
}
132
libsumo::TrafficLight::setRedYellowGreenState(id, state);
133
}
134
break;
135
case libsumo::TL_COMPLETE_PROGRAM_RYG: {
136
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
137
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
138
}
139
//read itemNo
140
inputStorage.readInt();
141
libsumo::TraCILogic logic;
142
if (!server.readTypeCheckingString(inputStorage, logic.programID)) {
143
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 1. parameter (programID) must be a string.", outputStorage);
144
}
145
logic.type = StoHelp::readTypedInt(inputStorage, "set program: 2. parameter (type) must be an int.");
146
logic.currentPhaseIndex = StoHelp::readTypedInt(inputStorage, "set program: 3. parameter (index) must be an int.");
147
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
148
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for the phases.", outputStorage);
149
}
150
const int numPhases = inputStorage.readInt();
151
for (int j = 0; j < numPhases; ++j) {
152
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
153
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for every phase.", outputStorage);
154
}
155
const int items = inputStorage.readInt();
156
if (items != 6 && items != 5) {
157
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A phase compound object requires 5 or 6 items.", outputStorage);
158
}
159
double duration = 0., minDuration = 0., maxDuration = 0.;
160
std::vector<int> next;
161
std::string name;
162
if (!server.readTypeCheckingDouble(inputStorage, duration)) {
163
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.1. parameter (duration) must be a double.", outputStorage);
164
}
165
std::string state;
166
if (!server.readTypeCheckingString(inputStorage, state)) {
167
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.2. parameter (phase) must be a string.", outputStorage);
168
}
169
if (!server.readTypeCheckingDouble(inputStorage, minDuration)) {
170
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.3. parameter (min duration) must be a double.", outputStorage);
171
}
172
if (!server.readTypeCheckingDouble(inputStorage, maxDuration)) {
173
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.4. parameter (max duration) must be a double.", outputStorage);
174
}
175
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
176
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program 4.5 parameter (next) must be a compound (list of ints).", outputStorage);
177
}
178
const int numNext = inputStorage.readInt();
179
for (int k = 0; k < numNext; k++) {
180
next.push_back(StoHelp::readTypedInt(inputStorage, "set program: 4.5. parameter (next) must be a list of int."));
181
}
182
if (items == 6) {
183
if (!server.readTypeCheckingString(inputStorage, name)) {
184
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.6. parameter (name) must be a string.", outputStorage);
185
}
186
}
187
logic.phases.emplace_back(new libsumo::TraCIPhase(duration, state, minDuration, maxDuration, next, name));
188
}
189
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
190
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 5. parameter (subparams) must be a compound object.", outputStorage);
191
}
192
const int numParams = inputStorage.readInt();
193
for (int j = 0; j < numParams; j++) {
194
std::vector<std::string> par;
195
server.readTypeCheckingStringList(inputStorage, par);
196
logic.subParameter[par[0]] = par[1];
197
}
198
libsumo::TrafficLight::setCompleteRedYellowGreenDefinition(id, logic);
199
}
200
break;
201
case libsumo::TL_CONSTRAINT_REMOVE: {
202
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
203
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for removing constraints.", outputStorage);
204
}
205
//read itemNo
206
inputStorage.readInt();
207
std::string tripId;
208
if (!server.readTypeCheckingString(inputStorage, tripId)) {
209
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
210
}
211
std::string foeSignal;
212
if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
213
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foeSignal id must be given as a string.", outputStorage);
214
}
215
std::string foeId;
216
if (!server.readTypeCheckingString(inputStorage, foeId)) {
217
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
218
}
219
libsumo::TrafficLight::removeConstraints(id, tripId, foeSignal, foeId);
220
}
221
break;
222
case libsumo::TL_CONSTRAINT_UPDATE: {
223
std::string tripId;
224
if (!server.readTypeCheckingString(inputStorage, tripId)) {
225
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId index must be given as a string.", outputStorage);
226
}
227
libsumo::TrafficLight::updateConstraints(id, tripId);
228
}
229
break;
230
case libsumo::TL_CONSTRAINT_ADD: {
231
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
232
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for adding constraints.", outputStorage);
233
}
234
//read itemNo
235
inputStorage.readInt();
236
std::string tripId;
237
if (!server.readTypeCheckingString(inputStorage, tripId)) {
238
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
239
}
240
std::string foeSignal;
241
if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
242
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe signal must be given as a string.", outputStorage);
243
}
244
std::string foeId;
245
if (!server.readTypeCheckingString(inputStorage, foeId)) {
246
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
247
}
248
const int type = StoHelp::readTypedInt(inputStorage, "The type must be an int.");
249
const int limit = StoHelp::readTypedInt(inputStorage, "The limit must be an int.");
250
libsumo::TrafficLight::addConstraint(id, tripId, foeSignal, foeId, type, limit);
251
}
252
break;
253
case libsumo::VAR_PARAMETER: {
254
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
255
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
256
}
257
//read itemNo
258
inputStorage.readInt();
259
std::string name;
260
if (!server.readTypeCheckingString(inputStorage, name)) {
261
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
262
}
263
std::string value;
264
if (!server.readTypeCheckingString(inputStorage, value)) {
265
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
266
}
267
libsumo::TrafficLight::setParameter(id, name, value);
268
}
269
break;
270
default:
271
break;
272
}
273
} catch (libsumo::TraCIException& e) {
274
return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, e.what(), outputStorage);
275
}
276
server.writeStatusCmd(libsumo::CMD_SET_TL_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
277
return true;
278
}
279
280
281
void
282
TraCIServerAPI_TrafficLight::writeConstraint(TraCIServer& server, const libsumo::TraCISignalConstraint& c) {
283
StoHelp::writeTypedString(server.getWrapperStorage(), c.signalId);
284
StoHelp::writeTypedString(server.getWrapperStorage(), c.tripId);
285
StoHelp::writeTypedString(server.getWrapperStorage(), c.foeId);
286
StoHelp::writeTypedString(server.getWrapperStorage(), c.foeSignal);
287
StoHelp::writeTypedInt(server.getWrapperStorage(), c.limit);
288
StoHelp::writeTypedInt(server.getWrapperStorage(), c.type);
289
StoHelp::writeTypedByte(server.getWrapperStorage(), c.mustWait);
290
StoHelp::writeTypedByte(server.getWrapperStorage(), c.active);
291
std::vector<std::string> paramItems;
292
for (auto item : c.param) {
293
paramItems.push_back(item.first);
294
paramItems.push_back(item.second);
295
}
296
StoHelp::writeTypedStringList(server.getWrapperStorage(), paramItems);
297
}
298
299
300
/****************************************************************************/
301
302