CARLA
 
载入中...
搜索中...
未找到
TrafficLightStage.cpp
浏览该文件的文档.
1
4
6
7namespace carla {
8namespace traffic_manager {
9
10// 引入一些常量
11using constants::TrafficLight::EXIT_JUNCTION_THRESHOLD; // 退出交叉口的阈值
12using constants::TrafficLight::MINIMUM_STOP_TIME; // 最小停止时间
13using constants::WaypointSelection::JUNCTION_LOOK_AHEAD; // 交叉口前瞻距离
14using constants::MotionPlan::EPSILON_RELATIVE_SPEED; // 相对速度的微小值
15
16// TrafficLightStage 构造函数
18 const std::vector<ActorId> &vehicle_id_list, // 车辆 ID 列表
19 const SimulationState &simulation_state, // 仿真状态
20 const BufferMap &buffer_map, // 缓存映射
21 const Parameters &parameters, // 参数设置
22 const cc::World &world, // 世界对象
23 TLFrame &output_array, // 输出数组
24 RandomGenerator &random_device) // 随机数生成器
25 : vehicle_id_list(vehicle_id_list), // 初始化车辆 ID 列表
26 simulation_state(simulation_state), // 初始化仿真状态
27 buffer_map(buffer_map), // 初始化缓存映射
28 parameters(parameters), // 初始化参数
29 world(world), // 初始化世界对象
30 output_array(output_array), // 初始化输出数组
31 random_device(random_device) {} // 初始化随机数生成器
32
33// 更新函数
34void TrafficLightStage::Update(const unsigned long index) {
35 bool traffic_light_hazard = false; // 交通信号灯危险标志
36
37 const ActorId ego_actor_id = vehicle_id_list.at(index); // 获取当前车辆 ID
38 if (!simulation_state.IsDormant(ego_actor_id)) { // 如果车辆不处于休眠状态
39
40 JunctionID current_junction_id = -1; // 当前交叉口 ID 初始化为 -1
41 if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) {
42 current_junction_id = vehicle_last_junction.at(ego_actor_id); // 获取上次的交叉口 ID
43 }
44 auto affected_junction_id = GetAffectedJunctionId(ego_actor_id); // 获取受影响的交叉口 ID
45
46 current_timestamp = world.GetSnapshot().GetTimestamp(); // 获取当前时间戳
47
48 const TrafficLightState tl_state = simulation_state.GetTLS(ego_actor_id); // 获取交通信号灯状态
49 const TLS traffic_light_state = tl_state.tl_state; // 交通信号灯当前状态
50 const bool is_at_traffic_light = tl_state.at_traffic_light; // 判断是否在交通信号灯处
51
52 // 如果车辆在交通信号灯处且信号灯为黄灯或红灯
53 if (is_at_traffic_light &&
54 traffic_light_state != TLS::Green &&
55 traffic_light_state != TLS::Off &&
57 // 如果车辆在受交通信号灯影响的非信号交叉口,移除车辆
58 if (current_junction_id != -1) {
59 RemoveActor(ego_actor_id);
60 }
61 traffic_light_hazard = true; // 设置交通信号灯危险标志为真
62 }
63 // 车辆在非信号交叉口,处理其优先级
64 // 不要使用下一个条件,因为边界框可能会变为绿色
65 else if (current_junction_id != -1) {
66 if (affected_junction_id == -1 || affected_junction_id != current_junction_id) {
67 RemoveActor(ego_actor_id); // 移除车辆
68 } else {
69 traffic_light_hazard = HandleNonSignalisedJunction(ego_actor_id, affected_junction_id, current_timestamp); // 处理非信号交叉口
70 }
71 }
72 // 如果在受影响的交叉口且不在交通信号灯处
73 else if (affected_junction_id != -1 &&
74 !is_at_traffic_light &&
75 traffic_light_state != TLS::Green &&
77
78 AddActorToNonSignalisedJunction(ego_actor_id, affected_junction_id); // 将车辆添加到非信号交叉口
79 traffic_light_hazard = true; // 设置交通信号灯危险标志为真
80 }
81 }
82 output_array.at(index) = traffic_light_hazard; // 将结果输出到数组
83}
84
85// 将车辆添加到非信号交叉口的函数
86void TrafficLightStage::AddActorToNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id) {
87
88 if (entering_vehicles_map.find(junction_id) == entering_vehicles_map.end()) {
89 // 初始化新的交叉口映射条目,使用空的车辆双端队列
90 std::deque<ActorId> entry_deque;
91 entering_vehicles_map.insert({junction_id, entry_deque});
92 }
93
94 auto& entering_vehicles = entering_vehicles_map.at(junction_id); // 获取进入该交叉口的车辆列表
95 if (std::find(entering_vehicles.begin(), entering_vehicles.end(), ego_actor_id) == entering_vehicles.end()){
96 // 如果车辆不在进入列表中,则添加车辆
97 entering_vehicles.push_back(ego_actor_id);
98 if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) {
99 // 如果车辆正在进入另一个交叉口,移除所有存储的数据
100 RemoveActor(ego_actor_id);
101 }
102 vehicle_last_junction.insert({ego_actor_id, junction_id}); // 更新车辆的最后交叉口信息
103 }
104}
105
106bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id,
107 cc::Timestamp timestamp) {
108
109 bool traffic_light_hazard = false; // 初始化交通信号危险标志为假
110
111 auto& entering_vehicles = entering_vehicles_map.at(junction_id); // 获取进入该交叉口的车辆列表
112
113 if (vehicle_stop_time.find(ego_actor_id) == vehicle_stop_time.end()) { // 检查该车辆是否已记录停车时间
114 // 确保车辆在执行其他操作之前已经停止
115 if (simulation_state.GetVelocity(ego_actor_id).Length() < EPSILON_RELATIVE_SPEED) { // 如果车辆速度接近零
116 vehicle_stop_time.insert({ego_actor_id, timestamp}); // 记录停车时间
117 }
118 traffic_light_hazard = true; // 标记为交通信号危险
119 }
120
121 else if (entering_vehicles.front() == ego_actor_id) { // 如果该车辆是进入交叉口的第一辆车
122 auto entry_elapsed_seconds = vehicle_stop_time.at(ego_actor_id).elapsed_seconds; // 获取停车已过的时间
123 if (timestamp.elapsed_seconds - entry_elapsed_seconds < MINIMUM_STOP_TIME) { // 如果停车时间不足
124 // 等待至少最低停车时间再进入交叉口
125 traffic_light_hazard = true; // 标记为交通信号危险
126 }
127 } else {
128 // 只有一辆车可以进入交叉口,其他车辆需停下。
129 traffic_light_hazard = true; // 标记为交通信号危险
130 }
131 return traffic_light_hazard; // 返回交通信号危险标志
132}
133
135 const Buffer &waypoint_buffer = buffer_map.at(ego_actor_id); // 获取车辆的路径缓冲区
136 const SimpleWaypointPtr look_ahead_point = GetTargetWaypoint(waypoint_buffer, JUNCTION_LOOK_AHEAD).first; // 获取前方目标路点
137 const auto front_point = waypoint_buffer.front(); // 获取路径中的第一个点
138
139 auto look_ahead_junction_id = look_ahead_point->GetJunctionId(); // 获取前方目标路点的交叉口ID
140 auto front_junction_id = front_point->GetJunctionId(); // 获取第一个点的交叉口ID
141
142 // 检查车辆是否当前在一个非信号化的交叉口
143 JunctionID current_junction_id = -1; // 初始化当前交叉口ID为-1
144 if (vehicle_last_junction.find(ego_actor_id) != vehicle_last_junction.end()) { // 如果已记录该车辆的最后交叉口
145 current_junction_id = vehicle_last_junction.at(ego_actor_id); // 获取当前交叉口ID
146 }
147
148 if (current_junction_id != -1) { // 如果正在处理一个交叉口
149 if (current_junction_id == look_ahead_junction_id) { // 如果当前交叉口与前方交叉口相同
150 return look_ahead_junction_id; // 返回前方交叉口ID
151 } else {
152 if (look_ahead_junction_id != -1) { // 如果前方交叉口不为-1
153 // 检测到不同的交叉口
154 return look_ahead_junction_id; // 返回前方交叉口ID
155 } else {
156 if (current_junction_id == front_junction_id) { // 如果当前交叉口与第一个点的交叉口相同
157 // 仍在同一交叉口
158 return front_junction_id; // 返回第一个点的交叉口ID
159 } else {
160 return -1; // 返回-1,表示没有有效交叉口
161 }
162 }
163 }
164 } else {
165 // 如果不在处理任何交叉口,返回前方检测到的交叉口
166 return look_ahead_junction_id; // 返回前方交叉口ID
167 }
168}
169
171 if (vehicle_last_junction.find(actor_id) != vehicle_last_junction.end()) { // 检查车辆是否有记录的最后交叉口
172 auto junction_id = vehicle_last_junction.at(actor_id); // 获取该车辆的最后交叉口ID
173
174 auto& entering_vehicles = entering_vehicles_map.at(junction_id); // 获取进入该交叉口的车辆列表
175 auto ent_index = std::find(entering_vehicles.begin(), entering_vehicles.end(), actor_id); // 查找该车辆在列表中的位置
176 if (ent_index != entering_vehicles.end()) { // 如果找到了该车辆
177 entering_vehicles.erase(ent_index); // 从列表中移除该车辆
178 }
179
180 if (vehicle_stop_time.find(actor_id) != vehicle_stop_time.end()) { // 检查车辆是否有停车时间记录
181 vehicle_stop_time.erase(actor_id); // 移除该车辆的停车时间记录
182 }
183
184 vehicle_last_junction.erase(actor_id); // 移除该车辆的最后交叉口记录
185 }
186}
187
189 entering_vehicles_map.clear(); // 清空进入车辆的映射
190 vehicle_last_junction.clear(); // 清空最后交叉口的映射
191 vehicle_stop_time.clear(); // 清空停车时间记录
192}
193
194} // namespace traffic_manager
195} // namespace carla
double elapsed_seconds
模拟自当前情境开始以来经过的秒数。
Definition Timestamp.h:40
const Timestamp & GetTimestamp() const
WorldSnapshot GetSnapshot() const
返回当前世界的快照。 快照(Snapshot)包含了模拟世界在某一时刻的整体状态信息,例如所有参与者的位置、状态,天气情况等, 可以用于记录、对比不同时刻的世界状态或者进行一些基于特定时刻状态的分析和操...
Definition World.cpp:102
float GetPercentageRunningSign(const ActorId &actor_id) const
获取百分比以运行任何交通灯的方法
float GetPercentageRunningLight(const ActorId &actor_id) const
获取百分比以运行任何交通灯的方法
该类保持了仿真中所有车辆的状态。
cg::Vector3D GetVelocity(const ActorId actor_id) const
TrafficLightState GetTLS(const ActorId actor_id) const
bool IsDormant(const ActorId actor_id) const
void AddActorToNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id)
void Update(const unsigned long index) override
更新方法。
JunctionID GetAffectedJunctionId(const ActorId ego_actor_id)
std::unordered_map< ActorId, JunctionID > vehicle_last_junction
std::unordered_map< ActorId, cc::Timestamp > vehicle_stop_time
void RemoveActor(const ActorId actor_id) override
移除参与者方法。
const std::vector< ActorId > & vehicle_id_list
std::unordered_map< JunctionID, std::deque< ActorId > > entering_vehicles_map
bool HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id, cc::Timestamp timestamp)
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::vector< bool > TLFrame
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
carla::road::JuncId JunctionID
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &target_point_distance)
carla::ActorId ActorId
参与者的智能指针类型
std::unordered_map< carla::ActorId, Buffer > BufferMap
CARLA模拟器的主命名空间。
Definition Carla.cpp:139