0
点赞
收藏
分享

微信扫一扫

Traffic Manager

仲秋花似锦 2022-01-23 阅读 65

What is the Traffic Manager?

在模拟环境中,交通管理器(Traffic Manager, TM)是控制自动驾驶模式下的车辆的模块。它的目标是模拟真实的城市交通状况。用户可以自定义一些行为,例如设置特定的学习环境(learning circumstances)

Structured design

TM 建立在 CARLA 的客户端上,其执行流程被划分为多个阶段,每个阶段都有独立的操作和目标。这促进了与阶段相关(phase-related)的功能和数据结构的开发,同时提高了计算效率。每个阶段运行在不同的线程上。通过同步消息(synchronous messaging)传递管理与其他阶段的通信,其信息是单向流动的。

User customization

用户可以通过设置参数来允许、强制或鼓励某些特定行为,从而对交通流量(traffic flow)进行一些控制。此外,用户可以在线或离线修改交通行为(如:汽车可以无视限速或强制换道)。在模拟现实场景时,能够自定义(play around with)交通行为是必不可少的。驾驶系统需要在特定和非典型情况下进行训练。

Architecture

Overview

在这里插入图片描述

上图展示了 TM 的内部架构,每个组件的 C++ 代码可以在LibCarla/source/carla/trafficmanager(carla 源码中)中找到。以下部分将详细解释每个组件,一个简单的逻辑概述如下:

  1. 存储和更新当前的模拟状态
    • 代理生命周期和状态管理(ALSM)扫描世界,跟踪所有出现的车辆和行人,并清理那些不再存在的实体。所有的数据来自服务器,这些数据会通过几个阶段进行传递。ALSM是唯一一个调用服务器的组件
    • 车辆注册表(vehicle registry)包括自动驾驶车辆的数组(由 TM 控制)和不是自动控制的行人和车辆的列表(不由 TM 控制)。
    • 仿真状态(simulation state)是仿真中所有车辆和行人的位置、速度和附加信息的缓存存储。
  1. 计算每个自动驾驶车辆的运动

TM 根据仿真状态为车辆注册表(vehicle registry)中的所有车辆生成可行的命令,每辆车的计算是分开进行的,这些计算被分为多个不同的阶段。控制循环通过在阶段之间创建同步屏蔽(synchronization barriers) 来确保所有计算是一致的。在当前阶段的所有车辆计算完成之前,没有车辆会进入下一阶段。每辆车都要经过以下几个阶段:

  • Localization Stage(定位阶段?)

    路径(Paths)是使用从 In-Memory Map 中收集的附近航点(waypoints)列表动态创建的,其作为航点(waypoints)网格的简化模拟地图,交叉口的方向是随机选择的。每辆车的路径由路径缓冲器和车辆跟踪(PBVT)组件存储和维护,以便于在未来阶段访问和修改。

  • 碰撞阶段

    边界框(Bounding boxes)扩展到每辆车的路径上,以识别并绕过潜在的碰撞危险。

  • 交通灯阶段

    与碰撞阶段类似,由于交通灯影响、停车标志和路口优先级等因素的原因,影响车辆路径的潜在危险也会被识别出来。

  • 运动规划阶段

    车辆的移动是基于已定义的路径来计算的。PID 控制器决定如何到达目标航点(waypoints),然后将其转换为 CARLA 的命令,以便在下一步中应用。

  • 车灯阶段

    车灯会根据环境因素(如:阳光、雾或雨的存在)和车辆行为(如:车辆在下个路口左转/右转时,亮方向灯;刹车时,亮停止灯)动态开关

  1. 在模拟中应用命令

将上一步生成的命令收集到命令数组(command array)中,批量发送到 CARLA 服务器,在同一帧中应用。下面的部分将更详细地解释上面描述的 TM 逻辑中的每个组件和阶段。

ALSM

