CARLA
TrafficLightStage.cpp
Go to the documentation of this file.
1 
4 
6 
7 namespace carla {
8 namespace traffic_manager {
9 
14 
16  const std::vector<ActorId> &vehicle_id_list,
17  const SimulationState &simulation_state,
18  const BufferMap &buffer_map,
19  const Parameters &parameters,
20  const cc::World &world,
21  TLFrame &output_array,
22  RandomGenerator &random_device)
23  : vehicle_id_list(vehicle_id_list),
24  simulation_state(simulation_state),
25  buffer_map(buffer_map),
26  parameters(parameters),
27  world(world),
28  output_array(output_array),
29  random_device(random_device) {}
30 
31 void TrafficLightStage::Update(const unsigned long index) {
32  bool traffic_light_hazard = false;
33 
34  const ActorId ego_actor_id = vehicle_id_list.at(index);
35  if (!simulation_state.IsDormant(ego_actor_id)) {
36 
37  JunctionID current_junction_id = -1;
38  if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) {
39  current_junction_id = vehicle_last_junction.at(ego_actor_id);
40  }
41  auto affected_junction_id = GetAffectedJunctionId(ego_actor_id);
42 
44 
45  const TrafficLightState tl_state = simulation_state.GetTLS(ego_actor_id);
46  const TLS traffic_light_state = tl_state.tl_state;
47  const bool is_at_traffic_light = tl_state.at_traffic_light;
48 
49  // We determine to stop if the vehicle found a traffic light in yellow / red.
50  if (is_at_traffic_light &&
51  traffic_light_state != TLS::Green &&
52  traffic_light_state != TLS::Off &&
54  // Remove actor from non-signalized junction if it is affected by a traffic light.
55  if (current_junction_id != -1) {
56  RemoveActor(ego_actor_id);
57  }
58  traffic_light_hazard = true;
59  }
60  // The vehicle is currently at a non signalized junction, so handle its priorities.
61  // Don't use the next condition as bounding boxes might switch to green
62  else if (current_junction_id != -1)
63  {
64  if ( affected_junction_id == -1 || affected_junction_id != current_junction_id ) {
65  RemoveActor(ego_actor_id);
66  }
67  else {
68  traffic_light_hazard = HandleNonSignalisedJunction(ego_actor_id, affected_junction_id, current_timestamp);
69  }
70  }
71  else if (affected_junction_id != -1 &&
72  !is_at_traffic_light &&
73  traffic_light_state != TLS::Green &&
75 
76  AddActorToNonSignalisedJunction(ego_actor_id, affected_junction_id);
77  traffic_light_hazard = true;
78  }
79  }
80  output_array.at(index) = traffic_light_hazard;
81 }
82 
83 void TrafficLightStage::AddActorToNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id) {
84 
85  if (entering_vehicles_map.find(junction_id) == entering_vehicles_map.end()) {
86  // Initializing new map entry for the junction with an empty actor deque.
87  std::deque<ActorId> entry_deque;
88  entering_vehicles_map.insert({junction_id, entry_deque});
89  }
90 
91  auto& entering_vehicles = entering_vehicles_map.at(junction_id);
92  if (std::find(entering_vehicles.begin(), entering_vehicles.end(), ego_actor_id) == entering_vehicles.end()){
93  // Initializing new actor entry to the junction maps.
94  entering_vehicles.push_back(ego_actor_id);
95  if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) {
96  // The actor was entering another junction, so remove all of its stored data
97  RemoveActor(ego_actor_id);
98  }
99  vehicle_last_junction.insert({ego_actor_id, junction_id});
100  }
101 }
102 
103 
104 bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id,
105  cc::Timestamp timestamp) {
106 
107  bool traffic_light_hazard = false;
108 
109  auto& entering_vehicles = entering_vehicles_map.at(junction_id);
110 
111  if (vehicle_stop_time.find(ego_actor_id) == vehicle_stop_time.end()) {
112  // Ensure the vehicle stops before doing anything else
114  vehicle_stop_time.insert({ego_actor_id, timestamp});
115  }
116  traffic_light_hazard = true;
117  }
118 
119  else if (entering_vehicles.front() == ego_actor_id) {
120  auto entry_elapsed_seconds = vehicle_stop_time.at(ego_actor_id).elapsed_seconds;
121  if (timestamp.elapsed_seconds - entry_elapsed_seconds < MINIMUM_STOP_TIME) {
122  // Wait at least the minimum amount of time before entering the junction
123  traffic_light_hazard = true;
124  }
125  } else {
126  // Only one vehicle can be entering the junction, so stop the rest.
127  traffic_light_hazard = true;
128  }
129  return traffic_light_hazard;
130 }
131 
133  const Buffer &waypoint_buffer = buffer_map.at(ego_actor_id);
134  const SimpleWaypointPtr look_ahead_point = GetTargetWaypoint(waypoint_buffer, JUNCTION_LOOK_AHEAD).first;
135  const auto front_point = waypoint_buffer.front();
136 
137  auto look_ahead_junction_id = look_ahead_point->GetJunctionId();
138  auto front_junction_id = front_point->GetJunctionId();
139 
140  // Check if the vehicle is currently at a non-signalized junction
141  JunctionID current_junction_id = -1;
142  if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) {
143  current_junction_id = vehicle_last_junction.at(ego_actor_id);
144  }
145 
146  if (current_junction_id != -1) {
147  // We are currently processing a junction
148  if (current_junction_id == look_ahead_junction_id) {
149  return look_ahead_junction_id;
150  } else {
151  if (look_ahead_junction_id != -1) {
152  // We are detecting a different junction
153  return look_ahead_junction_id;
154  } else {
155  if (current_junction_id == front_junction_id) {
156  // We are still in the same junction
157  return front_junction_id;
158  } else {
159  return -1;
160  }
161  }
162  }
163  } else {
164  // If we are not processing any junction, return the look ahead detected junction
165  return look_ahead_junction_id;
166  }
167 }
168 
170  if (vehicle_last_junction.find(actor_id) != vehicle_last_junction.end()) {
171  auto junction_id = vehicle_last_junction.at(actor_id);
172 
173  auto& entering_vehicles = entering_vehicles_map.at(junction_id);
174  auto ent_index = std::find(entering_vehicles.begin(), entering_vehicles.end(), actor_id);
175  if (ent_index != entering_vehicles.end()) {
176  entering_vehicles.erase(ent_index);
177  }
178 
179  if (vehicle_stop_time.find(actor_id) != vehicle_stop_time.end()) {
180  vehicle_stop_time.erase(actor_id);
181  }
182 
183  vehicle_last_junction.erase(actor_id);
184  }
185 }
186 
188  entering_vehicles_map.clear();
189  vehicle_last_junction.clear();
190  vehicle_stop_time.clear();
191 }
192 
193 } // namespace traffic_manager
194 } // namespace carla
float GetPercentageRunningLight(const ActorId &actor_id) const
Method to get % to run any traffic light.
Definition: Parameters.cpp:357
TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &target_point_distance)
std::vector< bool > TLFrame
TrafficLightState GetTLS(const ActorId actor_id) const
This class holds the state of all the vehicles in the simlation.
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:133
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
void RemoveActor(const ActorId actor_id) override
std::unordered_map< carla::ActorId, Buffer > BufferMap
float Length() const
Definition: geom/Vector3D.h:49
void Update(const unsigned long index) override
const std::vector< ActorId > & vehicle_id_list
const Timestamp & GetTimestamp() const
Get timestamp of this snapshot.
Definition: WorldSnapshot.h:34
bool IsDormant(const ActorId actor_id) const
carla::road::JuncId JunctionID
carla::ActorId ActorId
std::unordered_map< JunctionID, std::deque< ActorId > > entering_vehicles_map
Variables used to handle non signalized junctions.
float GetPercentageRunningSign(const ActorId &actor_id) const
Method to get % to run any traffic light.
Definition: Parameters.cpp:368
TrafficLightStage(const std::vector< ActorId > &vehicle_id_list, const SimulationState &Simulation_state, const BufferMap &buffer_map, const Parameters &parameters, const cc::World &world, TLFrame &output_array, RandomGenerator &random_device)
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
bool HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id, cc::Timestamp timestamp)
This controls all vehicle&#39;s interactions at non signalized junctions.
std::unordered_map< ActorId, JunctionID > vehicle_last_junction
Map linking the vehicles with their current junction. Used for easy access to the previous two maps...
cg::Vector3D GetVelocity(const ActorId actor_id) const
WorldSnapshot GetSnapshot() const
Return a snapshot of the world at this moment.
Definition: World.cpp:94
double elapsed_seconds
Simulated seconds elapsed since the beginning of the current episode.
Definition: Timestamp.h:33
std::unordered_map< ActorId, cc::Timestamp > vehicle_stop_time
Map containing the timestamp at which the actor first stopped at a stop sign.
JunctionID GetAffectedJunctionId(const ActorId ego_actor_id)
Get current affected junction id for the vehicle.
void AddActorToNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id)
Initialized the vehicle to the non-signalized junction maps.