Carla仿真二:Carla多视图切换代码详解

文章目录

  • 前言
  • 一、Carla多视图切换效果
  • 二、Camera安装坐标系
      • 1、Carla.Location
      • 2、Carla.Rotation
  • 三、接口及代码详解
      • 1、接口介绍
      • 2、生成上帝视图代码
      • 3、生成Camera视图代码
  • 四、完整代码


前言

1、Carla提供了大量的Python API接口,用户可以通过查找文档实现各类功能,本文介绍该如何通过Tab按键实现多视图切换的功能,视图切换方便我们调试功能以及摄像头画面注入;

2、一般的画面我们可以通过生成Camera,然后将Camera画面设置为当前视图;但是上帝视图我通过设置Camera来实现,但我发现画面会出现严重抖动,后面改成直接生成相对自车的视图就好了;


提示:以下是本篇文章正文内容,下面案例可供参考

一、Carla多视图切换效果

上帝视图:
在这里插入图片描述

后往前视图:
在这里插入图片描述

前视图:
在这里插入图片描述

后视图:
在这里插入图片描述

左视图:

在这里插入图片描述
右视图:
在这里插入图片描述

二、Camera安装坐标系

坐标原点是BoudingBox中心点

1、Carla.Location

在这里插入图片描述

2、Carla.Rotation

在这里插入图片描述

注意:生成摄像头的时候有三种附加方式,Rigid、SpringArm、SpringArmGhost,这里先引入这个坐标系,后面会具体讲到哪里会用到;

1、Rigid:生成摄像头的时候选择Rigid模式,视觉效果不好,画面会抖动,它附加在目标上的坐标系如下;
在这里插入图片描述

2、SpringArmGhost:叫做幽灵弹簧臂,不仅会跟随目标物跳过障碍物遮挡,还会自动调整运动的画面,使得画面变得平滑,UE4官方给出的SpringArmGhost效果如下图:

在这里插入图片描述
在这里插入图片描述

但是SpringArmGhost模式下的Roll有点奇怪,我调参的时候发现当Z轴值不为0时,0°的时候视角有点朝上,具体什么原因我也没搞懂,官方好像也不太清楚是什么原因,可能UE官方才知道什么原因,有懂的小伙伴可以分享下。

在这里插入图片描述

三、接口及代码详解

1、接口介绍

1)get_spectator是获得观察者,我们可以通过设置观察者的坐标系来获取视图;
在这里插入图片描述
2)获取坐标系信息,我们可以获取Camera坐标系,也可以获取车辆的坐标系;
在这里插入图片描述

3)set_transform设置观察者坐标系;
在这里插入图片描述
4)Carla坐标系,参考第二大点,Camera安装参照坐标系;
在这里插入图片描述

5)生成actor,可以用来生成车辆、Camera等,attahment设置附加的类型,上面有讲到他的种类
在这里插入图片描述
···
在这里插入图片描述

2、生成上帝视图代码

1)生成上帝视图不能使用Camera画面作为当前观察视图(会出现抖动的情况),而是通过直接设置相对于自车的观察视图,由于车的位置时刻在变因此更新每一帧的坐标:

import carla

#获得当前车辆的坐标系
Vehicle_transform = vehicle.get_transform()
#更新观察坐标系,在车辆坐标的基础上修改坐标
spectator_tranform = carla.Transform(Vehicle_transform .location + carla.Location(z=50),
            						carla.Rotation(pitch=-90))
#设置观察坐标系
world.get_spectator().set_transform(spectator_tranform )

3、生成Camera视图代码

import carla

#查找Camera蓝图
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
#设置生成Camera的附加类型为SpringArmGhost
Atment_SpringArmGhost = carla.libcarla.AttachmentType.SpringArmGhost
#设置Camera的安装坐标系
Camera_transform = carla.Transform(carla.Location(x=-8, y=0, z=5),
                            carla.Rotation(pitch=15, yaw=0, roll=0))
#生成Camera
camera = world.spawn_actor(camera_bp, Camera_transform,attach_to=vehicle,
							attachment_type=Atment_SpringArmGhost )
#设置观察者视图
 world.get_spectator().set_transform(camera.get_transform())

四、完整代码

import carla
import random
import time
import threading
import keyboard

threads = []

