【仿真】Carla世界的时间 [2]

引用参考

  1. 官方网页:https://carla.readthedocs.io/en/0.9.11/
  2. 知乎较为完全的介绍:https://www.zhihu.com/column/c_1324712096148516864
  3. Notion原笔记地址 主要是有时候我可能发现啥不对经就只在notion上更新了:https://www.notion.so/2-Carla-14133c3dfc6046a496d05a041f7dbf5a
    首先第一篇初入Carla请见:https://blog.csdn.net/qq_39537898/article/details/115921745

这篇前半段大部分是在翻译的感觉,有部分自己的疑惑或者是探索也会写在里面的,后半段写了上次留下的作业之设置行人重复过马路的场景,下一个应该看看如果设置测试场景,类似于自动驾驶的车开到了一个地方就开启一个场景比如超车、别车、前车突然刹停啥的,真·需求场景产品报告 hhh。自己最后探索的终点应该是以设置强化学习的车辆环境为主


Synchrony and time-step 同步与时间

主要是介绍在Carla世界里的时间概念,和Server服务器是怎样使得整个仿真一步步运行更新的

Simulation time-step 仿真里的时步

首先仿真世界和真实世界的时间肯定不一样的,仿真里有自己的宇宙,也就是自己的自转Balabala,所以在两个仿真画面之间的步数 two simulation moments ,我们统称为time-step

首先,我们要知道的是:一个Server通常需要几毫秒算一下这两步的仿真,而这个几毫秒我们也可以给他设成固定的一般来说按一秒
Time step可以是固定的例如设成一秒,也可以是一个变量 根据咱的设定来

Variable time-step 可变时步

这也是Carla里的默认模式,也就是仿真时间由Server计算时间来定

settings = world.get_settings()
settings.fixed_delta_seconds = None # Set a variable time-step
world.apply_settings(settings)

当然如果你已经启动了这个world也可以临时进行改变,0代表variable time-step的模式

cd PythonAPI/util && python3 config.py --delta-seconds 0

Fixed time-step 固定时步

通过上面的一部分介绍,这里就很显而易见是,给其非0值即可

settings = world.get_settings()
settings.fixed_delta_seconds = 0.05 # Set a fix time-step
world.apply_settings(settings)

Physics substepping

这里是指的物理的计算是需要比较精确的,所以如果你设的是固定时步的话,需要注意这个物理计算的时间规则:

fixed_delta_seconds <= max_substep_delta_time * max_substeps

关于物理substepping的设置修改如下:

settings = world.get_settings()
settings.substepping = True
settings.max_substep_delta_time = 0.01
settings.max_substeps = 10
world.apply_settings(settings)

官方的建议呢:In order to have an optimal physical simulation, the substep delta time should at least be below 0.01666 and ideally below 0.01.

总结 time step

  1. 也就是说如果设成None或者不设置都会是可变时步,这其实在做录bag的时候(没错 Carla里也有录bag 数据包之说的,而且和ROS的概念差不多的)是很麻烦的一件事,因为在你播bag的时候… 这个time step可能就不一样了 是会有影响的
  2. 设成固定时步用去录bag是比较好的一种方式,比如1毫秒一计算、5毫秒一回头 emm 但是我发现1毫米运行起来贼快 不太合适 5ms又很慢,所以:
  3. 其他时候没啥需求就默认,比如设置什么场景进行测试啦之类的,比较舒服?同时也不用太注意物理的sub step会不满足条件

Client-server synchrony

重点来了,CARLA其实是一个client-server的模式,用ROS比较熟的也应该知道ROS差不多,首先开一个master然后大家通过master交流(launch会自动开master)。但是这里的模式是指server负责运行整个仿真,client其实呢就是收取server里的信息,比如client给了辆车到server仿真世界里跑呀跑,如果client之后就不动了就是不能知道server的车跑了多久到哪里了,所以呢就得client自己去找server要数据,那多少时间去收?首先server没算完 你收了也没用(因为… 没算完呀 没变呀 🤪皮一下很开心)

首先,CARLA其实默认是异步模式,配合上面提到的variable time step,看server能算多快,我的仿真就运行多快,而异步模式也不需要考虑client,比如client说:你给我等一下,我没跟上你的步伐,异步的server会说:不等你,你自己看着办;所以结果就会是:server飞快的算,client只取最新的,那么就会导致拿到的传感器数据掉帧啥的

然后异步呢,server就会走一步等一步,但是注意他只等一个client,随着那个client代码里的world.wait_for_tick(),或者是world.tick()以下是随手画的一副漫画展示:

https://i-blog.csdnimg.cn/blog_migrate/28885091b399af2239a02c288c3d4b77.png

具体的设置为,注意这里官方提示了,如果是同步的话,代码里有traffic manager也在运行,也得设为同步,具体的后续会讲到

settings = world.get_settings()
settings.synchronous_mode = True # Enables synchronous mode
world.apply_settings(settings)

同样,这里也可以在外面disable掉同步模式,但是不能enable因为你enable的时候万一开了很多client,server不知道等哪个

