Line data Source code
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 73442 : TraCIServerAPI_TrafficLight::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
40 : tcpip::Storage& outputStorage) {
41 73442 : const int variable = inputStorage.readUnsignedByte();
42 73442 : const std::string id = inputStorage.readString();
43 73442 : server.initWrapper(libsumo::RESPONSE_GET_TL_VARIABLE, variable, id);
44 : try {
45 73442 : if (!libsumo::TrafficLight::handleVariable(id, variable, &server, &inputStorage)) {
46 74 : switch (variable) {
47 69 : case libsumo::TL_CONSTRAINT_SWAP: {
48 69 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
49 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for swapping constraints.", outputStorage);
50 : }
51 : //read itemNo
52 66 : inputStorage.readInt();
53 : std::string tripId;
54 66 : if (!server.readTypeCheckingString(inputStorage, tripId)) {
55 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
56 : }
57 : std::string foeSignal;
58 66 : if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
59 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foeSignal id must be given as a string.", outputStorage);
60 : }
61 : std::string foeId;
62 66 : if (!server.readTypeCheckingString(inputStorage, foeId)) {
63 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
64 : }
65 132 : server.wrapSignalConstraintVector(id, variable, libsumo::TrafficLight::swapConstraints(id, tripId, foeSignal, foeId));
66 : break;
67 : }
68 5 : default:
69 15 : return server.writeErrorStatusCmd(libsumo::CMD_GET_TL_VARIABLE, "Get TLS Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
70 : }
71 : }
72 6 : } catch (libsumo::TraCIException& e) {
73 3 : return server.writeErrorStatusCmd(libsumo::CMD_GET_TL_VARIABLE, e.what(), outputStorage);
74 3 : }
75 73434 : server.writeStatusCmd(libsumo::CMD_GET_TL_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);
76 73431 : server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
77 : return true;
78 : }
79 :
80 :
81 : bool
82 1887 : TraCIServerAPI_TrafficLight::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
83 : tcpip::Storage& outputStorage) {
84 1887 : std::string warning = ""; // additional description for response
85 : // variable
86 1887 : const int variable = inputStorage.readUnsignedByte();
87 1887 : if (variable != libsumo::TL_PHASE_INDEX && variable != libsumo::TL_PROGRAM && variable != libsumo::TL_PHASE_DURATION
88 1887 : && variable != libsumo::TL_RED_YELLOW_GREEN_STATE && variable != libsumo::TL_COMPLETE_PROGRAM_RYG
89 176 : && variable != libsumo::VAR_NAME
90 : && variable != libsumo::TL_CONSTRAINT_REMOVE
91 125 : && variable != libsumo::TL_CONSTRAINT_UPDATE
92 108 : && variable != libsumo::TL_CONSTRAINT_ADD
93 108 : && variable != libsumo::VAR_PARAMETER) {
94 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "Change TLS State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
95 : }
96 1886 : const std::string id = inputStorage.readString();
97 : try {
98 1886 : switch (variable) {
99 : case libsumo::TL_PHASE_INDEX: {
100 1646 : libsumo::TrafficLight::setPhase(id, StoHelp::readTypedInt(inputStorage, "The phase index must be given as an integer."));
101 : }
102 1642 : break;
103 : case libsumo::VAR_NAME: {
104 : std::string name;
105 8 : if (!server.readTypeCheckingString(inputStorage, name)) {
106 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase name must be given as a string.", outputStorage);
107 : }
108 8 : libsumo::TrafficLight::setPhaseName(id, name);
109 : }
110 : break;
111 : case libsumo::TL_PROGRAM: {
112 : std::string subID;
113 20 : if (!server.readTypeCheckingString(inputStorage, subID)) {
114 1 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The program must be given as a string.", outputStorage);
115 : }
116 20 : libsumo::TrafficLight::setProgram(id, subID);
117 : }
118 : break;
119 20 : case libsumo::TL_PHASE_DURATION: {
120 20 : double duration = 0.;
121 20 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
122 2 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase duration must be given as a double.", outputStorage);
123 : }
124 19 : libsumo::TrafficLight::setPhaseDuration(id, duration);
125 : }
126 19 : break;
127 : case libsumo::TL_RED_YELLOW_GREEN_STATE: {
128 : std::string state;
129 25 : if (!server.readTypeCheckingString(inputStorage, state)) {
130 2 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The phase must be given as a string.", outputStorage);
131 : }
132 24 : libsumo::TrafficLight::setRedYellowGreenState(id, state);
133 : }
134 : break;
135 43 : case libsumo::TL_COMPLETE_PROGRAM_RYG: {
136 43 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
137 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for setting a new program.", outputStorage);
138 : }
139 : //read itemNo
140 43 : inputStorage.readInt();
141 : libsumo::TraCILogic logic;
142 43 : if (!server.readTypeCheckingString(inputStorage, logic.programID)) {
143 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 1. parameter (programID) must be a string.", outputStorage);
144 : }
145 43 : logic.type = StoHelp::readTypedInt(inputStorage, "set program: 2. parameter (type) must be an int.");
146 43 : logic.currentPhaseIndex = StoHelp::readTypedInt(inputStorage, "set program: 3. parameter (index) must be an int.");
147 43 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
148 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for the phases.", outputStorage);
149 : }
150 43 : const int numPhases = inputStorage.readInt();
151 211 : for (int j = 0; j < numPhases; ++j) {
152 168 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
153 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for every phase.", outputStorage);
154 : }
155 168 : const int items = inputStorage.readInt();
156 168 : if (items != 6 && items != 5) {
157 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A phase compound object requires 5 or 6 items.", outputStorage);
158 : }
159 168 : double duration = 0., minDuration = 0., maxDuration = 0.;
160 : std::vector<int> next;
161 : std::string name;
162 168 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
163 0 : 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 168 : if (!server.readTypeCheckingString(inputStorage, state)) {
167 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.2. parameter (phase) must be a string.", outputStorage);
168 : }
169 168 : if (!server.readTypeCheckingDouble(inputStorage, minDuration)) {
170 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.3. parameter (min duration) must be a double.", outputStorage);
171 : }
172 168 : if (!server.readTypeCheckingDouble(inputStorage, maxDuration)) {
173 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.4. parameter (max duration) must be a double.", outputStorage);
174 : }
175 168 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
176 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program 4.5 parameter (next) must be a compound (list of ints).", outputStorage);
177 : }
178 168 : const int numNext = inputStorage.readInt();
179 177 : for (int k = 0; k < numNext; k++) {
180 18 : next.push_back(StoHelp::readTypedInt(inputStorage, "set program: 4.5. parameter (next) must be a list of int."));
181 : }
182 168 : if (items == 6) {
183 150 : if (!server.readTypeCheckingString(inputStorage, name)) {
184 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 4.6. parameter (name) must be a string.", outputStorage);
185 : }
186 : }
187 336 : logic.phases.emplace_back(new libsumo::TraCIPhase(duration, state, minDuration, maxDuration, next, name));
188 168 : }
189 43 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
190 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "set program: 5. parameter (subparams) must be a compound object.", outputStorage);
191 : }
192 43 : const int numParams = inputStorage.readInt();
193 43 : for (int j = 0; j < numParams; j++) {
194 : std::vector<std::string> par;
195 0 : server.readTypeCheckingStringList(inputStorage, par);
196 0 : logic.subParameter[par[0]] = par[1];
197 0 : }
198 : libsumo::TrafficLight::setCompleteRedYellowGreenDefinition(id, logic);
199 43 : }
200 : break;
201 15 : case libsumo::TL_CONSTRAINT_REMOVE: {
202 15 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
203 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for removing constraints.", outputStorage);
204 : }
205 : //read itemNo
206 15 : inputStorage.readInt();
207 : std::string tripId;
208 15 : if (!server.readTypeCheckingString(inputStorage, tripId)) {
209 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
210 : }
211 : std::string foeSignal;
212 15 : if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
213 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foeSignal id must be given as a string.", outputStorage);
214 : }
215 : std::string foeId;
216 15 : if (!server.readTypeCheckingString(inputStorage, foeId)) {
217 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
218 : }
219 15 : libsumo::TrafficLight::removeConstraints(id, tripId, foeSignal, foeId);
220 : }
221 : break;
222 : case libsumo::TL_CONSTRAINT_UPDATE: {
223 : std::string tripId;
224 2 : if (!server.readTypeCheckingString(inputStorage, tripId)) {
225 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId index must be given as a string.", outputStorage);
226 : }
227 4 : libsumo::TrafficLight::updateConstraints(id, tripId);
228 : }
229 : break;
230 3 : case libsumo::TL_CONSTRAINT_ADD: {
231 3 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
232 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for adding constraints.", outputStorage);
233 : }
234 : //read itemNo
235 3 : inputStorage.readInt();
236 : std::string tripId;
237 3 : if (!server.readTypeCheckingString(inputStorage, tripId)) {
238 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The tripId must be given as a string.", outputStorage);
239 : }
240 : std::string foeSignal;
241 3 : if (!server.readTypeCheckingString(inputStorage, foeSignal)) {
242 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe signal must be given as a string.", outputStorage);
243 : }
244 : std::string foeId;
245 3 : if (!server.readTypeCheckingString(inputStorage, foeId)) {
246 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The foe tripId must be given as a string.", outputStorage);
247 : }
248 3 : const int type = StoHelp::readTypedInt(inputStorage, "The type must be an int.");
249 3 : const int limit = StoHelp::readTypedInt(inputStorage, "The limit must be an int.");
250 3 : libsumo::TrafficLight::addConstraint(id, tripId, foeSignal, foeId, type, limit);
251 : }
252 : break;
253 104 : case libsumo::VAR_PARAMETER: {
254 104 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
255 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
256 : }
257 : //read itemNo
258 104 : inputStorage.readInt();
259 : std::string name;
260 104 : if (!server.readTypeCheckingString(inputStorage, name)) {
261 4 : 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 104 : if (!server.readTypeCheckingString(inputStorage, value)) {
265 4 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
266 : }
267 104 : libsumo::TrafficLight::setParameter(id, name, value);
268 : }
269 : break;
270 : default:
271 : break;
272 : }
273 10 : } catch (libsumo::TraCIException& e) {
274 10 : return server.writeErrorStatusCmd(libsumo::CMD_SET_TL_VARIABLE, e.what(), outputStorage);
275 10 : }
276 1874 : server.writeStatusCmd(libsumo::CMD_SET_TL_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
277 : return true;
278 : }
279 :
280 :
281 : void
282 0 : TraCIServerAPI_TrafficLight::writeConstraint(TraCIServer& server, const libsumo::TraCISignalConstraint& c) {
283 0 : StoHelp::writeTypedString(server.getWrapperStorage(), c.signalId);
284 0 : StoHelp::writeTypedString(server.getWrapperStorage(), c.tripId);
285 0 : StoHelp::writeTypedString(server.getWrapperStorage(), c.foeId);
286 0 : StoHelp::writeTypedString(server.getWrapperStorage(), c.foeSignal);
287 0 : StoHelp::writeTypedInt(server.getWrapperStorage(), c.limit);
288 0 : StoHelp::writeTypedInt(server.getWrapperStorage(), c.type);
289 0 : StoHelp::writeTypedByte(server.getWrapperStorage(), c.mustWait);
290 0 : StoHelp::writeTypedByte(server.getWrapperStorage(), c.active);
291 : std::vector<std::string> paramItems;
292 0 : for (auto item : c.param) {
293 0 : paramItems.push_back(item.first);
294 0 : paramItems.push_back(item.second);
295 : }
296 0 : StoHelp::writeTypedStringList(server.getWrapperStorage(), paramItems);
297 0 : }
298 :
299 :
300 : /****************************************************************************/
|