ALSM 代表代理生命周期和状态管理,它是 TM 逻辑循环(logic cycle)的第一步,提供了仿真环境当前状态的上下文。其具有以下特点:

  • 扫描世界(world),跟踪所有车辆和行人的位置和速度。如果启用了物理特性,则由Vehicle.get_velocity()来获取当前车辆速度。否则,速度是利用历史位置和时间来计算的。
  • 在模拟状态(simulation state)组件中存储每个车辆和行人的位置、速度和附加信息(交通灯影响、边界框等)。
  • 更新车辆注册表(vehicle registry)中 TM 控制车辆的名单
  • 更新控制循环(control loop)和 PBVT 组件中的实体,以匹配车辆注册表。

相关 cpp 文件:ALSM.h, ALSM.cpp

Vehicle registry

车辆注册表(vehicle registry)记录了模拟中的所有车辆和行人。其具有以下特点:

  • 通过 ALSM 更新的车辆和行人名单
  • 将注册到 TM 的车辆存储在一个单独的数组中,以便在控循环(control loop)期间进行迭代。

相关 cpp 文件:MotionPlannerStage.cpp

Simulation state

仿真状态(simulation state)存储关于仿真中所有车辆的信息,以便在后期方便地访问和修改。其具有以下特点:

  • 接收来自 ALSM 的数据,包括当前角色(actor)位置、速度、交通灯影响、交通灯状态等。
  • 将所有信息存储在缓存中,避免在控制循环(control loop)期间对服务器进行后续调用。

相关 cpp 文件:SimulationState.cpp, SimulationState.h

Control loop

控制循环(control loop)管理所有自动驾驶车辆的下一个命令的计算,因此它们是同步执行的。其由定位,碰撞,交通灯,运动规划和车灯这五个不同的阶段组成。其具有以下特点:

  • 从车辆注册表(vehicle registry)接收 TM 控制的车辆数组
  • 独立地在数列上循环执行每个车辆的计算
  • 将计算分为一系列阶段
  • 在阶段之间创建同步屏蔽(synchronization barriers)以保证一致性。所有车辆的计算在它们进入下一阶段之前完成,确保所有车辆在同一帧中更新
  • 协调阶段之间的转换,这样所有的计算都是同步完成
  • 当最后阶段(运动规划阶段和车灯阶段)结束时,发送命令数组(command array)到服务器,这样在命令计算和命令应用之间就没有帧延迟

相关 cpp 文件:TrafficManagerLocal.cpp

In-Memory Map

In-Memory Map 是 PBVT 中包含的一个辅助模块,其在定位阶段(Localization stage)使用。具有如下特点:

  • 将地图转换为离散航点(waypoints)的网格
  • 在特定的数据结构中包含具有更多信息的航点,以连接航点(waypoints)和识别道路、路口等
  • 用一个 ID(用来快速定位附近地区的车辆)来识别这些建筑

相关 cpp 文件:InMemoryMap.cppSimpleWaypoint.cpp

PBVT

PBVT 代表路径缓冲和车辆跟踪,它也是一种数据结构,包含了每辆车的预期路径,并允许在控制循环(control loop)中轻松访问数据。其具有以下特点:

  • 包含 deque 对象的映射,每个车辆有一个实体?
  • 包含每个车辆的一组航点,这些点描述了其当前位置和短期路径规划
  • 包含定位阶段使用的 In-Memory Map,将每辆车与最近的航点和可能重叠的路径联系起来

PID controller

PID 控制器是一个辅助模块,其在运动规划阶段执行计算。具有以下特点:

  • 利用运动规划阶段收集的信息,估计油门、刹车和转向所需的输入以达到一个目标值
  • 根据控制器的具体参数进行调整。如果需要,可以修改参数

相关 cpp 文件:PIDController.cpp

Command Array

命令数列(command array)是 TM 逻辑周期的最后一步,它接收所有注册车辆的命令并应用它们。其具有如下特点:

  • 接收一系列来自运动规划阶段的 carla.VehicleControl
  • 批量处理同一帧内应用的所有命令
  • 将批处理发送到 CARLA 服务器,从而在 carla.Client 中调用 apply_batch()apply_batch_sync(),这取决于仿真是在异步模式还是同步模式下运行

