gl-opendrive插件(车俩3D仿真模拟自动驾驶)

news2024/11/15 8:27:47

简介

本插件基于免费opendrive开源插件、Threejs和Webgl三维技术、vue前端框架,blender开源建模工具等进行二次开发。该插件由本人独立开发以及负责,目前处于demo阶段,功能还需待完善,由于开发仓促代码还需优化。

因此,使用和阅读者需要具备 :

  • opendrive源码基础,xodr文件格式理解
  • threejs三维渲染引擎
  • webgl三维协议以及相关着色器知识
  • 会使用blender,具备一定的建模基础
  • javaScript技术
  • vue框架
  • echarts数据可视化图表库
  • 熟悉各种坐标系,如 世界坐标系,st坐标系,uv坐标系,xyz惯性坐标系,物体坐标系,
  • 数学知识基础(极坐标,微分,向量)等
  • 离屏渲染思想、webgl着色器(vertexShader、fragmentShader)
  • glsl语法

核心功能

  • xodr文件解析
  • 地图渲染
  • 车辆三视图(算法优化)
  • 道路追踪
  • 全局路径规划展示
  • 自定义打点
  • 车辆运行
  • 车轮旋转
  • 鼠标定位(三维)
  • GPU颜色拾取
  • 支持远程或者本地数据文件加载
  • 其他

xodr文件解析

该功能由opendrive插件实现,具体的文件格式可查阅opendrive官方

或者推荐网址

自动驾驶场景仿真标准(一)- OpenDRIVE - 知乎

《OpenDRIVE1.6规格文档》1_opendrive官方文档-CSDN博客

《OpenDRIVE1.6规格文档》3_opendrive 1.6_YMWM_的博客-CSDN博客

道路追踪

利用离屏渲染技术以及定位功能实现

gpu拾取颜色获取车道ID

 //跟踪屏幕中间位置(近似跟踪车的位置)
        camera.setViewOffset(
          renderer.domElement.width, //画布的宽度
          renderer.domElement.height, //画布的高度
          renderer.domElement.width/2 | 0, //画布坐标系中,相机的x坐标位置
          renderer.domElement.height/2 | 0, //画布坐标系中,相机的y坐标位置
          1, //副相机的宽度
          1 //副相机的高度
        );
        //离屏渲染
        renderer.setRenderTarget(lane_picking_texture);
        renderer.render(lane_picking_scene, camera);

        renderer.setRenderTarget(roadmark_picking_texture);
        renderer.render(roadmark_picking_scene, camera);

        renderer.setRenderTarget(xyz_texture);
        renderer.render(xyz_scene, camera);

        renderer.setRenderTarget(st_texture);
        renderer.render(st_scene, camera);

        const lane_id_pixel_buffer = new Float32Array(4);
        //拾取颜色
        //console.log(mouse.x, window.innerHeight - mouse.y)
        renderer.readRenderTargetPixels(
          lane_picking_texture,
          0, //相机截图左上角为坐标原点,相对于截图左上角而言的渲染起始点x坐标
          0, //相机截图左上角为坐标原点,相对于截图左上角而言的渲染起始点y坐标
          1, //渲染宽度范围
          1, //渲染高度范围
          lane_id_pixel_buffer
        );

获取车道进行颜色渲染


        if (isValid(lane_id_pixel_buffer)) {
          //根据颜色值解码成车道ID
          const decoded_lane_id = decodeUInt32(lane_id_pixel_buffer);
          //自定义数据中获取所有车段中的所有车道数据
          const odr_lanes_mesh =
            road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
          //本次选中的区域车道ID是否和上次一样
          if (INTERSECTED_LANE_ID != decoded_lane_id) {
            //当前是否是初始化状态,如果不是则进行初始化,防止重复初始化
            if (INTERSECTED_LANE_ID != 0xffffffff) {
              //根据车道ID索引获取车道信息
              road_network_mesh.geometry.attributes.color.array.fill(
                COLORS.road
              );
            }

            //保存选中车道ID
            INTERSECTED_LANE_ID = decoded_lane_id;
            //根据车道ID获取车道信息
            const lane_vert_idx_interval =
              odr_lanes_mesh.get_idx_interval_lane(INTERSECTED_LANE_ID);
            //获取该车道长度
            const vert_count =
              lane_vert_idx_interval[1] - lane_vert_idx_interval[0];
            //修改离屏渲染场景中该车道的背景颜色
            applyVertexColors(
              road_network_mesh.geometry.attributes.color,
              new THREE.Color(COLORS.lane_highlight),
              lane_vert_idx_interval[0],
              vert_count
            );
            //手动更新颜色值
            road_network_mesh.geometry.attributes.color.needsUpdate = true;
            //显示左上角信息展示
            spotlight_info.style.display = "block";
          }
          //使用过后删除数据冗余,避免造成内存泄漏
          odr_lanes_mesh.delete();
        } else {
          //鼠标拾取无效色素

          //恢复初始化数据
          //当前是否已经是初始化状态如果不是则进行初始化
          if (INTERSECTED_LANE_ID != 0xffffffff) {
            const odr_lanes_mesh =
              road_network_mesh.userData.odr_road_network_mesh.lanes_mesh;
            const lane_vert_idx_interval =
              odr_lanes_mesh.get_idx_interval_lane(INTERSECTED_LANE_ID);
            road_network_mesh.geometry.attributes.color.array.fill(COLORS.road);
            road_network_mesh.geometry.attributes.color.needsUpdate = true;
            odr_lanes_mesh.delete();
            INTERSECTED_LANE_ID = 0xffffffff;
            spotlight_info.style.display = "none";
          }
        }