def updateSpectator(vehicle,world):
    spectator_obj_list =[]

    #获得车辆的中心点,并将点定位到右上角,便于运算
    bound_x = 0.5 + vehicle.bounding_box.extent.x
    bound_y = 0.5 + vehicle.bounding_box.extent.y
    bound_z = 0.5 + vehicle.bounding_box.extent.z

    #查找相机蓝图
    camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')

    #设置Camera的附加类型Camera跟随车辆(幽灵模式);
    Atment_SpringArmGhost = carla.libcarla.AttachmentType.SpringArmGhost

    Atment_Rigid = carla.libcarla.AttachmentType.Rigid

    #设置相对车辆的安装位置,配置上帝视图(Camera无法实现上帝视图,画面会抖动)
    Vehicle_transform_list = [
                            (carla.Location(z=50),carla.Rotation(pitch=-90))
    ]

    #设置camera的安装位置,配置后往前视图以及前后左右视图
    Camera_transform_list = [
                            (carla.Transform(carla.Location(x=-8, y=0, z=5),
                            carla.Rotation(pitch=15, yaw=0, roll=0)),Atment_SpringArmGhost),

                            (carla.Transform(carla.Location(x=bound_x, y=0, z=bound_z),
                            carla.Rotation(pitch=-15, yaw=180, roll=0)),Atment_SpringArmGhost),

                            (carla.Transform(carla.Location(x=-bound_x, y=0, z=bound_z),
                            carla.Rotation(pitch=-15, yaw=-180, roll=0)),Atment_SpringArmGhost),

                            (carla.Transform(carla.Location(x=bound_x-0.5, y=-bound_y, z=bound_z),
                            carla.Rotation(pitch=-15, yaw=120, roll=20)),Atment_SpringArmGhost),
                            
                            (carla.Transform(carla.Location(x=bound_x-0.5, y=bound_y, z=bound_z),
                            carla.Rotation(pitch=-15, yaw=-120, roll=-20)),Atment_SpringArmGhost)                                     
        ]
    

    #拼接两个transform_list
    spectator_transform_list = Vehicle_transform_list + Camera_transform_list
    
    #上帝视图坐标系以及所有camera对象填入spectator_obj_list;
    for spectator_transform_index in spectator_transform_list:
            
            #spectator_transform_list第0个元素为上帝视图坐标系
            if spectator_transform_list.index(spectator_transform_index) ==0:
                spectator_obj_list.append(spectator_transform_index)
            
            #spectator_transform_list其余元素为Camera安装参数,下面生成Camera对象
            else:
                camera = world.spawn_actor(camera_bp, spectator_transform_index[0],
                attach_to=vehicle,attachment_type=spectator_transform_index[1])
                spectator_obj_list.append(camera)
    
    #设置Vehicle_transform_list[0]为初始视图(上帝视图);
    spectator_obj = Vehicle_transform_list[0]

    # 每一帧都需要更新视图,因为坐标时刻在变化;
    while True:
        #按Tab键切换
        if keyboard.is_pressed("tab"):
            #上一个spectator的索引号;
            last_spectator_obj_index =  spectator_obj_list.index(spectator_obj)
            #计算下一个spectator的索引,如果列表索引超限则重新拿第0个spectator;
            spectator_obj_index = last_spectator_obj_index +1 if len(spectator_obj_list) - last_spectator_obj_index -1 > 0 else 0
            spectator_obj = spectator_obj_list[spectator_obj_index]
            time.sleep(0.2)

        #更新视图
        if spectator_obj_list.index(spectator_obj) == 0:
            #设置上帝视图
            Vehicle_transform = carla.Transform(vehicle.get_transform().location + spectator_obj_list[0][0],
            spectator_obj_list[0][1])
            world.get_spectator().set_transform(Vehicle_transform)
        else:
            #设置其他Camera视图
            world.get_spectator().set_transform(spectator_obj.get_transform())


def autopilot(vehicle):
    #自动领航
    vehicle.set_autopilot()
    
try:
    # 连接至服务器
    client = carla.Client('localhost', 2000)
    client.set_timeout(10)

    # 获取世界对象
    world = client.get_world()

    # 获取车辆原型
    car_blueprnt = world.get_blueprint_library().filter('vehicle.tesla.*')[0]
    car_blueprnt.set_attribute('role_name', 'ego_vehicle')

    # 在随机位置生成车辆
    spawn_point = random.choice(world.get_map().get_spawn_points())
    vehicle = world.spawn_actor(car_blueprnt, spawn_point)

    # 创建自动运行车辆的线程
    Thread_autopilot = threading.Thread(target=autopilot(vehicle))

    # 创建切换视图的线程
    Thread_updateSpectator = threading.Thread(target=updateSpectator(vehicle,world))

    #添加线程
    threads.append(Thread_autopilot)
    threads.append(Thread_updateSpectator)
    for thread in threads:
        thread.start()

finally:
    # 销毁车辆
    vehicle.destroy()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/10508.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无限制翻译软件-中英互译字数无限

翻译软件是我们工作及学习中必不可少的工具,然而许多翻译软件在使用时常常会出现字数限制的问题,这使得用户在处理长文本和大量文本时变得十分麻烦。如果你也遇到了类似的问题,那么哪个翻译软件不限制字数将为您带来全新的翻译体验。 以下是我们的哪个翻…

Vite打包后直接使用浏览器打开,显示空白问题