相关 cpp 文件:TrafficManagerLocal.cpp

Stages of the Control Loop

Stage 1- Localization Stage

定位阶段定义了由 TM 控制的车辆的短期路径规划,其具有如下特点:

  • 从仿真状态中获取所有车辆的位置和速度
  • 使用 In-Memory Map 将每辆车与一个航点(waypoints)列表联系起来,该列表描述了它的当前位置和根据其轨迹(trajectory)得出的短期路径规划。车子开得越快,该列表就越长
  • 根据规划决策(如:变道、限速、与前车距离参数化等)更新路径
  • 将所有车辆的路径存储在 PBVT 模块中
  • 相互比较路径,以估计可能的碰撞情况。结果被传递到碰撞阶段

相关 cpp 文件:LocalizationStage.cpp and LocalizationUtils.cpp

Stage 2- Collision Stage

碰撞阶段触发碰撞危险,其具有如下特点:

  • 从定位阶段接收车辆对(vehicle pairs)的列表,这些车辆对的路径可能重叠
  • 沿着前方道路(测地线边界)为每个车辆对扩展边界框,以检查它们是否真正重叠,并确定碰撞风险是否真实存在
  • 将所有可能碰撞的危险信息发送到运动规划阶段,以修改相应的路径

相关 cpp 文件:CollisionStage.cpp

Stage 3- Traffic Light Stage

由于交通监管(如:交通灯,停止标志,优先路口),交通灯阶段会引发危险。其具有如下特点:

  • 如果车辆受到黄灯、红灯或停止标志的影响,则设置交通危险(hazard)
  • 如果车辆在无信号路口,沿着车辆的路径扩展边界框。路径重叠的车辆按照“先进先出”的顺序移动。等待时间设置为固定值

相关 cpp 文件:TrafficLightStage.cpp

Stage 4- Motion Planner Stage

运动规划阶段产生应用于车辆的 CARLA 命令,其具有以下特点:

  • 收集车辆的位置和速度(simulation state)、路径(PBVT)和危险(Collision Stage and Traffic Light Stage)
  • 对车辆应该如何移动做出高层决策,例如,计算防止碰撞危险所需的刹车。用 PID 控制器根据目标值估计行为
  • 将期望的动作转换为carla.VehicleControl应用于车辆
  • 将最终产生的 CARLA 命令发送到命令数组(command array)

相关 cpp 文件:MotionPlannerStage.cpp

Stage 5- Vehicle Lights Stage

车灯阶段根据车辆的状况和周围环境激活车灯,其具有如下特点:

  • 获取车辆计划的航点,有关车辆灯的信息(如:灯光状态和计划的命令应用)和天气条件
  • 确定车灯新状态:
    • 如车辆计划在下一个路口左转/右转,则打开转向灯
    • 如果应用的命令要求车辆刹车,则打开刹车灯
    • 从日落到黎明,或在大雨下,打开近光灯和位置灯
    • 在浓雾条件下打开雾灯
  • 如果车灯状态发生变化,则更新车灯状态

相关 cpp 文件:VehicleLightStage.cpp

Using the Traffic Manager

Vehicle behavior considerations

当您将车辆设置为自动驾驶时,TM 实现了必须考虑的一般行为模式:

  • 车辆不是目标导向的(goal-oriented),它们遵循动态生成的轨迹,并在接近路口时随机选择一条路径。他们的道路是无尽的
  • 车辆的目标速度是其当前速度限制的 70%,除非被设置为其他值
  • 路口优先级不符合交通规则,TM 在路口使用自己的优先系统。解决这一限制的工作正在进行中。与此同时,可能会出现一些问题,例如,环岛内的车辆会避让试图进入的车辆

TM 的行为可以通过 Python API 进行调整。有关具体方法,请参阅 Python API 文档的 TM 部分。以下是通过API可以实现的一些功能:

