/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2011-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 NBLoadedSUMOTLDef.h14/// @author Jakob Erdmann15/// @author Michael Behrisch16/// @date Mar 201117///18// A complete traffic light logic loaded from a sumo-net. (opted to reimplement19// since NBLoadedTLDef is quite vissim specific)20/****************************************************************************/21#pragma once22#include <config.h>2324#include <vector>25#include <string>26#include <set>27#include "NBNode.h"28#include "NBEdgeCont.h"29#include "NBTrafficLightDefinition.h"30#include "NBTrafficLightLogic.h"31#include <utils/common/SUMOTime.h>323334// ===========================================================================35// class definitions36// ===========================================================================37/**38* @class NBLoadedSUMOTLDef39* @brief A loaded (complete) traffic light logic40*/41class NBLoadedSUMOTLDef : public NBTrafficLightDefinition {42public:4344/** @brief Constructor45* @param[in] id The id of the tls46* @param[in] programID The programID for the computed logic47* @param[in] offset The offset for the computed logic48* @param[in] type The algorithm type for the computed logic49*/50NBLoadedSUMOTLDef(const std::string& id, const std::string& programID, SUMOTime offset, TrafficLightType type);5152/** @brief Constructor that copies from an existing definition and its computed logic (used by netedit)53* @param[in] def The definition to copy54* @param[in] logic The computed logic of the given def55*/56NBLoadedSUMOTLDef(const NBTrafficLightDefinition& def, const NBTrafficLightLogic& logic);575859/// @brief Destructor60~NBLoadedSUMOTLDef();6162void setID(const std::string& newID);6364/** @brief Sets the programID65* @param[in] programID The new ID of the program (subID)66*/67void setProgramID(const std::string& programID);6869/** @brief Informs edges about being controlled by a tls70*/71void setTLControllingInformation() const;7273/** @brief Replaces occurrences of the removed edge in incoming/outgoing edges of all definitions74* @param[in] removed The removed edge75* @param[in] incoming The edges to use instead if an incoming edge was removed76* @param[in] outgoing The edges to use instead if an outgoing edge was removed77*/78void remapRemoved(NBEdge* removed,79const EdgeVector& incoming, const EdgeVector& outgoing);808182/** @brief Replaces a removed edge/lane83* @param[in] removed The edge to replace84* @param[in] removedLane The lane of this edge to replace85* @param[in] by The edge to insert instead86* @param[in] byLane This edge's lane to insert instead87*/88void replaceRemoved(NBEdge* removed, int removedLane,89NBEdge* by, int byLane, bool incoming);9091/** @brief patches signal plans by modifying lane indices92* with the given offset, only indices with a value above threshold are modified93*/94void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1);9596/** @brief Adds a phase to the logic97* the new phase is inserted at the end of the list of already added phases98* @param[in] duration The duration of the phase to add99* @param[in] state The state definition of a tls phase100* @param[in] minDur The minimum duration of the phase to add101* @param[in] maxDur The maximum duration of the phase to add102* @param[in] vehExt The vehExt of the phase to add103* @param[in] yellow The yellow of the phase to add104* @param[in] red The red of the phase to add105* @param[in] earliestEnd The early end of the phase to add106* @param[in] latestEnd The latest end of the phase to add107*/108void addPhase(const SUMOTime duration, const std::string& state, const SUMOTime minDur, const SUMOTime maxDur,109const SUMOTime earliestEnd, const SUMOTime latestEnd, const SUMOTime vehExt, const SUMOTime yellow,110const SUMOTime red, const std::vector<int>& next, const std::string& name);111112/// @brief mark phases as load113void phasesLoaded() {114myPhasesLoaded = true;115}116117/** @brief Adds a connection and immediately informs the edges118*/119void addConnection(NBEdge* from, NBEdge* to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct = true);120121122/** @brief removes the given connection from the traffic light123* if recontruct=true, reconstructs the logic and informs the edges for immediate use in netedit124* @note: tlIndex is not necessarily unique. we need the whole connection data here125*/126void removeConnection(const NBConnection& conn, bool reconstruct = true);127128/// @brief register changes that necessitate recomputation129void registerModifications(bool addedConnections, bool removedConnections);130131/** @brief Returns the internal logic132*/133NBTrafficLightLogic* getLogic() {134return myTLLogic;135}136137/** @brief Sets the offset of this tls138* @param[in] offset The offset of this cycle139*/140void setOffset(SUMOTime offset);141142/** @brief Sets the algorithm type of this tls143* @param[in] offset The algorithm type of this tls144*/145void setType(TrafficLightType type);146147/// @brief whether the given index must yield to the foeIndex while turing right on a red light148bool extraConflict(int index, int foeIndex) const;149150/* @brief shortens phase states to remove states that are not referenced by151* any controlled link and returns whether states were shortened152*/153bool cleanupStates();154155/// @brief whether this definition uses signal group (multiple connections with the same link index)156bool usingSignalGroups() const;157158/// @brief join nodes and states from the given logic (append red state)159void joinLogic(NBTrafficLightDefinition* def);160161/// @brief heuristically add minDur and maxDur when switching from tlType fixed to actuated162void guessMinMaxDuration();163164/// @brief let connections with the same state use the same link index165void groupSignals();166167/// @brief let all connections use a distinct link index168void ungroupSignals();169170/// @brief copy the assignment of link indices to connections from the given definition and rebuilt the states to match171// Note: Issues a warning when the grouping of def is incompatible with the current states172void copyIndices(NBTrafficLightDefinition* def);173174/// @brief perform optional final checks (on writing)175void finalChecks() const;176177/// @brief replace the given link index in all connections178void replaceIndex(int oldIndex, int newIndex);179180protected:181/// @brief Collects the links participating in this traffic light (only if not previously loaded)182void collectLinks();183184/// @brief Build the list of participating edges185void collectEdges();186187/** @brief Computes the traffic light logic finally in dependence to the type188* @param[in] brakingTime Duration a vehicle needs for braking in front of the tls in seconds189* @return The computed logic190*/191NBTrafficLightLogic* myCompute(int brakingTimeSeconds);192193bool amInvalid() const;194195/// @brief initialize myNeedsContRelation and set myNeedsContRelationReady to true196void initNeedsContRelation() const;197198/// @brief return the highest known tls link index used by any controlled connection or crossing199int getMaxIndex();200201///@brief Returns the maximum index controlled by this traffic light202int getMaxValidIndex();203204/// @brief get all states for the given link index205std::string getStates(int index);206207/// @brief return whether the given link index is used by any connectons208bool isUsed(int index) const;209210/// brief retrieve all edges with connections that use the given traffic light index211std::set<const NBEdge*> getEdgesUsingIndex(int index) const;212213private:214215/// @brief phases are added directly to myTLLogic which is then returned in myCompute()216NBTrafficLightLogic* myTLLogic;217218/// @brief repair the plan if controlled nodes received pedestrian crossings219void patchIfCrossingsAdded();220221/// @brief set of edges with shifted lane indices (to avoid shifting twice)222std::set<NBEdge*> myShifted;223224/// @brief whether the logic must be reconstructed225bool myReconstructAddedConnections;226bool myReconstructRemovedConnections;227bool myPhasesLoaded;228229/** @brief Collects the edges for each tlIndex230* @param[out] fromEdges The from-edge for each controlled tlIndex231* @param[out] toEdges The to-edge for each controlled tlIndex232* @param[out] fromLanes The from-lanes for each controlled tlIndex233*/234void collectEdgeVectors(EdgeVector& fromEdges, EdgeVector& toEdges, std::vector<int>& fromLanes) const;235236/// @brief adapt to removal or addition of connections237void reconstructLogic();238239/// @brief return whether all tls link indices are valid240bool hasValidIndices() const;241242/// @brief return whether the given connection is still valid243bool isValid(const NBConnection& con) const;244245private:246/// @brief class for identifying connections247class connection_equal {248public:249/// constructor250connection_equal(const NBConnection& c) : myC(c) {}251252bool operator()(const NBConnection& c) const {253return c.getFrom() == myC.getFrom() && c.getTo() == myC.getTo() &&254c.getFromLane() == myC.getFromLane() && c.getToLane() == myC.getToLane();255}256private:257const NBConnection& myC;258};259260};261262263