• 【仿真】Carla之收集数据快速教程 (附完整代码) [7]


    收集过程可视化展示,随后进入正文:

    参考与前言

    看到仿真群对这类任务下(用carla收集数据然后再做训练等) 需求量大,顺手马上写一个好了,首先收集数据需要考虑清楚:

    1. 收集什么数据,需要什么样的数据格式

    2. 数据之间的时间戳一定要同步,这就意味着对carla的时间设置有一定的认知

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

    3. 收集数据时一般没啥意外的话 我们倾向于车自己自动跑,有时候可能会想着 不考虑红绿灯、速度快一点等等等。这意味着要对traffic manager有一定认知

      【仿真】Carla之Traffic Manager [3]

    我一直以为... CARLA 写完的专栏已经很清晰的写了怎样使用 但是... 大家好像倾向于动手再说 就导致了 我们群里不止看到过一次以下问题:

    1. 怎样保证传感器之间的同步 → 同步模式设置
    2. 为什么我的CARLA看起来很卡 → 看看GPU能不能跟得上把 bro

    接下来 我们将完成这样一个任务:收集车辆行驶过程中的前端两个相机图,顶部雷达点云,同时保存自身IMU和GNSS数据(注意GPS和直接从carla拿的location是不一样的!)GNSS的数据是需要进行一定转换才能和carla location是一样的

    以下有些部分很基础,懒得看文字的直接看代码也行,代码地址:https://gitee.com/kin_zhang/carla-python-api/blob/develop/tutorial/collect_data.py

    相关参考链接及教学 一并在前言放出,后续不再进行单独复制:

    1. 知乎小飞哥 CARLA教程专栏:https://www.zhihu.com/column/c_1324712096148516864

    2. 博主自己的 CSDN教程专栏:https://blog.csdn.net/qq_39537898/category_11562137.html

    3. 最好的!!!还是CARLA 官方文档!!! 球球大家多查查官方文档把!! PS 记得对上自己的CARLA版本哦

      CARLA Simulator

      简单关注点,以下全部有官方文档对应部分:

      1. CARLA 世界的时间是怎样运行与规定的:https://carla.readthedocs.io/en/latest/adv_synchrony_timestep/
      2. 内部有哪些传感器可用:https://carla.readthedocs.io/en/latest/ref_sensors/

    0. 世界设置

    同步时间设置

    注意收集数据 一定要开CARLA同步模式,而如果要用trafficmanager,因为开过同步模式,trafficmanager也是需要一起同步的。这块的知识在前言里有给出链接

    球球大家看看时间设置把:CARLA时间设置

    以下直接截取了,完整代码请点击前言部分:

    python
    def main(args):
        # We start creating the client
        client = carla.Client(args.host, args.port)
        client.set_timeout(5.0)
        
        # world = client.get_world()
        world = client.load_world('Town01')
        blueprint_library = world.get_blueprint_library()
        try:
            original_settings = world.get_settings()
            settings = world.get_settings()
    
            # We set CARLA syncronous mode
            settings.fixed_delta_seconds = 0.05
            settings.synchronous_mode = True
            world.apply_settings(settings)
            spectator = world.get_spectator()
    
            # 手动规定
            # transform_vehicle = carla.Transform(carla.Location(0, 10, 0), carla.Rotation(0, 0, 0))
            # 自动选择
            transform_vehicle = random.choice(world.get_map().get_spawn_points())
            ego_vehicle = world.spawn_actor(random.choice(blueprint_library.filter("model3")), transform_vehicle)
            actor_list.append(ego_vehicle)
    1. client和server进行连接
    2. get_world就是CARLA现在这个界面上是什么地图 世界就是那个;load world呢就是自己可以选不默认的CARLA 内置的几个城镇
    3. 开启同步模式
    4. 放一辆特斯拉的车到上面

    自动模式开启

    因为简单起见,就不在进行专门的规则或者走carla 的behaviour agent了,直接用traffic manager里面的进行设置为自动驾驶模式,更多设置见官方文档,比如下面列举了:忽略红绿灯和限速

    python
    # 设置traffic manager
    tm = client.get_trafficmanager(args.tm_port)
    tm.set_synchronous_mode(True)
    # 是否忽略红绿灯
    # tm.ignore_lights_percentage(ego_vehicle, 100)
    # 如果限速30km/h -> 30*(1-10%)=27km/h
    tm.global_percentage_speed_difference(10.0)
    ego_vehicle.set_autopilot(True, tm.get_port())

    其中需要着重注意的是 因为前面设了同步 traffic manager也需要设为同步,同时销毁的时候要设置回来,刚刚写教程的时候 半天没找到bug 只看见车不动;前者是帮同学找问题的时候发现如果一个脚本设了同步 traffic manager不设同步 CARLA 整体npc会卡卡的


    不设同步模式在没那么好的GPU上就会出现一卡一卡的现象 如下两幅动图对比,那么就会导致传感器收到的数据有丢帧现象,没错那篇时间博文里的插图,很久之前我画的(第二幅 很明显有卡帧和丢帧情况出现):

    1. 布置传感器

    此处我们参考carla内部的示例,此处感谢李同学的提示 hhh 一开始打算直接暴力一点,想着都同步了 应该无需走queue了 不过还是frame保险起见比较好:

    python
    #-------------------------- 进入传感器部分 --------------------------#
    sensor_queue = Queue()
    cam_bp = blueprint_library.find('sensor.camera.rgb')
    lidar_bp = blueprint_library.find('sensor.lidar.ray_cast')
    imu_bp = blueprint_library.find('sensor.other.imu')
    gnss_bp = blueprint_library.find('sensor.other.gnss')
    
    # 可以设置一些参数 set the attribute of camera
    cam_bp.set_attribute("image_size_x", "{}".format(IM_WIDTH))
    cam_bp.set_attribute("image_size_y", "{}".format(IM_HEIGHT))
    cam_bp.set_attribute("fov", "60")
    # cam_bp.set_attribute('sensor_tick', '0.1')
    
    cam01 = world.spawn_actor(cam_bp, carla.Transform(carla.Location(z=args.sensor_h),carla.Rotation(yaw=0)), attach_to=ego_vehicle)
    cam01.listen(lambda data: sensor_callback(data, sensor_queue, "rgb_front"))
    sensor_list.append(cam01)
    
    cam02 = world.spawn_actor(cam_bp, carla.Transform(carla.Location(z=args.sensor_h),carla.Rotation(yaw=60)), attach_to=ego_vehicle)
    cam02.listen(lambda data: sensor_callback(data, sensor_queue, "rgb_left"))
    sensor_list.append(cam02)
    
    lidar_bp.set_attribute('channels', '64')
    lidar_bp.set_attribute('points_per_second', '200000')
    lidar_bp.set_attribute('range', '32')
    lidar_bp.set_attribute('rotation_frequency', str(int(1/settings.fixed_delta_seconds))) #
    
    lidar01 = world.spawn_actor(lidar_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
    lidar01.listen(lambda data: sensor_callback(data, sensor_queue, "lidar"))
    sensor_list.append(lidar01)
    
    imu01 = world.spawn_actor(imu_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
    imu01.listen(lambda data: sensor_callback(data, sensor_queue, "imu"))
    sensor_list.append(imu01)
    
    gnss01 = world.spawn_actor(gnss_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
    gnss01.listen(lambda data: sensor_callback(data, sensor_queue, "gnss"))
    sensor_list.append(gnss01)
    #-------------------------- 传感器设置完毕 --------------------------#

    以上主要是:

    1. 到库里去找到这样一个传感器
    2. 对传感器进行一些设置,比如相机的FOV,激光雷达的通道数
    3. 然后把传感器放到车上!所以有个attch到自己车上哈

    主要需要注意的是激光雷达的设置:

    1. points_per_second 越多 点越密集,同时和雷达通道数有关哈(可选我记得是:32、64、128)

    2. 一定要注意rotation_frequency 是自己fixed_delta_seconds 的频率 不然就会出现 只收了半面,比如这幅图:

    2. 收集数据

    主要参考carla官方示例里的sensor_synchronization.py,以下为while循环内截取

    python
    while True:
        # Tick the server
        world.tick()
    
        # 将CARLA界面摄像头跟随车动
        loc = ego_vehicle.get_transform().location
        spectator.set_transform(carla.Transform(carla.Location(x=loc.x,y=loc.y,z=35),carla.Rotation(yaw=0,pitch=-90,roll=0)))
    
        w_frame = world.get_snapshot().frame
        print("\nWorld's frame: %d" % w_frame)
        try:
            rgbs = []
    
            for i in range (0, len(sensor_list)):
                s_frame, s_name, s_data = sensor_queue.get(True, 1.0)
                print("    Frame: %d   Sensor: %s" % (s_frame, s_name))
                sensor_type = s_name.split('_')[0]
                if sensor_type == 'rgb':
                    rgbs.append(_parse_image_cb(s_data))
                elif sensor_type == 'lidar':
                    lidar = _parse_lidar_cb(s_data)
                elif sensor_type == 'imu':
                    imu_yaw = s_data.compass
                elif sensor_type == 'gnss':
                    gnss = s_data
            
            # 仅用来可视化 可注释
            rgb=np.concatenate(rgbs, axis=1)[...,:3]
            cv2.imshow('vizs', visualize_data(rgb, lidar, imu_yaw, gnss))
            cv2.waitKey(100)
        except Empty:
            print("    Some of the sensor information is missed")
    
    def sensor_callback(sensor_data, sensor_queue, sensor_name):
        # Do stuff with the sensor_data data like save it to disk
        # Then you just need to add to the queue
        sensor_queue.put((sensor_data.frame, sensor_name, sensor_data))

    至此完成了收集数据部分,同时运行完整代码即可见如下动态所示:

    3. 保存数据

    这个就是对应的save一下就行,展示效果如下:

    python
    if rgb is None or args.save_path is not None:
    	  # 检查是否有各自传感器的文件夹
    	  mkdir_folder(args.save_path)
    	
    	  filename = args.save_path +'rgb/'+str(w_frame)+'.png'
    	  cv2.imwrite(filename, np.array(rgb[...,::-1]))
    	  filename = args.save_path +'lidar/'+str(w_frame)+'.npy'
    	  np.save(filename, lidar)

    对于点云如果要有啥其他操作 推荐使用open3d进行,比如:

    python
    import numpy as np
    import open3d as o3d
    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(np.load('217.npy')[:,:3])
    o3d.visualization.draw_geometries([pcd])

    总结

    以上主要简单实现了一下CARLA内部简易版数据收集脚本,语重心长版:

    1. 要知道自己用CARLA的目的是什么
    2. 多看官方文档,很多API 官方解释的很到位
    3. 多看官方示例,很多都是宝藏 hhh

    另外完整代码在:gitee 外链


    __EOF__

  • 本文作者: Kin Zhang
  • 本文链接: https://www.cnblogs.com/kin-zhang/p/16057173.html
  • 关于博主: 欢迎评论区讨论,私信不一定回复
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    关于 Math.random()生成指定范围内的随机数的公式推导
    【C++】map & set
    使用企业订货软件的担忧与考虑|网上APP订货系统
    【CSS】解决对齐的小问题
    使用Harbor作为docker镜像仓库之安装运行Harbor
    C现代方法(第8章)笔记——数组
    [附源码]计算机毕业设计JAVA健身健康规划系统
    生成式AI:未来的发展方向是什么?
    《动手学深度学习 Pytorch版》 10.4 Bahdanau注意力
    [数字信号处理]应用FFT计算线性卷积
  • 原文地址:https://www.cnblogs.com/kin-zhang/p/16057173.html