TopicDescription
General:- Create a TM instance connected to a port.
- Retrieve the port where a TM is connected.
Safety conditions:- Set a minimum distance between stopped vehicles (for a single vehicle or for all vehicles). This will affect the minimum moving distance.
- Set the desired speed as a percentage of the current speed limit (for a single vehicle or for all vehicles).
- Reset traffic lights.
Collision managing:- Enable/Disable collisions between a vehicle and a specific actor.
- Make a vehicle ignore all other vehicles. - Make a vehicle ignore all walkers.
- Make a vehicle ignore all traffic lights.
Lane changes:- Force a lane change, ignoring possible collisions.
- Enable/Disable lane changes for a vehicle.
Hybrid physics mode:- Enable/Disable hybrid physics mode.
- Change the radius in which physics is enabled.

Creating a Traffic Manager

TM 被设计成在同步模式下工作,在异步模式下使用 TM 可能会导致意想不到的不良结果。一个 TM 实例由 carla.Client 创建,传递要使用的端口,默认端口为 8000。可通过以下代码创建 TM 实例:

tm = client.get_trafficmanager(port)

要为一组车辆启用自动驾驶(autopilot)模式,需要获取 TM 实例的端口,并将 set_autopilot 设置为 True,同时通过 TM 端口。如果没有提供端口,它将尝试连接到默认端口 8000。如果TM不存在,它将创建一个:

tm_port = tm.get_port()
 for v in vehicles_list:
     v.set_autopilot(True,tm_port)

多客户端情况下创建或连接到 TM 与上面的示例不同/PythonAPI/examples 中的 generate_traffic.py 脚本提供了一个例子,展示如何使用一个作为脚本参数的端口创建一个 TM 实例,并通过批量设置autopilot为 True 来注册每一辆生成的车辆:

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)

Configuring autopilot behavior

下面的例子创建了一个 TM 实例,并为特定的车辆配置危险行为,这样它就会忽略所有的交通灯,不与其他车辆保持安全距离,并以比当前限速快 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)

Delegating the Traffic Manager to automatically update vehicle lights

默认情况下,TM 管理的车辆的车灯(刹车、转弯指示灯等)永远不会更新。可以委托 TM 更新给定车辆的车灯:

tm = client.get_trafficmanager(port)
for actor in my_vehicles:
  tm.update_vehicle_lights(actor, True)

车辆的灯光管理必须在每辆车的基础上指定,在任何给定的时间,车辆都可以存在或不存在自动灯光管理。

Stopping a Traffic Manager

TM 不是一个需要被摧毁的 actor;当创建它的客户端关闭时,它也会关闭。这是由 API 自动管理的,用户不需要做任何事情。然而,当关闭一个 TM 时,用户必须摧毁它所控制的车辆,否则他们将在地图上保持静止。脚本 generate_traffic.py 会自动完成这个操作:

client.apply_batch([carla.command.DestroyActor(x) for x in vehicles_list])

:关闭一个 TM-Server 将关闭连接到它的 TM-Clients

Deterministic mode

在确定模式(deterministic mode)下,TM 在相同条件下将会产生相同的结果和行为。不要把 determinism 和 recorder 混为一谈。recorder 允许存储模拟的日志以进行回放,而 determinism 则是确保只要保持相同的条件,TM 在不同的脚本执行过程中始终具有相同的输出。

确定模式(deterministic mode)仅在同步模式下可用。在异步模式下,对仿真的控制更少,无法实现 determinism 。

要启用确定模式(deterministic mode),请使用以下方法:

my_tm.set_random_device_seed(seed_value)

seed_value 是一个整数,将根据它生成随机数。值本身是不相关的,但是相同的值总是会产生相同的输出。在相同的条件下,使用相同种子值的两个模拟将是确定的(deterministic)。

为了在多次模拟运行中保持确定性(determinism),必须为每个模拟设置种子。例如,每当玩家重新加载游戏世界时,他们便需要重新设置种子:

client.reload_world()
my_tm.set_random_device_seed(seed_value)

