最近参与了一个非常蛋疼的业余时间小项目:给定赛道和赛车模拟程序,求赛车跑完赛道的最快的办法。对于这个问题,我一开始的想法是:就像Google的自动驾驶一样,给定足够的训练数据,然后汽车对前方的画面做出判断决定当前时刻的驾驶策略。不过查了查文献,从游戏开发的角度,似乎一般都是用先找出赛车的最优路径,然后沿着路径驾驶就行了。我们最后采用的是后者,我负责了其中赛道产生中的一部分:近似求解最短路径(Shortest Path)和最小曲率路径(Minimum Curvature Path)。

给定的输入是赛道的图像文件,用OpenCV中的边缘检测模块得到赛道的线条和中心轮廓线:一堆按顺序排列好的像素点,描述了赛道的形状,输出则是最短路径和最小曲率路径按顺序排列的坐标点。

有了赛道轮廓之后,求解路径的办法主要采用的是[1]和[2]中描述的方法。

对赛道进行分段

分段的办法是在轮廓中心线上取间隔相等的垂直线段,然后将赛道上的控制点坐标表示为在垂直线段上的相对位置。比如上面这幅图中的第i个线段,假设这个线段的上面端点叫\(P_{i,1}\),下面的端点叫\(P_{i,0}\),令\(W_{i}=P_{i,1}-P_{i,0}\),则线段上任意一点\(P_{i}\)可以表示为:

\[\begin{align}
 & {{P}_{i}}={{P}_{i,0}}+{{\alpha }_{i}}{{W}_{i}}=\left( {{x}_{i,0}}+{{\alpha }_{i}}\left( {{x}_{i,1}}-{{x}_{i,0}} \right),{{y}_{i,0}}+{{\alpha }_{i}}\left( {{y}_{i,1}}-{{y}_{i,0}} \right) \right)=\left( {{x}_{i,0}}+{{\alpha }_{i}}\Delta {{x}_{i}},{{y}_{i,0}}+{{\alpha }_{i}}\Delta {{y}_{i}} \right) \\
\end{align}\]

这样做的好处是把需要用二维点坐标表示的赛道转化为一维的在赛道上的相对位置,如此一来需要处理的问题就变得简单而直观了。

最短路径

来看\(P_{i}\)和\(P_{i+1}\),两点间的距离为

\[\begin{align}
 & {{d}_{i}}=\left| {{P}_{i+1}}-{{P}_{i}} \right|=\sqrt{\Delta {{x}_{i+1,i}}^{2}+\Delta {{y}_{i+1,i}}^{2}} \\
\end{align}\]

其中,

\[\begin{align}
 & \Delta {{x}_{i+1,i}}={{x}_{i+1,0}}+{{\alpha }_{i+1}}\Delta {{x}_{i+1}}-\left( {{x}_{i,0}}+{{\alpha }_{i}}\Delta {{x}_{i}} \right)=\left( {{x}_{i+1,0}}-{{x}_{i,0}} \right)+\left[ \begin{matrix}
   \Delta {{x}_{i+1}} & -\Delta {{x}_{i}}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right) \\
\end{align}\]

\(\Delta y_{i+1,i}\)类似,就不写出来了。那么最短路径就可以看作是求下面这个优化问题:

\[\text{min: }\sum\limits_{i=1}^{n}{{{d}_{i}}^{2}} \]
\(\begin{align}
 & \text{subject to: }0\le {{\alpha }_{i}}\le 1 \\
\end{align}\)

注意到这里我们求的是\(\sum{{{d}_{i}}^{2}}\)而并非\(\sum{\left| {{d}_{i}} \right|}\),为什么呢?当然不仅仅是为了避免求绝对值,将\(d_{i}^{2}\)展开我们得到:

