CARLA
 
载入中...
搜索中...
未找到
ALSM.cpp
浏览该文件的文档.
1
2#include "boost/pointer_cast.hpp"
3
4#include "carla/client/Actor.h" //导入 Actor 类
5#include "carla/client/Vehicle.h" //导入 Vehicle (车辆)类
6#include "carla/client/Walker.h" //导入 Walker (行人)类
7
8#include "carla/trafficmanager/Constants.h" //导入交通管理中的常量定义
9#include "carla/trafficmanager/LocalizationUtils.h" //导入定义相关的工具
10#include "carla/trafficmanager/SimpleWaypoint.h" //导入 SimpleWaypoint 类
11
12#include "carla/trafficmanager/ALSM.h" //导入 ALSM 类的声明
13
14namespace carla {
15namespace traffic_manager {
16
17//ALSM 类的构造函数,用于初始化各个模块
18ALSM::ALSM(
19 AtomicActorSet &registered_vehicles, //已注册车辆的集合
20 BufferMap &buffer_map, //存储交通流中路径缓存
21 TrackTraffic &track_traffic, //用于追踪交通的模块
22 std::vector<ActorId>& marked_for_removal, //标记即将移除的车辆 ID 列表
23 const Parameters &parameters, //系统的参数配置
24 const cc::World &world, //代表仿真世界
25 const LocalMapPtr &local_map, //本地地图指针,用于交通管理
26 SimulationState &simulation_state, //仿真状态
27 LocalizationStage &localization_stage, //定位模块
28 CollisionStage &collision_stage,//碰撞检测模块
29 TrafficLightStage &traffic_light_stage, //交通信号灯控制模块
30 MotionPlanStage &motion_plan_stage, //运动规划模块
31 VehicleLightStage &vehicle_light_stage) //车辆灯光控制模块
32 : registered_vehicles(registered_vehicles), //初始化已注册车辆
33 buffer_map(buffer_map), //初始化路径缓存
34 track_traffic(track_traffic), //初始化交通追踪器
35 marked_for_removal(marked_for_removal), //初始化将移除的车辆列表
36 parameters(parameters), //初始化系统参数
37 world(world), //初始化仿真世界
38 local_map(local_map), //初始化本地地图
39 simulation_state(simulation_state), //初始化仿真状态
40 localization_stage(localization_stage), //初始化定位模块
41 collision_stage(collision_stage), //初始化碰撞检测模块
42 traffic_light_stage(traffic_light_stage), //初始化交通信号灯控制模块
43 motion_plan_stage(motion_plan_stage), //初始化运动规划模块
44 vehicle_light_stage(vehicle_light_stage) {} //初始化车辆灯光控制模块
45
46void ALSM::Update() {
47 //获取是否启用混合物理模式参数
48 bool hybrid_physics_mode = parameters.GetHybridPhysicsMode();
49 //定义两个集合用于存储世界中的车辆 ID 和行人 ID
50 std::set<ActorId> world_vehicle_ids;
51 std::set<ActorId> world_pedestrian_ids;
52 //存储待删除的未注册参与者的 ID 列表
53 std::vector<ActorId> unregistered_list_to_be_deleted;
54
55 current_timestamp = world.GetSnapshot().GetTimestamp(); //获取当前时间截
56 ActorList world_actors = world.GetActors();//获取当前世界中的所有参与者列表
57
58 // 找到已经销毁的参与者并进行清理
59 const ALSM::DestroyeddActors destroyed_actors = IdentifyDestroyedActors(world_actors);
60
61 //处理已注册的被销毁的参与者
62 const ActorIdSet &destroyed_registered = destroyed_actors.first;
63 for (const auto &deletion_id: destroyed_registered) {
64 RemoveActor(deletion_id, true); //删除角色并标记为注册参与者
65 }
66 //处理未注册的被销毁参与者
67 const ActorIdSet &destroyed_unregistered = destroyed_actors.second;
68 for (auto deletion_id : destroyed_unregistered) {
69 RemoveActor(deletion_id, false);
70 }
71
72 // 检查英雄参与者是否存活,如果英雄参与者已被销毁,则将其从英雄列表中移除
73 if (hero_actors.size() != 0u) {
74 ActorIdSet hero_actors_to_delete;
75 //遍历英雄参与者,查看它们是否已被销毁
76 for (auto &hero_actor_info: hero_actors) {
77 //如果在未注册销毁列表中找到英雄参与者,则标记其删除
78 if (destroyed_unregistered.find(hero_actor_info.first) != destroyed_unregistered.end()) {
79 hero_actors_to_delete.insert(hero_actor_info.first);
80 }
81 //如果在已注册销毁列表中找到英雄参与者,则标记其删除
82 if (destroyed_registered.find(hero_actor_info.first) != destroyed_registered.end()) {
83 hero_actors_to_delete.insert(hero_actor_info.first);
84 }
85 }
86
87 //删除所有已标记的英雄参与者
88 for (auto &deletion_id: hero_actors_to_delete) {
89 hero_actors.erase(deletion_id);
90 }
91 }
92
93 // 扫描并识别新的未注册参与者
94 IdentifyNewActors(world_actors);
95
96 // 更新所有已注册的车辆的动态状态和静态属性
97 ALSM::IdleInfo max_idle_time = std::make_pair(0u, current_timestamp.elapsed_seconds);
98 UpdateRegisteredActorsData(hybrid_physics_mode, max_idle_time);
99
100 // 如果某辆已注册的车在某位置停留过久,则销毁该车辆
101 if (IsVehicleStuck(max_idle_time.first)
102 && (current_timestamp.elapsed_seconds - elapsed_last_actor_destruction) > DELTA_TIME_BETWEEN_DESTRUCTIONS
103 && hero_actors.find(max_idle_time.first) == hero_actors.end()) {
104 // 如果车辆被卡住,且它不是英雄参与者,并且距离上次销毁的时间超过了预设的时间间隔,则销毁该车辆。
105
106 registered_vehicles.Destroy(max_idle_time.first); // 销毁长时间停滞不动的车辆
107 RemoveActor(max_idle_time.first, true); //从已注册的参与者中移除该辆车
108 elapsed_last_actor_destruction = current_timestamp.elapsed_seconds;//更新上一次销毁的时间
109 }
110
111 //分阶段销毁标记为移除的车辆
112 if (parameters.GetOSMMode()) {
113 //如果系统处于 OSM 模式,遍历标记为移除的参与者列表
114 for (const ActorId& actor_id: marked_for_removal) {
115 registered_vehicles.Destroy(actor_id); //销毁这些标记为移除的车辆
116 RemoveActor(actor_id, true); //从已注册参与者列表中移除
117 }
118 marked_for_removal.clear(); //清空标记为移除的参与者列表
119 }
120
121 // 更新未注册参与者的动态状态和静态属性
122 UpdateUnregisteredActorsData();
123}
124
125//识别新的参与者
126void ALSM::IdentifyNewActors(const ActorList &actor_list) {
127 //遍历传入的参与者列表
128 for (auto iter = actor_list->begin(); iter != actor_list->end(); ++iter) {
129 ActorPtr actor = *iter; //获取当前的参与者对象
130 ActorId actor_id = actor->GetId(); //获取当前参与者的唯一标识符(ID)
131 // 识别新的英雄车辆
132 if (actor->GetTypeId().front() == 'v') { //通过其类型(ID)判断当前参与者
133 //如果没有任何已识别的英雄车辆,或者该参与者不在英雄参与者列表中
134 if (hero_actors.size() == 0u || hero_actors.find(actor_id) == hero_actors.end()) {
135 //遍历该参与者的所有属性
136 for (auto&& attribute: actor->GetAttributes()) {
137 //如果属性的 ID 是 "role_name",并且其值是 "hero"
138 if (attribute.GetId() == "role_name" && attribute.GetValue() == "hero") {
139 //将英雄车辆插入到英雄列表中
140 hero_actors.insert({actor_id, actor});
141 }
142 }
143 }
144 }
145 //如果该参与者不在已注册车辆列表中,且不在未注册的参与者列表中
146 if (!registered_vehicles.Contains(actor_id)
147 && unregistered_actors.find(actor_id) == unregistered_actors.end()) {
148 //将该参与者添加到未注册参与者中
149 unregistered_actors.insert({actor_id, actor});
150 }
151 }
152}
153
154//识别已销毁的参与者
155ALSM::DestroyeddActors ALSM::IdentifyDestroyedActors(const ActorList &actor_list) {
156
157 ALSM::DestroyeddActors destroyed_actors; //用于存储销毁的参与者 ID
158 ActorIdSet &deleted_registered = destroyed_actors.first; //存储已销毁的注册车辆的 ID
159 ActorIdSet &deleted_unregistered = destroyed_actors.second; //存储已销毁的未注册参与者的 ID
160
161 //构建当前帧中存在的参与者的哈希集合
162 ActorIdSet current_actors;
163 for (auto iter = actor_list->begin(); iter != actor_list->end(); ++iter) {
164 current_actors.insert((*iter)->GetId()); //将当前参与者的 ID 插入集合中
165 }
166
167 // 查找被销毁的已注册车辆
168 std::vector<ActorId> registered_ids = registered_vehicles.GetIDList();
169 for (const ActorId &actor_id : registered_ids) {
170 //如果当前帧中不存在某个已注册车辆
171 if (current_actors.find(actor_id) == current_actors.end()) {
172 //将该车辆的 ID 加入到已销毁的注册车辆列表中
173 deleted_registered.insert(actor_id);
174 }
175 }
176
177 // 查找被销毁的未注册参与者
178 for (const auto &actor_info: unregistered_actors) {
179 const ActorId &actor_id = actor_info.first;
180 //如果当前帧中不存在某个未注册的参与者,或者该参与者已经注册为车辆
181 if (current_actors.find(actor_id) == current_actors.end()
182 || registered_vehicles.Contains(actor_id)) {
183 //将该参与者的 ID 加入到已销毁的未注册参与者列表中
184 deleted_unregistered.insert(actor_id);
185 }
186 }
187 //返回销毁的参与者列表
188 return destroyed_actors;
189}
190
191void ALSM::UpdateRegisteredActorsData(const bool hybrid_physics_mode, ALSM::IdleInfo &max_idle_time) {
192
193 //获取所有注册车辆的列表
194 std::vector<ActorPtr> vehicle_list = registered_vehicles.GetList();
195 //检查是否有英雄车辆存在
196 bool hero_actor_present = hero_actors.size() != 0u;
197 //获取混合物理模式下的半径值
198 float physics_radius = parameters.GetHybridPhysicsRadius();
199 //计算半径的平方值
200 float physics_radius_square = SQUARE(physics_radius);
201 //检查是否启用了重生功能
202 bool is_respawn_vehicles = parameters.GetRespawnDormantVehicles();
203 //如果启用了重生功能且没有英雄车辆,将英雄车辆设置为(0,0,0)
204 if (is_respawn_vehicles && !hero_actor_present) {
205 track_traffic.SetHeroLocation(cg::Location(0,0,0));
206 }
207 // 首先更新英雄车辆的信息
208 for (auto &hero_actor_info: hero_actors){
209 //如果启用了重生功能,设置英雄车辆的当前位置
210 if (is_respawn_vehicles) {
211 track_traffic.SetHeroLocation(hero_actor_info.second->GetTransform().location);
212 }
213 //更新英雄车辆的数据,传入是否处于混合物理模式、英雄车辆、是否有英雄车辆存在、物理半径平方等参数
214 UpdateData(hybrid_physics_mode, hero_actor_info.second, hero_actor_present, physics_radius_square);
215 }
216 // 更新其他注册车辆的信息
217 for (const Actor &vehicle : vehicle_list) {
218 //获取车辆的 ID
219 ActorId actor_id = vehicle->GetId();
220 //如果车辆不是英雄车辆,更新该车辆的数据
221 if (hero_actors.find(actor_id) == hero_actors.end()) {
222 //更新车辆数据
223 UpdateData(hybrid_physics_mode, vehicle, hero_actor_present, physics_radius_square);
224 //更新该车辆的空闲时间信息
225 UpdateIdleTime(max_idle_time, actor_id);
226 }
227 }
228}
229
230void ALSM::UpdateData(const bool hybrid_physics_mode, const Actor &vehicle,
231 const bool hero_actor_present, const float physics_radius_square) {
232
233 //获取车辆的ID和位置信息
234 ActorId actor_id = vehicle->GetId();
235 cg::Transform vehicle_transform = vehicle->GetTransform();
236 cg::Location vehicle_location = vehicle_transform.location;
237 cg::Rotation vehicle_rotation = vehicle_transform.rotation;
238 cg::Vector3D vehicle_velocity = vehicle->GetVelocity();
239 //检查仿真状态中是否包含当前车辆的状态信息
240 bool state_entry_present = simulation_state.ContainsActor(actor_id);
241
242 //初始化空闲时间
243 if (idle_time.find(actor_id) == idle_time.end() && current_timestamp.elapsed_seconds != 0.0) {
244 idle_time.insert({actor_id, current_timestamp.elapsed_seconds});
245 }
246
247 // 检查当前车辆是否在英雄车辆的范围内,并在混合物理模式下启用物理仿真
248 bool in_range_of_hero_actor = false;
249 if (hero_actor_present && hybrid_physics_mode) {
250 for (auto &hero_actor_info: hero_actors) {
251 const ActorId &hero_actor_id = hero_actor_info.first;
252 if (simulation_state.ContainsActor(hero_actor_id)) {
253 const cg::Location &hero_location = simulation_state.GetLocation(hero_actor_id);
254 if (cg::Math::DistanceSquared(vehicle_location, hero_location) < physics_radius_square) {
255 in_range_of_hero_actor = true;
256 break;
257 }
258 }
259 }
260 }
261
262 //根据混合物理模式和是否在英雄车辆范围内决定是否启用物理仿真
263 bool enable_physics = hybrid_physics_mode ? in_range_of_hero_actor : true;
264 if (!has_physics_enabled.count(actor_id) || has_physics_enabled[actor_id] != enable_physics) {
265 // 如果当前车辆不是英雄车辆,则更新物理仿真状态
266 if (hero_actors.find(actor_id) == hero_actors.end()) {
267 vehicle->SetSimulatePhysics(enable_physics);
268 has_physics_enabled[actor_id] = enable_physics;
269 //如果启用了物理仿真,并且仿真状态中存在车辆状态信息,则设置目标速度
270 if (enable_physics == true && state_entry_present) {
271 vehicle->SetTargetVelocity(simulation_state.GetVelocity(actor_id));
272 }
273 }
274 }
275
276 // 如果物理仿真被禁用,根据位置变化计算速度
277 // 不要使用 'enable_physics' ,因为在这一刻关闭物理仿真并不会移除当前速度
278 // 为了避免其他客户端导致的对象位置偏移问题,使用之前记录的输出位置
279 if (state_entry_present && !simulation_state.IsPhysicsEnabled(actor_id)){
280 cg::Location previous_location = simulation_state.GetLocation(actor_id);
281 cg::Location previous_end_location = simulation_state.GetHybridEndLocation(actor_id);
282 cg::Vector3D displacement = (previous_end_location - previous_location);
283 vehicle_velocity = displacement * INV_HYBRID_DT;
284 }
285
286 // 更新运动学状态对象
287 auto vehicle_ptr = boost::static_pointer_cast<cc::Vehicle>(vehicle);
288 KinematicState kinematic_state{vehicle_location, vehicle_rotation,
289 vehicle_velocity, vehicle_ptr->GetSpeedLimit(),
290 enable_physics, vehicle->IsDormant(), cg::Location()};
291
292 // 更新交通信号状态对象
293 TrafficLightState tl_state = {vehicle_ptr->GetTrafficLightState(), vehicle_ptr->IsAtTrafficLight()};
294
295 // 更新仿真状态
296 if (state_entry_present) {
297 simulation_state.UpdateKinematicState(actor_id, kinematic_state);
298 simulation_state.UpdateTrafficLightState(actor_id, tl_state);
299 }
300 else {
301 // 如果是新车辆,添加静态属性,包括车辆的类型和边界尺寸
302 cg::Vector3D dimensions = vehicle_ptr->GetBoundingBox().extent;
303 StaticAttributes attributes{ActorType::Vehicle, dimensions.x, dimensions.y, dimensions.z};
304
305 // 将新的车辆及其状态添加到仿真状态中
306 simulation_state.AddActor(actor_id, kinematic_state, attributes, tl_state);
307 }
308}
309
310
311void ALSM::UpdateUnregisteredActorsData() {
312 //遍历所有未注册的参与者
313 for (auto &actor_info: unregistered_actors) {
314
315 const ActorId actor_id = actor_info.first; //获取参与者的 ID
316 const ActorPtr actor_ptr = actor_info.second; //获取参与者的指针
317 const std::string type_id = actor_ptr->GetTypeId(); //获取参与者的类型 ID
318
319 const cg::Transform actor_transform = actor_ptr->GetTransform(); //获取参与者的变换信息
320 const cg::Location actor_location = actor_transform.location; //获取参与者的位置
321 const cg::Rotation actor_rotation = actor_transform.rotation; //获取参与者的旋转信息
322 const cg::Vector3D actor_velocity = actor_ptr->GetVelocity(); //获取参与者的速度
323 const bool actor_is_dormant = actor_ptr->IsDormant(); //判断参与者是否处于休眠状态
324 //创建运动状态对象
325 KinematicState kinematic_state {actor_location, actor_rotation, actor_velocity, -1.0f, true, actor_is_dormant, cg::Location()};
326
327 TrafficLightState tl_state; //交通灯状态
328 ActorType actor_type = ActorType::Any; //参与者类型
329 cg::Vector3D dimensions; //参与者的尺寸
330 std::vector<SimpleWaypointPtr> nearest_waypoints; //最近的路点
331
332 //检查参与者在模拟状态中是否存在条目
333 bool state_entry_not_present = !simulation_state.ContainsActor(actor_id);
334 if (type_id.front() == 'v') { //如果是车辆
335 auto vehicle_ptr = boost::static_pointer_cast<cc::Vehicle>(actor_ptr); //转换为车辆指针
336 kinematic_state.speed_limit = vehicle_ptr->GetSpeedLimit(); //获取车辆的速度限制
337
338 tl_state = {vehicle_ptr->GetTrafficLightState(), vehicle_ptr->IsAtTrafficLight()}; //获取交通灯状态
339
340 if (state_entry_not_present) {
341 dimensions = vehicle_ptr->GetBoundingBox().extent; //获取车辆的边界框尺寸
342 actor_type = ActorType::Vehicle; //设置参与者类型为车辆
343 StaticAttributes attributes {actor_type, dimensions.x, dimensions.y, dimensions.z}; //创建静态属性
344
345 //添加参与者到模拟状态
346 simulation_state.AddActor(actor_id, kinematic_state, attributes, tl_state);
347 } else {
348 // 更新运动状态和交通灯状态
349 simulation_state.UpdateKinematicState(actor_id, kinematic_state);
350 simulation_state.UpdateTrafficLightState(actor_id, tl_state);
351 }
352
353 // 确定占用的路点
354 cg::Vector3D extent = vehicle_ptr->GetBoundingBox().extent; // 获取车辆的尺寸
355 cg::Vector3D heading_vector = vehicle_ptr->GetTransform().GetForwardVector(); //获取车辆的朝向向量
356 // 计算车辆四个角的位置
357 std::vector<cg::Location> corners = {actor_location + cg::Location(extent.x * heading_vector),
358 actor_location,
359 actor_location + cg::Location(-extent.x * heading_vector)};
360 for (cg::Location &vertex: corners) {
361 SimpleWaypointPtr nearest_waypoint = local_map->GetWaypoint(vertex); //获取最近的路点
362 nearest_waypoints.push_back(nearest_waypoint); //添加到最近路点列表
363 }
364 }
365 else if (type_id.front() == 'w') { //如果是行人
366 auto walker_ptr = boost::static_pointer_cast<cc::Walker>(actor_ptr); //转换为行人指针
367
368 if (state_entry_not_present) {
369 dimensions = walker_ptr->GetBoundingBox().extent; //获取行人的边界框尺寸
370 actor_type = ActorType::Pedestrian; //设置参与者类型为行人
371 StaticAttributes attributes {actor_type, dimensions.x, dimensions.y, dimensions.z}; //创建静态属性
372
373 // 添加参与者到模拟状态
374 simulation_state.AddActor(actor_id, kinematic_state, attributes, tl_state);
375 } else {
376 // 更新运动状态
377 simulation_state.UpdateKinematicState(actor_id, kinematic_state);
378 }
379
380 // 确定占用的路点
381 SimpleWaypointPtr nearest_waypoint = local_map->GetWaypoint(actor_location); //获取最近的路线
382 nearest_waypoints.push_back(nearest_waypoint); //添加到最近路点列表
383 }
384 //更新未注册参与者的网络位置
385 track_traffic.UpdateUnregisteredGridPosition(actor_id, nearest_waypoints);
386 }
387}
388
389void ALSM::UpdateIdleTime(std::pair<ActorId, double>& max_idle_time, const ActorId& actor_id) {
390 // 检查参与者的空闲时间是否存在于空闲时间映射中
391 if (idle_time.find(actor_id) != idle_time.end()) {
392 // 获取参与者的空闲持续时间
393 double &idle_duration = idle_time.at(actor_id);
394 // 检查参与者的速度是否超过停止阈值
395 if (simulation_state.GetVelocity(actor_id).SquaredLength() > SQUARE(STOPPED_VELOCITY_THRESHOLD)) {
396 //如果速度超过阈值,则更新空闲时间为当前时间截
397 idle_duration = current_timestamp.elapsed_seconds;
398 }
399
400 // 检查并更新最大空闲时间
401 if (max_idle_time.first == 0u || max_idle_time.second > idle_duration) {
402 max_idle_time = std::make_pair(actor_id, idle_duration);
403 }
404 }
405}
406
407//检查车辆是否被卡住
408bool ALSM::IsVehicleStuck(const ActorId& actor_id) {
409 // 检查参与者的空闲时间是否存在
410 if (idle_time.find(actor_id) != idle_time.end()) {
411 // 计算自上次纪录以来的空闲时间增量
412 double delta_idle_time = current_timestamp.elapsed_seconds - idle_time.at(actor_id);
413 // 获取交通灯状态
414 TrafficLightState tl_state = simulation_state.GetTLS(actor_id);
415 // 检查是否超过红灯阻塞时间阈值或非红灯状态的阻塞时间阈值
416 if ((delta_idle_time >= RED_TL_BLOCKED_TIME_THRESHOLD)
417 || (delta_idle_time >= BLOCKED_TIME_THRESHOLD && tl_state.tl_state != TLS::Red))
418 {
419 return true; // 车辆被认为是卡住的
420 }
421 }
422 return false; //车辆被没有认为是卡住的
423}
424
425// 移除指定的参与者
426void ALSM::RemoveActor(const ActorId actor_id, const bool registered_actor) {
427 // 如果参与者是已注册的
428 if (registered_actor) {
429 // 从注册车辆中移除参与者
430 registered_vehicles.Remove({actor_id});
431 // 从缓冲区、空闲时间、定位阶段等中移除参与者
432 buffer_map.erase(actor_id);
433 idle_time.erase(actor_id);
434 localization_stage.RemoveActor(actor_id);
435 collision_stage.RemoveActor(actor_id);
436 traffic_light_stage.RemoveActor(actor_id);
437 motion_plan_stage.RemoveActor(actor_id);
438 vehicle_light_stage.RemoveActor(actor_id);
439 }
440 else {
441 // 如果参与者未注册,则从未注册参与者和英雄参与者集合中移除
442 unregistered_actors.erase(actor_id);
443 hero_actors.erase(actor_id);
444 }
445
446 //从交通监控系统中删除参与者
447 track_traffic.DeleteActor(actor_id);
448 // 从仿真状态中移除参与者
449 simulation_state.RemoveActor(actor_id);
450}
451
452// 重置状态
453void ALSM::Reset() {
454 // 清空未注册参与者、空闲时间、英雄参与者等数据
455 unregistered_actors.clear();
456 idle_time.clear();
457 hero_actors.clear();
458 elapsed_last_actor_destruction = 0.0; // 重置上次参与者销毁的时间
459 current_timestamp = world.GetSnapshot().GetTimestamp(); // 更新当前时间截
460}
461
462} // namespace traffic_manager
463} // namespace carla
TSharedPtr< const FActorInfo > carla::rpc::ActorState UWorld Actor
#define SQUARE(a)
This file contains various constants used in traffic manager arranged into sensible namespaces for re...
Definition Constants.h:13
uint32_t ActorId
Definition ActorId.h:20
carla::SharedPtr< cc::Actor > ActorPtr
使用别名简化代码中的命名
std::shared_ptr< InMemoryMap > LocalMapPtr
本地地图指针类型,使用智能指针管理InMemoryMap对象
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
std::unordered_set< ActorId > ActorIdSet
std::unordered_map< carla::ActorId, Buffer > BufferMap
CARLA模拟器的主命名空间。
Definition Carla.cpp:139