cd PythonAPI/util && python3 config.py --no-sync # Disables synchronous mode

Using synchronous mode 使用同步模式

首先设置同步模式,然后这里示例是加了一个相机,这不是完整的代码哈,然后在world.tick() 就读取队列里的一个

settings = world.get_settings()
settings.synchronous_mode = True
world.apply_settings(settings)

camera = world.spawn_actor(blueprint, transform)
image_queue = queue.Queue()
camera.listen(image_queue.put)

while True:
    world.tick()
    image = image_queue.get()

当然异步模式也可以去 make the client wait for a server tick or do something when it is received.

# Wait for the next tick and retrieve the snapshot of the tick.
world_snapshot = world.wait_for_tick()

# Register a callback to get called every time we receive a new snapshot.
world.on_tick(lambda world_snapshot: do_something(world_snapshot))

还有一个点其实官方没提到[可能在后面提到了…],但是看example文件夹里官方的一些示例可以看到,设置完同步后,在你CTRL+C 停止运行的时候,一定记得将world重新设置回异步模式,不然world直接会卡死的,因为他在等他认为还存在的client,[因为… 我cmd不好用的时候经常没办法进finally 然后就卡死了] 比如spawn_npc.py文件里的

try:
	#一大堆东西#

finally:
  if args.sync and synchronous_master:
      settings = world.get_settings()
      settings.synchronous_mode = False
      settings.fixed_delta_seconds = None
      world.apply_settings(settings)

  print('\ndestroying %d vehicles' % len(vehicles_list))
  client.apply_batch([carla.command.DestroyActor(x) for x in vehicles_list])

  # stop walker controllers (list is [controller, actor, controller, actor ...])
  for i in range(0, len(all_id), 2):
      all_actors[i].stop()

  print('\ndestroying %d walkers' % len(walkers_list))
  client.apply_batch([carla.command.DestroyActor(x) for x in all_id])

  time.sleep(0.5)

Possible configurations 可能的设置

Mode_Name
固定时步可变时步
同步模式非常好的一种设置
Client is in total control over the simulation and its information.
可能会由于物理计算时间太长导致不那么可靠,所以官方专门建议了在同步模式下请使用固定时步,不要使用此可变时步
Risk of non reliable simulations.
异步模式比较好的一种模式,Server会尽可能跑的快
Good time references for information. Server runs as fast as possible.
之所以比较好呢,是因为固定时步,client比较容易知道他要拿到的数据的对于仿真的准确时间
如果后续录数据,会有问题的不建议此种模式
Non easily repeatable simulations.

所以呢,首先明白两个py同时运行的时候只有一个里面可以设置同步模式,另一个需要保持默认的异步模式 可以把固定时步设置成一样的,同步模式的设定可以遵循example里的:

try:
	settings = world.get_settings()
	settings.synchronous_mode = True
	settings.fixed_delta_seconds = 0.05
	world.apply_settings(settings)
	
	# 一堆其他东西
	
	while True:
		world.tick()
		# 一堆其他东西

# 最后一定要寄的设置回去 别忘了
finally:
  settings = world.get_settings()
  settings.synchronous_mode = False
  settings.fixed_delta_seconds = None
  world.apply_settings(settings)

可以对比一下两者的连续和掉帧情况:【第一幅是同步模式下,基本上可以看出来是连续的图片;第二幅是异步,特别是后面可以看出来很严重的掉帧现象】
在这里插入图片描述
在这里插入图片描述


上次留下的作业 之 设置行人重复过马路场景

首先效果是这样的:
https://i-blog.csdnimg.cn/blog_migrate/b116e5aa29db7ff72a820239d7e435da.gif
直接贴对应的代码先:

# set walker as spawn_actor
walker_bp = random.choice(blueprint_library.filter('walker.pedestrian.*'))
spawn_point = carla.Transform(carla.Location(x=-15, y=124.1, z=2)) #设置行人出生的位置
pedestrain = world.spawn_actor(walker_bp, spawn_point) # 把行人放过去
control = carla.WalkerControl() # 拿到行人的控制权限
revert_flag = False # 这个主要是我的方法,就是到点了记得转头重复过马路嘛

while True:
    world.wait_for_tick()
    control = carla.WalkerControl()
    control.direction.y = 0
    control.direction.z = 0
    control.speed = 3
    if(pedestrain.get_location().x>10): # 我是提前知道了大概转头的x位置哈!
        revert_flag = True # 到了就转头
    if(pedestrain.get_location().x<-10):
        revert_flag = False
    if(revert_flag):
        control.direction.x = -1
    else:
        control.direction.x = 1
    pedestrain.apply_control(control)
    time.sleep(1)

应该比较浅显易懂我觉得… 然后完整的代码位置在gitee可见:https://gitee.com/kin_zhang/carla_-learning/blob/develop/spawn_npc_static.py

结语:多看官方文档,因为Carla是由国外社区做的,所以很多问题可能百度搜不到故有问题多google,google是个好东西

  • 17
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kin-Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值