\( {{d}_{i}}^{2}=\Delta {{x}_{i+1,i}}^{2}+\Delta {{y}_{i+1,i}}^{2} \)
\( ={{\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right)}^{T}}\left[ \begin{matrix}
   \Delta {{x}_{i+1}}^{2} & -\Delta {{x}_{i+1}}\Delta {{x}_{i}}  \\
   -\Delta {{x}_{i+1}}\Delta {{x}_{i}} & \Delta {{x}_{i}}^{2}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right)+{{\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right)}^{T}}\left[ \begin{matrix}
   \Delta {{y}_{i+1}}^{2} & -\Delta {{y}_{i+1}}\Delta {{y}_{i}}  \\
   -\Delta {{y}_{i+1}}\Delta {{y}_{i}} & \Delta {{y}_{i}}^{2}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right) \)
\( +2\left( {{x}_{i+1,0}}-{{x}_{i,0}} \right)\left[ \begin{matrix}
   \Delta {{x}_{i+1}} & -\Delta {{x}_{i}}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right)+2\left( {{y}_{i+1,0}}-{{y}_{i,0}} \right)\left[ \begin{matrix}
   \Delta {{y}_{i+1}} & -\Delta {{y}_{i}}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
\end{matrix} \right) \)
\(\begin{align}
 & +\text{costant terms} \\
\end{align}\)

这个形式的表达式,正是标准的Simply bounded Quadratic Programming问题啊,于是求解\(\alpha\)就方便多了。至于为什么\(\sum{{{d}_{i}}^{2}}\)和\(\sum{\left| {{d}_{i}} \right|}\)基本等效,是因为在我们的问题中有个假设是赛道分割的宽度近似相等,关于这个假设后面还有进一步讨论。

最小曲率路径

需要最小曲率路径的出发点是曲率越小,赛车能达到的最大速度越大,相应的关系[1]中有简单介绍。对于求解,这块的思路和最短路径思路类似,都是在一定假设下,先求局部量(曲率,距离),找到形如\(ax+b\)的表达式,然后平方一下转化为QP问题进行求解。在[1]中求曲率使用的cubic spline,实际实现其实未必用得着(当然也是因为我比较懒……二次的实现比三次简单很多),二次拟合和三次拟合求曲率的主要区别在于方向的影响,二次拟合求曲率时认为一个点周围的两个临近点是完全对称的,这和赛道分割的假设一致,所以可以用下面的公式来进行参数化:

\[\begin{align}
  & {{P}_{i}}={\mathbf{a}_{i}}+{\mathbf{b}_{i}}t+{\mathbf{c}_{i}}{{t}^{2}} \\
 & t=\frac{s-{{s}_{i}}}{{{s}_{i+1}}-{{s}_{i-1}}} \\
\end{align}\]

其中s是某一点到起点的路程,所以t的取值范围是-1到1。结合前面的假设来看只要分段等间隔可以被满足,那么\(\frac{dt}{ds}\)可以近似认为是个常数,经过一番和最短路径部分类似的繁琐推导,可以得到每一个路径点对应的曲率正比于\(\left| \mathbf{c} \right|\)。于是最小曲率路径又化成了一个QP问题:

\[ \text{min: }\sum\limits_{i=1}^{n}{{{c}_{i}}^{2}} \]
\(\begin{align}
 & \text{subject to: }0\le {{\alpha }_{i}}\le 1 \\
\end{align}\)

其中\(c_{i}^{2}\)的展开为:

\( {{c}_{i}}^{2}={{\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right)}^{T}}\left[ \begin{matrix}
   \Delta {{x}_{i+1}}^{2} & -2\Delta {{x}_{i+1}}\Delta {{x}_{i}} & \Delta {{x}_{i+1}}\Delta {{x}_{i-1}}  \\
   -2\Delta {{x}_{i}}\Delta {{x}_{i+1}} & 4\Delta {{x}_{i}}^{2} & -2\Delta {{x}_{i}}\Delta {{x}_{i-1}}  \\
   \Delta {{x}_{i-1}}\Delta {{x}_{i+1}} & -2\Delta {{x}_{i-1}}\Delta {{x}_{i}} & \Delta {{x}_{i-1}}^{2}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right) \)
