目标跟踪:什么时候可以加速和减速旋转炮塔?


24

假设我有一个移动的通知,target定义为:

Vector2 position;
Vector2 velocity;
float radius;

旋转的turret(安装在某种移动的车辆上)定义为:

Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second

(或沿这些方向移动。请注意,两者的位置和速度都在其他位置控制-假设速度是恒定的,并且位置根据速度而变化。)

我试图在给定的框架上编写两个相关的AI函数来确定:

  • 要对转塔的角度施加什么角加速度(以及朝哪个方向),以使转塔指向目标?

  • 如果目标当前处于可见状态,是否可以将其(半径范围内的任何部分)保持可见状态x几秒钟,哪怕x是几分之一秒?(或者:是否有另一种策略可以确保目标实际上是“锁定在”目标,而不是简单地飞越景点?)

我可以帮忙...


1
旋转加速度和减速度可能具有不同的值-在现实世界中,一个可能是电动机,另一个可能是制动器。
e100 2012年

Answers:


19

首先,您需要确定转塔面向方向与目标方向之间的角度差。

Vector2 turretToTarget = target.position - turret.position;
float desiredAngle = atan2(turretToTarget.y, turretToTarget.x);
float angleDiff = desiredAngle - turret.angle;

// Normalize angle to [-PI,PI] range. This ensures that the turret
// turns the shortest way.
while (angleDiff < -PI) angleDiff += 2*PI;
while (angleDiff >= PI) angleDiff -= 2*PI;

一旦获得这些数量,就可以为转塔角度设置第二度表达式。您需要在每次更新时都进行计算,以确保始终使用最新的位置和速度数据。

// Compute angular acceleration.
const float C0 = // Must be determined.
const float C1 = // Must be determined.
float angularAcc = C0 * angleDiff - C1 * turret.angularVelocity;

在此,加速度表达式中的第一个项(零度)将使转塔开始转向目标。但是,它不会及时停止,而是会在其上来回摆动。为了使其停止,我们需要阻尼第二项(一级),该项会使高转弯速度与高加速度相反。

现在,需要确定正常数(不一定是程序常数)并进行平衡,以使系统运行良好。C0是系统速度的主要控制。较高的值C0将提供快速的旋转速度,而较低的值将提供较低的旋转速度。实际值取决于许多因素,因此您应在此处使用反复试验。C1控制阻尼大小。二次方程的判别式告诉我们,如果C1*C1 - 4*C0 >= 0我们有一个非振动系统。

// New definition.
const float C1 = 2*sqrt(C0); // Stabilizes the system.

C1出于数字上的原因,您可能应该选择一个比这个大的值,但不要太大,因为它可能会变得过分阻尼并且响应速度很慢。同样,您需要调整。

同样重要的是要注意,该代码仅计算角加速度。需要使用某种形式的积分器从其他地方更新角度和角速度。根据这个问题,我认为已经解决了这一问题。

最后,还有关于滞后的说法,因为在跟踪快速目标时,炮塔可能总是落后。解决此问题的一种简单方法是向目标位置添加线性预测,即始终将目标对准目标的向前方向。

// Improvement of the first lines above.
const float predictionTime = 1; // One second prediction, you need to experiment.
Vector2 turretToTarget = target.position + predictionTime * target.velocity - turret.position;
/// ...

至于将转塔对准目标半径范围内一段时间,这可能是直接施加于此类系统上的一项艰巨要求。可以肯定的是,该控制器将一直努力将转塔始终对准目标(或预测位置)。如果结果证明不是令人满意,你必须修改参数predictionTimeC0以及C1(稳定的范围内)。


我没有资格说这是否对,但这听起来有些聪明!过去,我通过向前预测加速度的影响来解决这些类型的问题,从而确定何时需要加速以及何时“应用中断”。这是否意味着我做错了?
伊恩

由于atan2的x和y参数变得依赖于t,因此atan2使得该方法难以适应预测系统。
Skizz 2010年

这正是我在下面的答案中暗示的解决方案。出色的细节和展示!
drxzcl 2010年

@伊恩:不,这里没有是非。虽然我猜您的方法将具有两个离散状态:加速/减速,但此方法的灵感来自于控制理论的调节器,调整了加速度以做出快速响应,同时减少了过冲和振荡。
Staffan E 2010年

1
与其他注释一样,这将适用于固定的目标,但对于任何移动的目标都可能是不可接受的。C0和C1项是传统的阻尼弹簧材料,其中C0代表弹簧的强度(通常称为k),而C1是阻尼系数(通常称为“ B”或“ c”)。所以,是的,你可以通过最小化手摇阻尼,但问题是,这并不试图预测,其中目标振荡是,所以注定要滞后于预期的目标。
dash-tom-bang 2010年

3

您在这里拥有的是一个基本的控制问题。刀塔是系统,加速度是控制,传感器测量位置/速度。解决这些问题的方法很多,因为它是工程学中经过充分研究的问题。

关键是建立一个稳定的系统,即不产生振荡的系统。通常通过添加阻尼来完成。维基百科页面应该可以帮助您入门。


2

首先,计算从转塔到目标的向量。然后将其与转塔的当前向量进行比较。然后使用两者之间的差值计算出转塔在给定时间内指向正确方向所需的角加速度和角速度。

好,那看起来很简单。但是,您应该真正尝试预测目标的位置,因为在转塔时目标将移动。去做这个:-

Pd' = Pd + t.Vd
Ps' = Ps + t.Vs

其中P是位置,V是速度,下标是目的地(目标)的d,而下标是源(炮塔)的s,给出方向矢量:

Dsd' = Pd' - Ps' = Pd + t.Vd - (Ps + t.Vs) = Pd - Ps + (Vd - Vs).t

其中D是方向矢量,Dsd'是时间t所需的方向。现在,根据给定时间t的当前位置以及最大速度和加速度,确定转塔的方向:

Ds' = t.Ds.Rs -> this is a vector rotation

Ds和Ds'是源方向,Rs是旋转速度。综上所述,您想在Dsd'== Ds'时找到t,从而在Rs时找到所需的转速。不要忘记所有的P,D和V都有x和y分量。

我这里没有考虑加速-这增加了很多复杂性。一旦获得Rs和t,您就可以近似抛物线形Rs(即加速和减速)以得到相同的结果。


对于拦截计算来说,这似乎是一个很好的答案,但是不幸的是,可以阅读这种数学符号并将其转换为程序代码的人们与大多数不知道答案的人之间存在很大的差距。问题。换句话说,我认为可以阅读该数学符号的游戏开发人员可能已经可以弄清楚如何对射击解决方案进行编程。如果您解释术语的含义,它将帮助我理解您的公式。
Dronz


0

首先要做的是计算湍流和被跟踪物体之间的角度。
下一步是检查是否使用当前的种子速度并向后应用最大加速度(停止种子),种子将在被跟踪对象之前或之后停止。
如果答案是洪流将在被跟踪物体之前停止,则向前应用最大加速度(增加速度)。
如果答案是种子将在跟踪对象之后停止,请向后应用最大加速度(停止种子)。
这样,洪流将以最快的速度到达,并将在正确的位置(或之后的一小部分)停止。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.