无人机定位


9

想象一个“无人机”和一个二维平面上的目标点。有八个参数:

P = my position
Q = target position
V = my velocity
I = my moment of inertia
w = my angular velocity
s = my angular position
T = max thrust
U = max torque

(我们只是说目标是固定的)

无人机的工作是尽可能快地到达目标,并遵守最大扭矩和最大推力。只有两种方式施加扭矩,因为这仅在2d平面中。推力仅限于相对于飞行器方向的一个方向,并且不旋转无人机就无法瞄准。忽略任何阻力,您可以假装它在2D外部空间中漂浮。假设无人机t每隔一段时间(例如每0.01秒一次)检查一个方程式,插入参数,并相应地调整其扭矩和推力。推力和扭矩方程应该是什么?


3
如果推力只能沿一个方向进行,则您永远都不会改变方向。
MichaelHouse

1
我应该更清楚地指定-您不能平衡推力,即推力只能相对于飞行器方向沿一个方向进行。您仍然可以旋转飞行器并更改推力方向。
2013年

2
这个问题与nodewar有关吗?
塞斯·巴丁

1
然后,我想我可以为您提供一个好的解决方案(今晚晚一点)。:)
塞斯·

1
这个问题需要一个更具描述性的标题,但我想不到一个好标题。?
Anko

Answers:


5

根据您问题的上下文(http://nodewar.com/),您的解决方案有两个特定注意事项:

  1. 您有一个(低)最大角速度,并且有足够的最大扭矩可以在很短的时间内达到它。
  2. 您的无人机和目标都有与推力无关的速度和外部加速度(大量引力)。
  3. 您想要的目标改变得如此频繁,以至于无法完美地瞄准就浪费了。您应该尝试靠近,并在每一帧进行校正。

这些方法是我确定要达到所需加速度的方法。

加速而非速度

因为您已经具有给定的速度,并且目标正在移动,所以不需要向一点推力。您需要推力才能将速度更改为应该的速度。这意味着您的船不必指向前进的方向,而应指向前进的方向。

// My target velocity is for maintaining a circular orbit.  Yours may differ.
// Earlier, I calculated total gravity and the perpendicular direction.
// You may wish to subtract gravity from your total, rather than match it.
var targetVel = o.lib.vec.times(lateralDir, targetVelMag);

var targetAccel = lv.sum(
  o.lib.vec.diff(targetVel, o.me.vel), 
  o.lib.vec.times(gravity, 1 / o.me.mass)  
);

转向正确的方向

您有一个加速度矢量,现在要应用它。确定您需要旋转多远。我可能使用了比此处所需的步骤更多的步骤,但是旋转坐标使我感到困惑,而且我认为无上限的船舶旋转值仍然是API中的错误。

// convert acceleration to an angle
var polar = o.lib.vec.toPolar(targetAccel);
var traj = polar[1];

// constrain the angle to +/-2PI, because the ship's rotation is not limited 
// by default
var fixed_rot = o.lib.ang.rescale(o.me.rot);

// limit the correction to be +/-1PI
var traj_correction = traj - fixed_rot;
if (traj_correction > (Math.PI)){
  traj_correction = (2 * Math.PI) - traj_correction;
} else if (traj_correction < (-1 * Math.PI)){
  traj_correction = (2 * Math.PI) + traj_correction;
}

一个简单的公式。始终转动不会造成任何伤害,因此不要理会施加部分转矩值。如果您需要对角速度进行较小的校正,则无论如何每秒都可以多次进行此确定。

if (traj_correction > 0){
  torque = 1;
} else if (traj_correction < 0){
  torque = -1;
}

一个不太简单的公式。到了某个地方,您不想继续转弯,因为您最终想要停止。幸运的是,该角速度上限意味着您可以从最大角速度迅速降低到零。您只需要计算何时进行。

var max_a_accel = c.MAX_TORQUE / o.me.m_i;
var a_deccel_time = Math.abs(o.me.a_vel) / max_a_accel;
// the same math as linear acceleration, now in angles.
var stopping_angle = 0.5 * max_a_accel * a_deccel_time * a_deccel_time;


if (stopping_angle >= Math.abs(traj_correction)){
  // slowdown required.  Reverse torque
  torque *= -1;
}

在调整了上面的代码以适合您的需求之后,您的船应该迅速而精确地旋转到您给目标定的角度。

夯击速度

那么,什么时候推?再次,目标和其他因素的迅速变化为解决精确的解决方案带来了很大的困难。不要尝试。

// if the heading is close to the final value, thrust.
if (Math.abs(traj_correction ) < 0.02) {  // about 1 degree
  if (true 
      // some logical test, in case you don't want to accelerate past
      // a maximum speed, or some such.  Not required for your stated purpose.
     ){
    thrust = 1;
  } 
}

对于那些需要部分推力的情况,您可以再次依靠这样的事实,即每秒可以多次选择0到1次推力。这样可以在不改变实际值的情况下为您提供有效的部分推力。

祝好运!


太好了,谢谢,这很有帮助。我认为我将不得不对其进行一些修改。你的名字叫什么?
Gus 2013年

我还没有把他们推上阶梯。他们没有办法进攻。:)
塞斯·巴丁

3

一个类似的问题,有一些很好的答案,包括整个主题的明显名称“运动计划”:https :
//stackoverflow.com/questions/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

作为程序员,我喜欢user470365建议的实用性。但是,我将采取更为严格的方法。我的建议是从一开始就计算一个完整的计划,但是我想如果参数发生变化,您可以根据需要进行多次重新评估。

计划

  1. 转向某个方向d并保持该方向。
  2. 等到一定的时间t,然后做一个持续的推力,直到达到目标。

细节

我建议找到dt的迭代方法:

  1. 假设没有推力,使用一个循环和一个小的时间步长沿着无人机的未来轨迹移动:

    • 对于此未来时间的无人机位置和速度,请找到方向d,这样持续的推力会将无人机带到目标。为此,请在0到360度之间对很多方向进行采样,然后找到一个可以在最短时间内使无人机接近目标的方向。
    • 检查看看从现在到这个未来时间之间我们是否有足够的时间转向d。(转弯并不简单。请参见最后的讨论。)
    • 如果我们有足够的时间,那么我们的搜索就完成了,因此请跳出此循环。
  2. 现在我们找到了dt

  3. 转向d尽可能快地(再次参见下面的讨论)。
  4. 等到t,然后开始持续推力。
  5. 无人机最终应该击中目标。

转弯

当我说“转向d ”时,我的意思是,“执行一系列扭矩,使我们尽可能快地旋转到d,同时还将角速度设为零”。可能存在涉及当前方向,当前角速度和最大角加速度的方程式,但是由于角度的包裹行为而变得复杂。


有趣的方法。那么,什么决定了我们对未来时间的选择?似乎任何确定它的技术都存在问题,因此也可能需要进行迭代。
Gus 2013年
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.