交通管理器
什么是交通管理器?
交通管理器 (Traffic Manager, TM) 是在模拟中以自动驾驶模式控制车辆的模块。其目标是在模拟中填充真实的城市交通状况。用户可以自定义一些行为,例如设置特定的学习环境。
结构化设计
交通管理器构建于 Carla 的客户端之上。执行流程分为多个阶段,每个阶段都有独立的操作和目标。这有利于相位相关功能和数据结构的开发,同时提高计算效率。每个阶段都在不同的线程上运行。与其他阶段的通信通过同步消息传递进行管理。信息朝一个方向流动。
用户定制
用户可以通过设置允许、强制或鼓励特定行为的参数来对流量进行一定程度的控制。用户可以根据自己的喜好改变流量行为,无论是在线还是离线。例如,可以允许汽车忽略速度限制或强制变道。在尝试模拟现实时,能够尝试各种行为是必不可少的。驾驶系统需要在特定和非典型情况下进行训练。
架构
概述
上图是交通管理器的内部架构示意图。每个组件的 C++ 代码可以在 LibCarla/source/carla/trafficmanager
中找到。以下各节详细解释了每个组件。逻辑概述如下:
1. 存储并更新模拟的当前状态。
- 代理的生命周期和状态管理 (Agent Lifecycle & State Management, ALSM) 扫描世界,跟踪所有存在的车辆和行人,并清理不再存在的条目。所有数据均从服务器检索并经过多个阶段。ALSM 是唯一调用服务器的组件。
- 车辆注册表 包含一系列处于自动驾驶状态的车辆(由交通管理器控制)以及一系列不处于自动驾驶状态(不受交通管理器控制控制)的行人和车辆。
- 模拟状态 是模拟中所有车辆和行人的位置、速度和附加信息的缓存存储。
2. 计算每辆自动驾驶车辆的运动。
交通管理器根据模拟状态为车辆注册表中的所有车辆生成可行的命令。每辆车的计算都是单独进行的。这些计算分为不同的阶段。控制循环通过在阶段之间创建同步屏障来确保所有计算的一致性。在当前阶段的所有车辆计算完成之前,没有车辆进入下一阶段。每辆车都会经历以下阶段:
2.1 - 定位阶段
路径是使用从内存地图中收集的附近路径点列表动态创建的,内存地图是模拟地图作为路径点网格的简化。路口的方向是随机选择的。每辆车的路径均由路径缓存和车辆轨迹(Path Buffers & Vehicle Tracking, PBVT) 组件存储和维护,以便在未来阶段轻松访问和修改。
2.2 - 碰撞阶段
边界框延伸到每辆车的路径上,以识别和导航潜在的碰撞危险。
2.3 - 交通灯阶段.
与碰撞阶段类似,会识别由于交通灯影响、停车标志和路口优先级而影响每辆车路径的潜在危险。
2.4 - 运动规划器阶段.
车辆运动是根据定义的路径计算的。PID 控制器确定如何到达目标路径点。然后将其转换为 Carla 命令以供下一步应用。
2.5 - 车灯阶段.
车灯根据环境因素(例如阳光和雾或雨的存在)和车辆行为(例如,如果车辆将在下一个路口左转/右转,则打开方向指示灯;如果制动,则打开刹车灯)。
3. 在模拟中应用命令
上一步生成的命令被收集到命令数组中,批量发送到 Carla 服务器,在同一帧中应用。
以下部分将更详细地解释上述交通管理器逻辑中的每个组件和阶段。
代理的生命周期和状态管理
代理的生命周期和状态管理。它是交通管理器逻辑周期的第一步,提供模拟当前状态的上下文。
代理的生命周期和状态管理组件:
- 扫描世界以跟踪所有车辆和行人的位置和速度。如果启用物理功能,则通过Vehicle.get_velocity()检索速度。否则,将使用位置随时间更新的历史记录来计算速度。
- 存储模拟状态组件中每辆车和行人的位置、速度和附加信息(交通灯影响、边界框等)。
- 更新车辆注册表中交通管理器控制的车辆列表。
- 更新控制循环和路径缓存和车辆轨迹组件中的条目以匹配车辆注册表。
相关的 .cpp 文件: ALSM.h
, ALSM.cpp
.
车辆注册表
车辆注册表记录模拟中的所有车辆和行人。
车辆注册表:
- 从代理的生命周期和状态管理传递来最新的车辆和行人列表。
- 将注册到交通管理器的车辆存储在单独的数组中,以便在控制循环期间进行迭代。
相关的 .cpp 文件: MotionPlannerStage.cpp
.
模拟状态
模拟状态存储模拟中所有车辆的信息,以便在后期阶段轻松访问和修改。
模拟状态:
- 从代理的生命周期和状态管理接收数据,包括当前参与者位置、速度、交通灯影响、交通灯状态等。
- 将所有信息存储在缓存中,避免在控制循环期间对服务器的后续调用。
相关的 .cpp 文件: SimulationState.cpp
, SimulationState.h
.
控制循环
控制循环管理所有自动驾驶车辆的下一个命令的计算,以便它们同步执行。控制循环由五个不同的阶段组成;定位,碰撞,交通灯,运动规划和车辆灯。
控制循环:
- 从车辆注册表接收TM-控制的车辆数组。
- 通过循环遍历数组,分别对每辆车执行计算。
- 将计算分成一系列的阶段。
- 在阶段之间创建同步屏障以保证一致性。所有车辆的计算在任何车辆移动到下一阶段之前完成,确保所有车辆在同一帧中更新。
- 协调各阶段之间的过渡,使所有计算同步完成。
- 当最后一个阶段(运动规划阶段和车辆灯光阶段)完成时,将命令数组发送到服务器,因此在命令计算和命令应用之间没有帧延迟。
相关的 .cpp 文件: TrafficManagerLocal.cpp
.
内存地图
内存地图是包含在路径缓存和车辆轨迹中的辅助模块,在定位阶段使用。
内存地图:
- 将地图转换为离散路径点的网格。
- 包含特定数据结构中的路点,并提供更多信息来连接路点和识别道路、路口等。
- 通过识别这些建筑物的 ID 来快速定位附近区域的车辆。
相关的 .cpp 文件: InMemoryMap.cpp
and SimpleWaypoint.cpp
.
路径缓存和车辆轨迹
PBVT代表路径缓存和车辆轨迹。PBVT是一种数据结构,它包含每辆车的预期路径,并允许在控制循环期间轻松访问数据。
PBVT:
PID 控制器
PID控制器是在运动规划阶段执行计算的辅助模块。
PID 控制器:
相关的 .cpp 文件: PIDController.cpp
.
命令数组
命令数组表示交通管理器逻辑周期中的最后一步。它接收所有注册车辆的命令并应用它们。
命令数组:
- 从路径规划阶段接收一系列 carla.VehicleControl。
- 批处理要在同一帧内应用的所有命令。
- 将批处理发送到在 carla 中调用 apply_batch() 或 apply_batch_synch() 的 Carla 服务器.客户端,具体取决于模拟是分别以异步模式还是同步模式运行。
相关的 .cpp 文件: TrafficManagerLocal.cpp
.
控制循环的阶段
第 1 阶段 - 定位阶段
定位阶段为交通管理器控制的车辆定义了近未来的路径。
本地化阶段:
- 从模拟状态获取所有车辆的位置和速度。
- 使用内存地图将每辆车与路径点列表相关联,该路径点列表根据其轨迹描述其当前位置和近期路径。车辆行驶得越快,列表就越长。
- 根据规划决策更新路径,例如变道、限速、与前方车辆的距离参数化等。
- 将所有车辆的路径存储在 PBVT 模块中。
- 相互比较路径以估计可能的碰撞情况。结果将传递到碰撞阶段。
相关的 .cpp 文件: LocalizationStage.cpp
and LocalizationUtils.cpp
.
第 2 阶段 - 碰撞阶段
碰撞阶段会触发碰撞危险。
碰撞阶段:
- 从定位阶段接收路径可能重叠的车辆对列表。
- 前方路径(测地线边界)扩展每个车辆对的边界框,以检查它们是否实际重叠并确定碰撞风险是否真实。
- 将所有可能的碰撞的危险发送到 运动规划器阶段,以相应地修改路径。
相关的 .cpp 文件: CollisionStage.cpp
.
第三阶段 - 交通灯阶段
交通信号灯阶段会触发交通管制器造成的危险,例如交通信号灯、停车标志和路口的优先权。
交通灯阶段:
- 如果车辆受到黄色或红色交通信号灯或停车标志的影响,则设置交通危险。
- 如果边界框位于无信号灯的交汇点,则沿车辆路径延伸边界框。路径重叠的车辆遵循“先进先出”的顺序移动。等待时间设置为固定值。
相关的 .cpp 文件: TrafficLightStage.cpp
.
第 4 阶段 - 运动规划器阶段
“运动规划器阶段”(Motion Planner Stage) 生成要应用于车辆的 Carla 命令。
运动规划器阶段:
- 收集车辆的位置和速度(模拟状态))、路径 (路径缓存和车辆轨迹) 和危险(碰撞阶段和交通信号灯阶段)。
- 对车辆应如何移动做出高级决策,例如,计算防止碰撞危险所需的制动器。PID控制器用于根据目标值估计行为。
- 将期望的运动转化为适用于车辆的 carla.VehicleControl。
- 将生成的 Carla 命令发送到命令数组。
相关的.cpp文件: MotionPlannerStage.cpp
.
第 5 阶段 - 车灯阶段
车灯阶段根据车辆状况和周围环境激活车灯。
车灯阶段:
- 检索车辆的计划路径点、有关车辆灯光的信息(例如灯光状态和计划应用的命令)和天气状况。
- 确定车灯的新状态:
- 如果车辆计划在下一个路口左转/右转,则打开闪光灯。
- 如果应用的命令要求车辆制动,则打开停车灯。
- 从日落到黎明或在大雨中打开近光灯和位置灯。
- 在大雾条件下打开雾灯。
- 如果车灯状态已更改,请更新车灯状态。
相关的 .cpp 文件: VehicleLightStage.cpp
.
使用交通管理器
车辆行为考虑因素
交通管理器实现了将车辆设置为自动驾驶时必须考虑的一般行为模式:
- 车辆不是以目标为导向的,它们遵循动态产生的轨迹,并在接近路口时随机选择路径。他们的道路是无止境的。
- 除非设置了任何其他值,否则车辆的目标速度是其当前速度限制的 70%。
- 路口优先权不遵守交通法规。交通管理器在路口使用自己的优先级系统。此限制的解决工作正在进行中。同时,可能会出现一些问题,例如,环形交叉路口内的车辆让步给试图进入的车辆。
交通管理器行为可以通过 Python API 进行调整。有关具体方法,请参阅 Python API 文档的交通管理器部分。以下是通过 API 实现的功能的一般摘要:
主题 | 描述 |
---|---|
常规: | - 创建连接到端口的交通管理器实例。 - 检索交通管理器连接的端口。 |
安全条件: | - 设置停止车辆之间的最小距离(对于单个车辆或者所有车辆)。这将影响最小移动距离。 - 将所需速度设置为当前速度现状的百分比(对于单个车辆或所有车辆)。 - 重置交通信号灯。 |
碰撞管理: | - 启用/禁用车辆与特定参与者之间的碰撞。 - 让车辆忽略所有其他车辆。 - 让车辆忽略所有行人 - 让车辆忽略所有交通灯。 |
变道: | - 强制变道,忽略可能的碰撞。 - 启用/禁用车辆的变道。 |
混合物理模式: | - 启用/禁用混合物理模式。 - 更改启用物理的半径。 |
创建交通管理器
笔记
交通管理器设计为在同步模式下工作。在异步模式下使用交通管理器可能会导致意外和不良结果。有关详细信息,请参阅 同步模式。
交通管理器实例由 carla 创建.客户端
,传递要使用的端口。缺省端口为 8000
。
要创建交通管理器实例:
tm = client.get_trafficmanager(port)
要为一组车辆启用 autopilot,请检索交通管理器实例的端口并设置set_autopilot为True ,同时传递交通管理器端口。如果未提供端口,它将尝试连接到默认端口 (8000) 中的交通管理器。如果交通管理器不存在,它将创建一个。
tm_port = tm.get_port()
for v in vehicles_list:
v.set_autopilot(True,tm_port)
笔记
在多客户端情况下创建或连接到交通管理器与上述示例不同。
/PythonAPI/examples
中的 generate_traffic.py
脚本提供了一个示例,说明如何使用作为脚本参数传递的端口创建交通管理器实例,并通过批量将自动驾驶仪设置为以下值来注册生成的每辆车。
traffic_manager = client.get_trafficmanager(args.tm-port)
tm_port = traffic_manager.get_port()
...
batch.append(SpawnActor(blueprint, transform).then(SetAutopilot(FutureActor, True,tm_port)))
...
traffic_manager.global_percentage_speed_difference(30.0)
配置 autopilot 行为
以下示例创建一个交通管理器实例,并为特定车辆配置危险行为,使其忽略所有交通信号灯,不与其他车辆保持安全距离,并以比当前限速快 20% 的速度行驶:
tm = client.get_trafficmanager(port)
tm_port = tm.get_port()
for v in my_vehicles:
v.set_autopilot(True,tm_port)
danger_car = my_vehicles[0]
tm.ignore_lights_percentage(danger_car,100)
tm.distance_to_leading_vehicle(danger_car,0)
tm.vehicle_percentage_speed_difference(danger_car,-20)
以下示例将相同的车辆列表设置为自动驾驶仪,但将其配置为适度驾驶行为。车辆的行驶速度比当前限速慢 80%,与其他车辆之间至少留出 5 米的距离,并且从不进行变道:
tm = client.get_trafficmanager(port)
tm_port = tm.get_port()
for v in my_vehicles:
v.set_autopilot(True,tm_port)
danger_car = my_vehicles[0]
tm.global_distance_to_leading_vehicle(5)
tm.global_percentage_speed_difference(80)
for v in my_vehicles:
tm.auto_lane_change(v,False)
委派交通管理器自动更新车灯
默认情况下,交通管理器管理的车辆的车灯(刹车灯、转向灯等)永远不会更新。可以委托交通管理器来更新给定车辆参与者的车灯:
tm = client.get_trafficmanager(port)
for actor in my_vehicles:
tm.update_vehicle_lights(actor, True)
车灯管理必须按每辆车进行指定,并且在任何给定时间都可以有带和不带自动灯管理的车辆。
停止交通管理器
交通管理器是一个不需要被销毁的参与者;当创建它的客户端停止时,它将停止。这是由 API 自动管理的,用户无需执行任何操作。但是,在关闭交通管理器时,用户必须销毁由它控制的车辆,否则它们将在地图上保持不动。 generate_traffic.py
脚本会自动执行此操作:
client.apply_batch([carla.command.DestroyActor(x) for x in vehicles_list])
笔记
关闭 TM-Server 将关闭连接到它的 TM-Clients 。 要了解 TM-Server 和 TM-Client 之间的区别, 请阅读 Running multiple Traffic Managers。
确定性模式
在确定性模式下,交通管理器将在相同条件下产生相同的结果和行为。不要将确定性论误认为是记录器。虽然记录器允许您存储模拟日志以进行回放,但确定性可确保只要维持相同的条件,交通管理器在脚本的不同执行过程中始终具有相同的输出。
确定性模式 仅在同步模式下 可用。在异步模式下,对模拟的控制较少,并且无法实现确定性。在开始之前,请阅读同步模式部分的更多信息。
要启用确定性模式,请使用以下方法:
my_tm.set_random_device_seed(seed_value)
seed_value
是一个将生成随机数的数字的 int
种子数。该值本身并不相关,但相同的值将始终导致相同的输出。具有相同条件、使用相同种子值的两次模拟将是确定性的。
为了保持多次模拟运行的确定性,必须为每次模拟设置种子。例如,每次重新加载世界时,都必须重新设置种子:
client.reload_world()
my_tm.set_random_device_seed(seed_value)
可以通过将种子值作为参数传递来在示例脚本generate_traffic.py
中测试确定性模式。以下示例在同步模式下使用 50 个自动驾驶参与者填充地图,并将种子设置为任意值9
:
cd PythonAPI/examples
python3 generate_traffic.py -n 50 --seed 9
警告
在启用确定性模式之前,Carla 服务器和交通管理器必须处于同步模式。在此处阅读有关交通管理器中同步模式的更多信息。
混合物理模式
混合模式允许用户禁用所有自动驾驶车辆或标记为英雄
的车辆特定半径之外的自动驾驶车辆的大多数物理计算。这消除了模拟中的车辆物理瓶颈。物理功能被禁用的车辆将通过隐形传送移动。维持线性加速度的基本计算,以确保位置更新和车辆速度保持真实,并且车辆上物理计算的切换是流畅的。
混合模式使用 Actor.set_simulate_physics()
方法来切换物理计算。默认情况下它是禁用的。有两个选项可以启用它:
TrafficManager.set_hybrid_physics_mode(True)
— 此方法为调用它的交通管理器对象启用混合模式。- 以
--hybrid
标志运行generate_traffic.py
— 此示例脚本创建一个交通管理器并在自动驾驶仪中生成车辆。当标志--hybrid
作为脚本参数传递时,它将这些车辆设置为混合模式。
要修改混合模式的行为,请使用以下两个参数:
- Radius (默认 = 50 米) — 半径相对于标记有
英雄
的车辆。该半径内的所有车辆都将启用物理功能;半径之外的车辆将禁用物理功能。使用traffic_manager.set_hybrid_physics_radius(r)
修改半径的大小。 - Hero vehicle — 带有标记
role_name='hero'
的车辆作为半径的中心。 - 如果没有英雄车辆, 所有车辆的物理功能将被禁用。
- 如果有不止一辆英雄车辆, 则会考虑所有英雄车辆的半径,从而在启用物理功能的情况下创建不同的影响区域。
下面的剪辑显示了混合模式处于活动状态时如何启用和禁用物理功能。英雄车辆 标有 红色方块。禁用物理功能 的车辆标有 蓝色方块。当在英雄车辆的影响半径内时,启用物理功能 并且标签变为 绿色。
运行多个交通管理器
交通管理器的服务端和客户端
Carla 客户端通过向服务器指定要使用的端口来创建交通管理器。如果未指定端口,将使用默认 8000
端口。如果在同一端口上创建更多交通管理器,它们将成为 交通管理器的客户端,而原始交通管理器将成为 交通管理器的服务端。这些标题定义了交通管理器在模拟中的行为方式。
交通管理器的服务端
如果交通管理器的服务端是第一个连接到空闲端口的交通管理器,然后其他交通管理器(交通管理器的客户端)连接到它正在运行的同一端口,则创建交通管理器服务端。交通管理器服务端将规定所有交通管理器客户端的行为,例如,如果 交通管理器的服务端 停止,则所有 交通管理器客户端 将停止。
以下代码创建两个交通管理器服务端。每个端口都连接到不同且都未使用的端口:
tm01 = client01.get_trafficmanager() # tm01 --> tm01 (p=8000)
tm02 = client02.get_trafficmanager(5000) # tm02(p=5000) --> tm02 (p=5000)
交通管理器的客户端
当一个交通管理器连接到另一个交通管理器(交通管理器服务端)占用的端口时,就会创建交通管理器客户端。交通管理器客户端的行为将由交通管理器服务端决定。
以下代码创建两个交通管理器客户端,每一个都与上一节中创建的交通管理器服务端连接。
tm03 = client03.get_trafficmanager() # tm03 --> tm01 (p=8000).
tm04 = client04.get_trafficmanager(5000) # tm04(p=5000) --> tm02 (p=5000)
Carla 服务器通过存储链接到它们的端口和客户端 IP(对用户隐藏)来保存所有交通管理器实例的寄存器。目前无法检查到目前为止已创建的交通管理器实例。尝试创建实例时始终会尝试连接,并且它将创建新的 交通管理器服务端 或 交通管理器客户端 。
多客户端模拟
在多客户端模拟中,在同一端口上创建多个交通管理器。第一个交通管理器将是交通管理器服务器,其余的将是连接到它的交通管理器客户端。TM-Server 将规定所有交通管理器实例的行为:
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000
terminal 2: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server
terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Client
多交通管理器模拟
在多交通管理器模拟中,在不同的端口上创建多个交通管理器实例。每个交通管理器实例都会控制自己的行为:
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000
terminal 2: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server A
terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4550 # TM-Server B
多重模拟
多重模拟是指多个 Carla 服务器同时运行。交通管理器需要连接到相关的 Carla 服务器端口。只要计算能力允许,交通管理器可以一次运行多个模拟,不会出现任何问题:
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000 # simulation A
terminal 2: ./CarlaUE4.sh -carla-rpc-port=5000 # simulation B
terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server A connected to simulation A
terminal 4: python3 generate_traffic.py --port 5000 --tm-port 5050 # TM-Server B connected to simulation B
多重模拟的概念独立于交通管理器本身。上面的示例并行运行两个 Carla 模拟 A 和 B。在每个模拟中,都独立创建一个交通管理器服务端。模拟 A 可以运行多客户端交通管理程序,而模拟 B 则运行多交通管理器或根本不运行交通管理器。
上述设置最可能出现的问题是客户端尝试连接到未在所选模拟上运行的现有交通管理器。如果发生这种情况,将会出现错误消息,并且连接将被中止,以防止模拟之间的干扰。
同步模式
交通管理器设计为在同步模式下工作。Carla 服务器和交通管理器应设置为同步才能正常运行。在异步模式下使用交通管理器可能会导致意外和不良结果,但是,如果需要异步模式,则模拟应至少以 20-30 fps 运行。
下面的脚本演示了如何将服务器和交通管理器设置为同步模式:
...
# 将模拟设置为同步模式
init_settings = world.get_settings()
settings = world.get_settings()
settings.synchronous_mode = True
# 之后,将交通管理器设置为同步模式
my_tm.set_synchronous_mode(True)
...
# 在同一个客户端对直接发出节拍信号
world.apply_settings(init_settings)
world.tick()
...
# 始终在脚本结束前禁用同步模式,以防止服务器在等待节拍信号时阻塞
settings.synchronous_mode = False
my_tm.set_synchronous_mode(False)
示例脚本 generate_traffic.py
启动交通管理器并用车辆和行人填充地图。它自动将交通管理器和 Carla 服务器设置为同步模式:
cd PythonAPI/examples
python3 generate_traffic.py -n 50
如果需要异步模式,请在运行上述命令时使用 --async
标志。
如果多个交通管理器设置为同步模式,同步将会失败。请遵循以下准则以避免出现问题:
- 在多客户端情况下,只有 交通管理器服务端 应设置为同步模式。
- 在多交通管理器情况下,只需将一台 交通管理器服务端 设置为同步模式。
- ScenarioRunner 模块自动运行交通管理器。ScenarioRunner 内的交通管理器将自动设置为同步模式。
警告
在管理时钟的脚本完成之前禁用同步模式(对于世界和交通管理器),以防止服务器阻塞,永远等待时钟。
大地图中的交通管理器
要了解交通管理器如何在大地图上工作,请务必首先阅读此处的文档来熟悉大地图的工作原理。
自动驾驶车辆在大地图中的行为取决于是否存在英雄车辆:
不存在英雄车辆
所有自动驾驶车辆都将被视为休眠参与者。休眠的自动驾驶参与者将像混合模式一样在地图上移动。由于没有英雄车辆来触发地图瓦片流,因此不会渲染车辆。
呈现英雄车辆
当自动驾驶车辆超过 actor_active_distance
定义的值时,将进入休眠状态。要设置此值,请使用 Python API:
settings = world.get_settings()
# 离英雄车辆超过2公里的参与者将会休眠
settings.actor_active_distance = 2000
world.apply_settings(settings)
在交通管理器中,休眠的参与者可以配置为在英雄车辆周围不断重生,而不是在地图的其他部分保持休眠状态。可以使用set_respawn_dormant_vehicles
Python API 中的方法配置此选项。车辆将在英雄车辆的用户定义距离内重生。可重生距离的上下边界可以使用set_boundaries_respawn_dormant_vehicles
方法设置。注意,上距离不会大于大地图的瓦片流距离,距离最小为 20 米。
要使英雄车辆 25 米和 700 米范围内的休眠车辆重生:
my_tm.set_respawn_dormant_vehicles(True)
my_tm.set_boundaries_respawn_dormant_vehicles(25,700)
如果碰撞阻止休眠的参与者重生,交通管理器将重试下一个模拟步骤。
如果休眠车辆没有重生,它们的行为将取决于是否启用混合模式。如果启用了混合模式,则休眠的参与者将在地图上传送。如果未启用混合模式,则不会计算休眠参与者的物理特性,并且它们将保持在原位置,直到不再休眠。
如果你有任何关于交通管理器的问题,可以在 论坛 上提问。