根据您问题的上下文(http://nodewar.com/),您的解决方案有两个特定注意事项:
- 您有一个(低)最大角速度,并且有足够的最大扭矩可以在很短的时间内达到它。
- 您的无人机和目标都有与推力无关的速度和外部加速度(大量引力)。
- 您想要的目标改变得如此频繁,以至于无法完美地瞄准就浪费了。您应该尝试靠近,并在每一帧进行校正。
这些方法是我确定要达到所需加速度的方法。
加速而非速度
因为您已经具有给定的速度,并且目标正在移动,所以不需要向一点推力。您需要推力才能将速度更改为应该的速度。这意味着您的船不必指向前进的方向,而应指向前进的方向。
// 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次推力。这样可以在不改变实际值的情况下为您提供有效的部分推力。
祝好运!