OpenDRIVE地图图形化

  • 前言
  • 一、planViewplanViewplanView
    • 参数三次曲线
    • 弧线
    • 螺旋线
  • 二、elevationProfileelevationProfileelevationProfile
  • 三、lateralProfilelateralProfilelateralProfile
  • 总结

前言

关于OpenDRIVEOpenDRIVEOpenDRIVE的相关内容请查看这篇博客:一文读懂opendrive的xodr文件内容


我这篇的内容主要是将其中的数据可视化,采用数形结合的方式帮助自己更好地理解OpenDRIVEOpenDRIVEOpenDRIVE中的单个元素。把单个元素理解清楚了,后期就可以把单个元素组合起来,画出整个地图,前期会用matlabmatlabmatlab写一写,等单个元素理解清楚了后期会用pythonpythonpython来处理.xodr.xodr.xodr文件。

一、planViewplanViewplanView

planViewplanViewplanView下的元素是地图中最重要的参考线,参考线中主要有三类曲线,直线、螺旋线、弧线和含参的三次曲线。

参数三次曲线

在此用一段三次曲线的例子来说明,例子如下:

s1="0.000000000000e+00"; x1="-2.855056647744e+03" ;y1="5.163670291832e+03"; hdg1="3.678546924447e-02"; length1="2.500078567784e+01";
aU1="0.000000000000e+00"; bU1="2.500000000001e+01" ;cU1="-1.179775702581e-02" ;dU1="5.898878510380e-03"; aV1="0.000000000000e+00"; bV1="0.000000000000e+00" ;cV1="1.086110728936e+00"; dV1="-5.430553643517e-01" ;pRange1=1;s2="2.500078567784e+01"; x2="-2.830099427400e+03"; y2="5.165132192211e+03" ;hdg2="5.850939248778e-02" ;length2="2.500000000004e+01";
aU2="0.000000000000e+00"; bU2="2.500000000004e+01" ;cU2="-2.433465986771e-14"; dU2="1.625209696867e-14" ;aV2="0.000000000000e+00" ;bV2="2.220446049250e-16"; cV2="6.938933641603e-10" ;dV2="-4.614609867787e-10"; pRange2=1;s3="5.000078567788e+01" ;x3="-2.805142207057e+03" ;y3="5.166594092591e+03" ;hdg3="5.850939248792e-02"; length3="2.499999999990e+01";
aU3="0.000000000000e+00"; bU3="2.499999999990e+01" ;cU3="1.028584409687e-15"; dU3="0.000000000000e+00" ;aV3="0.000000000000e+00"; bV3="0.000000000000e+00"; cV3="-5.225974468605e-10" ;dV3="2.935688096311e-10" ;pRange3=1;s4="7.500078567777e+01"; x4="-2.780184986713e+03"; y4="5.168055992971e+03"; hdg4="5.850939248134e-02"; length4="3.259185499839e+01";
aU4="0.000000000000e+00" ;bU4="3.259077023178e+01" ;cU4="8.141001992985e-03"; dU4="-8.141001992975e-03"; aV4="0.000000000000e+00" ;bV4="2.220446049250e-16"; cV4="-7.284070115927e-01" ;dV4="7.284070116768e-01" ;pRange4=1;

该参考线由四段三次曲线组成,利用matlab代码将其合成一段曲线,代码如下:

