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