确定模式(deterministic mode)可以在 generate_traffic.py 示例脚本中通过传递一个种子值作为参数来测试。下面的例子在同步模式下设置一个带有 50 个自动驾驶角色(actors)的地图,并将 seed 设置为任意值 9

cd PythonAPI/examples
python3 generate_traffic.py -n 50 --seed 9

:在启用确定性模式(deterministic mode)之前,CARLA 服务器和 TM 必须处于同步模式

Hybrid physics mode

混合模式(Hybrid mode)允许用户禁用所有自动驾驶车辆的大多数物理计算,或将在标记为hero的车辆的一定半径外的自动驾驶车辆禁用物理计算?这消除了模拟中的车辆物理瓶颈(bottleneck)。物理失效的车辆将通过瞬间移动来移动。保持基本的线性加速度计算,以确保位置更新和车辆速度保持现实,车辆物理计算的切换是流动的。

混合模式(Hybrid mode)使用 Actor.set_simulate_physics() 方法来切换物理计算。默认禁用,有两个选项来启用它:

  • TrafficManager.set_hybrid_physics_mode(True)—— 这个方法为调用它的 TM 对象启用混合模式。
  • 运行 generate_traffic.py 并附加标志 --hybrid —— 这个示例脚本创建一个 TM,并在生成 autopilot 车辆。然后,当 --hybrid 标志作为脚本参数传递时,它将这些车辆设置为混合模式。

要修改混合模式的行为,可以使用以下两个参数:

  • Radius(default = 50 meters) —— 半径与标记 hero 的车辆相关。在此半径内的所有车辆将启用物理效果;在半径之外的车辆物理功能将失效。使用 traffic_manager.set_hybrid_physics_radius(r) 修改 radius 的大小。
  • Hero vehicle —— 标记为role_name='hero'的车辆,作为半径的中心
    • 如果没有hero vehicle,所有车辆的物理效果将被禁用
    • 如果有一个以上的hero vehicle,将考虑所有的半径,创造不同的影响区域,并启用物理特性

下面的剪辑显示了当混合模式激活时,物理是如何启用和禁用的。英雄的车辆标有一个红色方块,物理失效的车辆被标记为蓝色方块。在英雄车的影响范围内,物理效果被激活,标签变成绿色。
在这里插入图片描述

Running multiple Traffic Managers

Traffic Manager servers and clients

CARLA 客户端通过向服务器指定要使用的端口来创建 TM。如果未指定端口,则使用默认的 8000。如果在同一端口上创建更多的 TM,它们将成为 TM-Clients,而原来的 TM 将成为 TM-Server

TM-Server

TM-Server 是第一个连接到空闲端口的 TM,然后其他 TM (TM-Clients)连接到运行 TM-Server 的相同端口。TM-Server 将指示所有 TM-Clients 的行为,例如,如果 TM-Server 停止时,所有 TM-Clients 将停止。

下面的代码创建两个 TM-Server。每个都连接到一个不同的、未使用的端口:

tm01 = client01.get_trafficmanager()     # tm01 --> tm01 (p=8000)
tm02 = client02.get_trafficmanager(5000) # tm02(p=5000) --> tm02 (p=5000)

TM-Client

当一个 TM 连接到另一个 TM(TM-Server)所占用的端口时,将会创建 TM-Client,TM-Client 行为将由 TM-Server 决定。下面的代码将创建两个 TM-Client,每个都连接上一节中创建的 TM-Server:

tm03 = client03.get_trafficmanager()     # tm03 --> tm01 (p=8000). 
tm04 = client04.get_trafficmanager(5000) # tm04(p=5000) --> tm02 (p=5000)

Multi-client simulations

在多客户端模拟中,在同一个端口上创建多个 TM。第一个创建的 TM 将作为一个 TM-Server,后面再连接到该端口的作为 TM-Clients。TM-Server 将指定所有 TM 实例的行为:

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

Multi-TM simulations

在多 TM 模拟中,在不同的端口上创建多个 TM 实例。每个 TM 实例将控制它自己的行为:

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