vite打包后,直接用浏览器打开显示空白 1.需求: 安卓webview等浏览器直接打开文件显示 2.原因 (1)资源路径错误: vite.config.js 配置 base: “./” (在webpack中则配置publicPath: "./"即可…

ATTCK v12版本战术实战研究——提权(一)

一、概述 前几期文章中,我们中介绍ATT&CK 14项战术中提权战术(一),包括提权前6项子技术。那么从前文中介绍的相关提权技术来开展测试,进行更深一步的分析。本文主要内容是介绍攻击者在运用提权技术时,…

算法 贪心2 || 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

122.买卖股票的最佳时机II 如果想到其实最终利润是可以分解的,那么本题就很容易了! 如何分解呢? 假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。 相当于(prices[3] - prices[2]) (prices[2…

【华为OD机试】1043 - 从单向链表中删除指定值的节点

文章目录一、题目🔸题目描述🔸输入输出🔸样例1🔸样例2二、代码参考作者:KJ.JK🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &am…

8D和A3报告

8D和3A报告,他们都不仅仅是记录问题的一种文书,而是解决问题的工具。 A3发展于TPS (Toyota Production system),可以用来解决问题,沟通,记录,是一种流程,当人们在使用A3…

自定义类型详解

目录 一 结构体 1.1 结构的基础知识 1.2 结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 二 位段 2.1 什么是位段 2.2 位段的内存分配 2.3 位段的跨平台问题 三 枚举 3.1 枚…

JAVA本地监听与远程端口扫描的设计与开发

随着Internet的不断发展,信息技术已成为社会进步的巨大推动力。不管是存储于服务器里还是流通于Internet上的信息都已成为一个关系事业成败的关键,这就使保证信息的安全变得格外重要。本地监听与远程端口扫描程序就是在基于Internet的端口扫描的基础上&a…

VMware Horizon 8 2303 - 虚拟桌面基础架构 (VDI) 和应用软件

请访问原文链接:https://sysin.org/blog/vmware-horizon-8/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org Version2303DocumentationRelease NotesRelease Date2023-03-30 虚拟桌面基础架构 (VDI) 和应用软件 VMw…

使用Ubuntu22.04搭建k8s环境和一些k8s基础知识

minikube搭建 基本环境 我使用virtualBox构建的ubuntu,选择4核4G内存minikube是一个K8S集群模拟器,可以快速构建一个单节点的集群,用于在本地测试和开发首先使用官方脚本安装docker curl -fsSL https://test.docker.com -o test-docker.sh…

Vue——模板引用

目录 访问模板引用​ v-for 中的模板引用​ 函数模板引用​ 组件上的 ref​ 虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref att…

【FPGA】多功能ALU

目录 实验要求 源代码 顶层模块 数据输入模块 ALU运算模块 结果处理模块 扫描数码管模块 扫描数码管顶层 分频器 数码管显示 仿真代码 结构层图 管脚配置 实验板卡:xc7a100tlc sg324-2L,共20个开关 实验要求 通过高低位控制,实现32位数…

Spring boot基础学习之(十八):通过shiro框架使用Mybatis实现用户的认证完整的认证流程

在上几篇文章的基础上,实现本次案例 注意:本篇文章的实现代码在几篇文章都已经详细的讲过了,所以在此篇文章,将不再有理论知识的陈述,更过的流程,如何通过代码实现连接数据库进行认证 添加本次案例所需要的…

00后也太卷了吧!进厂起薪18K,原来面试时候都说了这些......

都说00后躺平了,但是有一说一,该牛的还是牛。 这不,前段时间公司来了个00后,工作都没两年,跳槽起薪18K。本来还以为是个年少有为的技术大牛呢,结果相处一个月下来发现技术也就那样。 问起他是如何做到和老…

NumPy 数组学习手册:6~7

原文:Learning NumPy Array 协议:CC BY-NC-SA 4.0 译者:飞龙 六、性能分析,调试和测试 分析,调试和测试是开发过程的组成部分。 您可能熟悉单元测试的概念。 单元测试是程序员编写的用于测试其代码的自动测试。 例如&…

android jetpack Navigation的使用(java)

简介 Navigation通过图形化的方式管理配置页面的切换。 基本使用 添加依赖 implementation androidx.navigation:navigation-fragment:2.5.3implementation androidx.navigation:navigation-ui:2.5.3创建xml文件(添加导航图)——nav_graph.xml nav_…

六个阶段形成CRM销售漏斗,优点有哪些

CRM销售漏斗是反映机会状态以及销售效率的重要的销售管理模型。对企业来说,CRM销售漏斗是一个必不可少的工具。通过销售漏斗,企业可以跟踪和分析客户旅程的每个阶段,并制定相应的销售战略。下面来说说,什么是CRM销售漏斗&#xff…

Nginx

文章目录一、目录结构二、多进程模型和请求基本流程三、基础配置3.1 最小配置文件3.2 servername的多种匹配方式3.2.1完整匹配3.2.2通配符匹配3.2.3通配符结束匹配3.2.4正则匹配四、反向代理4.1 反向代理到外网与内网主机的配置4.2 负载均衡配置五、动静分离六、URLRewrite 伪静…

C-关键字(下)

文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…

运行时内存数据区之虚拟机栈——动态链接、方法返回地址与一些附加信息

动态链接(Dynamic Linking)——指向运行时常量池的方法引用 每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)。比如:invokedynamic指令。…
最新文章