地图渲染

利用opendrive开源插件对xodr文件的加载和解析,使用threejs框架对数据进行渲染

车辆三视图(算法优化)

优点:避免了点过于分散和间距过大造成的视图摇晃和颠簸问题

正视图

 效果图

侧视图

效果图:

 俯视图

效果图

 全局路径规划展示

 车轮旋转

非车辆原地不动,车轮旋转,地图动的方式(录制软件掉帧问题,效果不太明显)

三维定位

左上角webgl坐标

自定义打点 

点击开始打点,可在地图上进行自定义路径,点击启动,将展示路径和启动模型运行

中间红色线则为路线 

其他

转弯

 直行

变道

 

 全局鸟瞰图

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

35岁测试人,面临职场危机,打了一场漂亮的翻身仗...

“夜深知雪重,时闻折竹声”。雪折,一种在雪的载荷下,植物(多指树)的躯干或枝条被不断堆积的雪花压断的现象。我的刚刚经历了人生的第一次“雪折”。 我是一个有点聪明且勤奋好学的人,从考入省重点大学起&a…

Windows环境下C++ 安装OpenSSL库 源码编译及使用(VS2019)

参考文章https://blog.csdn.net/xray2/article/details/120497146 之所以多次一举自己写多一篇文章,主要是因为原文内容还是不够详细。而且我安装的时候碰到额外的问题。 1.首先确认一下自己的代码是Win32的还是Win64的,我操作系统是64的,忘…

java websocket实现聊天室 附源码

目录 1.Socket基础知识 2.socket代码实现 2.1 引入依赖 2.2 配置websocket 2.3 websocket的使用 2.4 webSocket服务端模块 2.5 前端代码 3.测试发送消息 4.websocket源码地址 1.Socket基础知识 Socket(套接字)用于描述IP地址和端口&#xff0c…

4年测试工作经验,跳槽之后面试20余家公司的总结

先说一下自己的个人情况,普通二本计算机专业毕业,懂python,会写脚本,会selenium,会性能,然而离职后到今天都没有收到一份offer!一直在待业中,从离职第一天就开始准备简历&#xff0c…

【Vue 基础】尚品汇项目-02-路由组件的搭建