s1=double(s1);
s2=double(s2);
s3=double(s3);
s4=double(s4);x1=double(x1);
x2=double(x2);
x3=double(x3);
x4=double(x4);
y1=double(y1);
y2=double(y2);
y3=double(y3);
y4=double(y4);
hdg1=double(hdg1);
hdg2=double(hdg2);
hdg3=double(hdg3);
hdg4=double(hdg4);
length1=double(length1);
length2=double(length2);
length3=double(length3);
length4=double(length4);aU1=double(aU1);
aU2=double(aU2);
aU3=double(aU3);
aU4=double(aU4);
bU1=double(bU1);
bU2=double(bU2);
bU3=double(bU3);
bU4=double(bU4);
cU1=double(cU1);
cU2=double(cU2);
cU3=double(cU3);
cU4=double(cU4);
dU1=double(dU1);
dU2=double(dU2);
dU3=double(dU3);
dU4=double(dU4);aV1=double(aV1);
aV2=double(aV2);
aV3=double(aV3);
aV4=double(aV4);
bV1=double(bV1);
bV2=double(bV2);
bV3=double(bV3);
bV4=double(bV4);
cV1=double(cV1);
cV2=double(cV2);
cV3=double(cV3);
cV4=double(cV4);
dV1=double(dV1);
dV2=double(dV2);
dV3=double(dV3);
dV4=double(dV4);
uv1=zeros(101,2);
index1=0;
for i1=0:0.01:1u1=aU1+bU1*i1+cU1*i1.^2+dU1*i1.^3;v1=aV1+bV1*i1+cV1*i1.^2+dV1*i1.^3;index1=index1+1;[ X1,Y1]=Coordinate_rotation(u1,v1,hdg1);%u、v是局部坐标值,为了将其转换到全局坐标需要一次旋转和平移,这里是旋转一次,调用的函数Coordinate_rotation在后面有写;X1=x1+X1;%x值平移;Y1=Y1+y1;%y值平移,后面不再重复;uv1(index1,1)=X1;uv1(index1,2)=Y1;
end
figure(1)
plot(uv1(:,1),uv1(:,2))uv2=zeros(101,2);
index2=0;
for i2=0:0.01:1u2=aU2+bU2*i2+cU2*i2.^2+dU2*i2.^3;v2=aV2+bV2*i2+cV2*i2.^2+dV2*i2.^3;index2=index2+1;[ X2,Y2]=Coordinate_rotation(u2,v2,hdg2);X2=x2+X2;Y2=Y2+y2;uv2(index2,1)=X2;uv2(index2,2)=Y2;
end
figure(2)
plot(uv2(:,1),uv2(:,2))uv3=zeros(101,2);
index3=0;
for i3=0:0.01:1u3=aU3+bU3*i3+cU3*i3.^2+dU3*i3.^3;v3=aV3+bV3*i3+cV3*i3.^2+dV3*i3.^3;index3=index3+1;[ X3,Y3]=Coordinate_rotation(u3,v3,hdg3);X3=x3+X3;Y3=Y3+y3;uv3(index3,1)=X3;uv3(index3,2)=Y3;
end
figure(3)
plot(uv3(:,1),uv3(:,2))uv4=zeros(101,2);
index4=0;
for i4=0:0.01:1u4=aU4+bU4*i4+cU4*i4.^2+dU4*i4.^3;v4=aV4+bV4*i4+cV4*i4.^2+dV4*i4.^3;index4=index4+1;[ X4,Y4]=Coordinate_rotation(u4,v4,hdg4);X4=x4+X4;Y4=Y4+y4;uv4(index4,1)=X4;uv4(index4,2)=Y4;
end
figure(4)
plot(uv4(:,1),uv4(:,2))
point=zeros(404,2);
for j=1:101point(j,1)=uv1(j,1);point(j,2)=uv1(j,2);point(j+101,1)=uv2(j,1);point(j+101,2)=uv2(j,2);point(j+101*2,1)=uv3(j,1);point(j+101*2,2)=uv3(j,2);point(j+101*3,1)=uv4(j,1);point(j+101*3,2)=uv4(j,2);
end
figure(5)
plot(point(:,1),point(:,2))
function [x,y] = Coordinate_rotation(X,Y,theta)%X、Y是局部坐标值,theta对应于hdg角度,x、y全局坐标值。
x=X*cos(theta)-Y*sin(theta);
y=X*sin(theta)+Y*cos(theta);
end

生成的四段曲线分别如下,分别对应figure1figure1figure1,figure2figure2figure2,figure3figure3figure3,figure4figure4figure4,这里的横纵坐标就是全局坐标系下的x、yx、yx、y:



