Uzay gemisinin dinamik itici dengelemesi


14

Oyunumdaki uzay, herhangi bir rotasyonla herhangi bir yere bağlı keyfi miktarda itici ile oyuncu tarafından inşa edilecek şekilde geliyor. Şu anda gemiyi belirli bir açıya döndürmek için bazı kirli kodlarım var (hızlanma ve yavaşlama).

İşte kırmızı çizginin sola döndüğü söylenen simetrik bir gemi örneği.

Gemi

Ancak, tahmin edebileceğiniz gibi, oyuncunun iticileri nereye koyduğuna bağlı olarak, bazen istenmeyen doğrusal kuvvetler gemiyi etkiliyor. Bu durumda, gemi ilerlemeye başlar.

Bir iticinin doğrusal hıza neden olmamak için uygulayabileceği maksimum itme kuvvetini bulmanın mümkün olup olmadığına dikkat çekiyorum. (Yukarıdaki durumda, arka iticilerden gelen güçlere karşı koyacak hiçbir şey olmadığı ve ön tarafların birbirini öldürdüğü için bu hiç olmazdı).

Şimdiye kadar bulduğum şey, "dönüş verimliliğini" belirlemek için bir formüldür, örneğin doğrusal harekete bağlı olarak ne kadar dönüşe neden olduğu.

a - iticiye konum vektörü b - iticiye konum vektör b v1 - iticiye kuvvet a v2 - iticiye kuvvet b

verimliliğiDelta = a.cross (v1) / | v1 | - (a.cross (v1) + b.cross (v2)) / | v1 + v2 |

, temelde "a.cross (v1 * t) / | v1 |" dönüş verimliliği olması gerekiyordu. Ve sonra, yeni iticiyi ateşlemenin buna değip değmeyeceğini görmek için bir araya getirerek iticilerin dönüş verimliliği ile çıkarıyoruz.

Sorun, iticilerin açık / kapalı olması gerekmediğini fark ettiğimde ortaya çıkar, ancak itme kuvvetlerini 0'dan 1'e değiştirebilir. Ve oyuncu geminin ilerlemesini istediğinde nasıl devam edileceğini. Tabii ki, ne kadar döndürüleceği / hareket edileceği arasında bir denge olması gerekir.

Ben roket bilimcisi değilim, bu yüzden her iticinin gazını bu şekilde hesaplamanın ve bana doğru yönde itmenin mümkün olup olmadığını söyleyebilecek biri olmasını umuyorum.

Zaman ayırdığınız için teşekkürler! / Kim


3
Aynı yolda başladım, ancak birçok yapılandırmada, hem döndürmek hem de çevirmek imkansız. Peki rotasyonu alıyor musunuz? Veya çeviriye izin veriyor musunuz? Sonuçta, gemiyi tasarlayan kullanıcıya kalmış. İçin benim demo bu, bunu sahte. İlgili: gamedev.stackexchange.com/questions/58216/… , gamedev.stackexchange.com/questions/40615/…
MichaelHouse

Benzer bir yol izledim ve bu sayfada bir demo yazdım . İticileri hareket ettirdikçe (konumu ve gücü ayarlamak için gemide sürükleyin) üç şekil çizer. Sezgi, tüm olası hareketleri 3B alanda (x, y, döndürme) bir nokta olarak düşünebileceğiniz ve 0-1 ile sınırlı olmanın o alanda bir kısıtlama olduğudur. Böylece olası tüm hareketleri içeren bir 3d şekil elde edersiniz. Doğrusal hız istemiyorsanız, o alandaki (x = 0, y = 0) satırına
bakıyorsunuz

Yanıtlar:


7

Geminiz için fiziksel olarak doğru hareketiniz olduğunu varsayacağım, aksi takdirde bu analiz yapılmayacaktır. Bu sorunu doğru bir şekilde çözmek için verimlilikten daha güçlü bir şeye ihtiyacınız var.

Her itici, geminin hareketi üzerinde iki etki yaratacaktır: doğrusal ve açısal. Bunlar bağımsız olarak düşünülebilir. İtici fbir yönde bir kuvvet üretirse dirve kütle merkezinden bir vektörle r(geometrik merkez veya hareketli grafiğin merkezi değil!) Dengelenirse, doğrusal bileşen üzerindeki etki:

t = f * dir // f is a scalar, dir is unit length

Açısal hız üzerindeki etki tork tarafından verilir:

tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product

tbir kuvvet vektörüdür (yani doğrusal itme). taukütle atalet momenti ile bölündüğünde açısal ivme verecek olan imzalı bir skalerdir. Çok önemlidir dirve raynı her ikisi de yani hem yerel koordinatlarda veya her ikisi, dünya koordinatlarında, uzay koordinat.

