Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NEMAController.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-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/****************************************************************************/
19// An actuated NEMA-phase-compliant traffic light logic
20/****************************************************************************/
21#pragma once
22#include <config.h>
23
24#include <utility>
25#include <vector>
26#include <bitset>
27#include <map>
28#include <set>
33#include "MSPhaseDefinition.h"
34
35
36// ===========================================================================
37// class declarations
38// ===========================================================================
40class MSE2Collector;
41class NEMAPhase;
43
44// ===========================================================================
45// Enumeration
46// ===========================================================================
47enum class LightState {
48 RedXfer,
49 Red,
50 Yellow,
51 Green,
54};
55
56
57// ===========================================================================
58// class definitions
59// ===========================================================================
65public:
66
68
69 typedef std::map<MSLane*, MSE2Collector*> LaneDetectorMap;
70
71 typedef std::map<MSE2Collector*, MSLane*, ComparatorIdLess> DetectorLaneMap;
72
73 // Small structure for storing two ring transitions and the average distance
79
84
86 const std::string lightHeadPriority = "GgyuOs";
87
88 typedef std::vector<transitionInfo> TransitionPairs;
89
99 NEMALogic(MSTLLogicControl& tlcontrol,
100 const std::string& id, const std::string& programID,
101 const SUMOTime offset,
103 int step, SUMOTime delay,
104 const std::map<std::string, std::string>& parameter,
105 const std::string& basePath);
106
107
112 void init(NLDetectorBuilder& nb) override;
113
115 ~NEMALogic();
116
118 SUMOTime trySwitch() override;
119
122
126 const MSPhaseDefinition& getCurrentPhaseDef() const override;
128
129
130 void activateProgram() override;
131 void deactivateProgram() override;
132
133 bool showDetectors() const {
134 return myShowDetectors;
135 }
136
137 void setShowDetectors(bool show);
138
140 std::map<std::string, double> getDetectorStates() const override;
141
147 void getNextPhases(TransitionPairs& transitions);
148
158
159
167 void getLaneInfoFromNEMAState(std::string state, StringVector& laneIDs, IntVector& stateIndex);
168
174 void setNewMaxGreens(std::vector<double> newMaxGreens);
175
181 void setNewSplits(std::vector<double> newSplits);
182
188 void setNewCycleLength(double newCycleLength);
189
195 void setNewOffset(double newOffset);
196
205
207 void setParameter(const std::string& key, const std::string& value) override;
208
210 const std::string getParameter(const std::string& key, const std::string defaultValue = "") const override;
211
213 inline SUMOTime getCurrentTime(void) const {
214 return simTime;
215 }
216
217 // /// @brief Wrapper Function to Simplify Accessing Offset Cycle Time
218 // inline SUMOTime getCurrentOffsetTime(void) const {return simTime - cycleRefPoint - offset; };
219
221 inline SUMOTime getTimeInCycle() const {
223 }
224
225
227 void setActivePhase(PhasePtr phase);
228
235 inline PhasePtr getActivePhase(int ringNum) {
236 return myActivePhaseObjs[ringNum];
237 }
238
245 std::vector<PhasePtr> getPhasesByRing(int ringNum);
246
255 PhasePtr getPhaseObj(int phaseNum, int ringNum = -1);
256
262 inline std::vector<PhasePtr> getPhaseObjs(void) {
263 return myPhaseObjs;
264 }
265
274 int measureRingDistance(int p1, int p2, int ringNum);
275
282 inline bool isType170(void) const {
283 return myControllerType == Type170;
284 }
285
293
296
301 void implementTraciChanges(void);
302
306
307protected:
308
311
316
321
324
327
330
332 inline void setCurrentTime(void) {
334 }
335
337 PhasePtr myActivePhaseObjs[2] = { nullptr, nullptr };
338
340 std::vector<PhasePtr > myPhaseObjs;
341
344
353 void constructTimingAndPhaseDefs(std::string& barriers, std::string& coordinates,
354 std::string& ring1, std::string& ring2);
355
359 std::string composeLightString();
360
366 bool vectorContainsPhase(std::vector<int> v, int phaseNum);
367
368 // create a small datatype for mapping detector to phase index
369 // This is the one copied from MSActuatedTrafficLightLogic
370 // not used in our controller, but it is here for meeting the SUMO default traffic logic light check
371 // this one and related could be removed with extra efforts
373 DetectorInfo(MSE2Collector* _det, int numPhases) :
374 det(_det),
375 servedPhase(numPhases, false)
376 {}
379 std::vector<bool> servedPhase;
380 };
381 typedef std::vector<std::vector<DetectorInfo*>> detectorMap;
384 std::vector<DetectorInfo> myDetectorInfoVector;
385
386
388 bool hasMajor(const std::string& state, const LaneVector& lanes) const;
389
397 std::vector<int> readParaFromString(std::string s);
398
406 bool isLeftTurnLane(const MSLane* const lane) const;
407
409 int string2int(std::string s);
410
413
415 std::map<std::string, int> myLanePhaseMap;
416
419
422
425
428
430 std::string myFile;
431
434
436 std::string myVehicleTypes;
437
438 /*
439 {
440 {3,4,1,2},
441 {7,8,5,6}
442 }
443 */
444 std::vector<std::vector<int>> rings;
445
446 /*
447 {
448 {1 : PhaseDetectorInfo{
449 detectors: {det1, det2, ...},
450 crossPhaseDetector: 6
451 },
452 },
453 {2 : ...
454 }
455 */
456 // std::map<int, PhaseDetectorInfo> phase2DetectorMap;
457 std::map<int, std::vector<std::string>> phase2ControllerLanesMap;
458
460 SUMOTime cycleRefPoint;// missing update
463
472
473 // Store the cabinet type
475
482 controllerType parseControllerType(std::string inputType);
483
486
493 void error_handle_not_set(std::string param_variable, std::string param_name);
494
500 void validate_timing();
501
513
516 switch (myControllerType) {
517 case Type170:
518 return calculateForceOffs170();
519 case TS2:
520 return calculateForceOffsTS2();
521 default:
522 return calculateForceOffs170();
523 }
524 }
525
526
533 switch (myControllerType) {
534 case Type170:
536 case TS2:
538 default:
539 // Default to Type170
541 }
542 }
543};
544
545
555public:
558
586
587 // create a PhaseDetectorInfo type
589
606 bool isBarrier,
607 bool isGreenRest,
608 bool isCoordinated,
609 bool minRecall,
610 bool maxRecall,
611 bool fixForceOff,
612 int barrierNum,
613 int ringNum,
614 IntVector phaseStringInds,
615 MSPhaseDefinition* phase);
616
618 ~NEMAPhase();
619
622 return myLightState;
623 }
625 inline std::vector<MSE2Collector*> getDetectors() const {
627 }
628
629
631 inline void setDetectors(std::vector<MSE2Collector*> detectors) {
632 myDetectorInfo.detectors = detectors;
633 }
634
636 inline bool isTransitionActive() const {
638 }
639
640 // Build a Map of Valid Transitions and store the detector-based information
649 void init(NEMALogic* controller, int crossPhaseTarget, int crossPhaseSource, bool latching);
650
656 void update(NEMALogic* controller);
657
664 void exit(NEMALogic* controller, PhaseTransitionLogic* nextPhases[2]);
665
672 void handleGreenRestOrTransfer(NEMALogic* controller, PhaseTransitionLogic* nextPhases[2]);
673
679 void enterYellow(NEMALogic* controller);
680
686 void handleRedXferOrNextPhase(NEMALogic* controller, PhaseTransitionLogic* nextPhases[2]);
687
689 inline bool hasRecall(void) {
690 return minRecall || maxRecall;
691 }
692
694 inline bool callActive(void) {
696 }
697
699 inline bool detectActive(void) {
701 }
702
704 void checkMyDetectors(void);
705
707 void clearMyDetectors(void);
708
709 // Need-to-know Phase Settings
719
722
728
731
739
747 return yellow + red;
748 }
749
753 }
754
756 inline void setSequentialPriorPhase(PhasePtr priorPhase) {
757 sequentialPriorPhase = priorPhase;
758 }
759
766 std::vector<PhaseTransitionLogic*> trySwitch(NEMALogic* controller);
767
775
777 char getNEMAChar(int i);
778
780 void recalculateTiming(void);
781
783 inline void forceEnter(NEMALogic* controller) {
784 enter(controller, sequentialPriorPhase);
785 }
786
788 inline bool controlledIndex(int i) {
789 return std::count(myPhaseStringInds.begin(), myPhaseStringInds.end(), i) > 0;
790 }
791
801
803 inline void cleanupExit(void) {
804 transitionActive = false;
805 readyToSwitch = false;
807 }
808
810 inline bool okay2ForceSwitch(NEMALogic* controller) {
811 return readyToSwitch && !transitionActive && (getTransitionTime(controller) <= TIME2STEPS(0));
812 }
813
814private:
817
824
825 // Phase Knowledge Space
828
836
840 std::string myGreenString;
841 std::string myYellowString;
842 std::string myRedString;
844
852
854 std::vector<PhaseTransitionLogic*> myTransitions;
855
863 void enter(NEMALogic* controller, PhasePtr lastPhase);
864
869 void setMyNEMAStates(void);
870
873
876
877};
878
879
889public:
892
902 );
903
912 bool okay(NEMALogic* controller);
913
920 int getDistance(PhaseTransitionLogic* otherTrans);
922 inline void setDistance(int d) {
923 distance = d;
924 }
926
929
931 inline PhasePtr getToPhase(void) const {
932 return toPhase;
933 }
934
936 inline PhasePtr getFromPhase(void) const {
937 return fromPhase;
938 }
939
940private:
943
945 void buildLogic(void);
946
955 bool fromBarrier(NEMALogic* controller);
956
965 bool fromCoord(NEMALogic* controller);
966
975 bool freeBase(NEMALogic* controller);
976
985 bool coordBase(NEMALogic* controller);
986};
long long int SUMOTime
Definition GUI.h:36
LightState
std::vector< std::string > StringVector
Definition of a vector of strings.
Definition Option.h:42
std::vector< int > IntVector
Definition of a vector of ints.
Definition Option.h:37
#define TIME2STEPS(x)
Definition SUMOTime.h:57
An areal detector corresponding to a sequence of consecutive lanes.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:320
The definition of a single phase of a tls logic.
A fixed traffic light logic.
A class that stores and controls tls and switching of their programs.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
A NEMA (adaptive) traffic light logic based on E2Detector.
SUMOTime cycleRefPoint
std::vector< std::vector< DetectorInfo * > > detectorMap
std::map< std::string, double > getDetectorStates() const override
retrieve all detectors used by this program
int measureRingDistance(int p1, int p2, int ringNum)
return the ring distance between two phases
SUMOTime getTimeInCycle() const
override Function to Simplify Accessing Offset Cycle Time
void getLaneInfoFromNEMAState(std::string state, StringVector &laneIDs, IntVector &stateIndex)
returns the IDs of the phase's controlled lanes. Found by looking for the "G" in the light state stri...
void getNextPhases(TransitionPairs &transitions)
extends the transitions vector with valid Transitions given the current traffic light state
void setNewMaxGreens(std::vector< double > newMaxGreens)
Set the max green of all phases.
void calculateForceOffs170()
calculate the forceOffs for a Type 170 style offset From https://ops.fhwa.dot.gov/publications/fhwaho...
void calculateInitialPhases()
directs the controller to the correct calculate phases function
const std::string lightHeadPriority
constant for storing the priority order for light heads. Iterates left to right and stops when finds ...
const std::string getParameter(const std::string &key, const std::string defaultValue="") const override
try to get the value of the given parameter. Parameters prefixed with 'NEMA.' control functionality
std::vector< DetectorInfo > myDetectorInfoVector
storing the detector info in a vector
SUMOTime myNextCycleLength
the next cycle length (set by traci)
void init(NLDetectorBuilder &nb) override
Initialises the tls with information about incoming lanes.
void calculateInitialPhasesTS2()
calculate the initial phases for the TS2 style controller to start in
std::string myVehicleTypes
Whether detector output separates by vType.
std::string myFile
The output file for generated detectors.
PhasePtr getActivePhase(int ringNum)
Get the Active Phase object for a specified ring.
double myDetectorLength
store the generated detector length
SUMOTime getCurrentCycleLength()
Get the current cycle length.
bool showDetectors() const
std::vector< std::vector< int > > rings
SUMOTime myFreq
The frequency for aggregating detector output.
DetectorLaneMap myDetectorLaneMap
A map from detectors to lanes.
SUMOTime trySwitch() override
overrides the MSSimpleTrafficLightLogic trySwitch method
bool isType170(void) const
checks if the controller is of type170
void validate_timing()
validates the NEMA timing. Writes warnings if ignoreError set to true else throws ProcessError
bool queuedTraciChanges
flag to keep track of whether a timing change has been requested via traci
SUMOTime simTime
stores the simulation time to make it easily accessible
void activateProgram() override
called when switching programs
void setShowDetectors(bool show)
bool whetherOutputState
void constructTimingAndPhaseDefs(std::string &barriers, std::string &coordinates, std::string &ring1, std::string &ring2)
constructs phase using the configuration file
int myPhaseStrLen
stores the length of phase string for the controller "GGrrrrs" = 6. Must be the same length for all p...
NEMAPhase * PhasePtr
int myNumberRings
stores controllers # of rings
PhasePtr defaultBarrierPhases[2][2]
an array to store the phases located at a barrier for each ring
SUMOTime getCurrentTime(void) const
Wrapper Function to Simplify Accessing Time.
std::vector< PhasePtr > myPhaseObjs
a vector that stores a pointer to the instantiated NEMAPhase objects
void setParameter(const std::string &key, const std::string &value) override
try to set the given parameter. Parameters prefixed with 'NEMA.' control functionality
void error_handle_not_set(std::string param_variable, std::string param_name)
throw an InvalidArgument error if the param_name is not set
void implementTraciChanges(void)
implement any pending traci changes This function is called once per cycle
PhasePtr getPhaseObj(int phaseNum, int ringNum=-1)
get the phase object matching the phaseNum If ringNum is passed, it will only search for the phase in...
void setNewOffset(double newOffset)
Set the new offset for the controller.
std::vector< PhasePtr > getPhasesByRing(int ringNum)
get all phases for a given ring
std::map< MSLane *, MSE2Collector * > LaneDetectorMap
controllerType parseControllerType(std::string inputType)
parse the controllerType from the tllogic description
SUMOTime myCycleLength
the coordinated cycle length
SUMOTime offset
the controller's offset
void calculateInitialPhases170()
calculate the initial phases for Type 170
SUMOTime myNextOffset
the next offset to implement
SUMOTime ModeCycle(SUMOTime a, SUMOTime b)
Calculates the modulus a / b, normally used to calculate the cycle time between two times....
void calculateForceOffs()
directs the code to the correct force off function accorifing to its cabinet type
std::vector< int > readParaFromString(std::string s)
converts a comma separated string into a integer vector "1,2,3,4" -> {1,2,3,4}
std::map< MSE2Collector *, MSLane *, ComparatorIdLess > DetectorLaneMap
std::vector< PhasePtr > getPhaseObjs(void)
get a vector of all phase objects
bool myShowDetectors
Whether the detectors shall be shown in the GUI.
detectorMap myDetectorForPhase
int string2int(std::string s)
convert a string to an integer
bool hasMajor(const std::string &state, const LaneVector &lanes) const
return whether there is a major link from the given lane in the given phase
bool coordinateMode
whether the controller is in coordinated mode or not
PhasePtr myActivePhaseObjs[2]
variable to store the active phases
void deactivateProgram() override
void setCurrentTime(void)
Set the simTime.
~NEMALogic()
Destructor.
MSPhaseDefinition myPhase
virtual phase that holds the current state
PhaseTransitionLogic * getDefaultTransition(PhaseTransitionLogic *t, PhaseTransitionLogic *ot)
return the default transition for t give its and the ot's state
bool vectorContainsPhase(std::vector< int > v, int phaseNum)
check if a vector contains an element
void calculateForceOffsTS2()
calculate the forceOffs for a TS2 style offset From https://ops.fhwa.dot.gov/publications/fhwahop0802...
PhasePtr getOtherPhase(PhasePtr p)
Get the opposite active phase.
double myDetectorLengthLeftTurnLane
store the left turn lane detestor length
controllerType myControllerType
bool isLeftTurnLane(const MSLane *const lane) const
decide whether the detector is for left turn lane if it is, use the detector length for left turn lan...
LaneDetectorMap myLaneDetectorMap
A map from lanes to detectors.
PhasePtr coordinatePhaseObjs[2]
a store of the coordinated phase objects. Only used meaningfully when the controller is in coordinate...
std::map< std::string, int > myLanePhaseMap
A map from lanes names to phases.
std::string composeLightString()
iterates over the two active phases (myActivePhaseObjs) and merges the two active phases
void setNewCycleLength(double newCycleLength)
set the new cycle length for the controller
void setActivePhase(PhasePtr phase)
set the active phase
std::vector< transitionInfo > TransitionPairs
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns myPhase, which doesn't correspond to a NEMA phase, but rather the composite light string.
std::map< int, std::vector< std::string > > phase2ControllerLanesMap
void setNewSplits(std::vector< double > newSplits)
Set the new splits of all phases.
One phase in the NEMAController.
bool lastDetectActive
store the last detect check for traci purposes
std::string myYellowString
NEMAPhase * PhasePtr
Typedef for commonly used phase pointer.
void setDetectors(std::vector< MSE2Collector * > detectors)
sets the detectors for the phase
SUMOTime myLastEnd
SUMOTime vehExt
SUMOTime nextMaxDuration
void cleanupExit(void)
public method to set whether phase is active or not
MSPhaseDefinition * myCorePhase
A reference to the core phase of which NEMAPhase wraps.
LightState myLightState
std::string myGreenString
LightState getCurrentState() const
gets the current light state
SUMOTime myExpectedDuration
void setMyNEMAStates(void)
this function replaces getNEMAStates calculation at every call It sets my myGreenString,...
~NEMAPhase()
Destructor.
PhasePtr getSequentialPriorPhase(void)
get the prior phase
bool controlledIndex(int i)
Return whether or not the phase index is controlled by me.
bool coordinatePhase
SUMOTime greenRestTimer
a count down timer to track green rest transition time
void clearMyDetectors(void)
Clear My Detectors. Called on all phases at every step.
void checkMyDetectors(void)
Check Detectors. Called on all phases at every step.
SUMOTime yellow
SUMOTime minDuration
PhaseDetectorInfo myDetectorInfo
PhasePtr sequentialPriorPhase
void setSequentialPriorPhase(PhasePtr priorPhase)
set the prior phase
SUMOTime greatestStartTime
PhaseDetectorInfo PhaseDetectorInfo
std::vector< PhaseTransitionLogic * > trySwitch(NEMALogic *controller)
calculate a vector of potention next phases
std::vector< MSE2Collector * > getDetectors() const
returns a vector of the phases detectors
char getNEMAChar(int i)
Return the ryg light string for the phase.
SUMOTime forceOffTime
stores the force off time in coordinated mode
SUMOTime red
void recalculateTiming(void)
accessory function to recalculate timing
void handleRedXferOrNextPhase(NEMALogic *controller, PhaseTransitionLogic *nextPhases[2])
handles the transition into a red xfer state, which is roughly the same as green rest
SUMOTime getTransitionTimeStateless(void)
Get the Transition time given.
SUMOTime calcVehicleExtension(SUMOTime duration)
}
bool okay2ForceSwitch(NEMALogic *controller)
simple internal check to see if done okay to transition
void init(NEMALogic *controller, int crossPhaseTarget, int crossPhaseSource, bool latching)
initializes the object
PhasePtr myInstance
bool isTransitionActive() const
check if a transition is active
void enterYellow(NEMALogic *controller)
handles the transition into yellow
PhaseTransitionLogic * getTransition(int toPhase)
return the PhaseTransitionLogic matching the toPhase
SUMOTime maxDuration
void handleGreenRestOrTransfer(NEMALogic *controller, PhaseTransitionLogic *nextPhases[2])
handles the transition into a green rest state
bool readyToSwitch
flag to for the supervisory controller to denote whether phase is ready to switch or not.
bool transitionActive
variable to store whether a transition is active or not
std::vector< PhaseTransitionLogic * > myTransitions
stores a sorted list of potential transitions
SUMOTime myStartTime
void forceEnter(NEMALogic *controller)
Force Enter. This Should only be called at initialization time.
PhasePtr myLastPhaseInstance
bool callActive(void)
simple method to check if there is either a recall or an active detector
std::string myRedString
SUMOTime getTransitionTime(NEMALogic *controller)
Get the Transition Time.
PhaseTransitionLogic * lastTransitionDecision
pointer to save the last transition
void enter(NEMALogic *controller, PhasePtr lastPhase)
handles entry to the phase during simulation Sets the color to green and determines maximum duration
SUMOTime maxGreenDynamic
bool hasRecall(void)
simple method to check if there is a recall on the phase.
IntVector myPhaseStringInds
void exit(NEMALogic *controller, PhaseTransitionLogic *nextPhases[2])
handles the transition out of a phase into the next (puts the phase through (G -> Y -> R) transition
bool detectActive(void)
simple method to check if a detector is active
Builds detectors for microsim.
This class handles the transition logic between two phases.
void setDistance(int d)
set the transition distance
int getDistance(PhaseTransitionLogic *otherTrans)
return the ring distance that this transition represents
bool okay(NEMALogic *controller)
This function is the main PhaseTransitionLogic function It is called by the fromPhase to check if a t...
bool freeBase(NEMALogic *controller)
this represents the bare minimum logic, that the toPhase has an active detector and that the fromPhas...
bool coordBase(NEMALogic *controller)
represents the bare minimum coordinate mode logic. Requires that the toPhase can fit its minimum gree...
bool fromBarrier(NEMALogic *controller)
If the fromPhase is at a barrier, then this function will be called to check whether the transition i...
bool fromCoord(NEMALogic *controller)
if the fromPhase is a coordinated phase, then this logic will be checked
PhasePtr getFromPhase(void) const
get the from phase
~PhaseTransitionLogic()
deconstructor
PhasePtr getToPhase(void) const
get the to phase
void buildLogic(void)
build the transition logic based on the from and to phase
NEMAPhase * PhasePtr
Typedef for commonly used phase pointer.
DetectorInfo(MSE2Collector *_det, int numPhases)
std::vector< bool > servedPhase
PhaseTransitionLogic * p2
PhaseTransitionLogic * p1
stores information about the phase's detector(s)
bool detectActive
where any of my detectors are active or not
std::vector< MSE2Collector * > detectors
a vector of pointers to the phase's detectors
PhaseDetectorInfo(bool latching, PhasePtr cpdSource, PhasePtr cpdTarget)
PhasePtr cpdSource
the cross-phase switching source for myself (1 if 6 should check 1 if 6 is green and I am phase 6)
PhasePtr cpdTarget
the cross-phase switching target for myself (6 if 6 should check 1 if 6 is green and I am phase 1)
bool latching
whether the detectors are latching or not