当前位置: 首页 > article >正文

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

简介

本插件基于免费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.kler.cn/a/16281.html

相关文章:

  • 为什么海外服务器IP会被封
  • js中typeOf无法区分数组对象
  • 提升前端性能:如何优化多个异步请求的执行效率Promise.all()
  • Kettle配置数据源错误“Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found”解决记录
  • 深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
  • 鸿蒙学习基本概念
  • MATLAB | 如何使用MATLAB绘制高度自定义的桑基图(sankey)
  • 废物,我TMD一个985却斗不过专科生(大厂自动化测试2年被裁)
  • Java使用 Scanner连续输入int, String 异常错误输出原因分析
  • 轻叶H5营销单页,让你的营销更加清爽高效
  • 实训笔记1
  • 15-4-线程-线程同步之互斥量加锁解锁
  • matlab绘制折线图基本操作
  • 『python爬虫』04. 爬虫需要知道的HTTP协议知识(保姆级图文)
  • 云和恩墨荣获2023数字中国创新大赛·信创赛道“最具发展潜力奖”等4个奖项
  • C语言从入门到精通第16天(指针的定义与基本使用)
  • PID控制---基于python模拟
  • 面向画布(Canvas)的JavaScript库
  • 【c语言小项目】基于easyX的俄罗斯方块
  • Analysis For Office的一些使用技巧
  • C++练级之初级:第六篇
  • 使用PyTorch和Flower 进行联邦学习
  • 重载new和delete
  • Flutter集成个推推送-安卓原生篇
  • 【电商必学】 WhatsApp 全新攻略:什么是交互式消息模板
  • 【Zookeeper源码走读】第一章 客户端与服务器的连接过程