Geminin toplam doğrusal ivmesi, ther itici için geminin kütlesine bölünmesiyle elde edilen toplamın toplamıdır . Benzer şekilde, açısal ivme sadece torkların toplam kütle atalet momentine (yani başka bir skaler) bölünmesidir. Toplam tork sıfırsa, gemi dönmeyecektir. Benzer şekilde, toplam itme sıfır olduğunda hareket etmeyecektir. Geri çağırma torku skalerdir, ancak itme ( t's toplamı ) bir 2D vektörüdür.

Bu serginin amacı artık problemimizi Doğrusal Program olarak yazabilmemizdir . Önce gemimizin hareket etmeden dönmesini istiyoruz . Her itici için bir değişkenimiz var, $ x_1, x_2, ... $, iticinin sağlayacağı itme miktarı. Bir kısıtlama kümesi:

0 <= x_i < fmax_i  //for each i

fmaxbu itici için maksimum kuvvet nerede (bu, daha güçlü veya daha zayıf olanlara sahip olmamızı sağlar). Sonra, her iki eşitliğin de dedik:

0 = Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y

Bu, toplam itmenin sıfır olduğunu söyleyerek doğrusal bir ivme uygulamadığımız kısıtlamayı kodlar (itme bir vektördür, bu yüzden her parçanın sıfır olduğunu söyleriz).

Şimdi gemimizin dönmesini istiyoruz. Muhtemelen bunu mümkün olduğunca çabuk yapmak istiyoruz, bu yüzden şunları yapmak istiyoruz:

max (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>

İçin Çözme x_itoplamıdır yukarıda üst düzeye çıkarırken, yukarıda eşitsizlikleri ve Eşitlikler tatmin ederken 's, bize istenen itme verecektir. Çoğu programlama dilinde LP kütüphanesi bulunur. Sadece yukarıdaki sorunu içine koyun ve cevabınızı üretecektir.

Benzer bir problem dönmeden hareket etmemizi sağlayacaktır. Diyelim ki sorunumuzu pozitif x yönünde hareket etmek istediğimiz bir koordinat sistemine yeniden yazıyoruz. Sonra kısıtlamalar:

0 <= x_i < fmax_i  //for each i
max Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y
0 = (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before

İticilerin yalnızca tek bir yönde itme kuvveti üretebileceği kısıtlamasıyla, elde edebileceğiniz dönme türlerinin ve doğrusal hızların sınırları olacaktır. Bu çözüm olarak ortaya çıkacaktır 0 = x_1 = x_2 = ... = x_n, bu da hiçbir yere ulaşamayacağınız anlamına gelir. Bunu hafifletmek için, her iki tarafa 45 derecelik bir itici yerleştirilen her oyuncu için bir çift küçük, zayıf (% 5 veya% 10) iticiler eklemenizi öneririm. Bu, çözüme daha fazla esneklik kazandıracaktır, çünkü bunlar ana iticilerin zayıf ikincil etkilerine karşı koymak için kullanılabilir.

Son olarak, belki 100 iticiye kadar, LP'ye çözüm çerçeve başına yapılacak kadar hızlıdır. Bununla birlikte, çözüm konuma veya mevcut duruma bağlı olmadığından, şekil değiştiğinde her makul denetleyici giriş kombinasyonu için çözümü önceden hesaplayabilirsiniz (bu, eylemsizlik momentini veya geminin kütlesini değiştiren itici olmayanlar eklemeyi içerir, çünkü iticiler kütle merkezine göre farklı bir konumdadır!). Bu 24 olasılıktır (yani 8 yön kez {sola dönüş, dönüş yok, sağa dönüş}).


Çok iyi açıkladı!
Kim

1
Sum_iBu bağlamda ne anlama geliyor?
S. Tarık Çetin

1

İlk düşüncem tamamen ampirik bir çözümdü, bu nasıl davrandığını anlamak için değişen derecelerde itme için bir sandbox ortamında teçhizatı simüle ediyordu. Deterministik bir çözüm arayışında birçok karmaşık matematiği dengelemek yerine, örneğin newton'un yöntemini kullanarak sayısal olarak ulaşabilirsiniz. Misal:

İtme aralığı 0 ila 1000'dir, burada 1000 ALOT'tur.

Aşama 1

Güvenle simüle edin (0 + 1000) / 2 = 500. Sonuç: çok fazla güven

Adım 2

Menzil artık 0 ila 500 Güvenle simüle et (0 + 500) / 2 = 250. Sonuç: çok fazla güven

Aşama 3

Aralık şimdi 0 ile 250 arasında Güvenle simüle et (0 + 250) / 2 = 125 Sonuç: çok az güven

Adım # 4

Menzil artık 125 ila 250 Güvenle simüle et (125 + 250) /2=187.5 Sonuç çok fazla güven

Adım # 5 Aralık şimdi 125 ila 187.5 Güvenle simüle et (125 + 187.5) /2=156.25 Sonuç çok az güven

Adım # 6 Aralık şimdi 156,25 ila 187,5 Aralık 35 eşik değerinin altında, bu da yeterince iyi bir tahmin olduğu anlamına geliyor

Nihai sonuç = (187.5 + 156.25) / 2 = 171.875

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.