\( +{{\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right)}^{T}}\left[ \begin{matrix}
   \Delta {{y}_{i+1}}^{2} & -2\Delta {{y}_{i+1}}\Delta {{y}_{i}} & \Delta {{y}_{i+1}}\Delta {{y}_{i-1}}  \\
   -2\Delta {{y}_{i}}\Delta {{y}_{i+1}} & 4\Delta {{y}_{i}}^{2} & -2\Delta {{y}_{i}}\Delta {{y}_{i-1}}  \\
   \Delta {{y}_{i-1}}\Delta {{y}_{i+1}} & -2\Delta {{y}_{i-1}}\Delta {{x}_{i}} & \Delta {{y}_{i-1}}^{2}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right) \)
\( +2\left( \left( {{x}_{i+1,0}}-{{x}_{i,0}} \right)-\left( {{x}_{i,0}}-{{x}_{i-1,0}} \right) \right)\left[ \begin{matrix}
   \Delta {{x}_{i+1}} & -2\Delta {{x}_{i}} & \Delta {{x}_{i-1}}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right) \)
\( +2\left( \left( {{y}_{i+1,0}}-{{y}_{i,0}} \right)-\left( {{y}_{i,0}}-{{y}_{i-1,0}} \right) \right)\left[ \begin{matrix}
   \Delta {{y}_{i+1}} & -2\Delta {{y}_{i}} & \Delta {{y}_{i-1}}  \\
\end{matrix} \right]\left( \begin{matrix}
   {{\alpha }_{i+1}}  \\
   {{\alpha }_{i}}  \\
   {{\alpha }_{i-1}}  \\
\end{matrix} \right) \)
\(\begin{align}
 & +\text{constant terms} \\
\end{align}\)

这种解法近似求得了全局曲率和的最小解,但是这个解对于赛车而言未必是最优的,因为求和值最小的解法,对于赛道这种分段数量庞大的情况,单个极值的影响总会被平均掉,仍很可能有的地方曲率特别大,导致成了整个赛道上保持高速的一个瓶颈。

更多关于等间隔假设

基于最短路径和最小曲率路径的推导,可以看到等间隔假设在这种分段方法中非常重要。在最短路径中因为有了等间隔假设, 所以相邻的两段路径长度就被耦合在一起,不会出现相邻两段的路径差得很远的情况,所以最短路径推导中用\(\sum{{{d}_{i}}^{2}}\)才近似合理。而在最小曲率路径的推导中就更重要了,否则曲率项就变得非常复杂。然而这个假设是不是真的实用呢,其实还需要一个更强的假设,那就是每段之间的间隔远大于赛道宽度

比如图中的例子,因为赛道间隔比较密,转弯半径特别小的时候,靠弯道内部分的间隔会很小,弯道外侧部分间隔很大,这使得最短路径和最小曲率路径的假设都受到影响,尤其是最小曲率路径,会得到很不好的结果,比如下图的最小曲率路径:

然而如果线段的间隔过大,当转弯很急的时候,采样点的数量会显得不够。对于这种情况,我解决的办法是将分段的线段分组,比如每隔一个取一个分段线段,相当于得到了错位开来的两组分段线段,每组的间隔都是原来分段间隔的二倍,然后做两次路径求解,取平均,当然也可以加入一些后处理,比如向上重采样然后做平均平滑等等,结果在下面一节的图里可以看到。不过即便采用了一些手段来确保产生合理的赛道,对于最小曲率路径而言,这还是一个trade off的问题,因为间隔越大的情况对急转弯的采样会越差,如果特别急的弯道还会因为漏采样出现“撞赛道”问题,需要更多后处理。总结来说,就是这种基于QP的算法,无论二次还是三次,都不能很好应对急转弯,不过在实际的赛车游戏当中,像上面图里的那种急转弯相对来说不是特别常见,所以用起来效果还可以,需要考虑的往往是在赛道预处理、分段和QP时因为采样过密导致的时间和内存消耗。

