這是我在嘗試使用LÖVE引擎實現遊戲時遇到的一個問題,它使用Lua腳本涵蓋了box2d。物理遊戲編程box2d - 使用扭矩定向類似炮塔的物體
目標很簡單:一個類似炮塔的物體(從頂部看,在2D環境中)需要定向自身,以便指向目標。
炮塔位於x,y座標上,目標位於tx,ty。我們可以認爲x,y是固定的,但是tx,ty往往會在一瞬間變化(即它們會是鼠標光標)。
轉塔有一個轉子,可以在任何給定的時刻,順時針或逆時針施加轉動力(轉矩)。該力量的大小有一個稱爲maxTorque的上限。
該轉檯還具有一定的轉動慣量,該轉動慣量對質量作用於線性運動的角度運動起作用。沒有任何形式的摩擦,所以如果它有一個角速度,炮塔將繼續旋轉。
炮塔有一個小的AI功能,重新評估其方向,以驗證它指向正確的方向,並激活旋轉器。這發生在每個dt(〜每秒60次)。它現在看起來像這樣:
function Turret:update(dt)
local x,y = self:getPositon()
local tx,ty = self:getTarget()
local maxTorque = self:getMaxTorque() -- max force of the turret rotor
local inertia = self:getInertia() -- the rotational inertia
local w = self:getAngularVelocity() -- current angular velocity of the turret
local angle = self:getAngle() -- the angle the turret is facing currently
-- the angle of the like that links the turret center with the target
local targetAngle = math.atan2(oy-y,ox-x)
local differenceAngle = _normalizeAngle(targetAngle - angle)
if(differenceAngle <= math.pi) then -- counter-clockwise is the shortest path
self:applyTorque(maxTorque)
else -- clockwise is the shortest path
self:applyTorque(-maxTorque)
end
end
......它失敗。讓我來解釋兩種說明情況:
- 炮塔在目標角上「擺動」。
- 如果目標是「恰好在炮塔後面,只是一點點順時針」,炮塔將開始施加順時針轉矩,並繼續使用它們直到它超過目標角度。此時它將開始在相反的方向上施加扭矩。但它會獲得顯着的角速度,所以它會持續順時針旋轉一段時間......直到目標將「在後面,但有一點逆時針」。它會重新開始。所以炮塔會振盪,甚至會繞着圓圈。
我認爲我的炮塔應該在到達目標角度(如停車前的汽車剎車)之前開始在「最短路徑的相反方向」施加扭矩。直覺上,我認爲炮塔應該「開始在最短路徑的相反方向上施加扭矩,當它到達目標物體的中途時」。我的直覺告訴我,它與角速度有關。然後有一個事實,即目標是移動的 - 我不知道是否應該考慮到這一點,或者忽略它。
如何計算何時炮塔必須「開始剎車」?
這種方法的麻煩在於它是爲諸如加熱系統之類的東西而設計的,溫度的一階導數; egarcia正在控制扭矩,這是第二個。 P會因爲針對a = 0而不是w = 0而瘋狂地超調,我沒有幫助振盪,D可能會工作,但它會使過程變慢。 – Beta 2010-04-11 16:40:53
你說得對,我給出的例子並不直接處理扭矩。然而,當考慮到炮塔旋轉「機制」中的摩擦力時,'maxAngleMomentum'與'maxTorque'成正比 - 使用任意單位時可以認爲它們是可互換的。 – Brendan 2010-04-12 15:41:30
實現看起來不錯。 「保存角動量」的想法很有趣。然而,這不是我所要求的 - 我想要施加扭矩,而最終你自己設定角度。但是用於製作演示和代碼優雅的+1。 – kikito 2010-04-14 00:23:21