# AI:选择即时加速度/旋转以到达最终点

我正在开发一款游戏,在游戏循环的每次更新时,都会运行AI。在这次更新中,我有机会转动AI控制的实体和/或使其沿其面向的方向加速。我希望它到达最终位置(在合理的范围内),并且在该位置具有特定的速度和方向(同样,不需要完全精确)。也就是说,给定当前的:

  • P0(x, y) = 当前位置向量
  • V0(x, y) = 当前速度向量(单位/秒)
  • θ0 = 当前方向(弧度)
  • τmax = 最大转弯速度(弧度/秒)
  • αmax = 最大加速度(单位/秒2
  • |V|max = 绝对最大速度(单位/秒)
  • Pf(x, y) = 目标位置向量
  • Vf(x, y) = 目标速度向量(单位/秒)
  • θf = 目标旋转(弧度)

选择一个即时的:

  • τ = 在[-τmax, τmax]范围内的转弯速度
  • α = 在[0, αmax]范围内的加速度标量(必须沿当前面向的方向加速)

使得以下各项最小化:

  • t = 移动到目标位置的总时间
  • |Pt-Pf| = 结束时与目标位置的距离
  • |Vt-Vf| = 结束时与目标速度的偏差
  • tf| = 结束时与目标旋转的偏差(包裹到(-π,π))

这些参数可以在游戏循环的每次迭代中重新计算。一张图片胜过千言万语,所以举例来说,给定当前状态为蓝色家伙,在尽可能短的时间内近似达到红色家伙的状态(箭头是速度):

Pic http://public.blu.livefilestore.com/y1p6zWlGWeATDQCM80G6gaDaX43BUik0DbFukbwE9I4rMk8axYpKwVS5-43rbwG9aZQmttJXd68NDAtYpYL6ugQXg/words.gif

假设在Δt内 α 和 τ 恒定 (Δt → 0 代表理想解),并将位置/速度分解为分量,这会给出(我认为,我的数学可能不对):

Equations http://public.blu.livefilestore.com/y1p6zWlGWeATDTF9DZsTdHiio4dAKGrvSzg904W9cOeaeLpAE3MJzGZFokcZ-ZY21d0RGQ7VTxHIS88uC8-iDAV7g.equations.gif

(编辑:最后一个应该是 θ = θ0 + τΔt)

那么,我如何选择一个即时的 α 和 τ(记住这些将在游戏循环的每次迭代中重新计算,通常 > 100 fps)?我能想到的最简单、最幼稚的方法是:

  1. 选择一个 Δt,该 Δt 等于游戏循环更新之间最后几个 Δt 的平均值(即非常小)
  2. 计算下一步的上述 5 个方程,针对 (α, τ) = {0, αmax} x {-τmax, 0, τmax} 的所有组合(只有 6 个组合,每个组合 5 个方程,因此不应该花费太长时间,并且由于它们运行如此频繁,因此最终会摊销相当严格的范围)
  3. 为位置、速度和旋转分配权重。也许这些权重可以是动态的(即,实体距离位置越远,位置的权重就越大)。
  4. 贪婪地选择一个在 Δt 之后最小化这些因素的位置。

它可能很快 & 简单,但是,这存在一些明显的题:

  • 权重的任意选择
  • 它是一种贪婪算法,(就其本质而言)无法回溯
  • 它并没有真正考虑到问题空间
  • 如果它频繁地改变加速度或转弯,动画可能会看起来“生涩”。

请注意,虽然该算法可以(并且可能应该)在迭代之间保存状态,但 Pf、Vf 和 θf 可以在每次迭代时更改(即,如果实体试图跟随/定位在另一个实体附近),因此该算法需要能够适应不断变化的条件。

有什么想法吗?我是否遗漏了一个简单的解决方案?

谢谢,Robert


回答:

听起来你想要一个PD控制器。基本上,从当前位置到目标位置画一条线。然后取该线的方向(弧度),这就是你的目标弧度。当前的弧度误差是当前朝向 – 线朝向。称之为Eh。(heading error) 然后你说当前的转弯率将是 KpEh+d/dt EhKd. 每一帧都用一条新线来做这个。

这是针对朝向的

加速度是“加速直到我达到最大速度或者我无法及时停止”。你提出了一堆积分,所以我相信你肯定能搞定这个计算。

如果你想知道,是的,我之前解决过这个问题,PD控制器是有效的。不要费心使用PID,在这种情况下不需要它。在matlab中进行原型设计。有一件事我遗漏了,你需要有一个触发器,比如“我现在越来越近了”,所以我应该开始转向进入目标。我刚刚阅读了你关于“只能在我们前进的方向上加速”的说明。这稍微改变了一些事情,但不多。这意味着需要“从后面”接近目标,这意味着线条目标必须在实际目标的后面,当你接近后面目标时,遵循一条新线,引导你到实际目标。你也会想要跟随这些线,而不是仅仅选择一个朝向并尝试坚持下去。所以不要每帧都更新这条线,只需要说误差等于与当前目标线的符号距离。PD会给你一个转弯率,加速度是微不足道的,所以你已经设置好了。你需要通过试错来调整Kd和Kp,这就是为什么我先说matlab。(Octave也不错)

祝你好运,希望这能给你指明正确的方向;)

双关语。

编辑:我刚刚读到…很多东西,写得很快。这是你的问题的一个循线解决方案,如果你想以这个解决方案为基础来解决问题,只需谷歌循线即可。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注