基于最短路径和最小曲率路径的最优赛道

有了最短路径和最小曲率路径后,求最佳路径的办法可以参考[2],大体描述如下:首先找到最短路径和最小曲率路径的每个交点,将两个交点之间的划为一组,这样相当于降维,把优化所有的\(\alpha\)转化为优化好几组\(\alpha\)。对于第j组分组中,\(\alpha_{j}\)的值表示为最短路径的\(\alpha_{j,sp}\)和最小曲率路径的\(\alpha_{j,mcp}\)的加权平均:

\[\begin{align}
 & {{\alpha }_{j}}=\varepsilon {{\alpha }_{j,sp}}+\left( 1-\varepsilon  \right){{\alpha }_{j,mcp}} \\
\end{align}\]

比如下图是令\(\varepsilon\)为0.5时得到的一个路径,和对应的最短路径、最小曲率路径,以及分段。

对得到的路径进行模拟,得到跑圈时间,于是转化成一个全局优化的问题:

\[ \text{min: lap time} \]
\(\begin{align}
 & \text{subject to: }0\le {{\varepsilon }_{j}}\le 1 \\
\end{align}\)

[2]中用的是基因算法(Genetic Algorithm),其实如果赛道不是很复杂的话,分段应该不多,低维情况可以考虑用比GA收敛快的算法。

如何沿指定赛道驾驶

这部分我没有参与,也没有进行过调研,应该也没有时间去参与了。不过我觉得一个也许可行的办法是将赛道上每一点对应的最大速度和该点到起点的距离表达出来\(v_{\max }\left( s \right)\),最大速度的求法根据不同情况会有不同答案,对于一般的赛道而言,近似认为最大速度被转弯离心力和风阻限制,相应的公式[2]中有提到。另外从任意速度开始以恒定加速度进行加速和减速也可以得到一个以该点为起点距离为变量的速度表达式\(v\left( r \right)\)(似乎大约是个\(\propto \sqrt{r-{{r}_{0}}}\)的关系),那么又转化为一个优化问题:

\[ \text{max: }\int{v\left( s \right)} \]
\(\begin{align}
 & \text{subject to: }v\left( s \right)<{{v}_{\max }}\left( s \right) \\
\end{align}\)

这个问题甚至也许不需要优化就能求出解析解。

参考文献:

[1] F. Braghin, F. Cheli, S. Melzi, and E. Sabbioni. Race driver model. Comput. Struct., 86(13-14):1503–1516, 2008.

[2] Cardamone, L., Loiacono, D., Lanzi, P.L., & Bardelli, A.P. Searching for the optimal racing line using genetic algorithms. In Proceedings of the 2010 IEEE Conference on Computational Intelligence and Games (pp. 388–394).

转载于:https://www.cnblogs.com/frombeijingwithlove/p/3648673.html

