Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2017-2024 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 TrafficLight.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Mario Krumnow
17 : /// @author Jakob Erdmann
18 : /// @author Michael Behrisch
19 : /// @date 30.05.2012
20 : ///
21 : // C++ TraCI client API implementation
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #define LIBTRACI 1
26 : #include <libsumo/StorageHelper.h>
27 : #include <libsumo/TraCIConstants.h>
28 : #include <libsumo/TrafficLight.h>
29 : #include "Domain.h"
30 :
31 :
32 : namespace libtraci {
33 :
34 : typedef Domain<libsumo::CMD_GET_TL_VARIABLE, libsumo::CMD_SET_TL_VARIABLE> Dom;
35 :
36 : // ===========================================================================
37 : // static member definitions
38 : // ===========================================================================
39 : std::vector<std::string>
40 82 : TrafficLight::getIDList() {
41 163 : return Dom::getStringVector(libsumo::TRACI_ID_LIST, "");
42 : }
43 :
44 :
45 : int
46 3 : TrafficLight::getIDCount() {
47 6 : return Dom::getInt(libsumo::ID_COUNT, "");
48 : }
49 :
50 :
51 : std::string
52 22 : TrafficLight::getRedYellowGreenState(const std::string& tlsID) {
53 22 : return Dom::getString(libsumo::TL_RED_YELLOW_GREEN_STATE, tlsID);
54 : }
55 :
56 :
57 : std::vector<libsumo::TraCILogic>
58 19 : TrafficLight::getAllProgramLogics(const std::string& tlsID) {
59 19 : std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
60 : tcpip::Storage& ret = Dom::get(libsumo::TL_COMPLETE_DEFINITION_RYG, tlsID);
61 : std::vector<libsumo::TraCILogic> result;
62 19 : int numLogics = ret.readInt();
63 52 : while (numLogics-- > 0) {
64 66 : StoHelp::readCompound(ret, 5);
65 : libsumo::TraCILogic logic;
66 33 : logic.programID = StoHelp::readTypedString(ret);
67 33 : logic.type = StoHelp::readTypedInt(ret);
68 33 : logic.currentPhaseIndex = StoHelp::readTypedInt(ret);
69 33 : int numPhases = StoHelp::readCompound(ret);
70 249 : while (numPhases-- > 0) {
71 216 : StoHelp::readCompound(ret, 6);
72 216 : libsumo::TraCIPhase* phase = new libsumo::TraCIPhase();
73 216 : phase->duration = StoHelp::readTypedDouble(ret);
74 216 : phase->state = StoHelp::readTypedString(ret);
75 216 : phase->minDur = StoHelp::readTypedDouble(ret);
76 216 : phase->maxDur = StoHelp::readTypedDouble(ret);
77 216 : int numNext = StoHelp::readCompound(ret);
78 261 : while (numNext-- > 0) {
79 90 : phase->next.push_back(StoHelp::readTypedInt(ret));
80 : }
81 216 : phase->name = StoHelp::readTypedString(ret);
82 216 : logic.phases.emplace_back(phase);
83 : }
84 33 : int numParams = StoHelp::readCompound(ret);
85 36 : while (numParams-- > 0) {
86 6 : const std::vector<std::string> key_value = StoHelp::readTypedStringList(ret);
87 3 : logic.subParameter[key_value[0]] = key_value[1];
88 3 : }
89 33 : result.emplace_back(logic);
90 33 : }
91 19 : return result;
92 0 : }
93 :
94 :
95 : std::vector<std::string>
96 1 : TrafficLight::getControlledJunctions(const std::string& tlsID) {
97 1 : return Dom::getStringVector(libsumo::TL_CONTROLLED_JUNCTIONS, tlsID);
98 : }
99 :
100 :
101 : std::vector<std::string>
102 9 : TrafficLight::getControlledLanes(const std::string& tlsID) {
103 9 : return Dom::getStringVector(libsumo::TL_CONTROLLED_LANES, tlsID);
104 : }
105 :
106 :
107 : std::vector<std::vector<libsumo::TraCILink> >
108 9 : TrafficLight::getControlledLinks(const std::string& tlsID) {
109 9 : std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
110 : tcpip::Storage& ret = Dom::get(libsumo::TL_CONTROLLED_LINKS, tlsID);
111 : std::vector< std::vector<libsumo::TraCILink> > result;
112 9 : ret.readInt();
113 9 : int numSignals = StoHelp::readTypedInt(ret);
114 161 : while (numSignals-- > 0) {
115 : std::vector<libsumo::TraCILink> controlledLinks;
116 152 : int numLinks = StoHelp::readTypedInt(ret);
117 304 : while (numLinks-- > 0) {
118 304 : std::vector<std::string> link = StoHelp::readTypedStringList(ret);
119 152 : controlledLinks.emplace_back(link[0], link[2], link[1]);
120 152 : }
121 152 : result.emplace_back(controlledLinks);
122 152 : }
123 9 : return result;
124 0 : }
125 :
126 :
127 : std::string
128 194 : TrafficLight::getProgram(const std::string& tlsID) {
129 194 : return Dom::getString(libsumo::TL_CURRENT_PROGRAM, tlsID);
130 : }
131 :
132 :
133 : int
134 18141 : TrafficLight::getPhase(const std::string& tlsID) {
135 18141 : return Dom::getInt(libsumo::TL_CURRENT_PHASE, tlsID);
136 : }
137 :
138 :
139 : std::string
140 13778 : TrafficLight::getPhaseName(const std::string& tlsID) {
141 13778 : return Dom::getString(libsumo::VAR_NAME, tlsID);
142 : }
143 :
144 :
145 : double
146 10 : TrafficLight::getPhaseDuration(const std::string& tlsID) {
147 10 : return Dom::getDouble(libsumo::TL_PHASE_DURATION, tlsID);
148 : }
149 :
150 :
151 : double
152 233 : TrafficLight::getNextSwitch(const std::string& tlsID) {
153 233 : return Dom::getDouble(libsumo::TL_NEXT_SWITCH, tlsID);
154 : }
155 :
156 :
157 : double
158 185 : TrafficLight::getSpentDuration(const std::string& tlsID) {
159 185 : return Dom::getDouble(libsumo::TL_SPENT_DURATION, tlsID);
160 : }
161 :
162 :
163 : int
164 802 : TrafficLight::getServedPersonCount(const std::string& tlsID, int index) {
165 802 : tcpip::Storage content;
166 802 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
167 802 : content.writeInt(index);
168 1604 : return Dom::getInt(libsumo::VAR_PERSON_NUMBER, tlsID, &content);
169 802 : }
170 :
171 : std::vector<std::string>
172 1600 : TrafficLight::getBlockingVehicles(const std::string& tlsID, int linkIndex) {
173 1600 : tcpip::Storage content;
174 1600 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
175 1600 : content.writeInt(linkIndex);
176 3200 : return Dom::getStringVector(libsumo::TL_BLOCKING_VEHICLES, tlsID, &content);
177 1600 : }
178 :
179 : std::vector<std::string>
180 1598 : TrafficLight::getRivalVehicles(const std::string& tlsID, int linkIndex) {
181 1598 : tcpip::Storage content;
182 1598 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
183 1598 : content.writeInt(linkIndex);
184 3196 : return Dom::getStringVector(libsumo::TL_RIVAL_VEHICLES, tlsID, &content);
185 1598 : }
186 :
187 : std::vector<std::string>
188 1598 : TrafficLight::getPriorityVehicles(const std::string& tlsID, int linkIndex) {
189 1598 : tcpip::Storage content;
190 1598 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
191 1598 : content.writeInt(linkIndex);
192 3196 : return Dom::getStringVector(libsumo::TL_PRIORITY_VEHICLES, tlsID, &content);
193 1598 : }
194 :
195 : std::vector<libsumo::TraCISignalConstraint>
196 247 : TrafficLight::getConstraints(const std::string& tlsID, const std::string& tripId) {
197 : std::vector<libsumo::TraCISignalConstraint> result;
198 247 : tcpip::Storage content;
199 : StoHelp::writeTypedString(content, tripId);
200 247 : std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
201 : tcpip::Storage& ret = Dom::get(libsumo::TL_CONSTRAINT, tlsID, &content);
202 247 : ret.readInt(); // components
203 : // number of items
204 247 : ret.readUnsignedByte();
205 247 : const int n = ret.readInt();
206 444 : for (int i = 0; i < n; ++i) {
207 : libsumo::TraCISignalConstraint c;
208 197 : c.signalId = StoHelp::readTypedString(ret);
209 197 : c.tripId = StoHelp::readTypedString(ret);
210 197 : c.foeId = StoHelp::readTypedString(ret);
211 197 : c.foeSignal = StoHelp::readTypedString(ret);
212 197 : c.limit = StoHelp::readTypedInt(ret);
213 197 : c.type = StoHelp::readTypedInt(ret);
214 197 : c.mustWait = StoHelp::readTypedByte(ret) != 0;
215 197 : c.active = StoHelp::readTypedByte(ret) != 0;
216 197 : const std::vector<std::string> paramItems = StoHelp::readTypedStringList(ret);
217 289 : for (int j = 0; j < (int)paramItems.size(); j += 2) {
218 92 : c.param[paramItems[j]] = paramItems[j + 1];
219 : }
220 197 : result.push_back(c);
221 197 : }
222 247 : return result;
223 247 : }
224 :
225 : std::vector<libsumo::TraCISignalConstraint>
226 2 : TrafficLight::getConstraintsByFoe(const std::string& foeSignal, const std::string& foeId) {
227 : std::vector<libsumo::TraCISignalConstraint> result;
228 2 : tcpip::Storage content;
229 : StoHelp::writeTypedString(content, foeId);
230 2 : std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
231 : tcpip::Storage& ret = Dom::get(libsumo::TL_CONSTRAINT_BYFOE, foeSignal, &content);
232 2 : ret.readInt(); // components
233 : // number of items
234 2 : ret.readUnsignedByte();
235 2 : const int n = ret.readInt();
236 9 : for (int i = 0; i < n; ++i) {
237 : libsumo::TraCISignalConstraint c;
238 7 : c.signalId = StoHelp::readTypedString(ret);
239 7 : c.tripId = StoHelp::readTypedString(ret);
240 7 : c.foeId = StoHelp::readTypedString(ret);
241 7 : c.foeSignal = StoHelp::readTypedString(ret);
242 7 : c.limit = StoHelp::readTypedInt(ret);
243 7 : c.type = StoHelp::readTypedInt(ret);
244 7 : c.mustWait = StoHelp::readTypedByte(ret) != 0;
245 7 : c.active = StoHelp::readTypedByte(ret) != 0;
246 7 : const std::vector<std::string> paramItems = StoHelp::readTypedStringList(ret);
247 11 : for (int j = 0; j < (int)paramItems.size(); j += 2) {
248 4 : c.param[paramItems[j]] = paramItems[j + 1];
249 : }
250 7 : result.push_back(c);
251 7 : }
252 2 : return result;
253 2 : }
254 :
255 1080 : LIBTRACI_PARAMETER_IMPLEMENTATION(TrafficLight, TL)
256 :
257 : void
258 8 : TrafficLight::setRedYellowGreenState(const std::string& tlsID, const std::string& state) {
259 8 : Dom::setString(libsumo::TL_RED_YELLOW_GREEN_STATE, tlsID, state);
260 8 : }
261 :
262 :
263 : void
264 9 : TrafficLight::setPhase(const std::string& tlsID, const int index) {
265 9 : Dom::setInt(libsumo::TL_PHASE_INDEX, tlsID, index);
266 9 : }
267 :
268 :
269 : void
270 3 : TrafficLight::setPhaseName(const std::string& tlsID, const std::string& name) {
271 3 : Dom::setString(libsumo::VAR_NAME, tlsID, name);
272 3 : }
273 :
274 :
275 : void
276 5 : TrafficLight::setProgram(const std::string& tlsID, const std::string& programID) {
277 5 : Dom::setString(libsumo::TL_PROGRAM, tlsID, programID);
278 5 : }
279 :
280 :
281 : void
282 7 : TrafficLight::setPhaseDuration(const std::string& tlsID, const double phaseDuration) {
283 7 : Dom::setDouble(libsumo::TL_PHASE_DURATION, tlsID, phaseDuration);
284 7 : }
285 :
286 :
287 : void
288 12 : TrafficLight::setProgramLogic(const std::string& tlsID, const libsumo::TraCILogic& logic) {
289 12 : tcpip::Storage content;
290 : StoHelp::writeCompound(content, 5);
291 12 : StoHelp::writeTypedString(content, logic.programID);
292 12 : StoHelp::writeTypedInt(content, logic.type);
293 12 : StoHelp::writeTypedInt(content, logic.currentPhaseIndex);
294 12 : StoHelp::writeCompound(content, (int)logic.phases.size());
295 66 : for (const std::shared_ptr<libsumo::TraCIPhase>& phase : logic.phases) {
296 : StoHelp::writeCompound(content, 6);
297 54 : StoHelp::writeTypedDouble(content, phase->duration);
298 54 : StoHelp::writeTypedString(content, phase->state);
299 54 : StoHelp::writeTypedDouble(content, phase->minDur);
300 54 : StoHelp::writeTypedDouble(content, phase->maxDur);
301 54 : StoHelp::writeCompound(content, (int)phase->next.size());
302 57 : for (int n : phase->next) {
303 : StoHelp::writeTypedInt(content, n);
304 : }
305 54 : StoHelp::writeTypedString(content, phase->name);
306 : }
307 12 : StoHelp::writeCompound(content, (int)logic.subParameter.size());
308 12 : for (const auto& key_value : logic.subParameter) {
309 0 : StoHelp::writeTypedStringList(content, std::vector<std::string> {key_value.first, key_value.second});
310 : }
311 12 : Dom::set(libsumo::TL_COMPLETE_PROGRAM_RYG, tlsID, &content);
312 12 : }
313 :
314 :
315 : void
316 1 : TrafficLight::addConstraint(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId, const int type, const int limit) {
317 1 : tcpip::Storage content;
318 : StoHelp::writeCompound(content, 5);
319 : StoHelp::writeTypedString(content, tripId);
320 : StoHelp::writeTypedString(content, foeSignal);
321 : StoHelp::writeTypedString(content, foeId);
322 : StoHelp::writeTypedInt(content, type);
323 : StoHelp::writeTypedInt(content, limit);
324 1 : Dom::set(libsumo::TL_CONSTRAINT_ADD, tlsID, &content);
325 1 : }
326 :
327 :
328 : std::vector<libsumo::TraCISignalConstraint>
329 22 : TrafficLight::swapConstraints(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId) {
330 : std::vector<libsumo::TraCISignalConstraint> result;
331 22 : tcpip::Storage content;
332 : StoHelp::writeCompound(content, 3);
333 : StoHelp::writeTypedString(content, tripId);
334 : StoHelp::writeTypedString(content, foeSignal);
335 : StoHelp::writeTypedString(content, foeId);
336 22 : std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
337 : tcpip::Storage& ret = Dom::get(libsumo::TL_CONSTRAINT_SWAP, tlsID, &content);
338 22 : ret.readInt(); // components
339 : // number of items
340 22 : ret.readUnsignedByte();
341 22 : const int n = ret.readInt();
342 42 : for (int i = 0; i < n; ++i) {
343 : libsumo::TraCISignalConstraint c;
344 20 : c.signalId = StoHelp::readTypedString(ret);
345 20 : c.tripId = StoHelp::readTypedString(ret);
346 20 : c.foeId = StoHelp::readTypedString(ret);
347 20 : c.foeSignal = StoHelp::readTypedString(ret);
348 20 : c.limit = StoHelp::readTypedInt(ret);
349 20 : c.type = StoHelp::readTypedInt(ret);
350 20 : c.mustWait = StoHelp::readTypedByte(ret) != 0;
351 20 : c.active = StoHelp::readTypedByte(ret) != 0;
352 20 : const std::vector<std::string> paramItems = StoHelp::readTypedStringList(ret);
353 36 : for (int j = 0; j < (int)paramItems.size(); j += 2) {
354 16 : c.param[paramItems[j]] = paramItems[j + 1];
355 : }
356 20 : result.push_back(c);
357 20 : }
358 22 : return result;
359 22 : }
360 :
361 :
362 : void
363 5 : TrafficLight::removeConstraints(const std::string& tlsID, const std::string& tripId, const std::string& foeSignal, const std::string& foeId) {
364 5 : tcpip::Storage content;
365 : StoHelp::writeCompound(content, 3);
366 : StoHelp::writeTypedString(content, tripId);
367 : StoHelp::writeTypedString(content, foeSignal);
368 : StoHelp::writeTypedString(content, foeId);
369 5 : Dom::set(libsumo::TL_CONSTRAINT_REMOVE, tlsID, &content);
370 5 : }
371 :
372 : void
373 1 : TrafficLight::updateConstraints(const std::string& vehID, std::string tripId) {
374 1 : Dom::setString(libsumo::TL_CONSTRAINT_UPDATE, vehID, tripId);
375 1 : }
376 :
377 : std::string
378 1 : to_string(const std::vector<double>& value) {
379 1 : std::ostringstream tmp;
380 9 : for (double d : value) {
381 8 : tmp << d << " ";
382 : }
383 : std::string tmp2 = tmp.str();
384 : tmp2.pop_back();
385 1 : return tmp2;
386 1 : }
387 :
388 :
389 : void
390 0 : TrafficLight::setNemaSplits(const std::string& tlsID, const std::vector<double>& splits) {
391 0 : setParameter(tlsID, "NEMA.splits", to_string(splits));
392 0 : }
393 :
394 : void
395 1 : TrafficLight::setNemaMaxGreens(const std::string& tlsID, const std::vector<double>& maxGreens) {
396 2 : setParameter(tlsID, "NEMA.maxGreens", to_string(maxGreens));
397 1 : }
398 :
399 : void
400 0 : TrafficLight::setNemaCycleLength(const std::string& tlsID, double cycleLength) {
401 0 : setParameter(tlsID, "NEMA.cycleLength", std::to_string(cycleLength));
402 0 : }
403 :
404 : void
405 0 : TrafficLight::setNemaOffset(const std::string& tlsID, double offset) {
406 0 : setParameter(tlsID, "NEMA.offset", std::to_string(offset));
407 0 : }
408 :
409 :
410 136 : LIBTRACI_SUBSCRIPTION_IMPLEMENTATION(TrafficLight, TL)
411 :
412 : }
413 :
414 :
415 : /****************************************************************************/
|