项目路由说明: 前端的路由:Key-Value键值对 Key:URL(地址栏中的路径) Value:相应的路由组件 作用:设定访问路径,并将路径和组件映射起来(就是用于局部刷新页面&#xff0…

Vue+Openlayers+proj4实现坐标系转换

场景 Vue中使用Openlayers加载Geoserver发布的TileWMS: Vue中使用Openlayers加载Geoserver发布的TileWMS_霸道流氓气质的博客-CSDN博客 在上面的基础上实现不同坐标系坐标数据的转换。 Openlayers中默认的坐标系是EPSG:900913 EPSG:900913等效于EPSG:3857 可在…

kafka集群压测与优化

影响kafka集群性能的因数有多个,网络带宽、cpu、内存、磁盘读写速度、副本数、分区数、broker数量、内存缓存等因素都会影响kafka集群的性能 1.优化kafka集群配置 server.properties配置文件优化 num.network.threads4 num.io.threads4 socket.send.buffer.bytes…

提升供应链运营效率:企业如何规范化供应商关系?

在现代企业运营中,采购和供应链管理已成为至关重要的环节。企业尤其需要管理好自身供应商,才能够获得优质的原材料和零部件,并确保生产和销售的正常进行。本文将从供应商的筛选、双方合作的流程管理、团队建设等方面,为大家介绍如…

腾讯云COS+SpringBOot实现文件上传下载功能

文章目录 第一步:在.yml文件中配置对应秘钥内容第二步:完成COSConfig类编写第三步:编写Controller类Bug提示: 最近一直在做一个项目,需要支持视频,音频,图片的上传,前面介绍的都是把…

新一代边缘计算盒子,英码科技边缘计算盒子SY-E160

SY-E160 是英码科技推出的新一代智能工作站,内部集成了 4 核强悍处理器 A551.5 GHz,其内置的算力核拥有 16Tops 超强算力。SY-E160 工作站采用低功耗技术设计,支持 宽温度环境工作,可以灵活部署于各种 AI 场景中。 SY-E160 深元 A…

在SaleSmartly管理客户互动的 3 个好处

交互是关系的小组成部分。随着时间的推移,互动的质量决定了人们对这段关系的投入程度,同样的动态也适用于客户和品牌。在跨境电商业务中,每一次互动都是建立信任或失望的机会。 对于许多公司来说,客户互动的主要领域是客户服务功能…

机器学习 - Seaborn 练习, 常见功能查阅

机器学习记录 Seaborn Seaborn 是一个基于 Matplotlib 的 Python 可视化库,提供了一些内置数据集以及进行统计数据可视化和模型现场的 API。 sns.get_dataset_names() 方法会返回一个字符串列表,包含所有内置数据集的名称 练习 Seaborn 依赖Matplotlib, NumPy, SciPy, Pan…

python装不上库的心得

如果在相同的环境下别人能安装上,但你安装不上,可以考虑下面几点 目录 1 升级pip 2 有的包不用刻意装,它跟着别的就一起装了 3 缺少外部依赖 4 有的库用conda安装要方便一点 5 导入名不一定是包名 6 编译安装 7 安装包时&…

西门子S7-1500与FANUC机器人进行EtherNetIP通信的具体方法示例

西门子S7-1500与FANUC机器人进行EtherNetIP通信的具体方法示例 具体方法可参考以下内容: 以下示例中TIA博途的版本为V17,本例中PLC做主站,机器人做从站 一、 西门子PLC一侧的组态设置和编程 首先,我们需要到下载所需的EtherNetIP通信库文件,大家可自行百度获取或者从以下链…

Kafka的核心概念

一、消息(Record) 消息是 Kafka 中最基本的数据单元。消息由一串字节构成,其中主要由 key 和 value 构成,key 和 value 也都是 byte 数组。消息的真正有效负载是 value 部分的数据。为了提高网络和存储的利用率,生产者…

TCP流量控制与拥塞控制

什么是流量控制 一条TCP连接的每一侧主机都为该连接设置了接收缓存。当该TCP连接接收到正确的、有序的报文段,就会将数据放入接收缓存。相关联的应用会从缓存中读取数据。 如果发送者发送数据过快、过多,而接收方的应用程序从缓冲区读取的速度较慢&…

【C++】二叉搜索树经典OJ题目

文章目录 根据二叉树创建字符串二叉树的层序遍历二叉树的层序遍历II二叉树的最近公共祖先二叉搜索树与双向链表从前序与中序遍历序列构造二叉树从中序与后序遍历序列构造二叉树二叉树的前序遍历(非递归)二叉树的中序遍历(非递归)二叉树的后序遍历(非递归) 根据二叉树创建字符串…

捷报连连丨小匠物联SILA第六届“智光杯”荣获两项跨界大奖

2023年4月26日,SILA第六届“智光杯”跨界奖项名单公布。 喜讯传来,小匠物联荣获SILA第六届“智光杯”跨界奖项-全屋智能及商用系统优秀新供应链奖、智能照明新锐优秀新供应链奖。 “智光杯”“智光杯”由上海浦东智能照明联合会(SILA&#xf…

【校招VIP】简历上项目名称看起来不重复,是安全相关项目,但是为什么简历通过率还是低?

在简历指导的直播里面,我看了一个新的项目。 这是个信息安全方向的一个项目,之前倒是没有看过。 所以项目的介绍本身是看不出它的重复度的。 但是一往下看 12345的要点,就发现这又是一个烂大街的。 项目本身的逻辑是没有写的。 然后又是所…

【Linux脚本篇】shell变量的使用

目录 🍁shell变量替换 🍁定义变量 🍁shell变量运算 🍂整数运算 🍂小数运算 🦐博客主页:大虾好吃吗的博客 🦐专栏地址:Linux从入门到精通 shell变量替换 ${变量#匹配规则}…