4. 异步模式与同步模式对比

做仿真时间同步,说白了就是解决一个问题:仿真器里的时间怎么跟现实世界的时间对齐?

CARLA 给了我们两种选择——异步模式和同步模式。这两种模式我用了好几年,踩过不少坑,今天跟你好好聊聊。

4.1 异步模式(Asynchronous Mode)原理

异步模式是 CARLA 的默认行为。什么意思呢?

服务器自己跑自己的,客户端只管发请求。服务器每完成一帧计算,就立刻推送给客户端。客户端收到多少算多少,不会去等。

打个比方:就像你看视频,服务器是视频源,客户端是播放器。源端一直往外发数据,播放器能播多快取决于它自己的处理能力。

核心特点:

  • 服务器不受客户端控制,自主推进仿真时间
  • 客户端接收帧的速率取决于网络和计算能力
  • 帧率可能波动,不保证每帧都处理

我记得刚开始用 CARLA 时,直接跑异步模式做感知算法测试。结果发现,每次跑出来的结果都不一样。后来才意识到——异步模式下,客户端丢帧是常态。

4.2 同步模式(Synchronous Mode)原理

同步模式就完全不一样了。服务器会乖乖等着,直到客户端说「好了,下一帧」。客户端不发 tick 指令,服务器就卡在那不动。

还是那个视频的比喻:这次服务器变成了一个听话的播放器,你按一下「播放」它才走一帧。你不按,它就暂停。

核心特点:

  • 服务器等待客户端的 tick 指令
  • 每一帧都精确可控
  • 仿真时间与真实时间解耦

我做过一个多传感器融合的项目,需要激光雷达、摄像头、毫米波雷达的数据严格对齐。异步模式根本没法用,必须上同步模式。每次 tick 之后,所有传感器的数据都是同一时刻的,这才靠谱。

4.3 两种模式的对比

直接上表格,一目了然:

对比维度 异步模式 同步模式
时间控制 服务器自主推进 客户端控制推进
帧率稳定性 可能波动 完全可控
数据对齐 难以保证 精确对齐
实现复杂度 低,开箱即用 高,需要手动 tick
性能开销 较低 较高(需等待客户端)

4.4 适用场景与优缺点

异步模式适合的场景

  • 可视化展示:比如跑个演示视频,不需要精确控制
  • 快速原型验证:算法刚写完,先跑跑看效果
  • 性能测试:想看看服务器能跑多快

我的经验:如果你只是看看场景长什么样,异步模式完全够用。我曾经用它做场景编辑器预览,效果很好,代码量还少。

同步模式适合的场景

  • 多传感器融合:需要所有传感器数据时间戳一致
  • 强化学习训练:每一步都需要精确的状态和奖励
  • 确定性仿真:要求每次运行结果完全一致
  • 硬件在环测试:需要与真实硬件同步

避坑指南:我曾经在同步模式下忘记加超时处理,结果仿真卡死了一整晚。同步模式一定要设置 tick 超时,否则客户端崩了,服务器就永远等下去了。

4.5 知识结构图

下面这张图帮你理清两种模式的核心逻辑:

CARLA 仿真时间同步模式 异步模式 服务器 客户端 服务器自主推进 客户端被动接收 帧率可能波动 同步模式 服务器 客户端 客户端发送 tick 服务器等待指令 帧率完全可控 选择哪种模式?看你的需求:要简单用异步,要精确用同步

4.6 代码示例

给你看看两种模式在代码上的区别:

# 异步模式(默认)
client = carla.Client('localhost', 2000)
world = client.get_world()
# 什么都不用做,直接跑

# 同步模式
client = carla.Client('localhost', 2000)
world = client.get_world()
settings = world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05  # 20 FPS
world.apply_settings(settings)

# 手动推进
for i in range(100):
    world.tick()
    # 在这里处理传感器数据
    # 所有数据都是同一时刻的

小技巧:我习惯在同步模式下把 fixed_delta_seconds 设成 0.05,也就是 20 FPS。这个帧率对大多数算法测试都够用,而且计算压力不大。

嗯,两种模式各有千秋。异步模式省心,同步模式精确。我个人建议:做算法开发用同步模式,做展示用异步模式。别问我怎么知道的,都是血泪教训。

可可精品资料库