最终合成一段曲线figure5如下:

弧线

直线就不说了,在做弧线时,注意曲率的正负,决定了是右曲线还是左曲线,以下这个例子曲率为正,那么就是左曲线,从起点处x=278,y=−828x=278, y=-828x=278,y=−828逆时针画圆弧,可以看出圆弧完全位于起点的左边,若曲率为负,就和例子相反了,示例如下:

clear all
clc
% %%
% <planView>
%     <geometry x="278" y="-828" hdg="0.50" s="0" length="34">
%         <arc curvature="0.06"/>
%     </geometry>
% </planView>
% %%
x_arc=278 ;y_arc=-828;hdg_arc=0.50; s_arc=0 ;length_arc=34;
curvature=0.06;
r_arc=1/curvature;
xc=x_arc-r_arc*sin(hdg_arc);
yc=y_arc+r_arc*cos(hdg_arc);
theta=length_arc/r_arc;
angle_start=pi/2-hdg_arc;
angle_end=theta+pi/2-hdg_arc;
t=-angle_start:0.01:angle_end;
x=xc+r_arc* cos(t);
y= yc+r_arc*sin(t);
plot(x,y);

螺旋线

直线和弧线的连接需要用到螺旋线,曲线的曲率从000(直线)开始随着曲线的长度线性增加,直至最大值(弧线),这里的螺旋线为欧拉螺旋线,欧拉螺线(EulerspiralEuler spiralEulerspiral)/ 羊角螺线(clothoidclothoidclothoid)的特性是它的曲率随着它的曲线长度线性地改变,因为它的这个性质,该曲线存在于很多地方,在PreScanPreScanPreScan中的道路元素里就有它,比如过山车 、公路的连接都会用到它,这个曲线不好画,参数方程如下:{x=C(t)y=S(t)\left\{ \begin{array}{c} x=C(t) \\ y=S(t) \end{array} \right. {x=C(t)y=S(t)​
其中C(t)C(t)C(t), S(t)S(t)S(t) 是 菲涅耳积分 (FresnelintegralFresnel integralFresnelintegral)
{C(x)=∫0xcos(t2)dt=∑n=0∞(−1)nx4n+1(4n+1)(2n)!S(x)=∫0xsin(t2)dt=∑n=0∞(−1)nx4n+3(4n+3)(2n+1)!\left\{ \begin{array}{c} C(x)&=\int_0^x cos(t^2) \mathrm{d}t=\sum_{n=0}^{\infty}(-1)^n\frac{x^{4n+1}}{(4n+1)(2n)!}\\ S(x)& =\int_0^x sin(t^2)\mathrm{d}t=\sum_{n=0}^{\infty}(-1)^n\frac{x^{4n+3}}{(4n+3)(2n+1)!} \end{array} \right. {C(x)S(x)​=∫0x​cos(t2)dt=∑n=0∞​(−1)n(4n+1)(2n)!x4n+1​=∫0x​sin(t2)dt=∑n=0∞​(−1)n(4n+3)(2n+1)!x4n+3​​
在OpenDRIVEOpenDRIVEOpenDRIVE示例如下:

% curvStart="0.0" ;curvEnd="0.013";
% s="100.0" ;x="38.00"; y="-1.81" ;hdg="0.33" ;length="30.00";

画图的MatlabMatlabMatlab代码如下,没有做旋转和平移,自行实践:

ls=0:0.001:0.1950;
len_ls=length(ls);
syms t;
c1=(1/sqrt(2*pi))*(cos(t)/sqrt(t));
s1=(1/sqrt(2*pi))*(sin(t)/sqrt(t));
xy=zeros(len_ls,2);
ccc=sqrt(pi*30/0.013);
for i=1:len_lsC_ls=int(c1,0,ls(1,i));S_ls=int(s1,0,ls(1,i));xy(i,1)=ccc*C_ls;xy(i,2)=ccc*S_ls;
end
plot(xy(:,1),xy(:,2))

画图的原理如下:

二、elevationProfileelevationProfileelevationProfile

在OpenDRIVEOpenDRIVEOpenDRIVE中,在纵向上,高程RoadelevationRoad elevationRoadelevation用 elevationProfileelevationProfileelevationProfile 元素中的 elevationelevationelevation 元素来表示。从图中可以看到两段不同颜色的两段曲线无缝衔接,基本确定是对的,在真实的道路中高程也是平滑过渡的。

clear
clc
close all
a1=1.444489536620e+01; b1=-3.697162779849e-03; c1=0.000000000000e+00 ;d1=0.000000000000e+00;
ds1=0:0.1:1.181968724741e+01;
elev1=a1 + b1*ds1 + c1*ds1.^2 + d1*ds1.^3;
a2=1.440119605844e+01;b2=-3.697162779849e-03; c2=0.000000000000e+00; d2=0.000000000000e+00;
ds2=(1.181968724741e+01-1.181968724741e+01):0.1:(1.826078551400e+01+5.378588980816e+00-1.181968724741e+01);
elev2=a2 + b2*ds2 + c2*ds2.^2 + d2*ds2.^3;
close all
plot(ds1,elev1);hold on ; plot(ds2+1.181968724741e+01,elev2);

三、lateralProfilelateralProfilelateralProfile

在OpenDRIVEOpenDRIVEOpenDRIVE中,在横向上,超高程用lateralProfilelateralProfilelateralProfile元素中的 superelevationsuperelevationsuperelevation 元素来表示。超高程的是代表坡度信息的,单位radradrad,横坐标s值,纵坐标横向坡度值。从图中可以看到两段不同颜色的两段曲线无缝衔接,在真实的道路中横向坡度肯定也是平滑过渡的,而且这个值一般不会很大。

s1="0.000000000000e+00"; a1="2.421718612644e-02" ;b1="-3.526382981560e-04"; c1="0.000000000000e+00"; d1="0.000000000000e+00";
s2="1.181968724741e+01"; a2="2.004911173078e-02"; b2="-3.526382981560e-04" ;c2="0.000000000000e+00" ;d2="0.000000000000e+00";
a1=double(a1);
b1=double(b1);
c1=double(c1);
d1=double(d1);
a2=double(a2);
b2=double(b2);
c2=double(c2);
d2=double(d2);
ds1=0:0.1:1.181968724741e+01;
ds2=(1.181968724741e+01-1.181968724741e+01):0.1:(1.826078551400e+01+5.378588980816e+00-1.181968724741e+01);
selev1=a1 + b1*ds1 + c1*ds1.^2 + d1*ds1.^3;
selev2=a2 + b2*ds2 + c2*ds2.^2 + d2*ds2.^3;
close all
plot(ds1,selev1);hold on ; plot(ds2+1.181968724741e+01,selev2);


总结

有了referencereferencereference linelineline地图的基本线条有了,线的宽度为000,车辆还是没法通过,下一篇继我们接着理解OpenDRIVEOpenDRIVEOpenDRIVE中的单个元素。

OpenDRIVE地图图形化相关推荐

  1. python迷宫万花筒代码_用Python3写一个走迷宫的小程序(图形化:matplotlib,dfs,prim)...

    先看一下动态效果图(慢放): 首先生成迷宫: 主要用了两个算法:Prim和dfs 总结:Prim生成的比较像真正的迷宫,所以默认用了Prim生成迷宫 先输入n,m,会生成一个迷宫(prim生成),然后 ...

  2. 2015-03-29-绘图和可视化(3)-绘制地图:图形化显示海地地震危机数据

    --------------------------------------------------------------------------------------- -----(三)绘制地图 ...

  3. c语言编程游戏界面,震惊!!!一个关于c语言图形化界面编程的小游戏-Go语言中文社区...

    关于C语言的图形化界面编程 第一个小程序<飞翔的小鸟> 效果图 本人也是小白,大家轻点喷!!!! 下面是源码 作者: @追风 #include #include #include #inc ...

  4. Kibana——数据图形化制作

    Kibana把数据图形化,可以帮助我们更好的去分析数据,找到数据里面的结构 注意看一下,上面缩看的界面,是一个聚合的结果,他是由CPU Usage图表.System Load图表.CPU usage ...

  5. GTK+图形化应用程序开发学习笔记(一)—概述

    GTK+图形化应用程序开发学习笔记(一)-概述 一.什么是GNOME. GNOME的意思是"GNU Network Object Model Environment"(GNU网络对 ...

  6. 信息图形化探索:图形化简历

    转载自:http://www.cnbeta.com/articles/123719.htm 有些设计师开始尝试"图形化简历"(Infographic Resume),即以图形为主. ...

  7. 用Python写一个走迷宫的小程序(图形化:matplotlib,dfs,prim)

    不要脸的放到了Github上面,嘿嘿. Github:https://github.com/Radium1209/Maze 先看一下动态效果图(慢放): 首先生成迷宫: 主要用了两个算法:Prim和d ...

  8. 构造Linux的图形化安装程序(4)(转)

    构造Linux的图形化安装程序(4)(转) rpm包管理和安装盘定制 本文是构造Linux的图形化安装程序系列文章的第四部分,内容主要包括RPM基本命令介绍,RPM包的定制过程,RPM SPEC文件的 ...

  9. 如何轻松搞定各种图形化展现

    近期,大屏展示再次把 "统计图" 推向热搜榜.或许你会问为什么,这多半是因为大屏通过各种图形组件集中呈现了用户关心的数据,而其中每个组件基本都是一个呈现形态各异的统计图,有的体现了 ...

  10. 震惊!!!一个关于c语言图形化界面编程的小游戏

    关于C语言的图形化界面编程 第一个小程序<飞翔的小鸟> 效果图 本人也是小白,大家轻点喷!!!! 下面是源码 作者: @追风#include<graphics.h> #incl ...

最新文章

  1. python turtle画滑稽_使用python的turtle函数绘制一个滑稽表情的方法
  2. PAT(甲级)2018年冬季考试 7-3 Vertex Coloring
  3. ios 即时聊天轻松搞定
  4. Python环境安装与配置
  5. 【mysql解决方案】ERROR 1248 (42000): Every derived table must have its own alias
  6. 计算机网络技术中的数据通信
  7. [转载]如何判断js中的数据类型
  8. mysql存储过程split_mysql存储过程实现split示例
  9. python入门简单小程序
  10. 吴恩达神经网络和深度学习-学习笔记-40-目标定位
  11. 如何使用ant_从 0 开始,成为 Ant-Design Contributor
  12. slub分配流程-kmem_cache_alloc函数
  13. Autodesk 首届中国开发者训练营将开始报名,5月24日前报名6折优惠!
  14. MIPS汇编语言指令
  15. 浏览器打开页面的几种方式
  16. 什么是互联网外包公司
  17. org.dom4j.DocumentException: 1 字节的 UTF-8 序列的字节 1 无效。
  18. 国产电机驱动芯片TMI8870应用在智能马桶翻盖/翻圈上
  19. SpringBoot application.properties和application.yml配置详解
  20. 强强联合 数睿数据与霍尼韦尔Tridium达成战略合作

热门文章

  1. Soulver 3 for Mac(Mac计算器软件)
  2. 《商务与经济统计》学习笔记(一)---数据与统计资料
  3. JavaWeb宠物管理系统(源码+文档)
  4. 重磅 | 数据挖掘之父韩家炜:文本语料库的数据挖掘(附视频+PPT下载)
  5. 100个Python实战项目(一)使用 Python 生成二维码
  6. hyperterminal使用教程_Win 7 使用 XP的超级终端 hyper terminal
  7. sql插入数据时自动插入时间
  8. ADI官方提供的源码AD9361+ZC706 利用TCL构建Vivado工程,利用no-OS-master搭建SDK工程
  9. 一键恢复CGI v3.2.1.0 增强版
  10. 阿里云长视频上传以及返回播放地址