赛车游戏中求解最短路径和最小曲率路径相关推荐

  1. 技术干货:赛车游戏中最短路径和最小曲率路径算法

    转自:https://www.gameres.com/492096.html 最近参与了一个非常蛋疼的业余时间小项目:给定赛道和赛车模拟程序,求赛车跑完赛道的最快的办法.对于这个问题,我一开始的想法是 ...

  2. 赛车游戏中赛车的物理建模

    一般情况下,赛车的物理建模可能需要需要以下的这些数据: 1.最高时速: 2.最大功率,用于计算牵引力或速度,功率(W)=速度(m/s)*力(N)),0-100km/h的加速时间,可以用于计算启动阶段大 ...

  3. 赛车游戏中的力学模型

    注:这章博客主要对前面一篇物理建模进行扩充. 首先,说明一下,赛车轮胎与公路路面的摩擦力大致大小为:滚动摩擦系数为0.01左右,滑动摩擦系数为0.1左右,静摩擦系数为1.0左右. 下面重点说明一下汽车 ...

  4. 机器学习如何彻底改变游戏中的物理模拟

    来源:AI科技评论本文约2600字,建议阅读10分钟 神经网络模拟物理比物理解算器快5000倍. 量子力学奠基者之一.英国理论物理学家保罗·狄拉克(Paul Dirac)在1929年说过:" ...

  5. 机器学习是如何改变游戏中的物理模拟?

    量子力学奠基者之一.英国理论物理学家保罗·狄拉克(Paul Dirac)在1929年说过:"大部分物理和化学所需要的数学理论的定律都是已知的,但这些定律的方程太复杂无法求得精确解" ...

  6. python编写赛车游戏单机版_使用Keras和DDPG玩赛车游戏(自动驾驶)

    为什么选择TORCS游戏 <The Open Racing Car Simulator>(TORCS)是一款开源3D赛车模拟游戏 看着AI学会开车是一件很酷的事 可视化并考察神经网络的学习 ...

  7. 无缝切地图的3D赛车游戏火了,小哥花16个月用JS打造,浏览器免费就能玩

    萧箫 发自 凹非寺 量子位 | 公众号 QbitAI 一位小哥耗时16个月打造的3D版赛车游戏,这两天忽然火了起来. 只需一个浏览器,就能驾车从森林.海滩,"无缝切换"到广袤的沙漠 ...

  8. 使用Keras和DDPG玩赛车游戏(自动驾驶)

    Using Keras and Deep Deterministic Policy Gradient to play TORCS--300行python代码展示DDPG(基于Keras)--视频 可以 ...

  9. NFT赛车游戏F1® Delta Time启动第二轮2019赛车NFT质押活动

    NFT赛车游戏F1® Delta Time启动第二轮2019赛车NFT质押活动,活动截至日期为2021年3月23日,将共奖励200万枚REVV.奖励数量将取决于玩家质押的赛车NFT数量占比以及稀有程度 ...

最新文章

  1. EL表达式介绍(1)
  2. c语言:找出1到4000中,数字的各位数之和能被4整除的数有多少个?
  3. Xamarin Essentials应用教程文件系统FileSystem
  4. SVN 报错svn: E200014: Checksum mismatch for 。。。。。
  5. Eclipse下编写C++程序——CDT环境搭建
  6. 怎样查看电脑系统版本_微信7.0.0自动更新后怎样去还原以前的旧版本?
  7. NSMutable属性声明时为什么不能使用copy
  8. mysql第四篇:数据操作之多表查询
  9. 浅析Block的内部结构 , 及分析其是如何利用 NSInvocation 进行调用
  10. oracle允许空行,oracle用户权限的一些基本操作
  11. YUI事件体系之Y.Do
  12. 1601 - The Morning after Halloween
  13. Installation error: INSTALL_FAILED_UID_CHANGED
  14. CCF 送货(满分代码)2015-12-4
  15. java的HashCode方法(转载)
  16. 最新免费计算机编程视频教程
  17. 使用PHP来获取客户端和服务端IP
  18. 计算机顶级水平,中国10年前的顶级电脑的配置、性能上相当于现在电脑的什么水平?...
  19. python中oct函数_Python内置函数OCT详解
  20. 过去的Tony老师你爱理不理,现在的Tony老师你高攀不起

热门文章

  1. JavaScript判断设备类型的实现
  2. 全网最详细的接口测试实战案例【全文57000字】
  3. Python小白到老司机,快跟我上车!基础篇(二十)
  4. Apache LICENSE 2.0 授权介绍
  5. 微信视频号火力全开,新增直播三件套+巨大流量入口丨国仁网络
  6. 记一次app上架苹果应用商店
  7. Java - 校园类型系统班级升年级
  8. pgsql获取上一个月,上一个月第一天,上一个月最后一天
  9. 数据质量管理_第四篇 对数变换
  10. python照片转彩色手绘_用PS把女生照片转成炫彩渐变手绘效果