Eclipse SUMO - Simulation of Urban MObility
NEMAController.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 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 Red,
49 Yellow,
50 Green,
53};
54
55
56// ===========================================================================
57// class definitions
58// ===========================================================================
64public:
65
67
68 typedef std::map<MSLane*, MSE2Collector*> LaneDetectorMap;
69
70 typedef std::map<MSE2Collector*, MSLane*, ComparatorIdLess> DetectorLaneMap;
71
72 // Small structure for storing two ring transitions and the average distance
76 float distance;
77 };
78
81 TS2
82 };
83
85 const std::string lightHeadPriority = "GgyuOs";
86
87 typedef std::vector<transitionInfo> TransitionPairs;
88
98 NEMALogic(MSTLLogicControl& tlcontrol,
99 const std::string& id, const std::string& programID,
100 const SUMOTime offset,
102 int step, SUMOTime delay,
103 const std::map<std::string, std::string>& parameter,
104 const std::string& basePath);
105
106
111 void init(NLDetectorBuilder& nb) override;
112
114 ~NEMALogic();
115
117 SUMOTime trySwitch() override;
118
121
125 const MSPhaseDefinition& getCurrentPhaseDef() const override;
127
128
129 void activateProgram() override;
130 void deactivateProgram() override;
131
132 bool showDetectors() const {
133 return myShowDetectors;
134 }
135
136 void setShowDetectors(bool show);
137
139 std::map<std::string, double> getDetectorStates() const override;
140
146 void getNextPhases(TransitionPairs& transitions);
147
157
158
166 void getLaneInfoFromNEMAState(std::string state, StringVector& laneIDs, IntVector& stateIndex);
167
173 void setNewMaxGreens(std::vector<double> newMaxGreens);
174
180 void setNewSplits(std::vector<double> newSplits);
181
187 void setNewCycleLength(double newCycleLength);
188
194 void setNewOffset(double newOffset);
195
202 return myCycleLength;
203 }
204
206 void setParameter(const std::string& key, const std::string& value) override;
207
209 const std::string getParameter(const std::string& key, const std::string defaultValue = "") const override;
210
212 inline SUMOTime getCurrentTime(void) const {
213 return simTime;
214 }
215
216 // /// @brief Wrapper Function to Simplify Accessing Offset Cycle Time
217 // inline SUMOTime getCurrentOffsetTime(void) const {return simTime - cycleRefPoint - offset; };
218
220 inline SUMOTime getTimeInCycle() const {
222 }
223
224
226 void setActivePhase(PhasePtr phase);
227
234 inline PhasePtr getActivePhase(int ringNum) {
235 return myActivePhaseObjs[ringNum];
236 }
237
244 std::vector<PhasePtr> getPhasesByRing(int ringNum);
245
254 PhasePtr getPhaseObj(int phaseNum, int ringNum = -1);
255
261 inline std::vector<PhasePtr> getPhaseObjs(void) {
262 return myPhaseObjs;
263 }
264
273 int measureRingDistance(int p1, int p2, int ringNum);
274
281 inline bool isType170(void) const {
282 return myControllerType == Type170;
283 }
284
292
295
300 void implementTraciChanges(void);
301
305
306protected:
307
310
315
320
323
326
329
331 inline void setCurrentTime(void) {
333 }
334
336 PhasePtr myActivePhaseObjs[2] = { nullptr, nullptr };
337
339 std::vector<PhasePtr > myPhaseObjs;
340
343
352 void constructTimingAndPhaseDefs(std::string& barriers, std::string& coordinates,
353 std::string& ring1, std::string& ring2);
354
358 std::string composeLightString();
359
365 bool vectorContainsPhase(std::vector<int> v, int phaseNum);
366
367 // create a small datatype for mapping detector to phase index
368 // This is the one copied from MSActuatedTrafficLightLogic
369 // not used in our controller, but it is here for meeting the SUMO default traffic logic light check
370 // this one and related could be removed with extra efforts
372 DetectorInfo(MSE2Collector* _det, int numPhases) :
373 det(_det),
374 servedPhase(numPhases, false)
375 {}
378 std::vector<bool> servedPhase;
379 };
380 typedef std::vector<std::vector<DetectorInfo*>> detectorMap;
383 std::vector<DetectorInfo> myDetectorInfoVector;
384
385
387 bool hasMajor(const std::string& state, const LaneVector& lanes) const;
388
396 std::vector<int> readParaFromString(std::string s);
397
405 bool isLeftTurnLane(const MSLane* const lane) const;
406
408 int string2int(std::string s);
409
412
414 std::map<std::string, int> myLanePhaseMap;
415
418
421
424
427
429 std::string myFile;
430
433
435 std::string myVehicleTypes;
436
437 /*
438 {
439 {3,4,1,2},
440 {7,8,5,6}
441 }
442 */
443 std::vector<std::vector<int>> rings;
444
445 /*
446 {
447 {1 : PhaseDetectorInfo{
448 detectors: {det1, det2, ...},
449 crossPhaseDetector: 6
450 },
451 },
452 {2 : ...
453 }
454 */
455 // std::map<int, PhaseDetectorInfo> phase2DetectorMap;
456 std::map<int, std::vector<std::string>> phase2ControllerLanesMap;
457
459 SUMOTime cycleRefPoint;// missing update
462
471
472 // Store the cabinet type
474
481 controllerType parseControllerType(std::string inputType);
482
485
492 void error_handle_not_set(std::string param_variable, std::string param_name);
493
499 void validate_timing();
500
512
515 switch (myControllerType) {
516 case Type170:
517 return calculateForceOffs170();
518 case TS2:
519 return calculateForceOffsTS2();
520 default:
521 return calculateForceOffs170();
522 }
523 }
524
525
532 switch (myControllerType) {
533 case Type170:
535 case TS2:
537 default:
538 // Default to Type170
540 }
541 }
542};
543
544
554public:
557
562 detectors(),
563 cpdTarget(),
564 cpdSource(),
565 detectActive(),
566 latching()
567 {}
571 detectActive(false),
573 {}
575 std::vector<MSE2Collector*> detectors;
584 };
585
586 // create a PhaseDetectorInfo type
588
605 bool isBarrier,
606 bool isGreenRest,
607 bool isCoordinated,
608 bool minRecall,
609 bool maxRecall,
610 bool fixForceOff,
611 int barrierNum,
612 int ringNum,
613 IntVector phaseStringInds,
614 MSPhaseDefinition* phase);
615
617 ~NEMAPhase();
618
621 return myLightState;
622 }
624 inline std::vector<MSE2Collector*> getDetectors() const {
626 }
627
628
630 inline void setDetectors(std::vector<MSE2Collector*> detectors) {
631 myDetectorInfo.detectors = detectors;
632 }
633
635 inline bool isTransitionActive() const {
637 }
638
639 // Build a Map of Valid Transitions and store the detector-based information
648 void init(NEMALogic* controller, int crossPhaseTarget, int crossPhaseSource, bool latching);
649
655 void update(NEMALogic* controller);
656
663 void exit(NEMALogic* controller, PhaseTransitionLogic* nextPhases[2]);
664
666 inline bool hasRecall(void) {
667 return minRecall || maxRecall;
668 }
669
671 inline bool callActive(void) {
673 }
674
676 inline bool detectActive(void) {
678 }
679
681 void checkMyDetectors(void);
682
684 void clearMyDetectors(void);
685
686 // Need-to-know Phase Settings
696
699
705
708
716
720 }
721
723 inline void setSequentialPriorPhase(PhasePtr priorPhase) {
724 sequentialPriorPhase = priorPhase;
725 }
726
733 std::vector<PhaseTransitionLogic*> trySwitch(NEMALogic* controller);
734
742
744 char getNEMAChar(int i);
745
747 void recalculateTiming(void);
748
750 inline void forceEnter(NEMALogic* controller) {
751 enter(controller, sequentialPriorPhase);
752 }
753
755 inline bool controlledIndex(int i) {
756 return std::count(myPhaseStringInds.begin(), myPhaseStringInds.end(), i) > 0;
757 }
758
768
769private:
772
779
780 // Phase Knowledge Space
783
791
795 std::string myGreenString;
796 std::string myYellowString;
797 std::string myRedString;
799
807
809 std::vector<PhaseTransitionLogic*> myTransitions;
810
818 void enter(NEMALogic* controller, PhasePtr lastPhase);
819
824 void setMyNEMAStates(void);
825
828
831
832};
833
834
844public:
847
857 );
858
867 bool okay(NEMALogic* controller);
868
875 int getDistance(PhaseTransitionLogic* otherTrans);
877 inline void setDistance(int d) {
878 distance = d;
879 }
881
884
886 inline PhasePtr getToPhase(void) const {
887 return toPhase;
888 }
889
891 inline PhasePtr getFromPhase(void) const {
892 return fromPhase;
893 }
894
895private:
898
900 void buildLogic(void);
901
910 bool fromBarrier(NEMALogic* controller);
911
920 bool fromCoord(NEMALogic* controller);
921
930 bool freeBase(NEMALogic* controller);
931
940 bool coordBase(NEMALogic* controller);
941};
long long int SUMOTime
Definition: GUI.h:36
LightState
std::vector< std::string > StringVector
Definition of a vector of strings.
Definition: Option.h:43
std::vector< int > IntVector
Definition of a vector of ints.
Definition: Option.h:38
An areal detector corresponding to a sequence of consecutive lanes.
Definition: MSE2Collector.h:79
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:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:321
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
NEMALogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const SUMOTime offset, const MSSimpleTrafficLightLogic::Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > &parameter, const std::string &basePath)
Constructor.
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.
bool fixForceOff
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 seperated 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 it's 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...
bool ignoreErrors
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
NEMAPhase(int phaseName, bool isBarrier, bool isGreenRest, bool isCoordinated, bool minRecall, bool maxRecall, bool fixForceOff, int barrierNum, int ringNum, IntVector phaseStringInds, MSPhaseDefinition *phase)
Construct a new NEMAPhase object.
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
SUMOTime calcVehicleExtension(SUMOTime duration)
}
void init(NEMALogic *controller, int crossPhaseTarget, int crossPhaseSource, bool latching)
initializes the object
PhasePtr myInstance
bool isTransitionActive() const
check if a transition is active
bool isAtBarrier
PhaseTransitionLogic * getTransition(int toPhase)
return the PhaseTransitionLogic matching the toPhase
SUMOTime maxDuration
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
bool isGreenRest
void update(NEMALogic *controller)
update is called on the active phases by the NEMAController at every time step
bool fixForceOff
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
PhaseTransitionLogic(PhasePtr fromPhase, PhasePtr toPhase)
Construct a new Phase Transition Logic object.
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