Multi-simulation

多仿真(Multi-simulation)是指同时运行多个 CARLA 服务器。TM 需要连接到相关的 CARLA 服务器端口,只要计算能力允许,TM 可以在同一时间运行多个模拟:

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

多仿真的概念独立于 TM 本身。上面的例子并行地运行了两个 CARLA 模拟,在每个模拟中,一个 TM-Server 是独立于另一个创建的。模拟 A 可以运行一个多客户端(multi-client)的 TM,而模拟 B 运行多个 TM 或者根本不运行 TM。

上述设置最可能产生的问题是,客户端试图连接到一个已经存在的 TM,而 TM 没有运行在选定的模拟上。如果发生这种情况,连接将会被中止,以防止模拟之间的干扰。

Synchronous mode

TM 被设计成在同步模式下工作,为了正常工作,CARLA 服务器和 TM 都应该设置为同步。在异步模式下使用TM可能会导致意想不到的结果。但如果需要异步模式,模拟至少应该以 20-30fps 的速度运行。

下面的脚本演示了如何将服务器和 TM 设置为同步模式:

...
# Set the simulation to sync mode
init_settings = world.get_settings()
settings = world.get_settings()
settings.synchronous_mode = True
# After that, set the TM to sync mode
my_tm.set_synchronous_mode(True)
...
# Tick the world in the same client
world.apply_settings(init_settings)
world.tick()
...
# Always disable sync mode before the script ends to prevent the server blocking whilst waiting for a tick
settings.synchronous_mode = False
my_tm.set_synchronous_mode(False)

generate_traffic.py示例脚本启动一个 TM,并用车辆和行人填充地图。它自动将 TM 和 CARLA 服务器设置为同步模式:

cd PythonAPI/examples
python3 generate_traffic.py -n 50

如果需要异步模式,在运行上述命令时使用--async标志

如果多个 TM 被设置为同步模式,同步将会失败。请遵循以下指引以避免该问题:

  • 在多客户端(multiclient)情况下,只有 TM-Server 应该被设置为同步模式
  • 在多 TM(multiTM)的情况下,只有一个 TM-Server 应该被设置为同步模式
  • ScenarioRunner 模块自动运行一个 TM,ScenarioRunner 内部的 TM 将自动被设置为同步模式

Traffic manager in large maps

Hero vehicle not present

所有自动驾驶车辆都将被视为休眠角色( dormant actors)。在混合模式下,休眠的自动驾车辆会在地图上移动。车辆将不会被渲染,因为没有hero vehicle触发地图贴图流(map tile streaming)。

Hero vehicle present

当自动驾驶车辆超过了定义的actor_active_distance的值时,它们将休眠(dormant)。要设置此值,可使用以下 Python API:

settings = world.get_settings()

# Actors will become dormant 2km away from the ego vehicle
settings.actor_active_distance = 2000

world.apply_settings(settings)

在 TM 中,休眠角色可以被设置为在 hero vehicle周围持续重生,而不是在地图的其他地方保持休眠状态。这个选项可以在 Python API 中使用 set_respawn_dormant_vehicles方法配置。车辆将在hero vehicle周围重生,其距离是在用户指定距离内。respawnable 距离的上下边界可以使用set_boundaries_respawn_dormant_vehicles方法设置。注意,最大距离不会大于大地图的贴图流距离,最小距离是20米。

hero vehicle25 米和 700 米范围内,休眠车辆可以重生:

my_tm.set_respawn_dormant_vehicles(True)
my_tm.set_boundaries_respawn_dormant_vehicles(25,700)

如果碰撞阻止了休眠角色(dormant actor)被重生,TM 将在下一个模拟步骤中重试。

如果休眠车辆没有重生,它们的行为将取决于混合模式是否启用。如果混合模式已经启用,那么休眠的角色将被传送到地图上。如果不启用混合模式,那么休眠者的物理状态将不会被计算出来,它们将保持在原来的位置,直到它们不再休眠。

举报

相关推荐

0 条评论