Dynamic thruster balancing kapal ruang angkasa

14

Ruang kapal dalam game saya dimaksudkan untuk dibangun oleh pemain dengan jumlah pendorong yang sewenang-wenang yang terpasang di mana saja dengan rotasi apa pun. Saat ini saya memiliki beberapa kode kotor untuk memutar kapal ke sudut tertentu (percepatan dan perlambatan).

Ini adalah contoh dari sebuah kapal simetris menghadap ke tempat garis merah menunjuk, disuruh berputar ke kiri.

Kapal

Namun, seperti yang Anda bayangkan, tergantung di mana pemain meletakkan pendorongnya, kadang-kadang kekuatan linier yang tidak diinginkan mempengaruhi kapal. Dalam hal ini, kapal mulai bergerak maju.

Saya menguraikan apakah mungkin untuk menemukan daya dorong maksimum yang dapat diterapkan pendorong untuk tidak menyebabkan kecepatan linier. (Dalam kasus di atas yang tidak akan ada karena tidak ada yang menangkal kekuatan dari pendorong belakang, dan yang depan membunuh satu sama lain).

Apa yang saya buat sejauh ini adalah formula untuk menentukan "efisiensi belokan" misalnya berapa banyak rotasi yang disebabkan dalam kaitannya dengan gerakan linear.

a - position vector to thruster a - posisi vektor to thruster b v1 - force from thruster a v2 - force from thruster b

efficiencyDelta = a.cross (v1) / | v1 | - (a.cross (v1) + b.cross (v2)) / | v1 + v2 |

, pada dasarnya "a.cross (v1 * t) / | v1 |" seharusnya menjadi efisiensi belokan. Dan kemudian kita kurangi dengan pergantian efisiensi pendorong dikombinasikan, untuk melihat apakah menembakkan pendorong baru sepadan.

Masalah muncul ketika saya menyadari bahwa pendorong tidak diharapkan untuk on / off, tetapi dapat memvariasikan dorong mereka dari 0 hingga 1. Dan bagaimana cara pergi ketika pemain ingin kapal untuk maju. Tentu, perlu ada keseimbangan berapa banyak untuk memutar / bergerak.

Saya bukan ilmuwan roket, jadi saya berharap ada seseorang yang dapat memberi tahu saya apakah mungkin menghitung kecepatan setiap pendorong dengan cara ini dan memberi saya dorongan ke arah yang benar.

Terima kasih telah meluangkan waktu! / Kim

Kim
sumber
3
Saya mulai di jalur yang sama, tetapi dengan banyak konfigurasi, tidak mungkin memutar dan tidak menerjemahkan. Jadi, apakah Anda menghilangkan rotasi? Atau apakah Anda mengizinkan terjemahan? Pada akhirnya, tergantung pada pengguna yang mendesain kapal. Untuk demo saya tentang ini, saya memalsukannya. Terkait: gamedev.stackexchange.com/questions/58216/… , gamedev.stackexchange.com/questions/40615/…
MichaelHouse
Saya menempuh jalan yang sama dan akhirnya menulis demo di halaman ini . Saat Anda memindahkan pendorong di sekitar (seret mereka di kapal untuk mengatur posisi dan kekuatan) itu menarik tiga bentuk. Intuisi adalah bahwa Anda dapat menganggap semua gerakan yang mungkin sebagai titik dalam ruang 3d (x, y, rotasi), dan terbatas pada 0-1 adalah kendala dalam ruang itu. Jadi Anda berakhir dengan bentuk 3d yang berisi semua gerakan yang mungkin. Jika Anda tidak menginginkan kecepatan linier, Anda sedang melihat garis (x = 0, y = 0) di ruang tersebut (Q, W, E, S semua 0 di demo saya)
amitp

Jawaban:

7

Saya akan berasumsi bahwa Anda memiliki gerakan yang benar secara fisik untuk kapal Anda, karena jika tidak analisis ini tidak akan berlaku. Anda membutuhkan sesuatu yang lebih kuat daripada efisiensi untuk menyelesaikan masalah ini dengan benar.

Setiap pendorong akan menghasilkan dua efek pada pergerakan kapal: linear dan angular. Ini dapat dipertimbangkan secara independen. Jika pendorong menghasilkan gaya fdalam arah dir, dan diimbangi dari pusat massa oleh vektor r(bukan pusat geometris atau pusat sprite!), Maka efek pada komponen linier adalah:

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

Efek pada kecepatan sudut diberikan oleh torsi:

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

tadalah vektor gaya (yaitu dorongan linier). tauadalah skalar yang ditandatangani, yang bila dibagi dengan momen massa inersia, akan memberikan percepatan sudut. Adalah penting bahwa dirdan rkeduanya berada dalam ruang koordinat yang sama, yaitu dalam koordinat lokal atau keduanya dalam koordinat dunia.

Akselerasi linear keseluruhan kapal diberikan oleh jumlah t's untuk setiap pendorong dibagi dengan massa kapal. Demikian pula, percepatan sudut hanyalah jumlah torsi yang dibagi dengan momen massa inersia (yang merupakan skalar lain). Kapal tidak akan berputar jika torsi totalnya nol. Demikian pula, itu tidak akan bergerak jika total dorong adalah nol. Ingat torsi adalah skalar tetapi dorong (jumlah dari t) adalah vektor 2D.

Maksud dari paparan ini adalah bahwa sekarang kita dapat menulis masalah kita sebagai Program Linear . Katakan dulu kita ingin kapal kita berputar tanpa bergerak . Kami memiliki variabel untuk setiap pendorong, $ x_1, x_2, ... $, yang merupakan jumlah daya dorong yang akan diberikan pendorong. Satu set kendala adalah:

0 <= x_i < fmax_i  //for each i

di mana fmaxkekuatan maksimum untuk pendorong itu (ini memungkinkan kita memiliki yang lebih kuat atau lebih lemah). Selanjutnya, kita katakan bahwa keduanya sama:

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

Ini mengkodekan batasan bahwa kita tidak akan menerapkan percepatan linear, dengan mengatakan total dorong adalah nol (dorong adalah vektor, jadi kita hanya mengatakan setiap bagian adalah nol).

Sekarang kami ingin kapal kami berputar. Mungkin kami ingin melakukannya secepat mungkin, jadi kami ingin:

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>

Memecahkan untuk x_isementara memuaskan ketidaksetaraan dan kesetaraan di atas, sambil memaksimalkan penjumlahan di atas, akan memberi kita dorongan yang diinginkan. Sebagian besar bahasa pemrograman memiliki perpustakaan LP yang tersedia untuk mereka. Masukkan saja masalah di atas ke dalamnya dan itu akan menghasilkan jawaban Anda.

Masalah serupa akan membuat kita bergerak tanpa berbelok. Katakanlah kita menulis ulang masalah kita dalam sistem koordinat di mana kita ingin bergerak ke arah x positif. Maka kendalanya adalah:

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

Dengan batasan bahwa pendorong hanya dapat menghasilkan pendorong dalam satu arah, akan ada batasan untuk jenis rotasi dan kecepatan linier yang dapat Anda capai. Ini akan bermanifestasi sebagai solusi 0 = x_1 = x_2 = ... = x_n, yang berarti Anda tidak akan pernah ke mana pun. Untuk mengurangi ini, saya sarankan menambahkan sepasang pendorong kecil, lemah (katakanlah 5%, atau 10%) untuk setiap pemain menempatkan pendorong pada 45 derajat di kedua sisi. Ini akan memberikan solusi lebih fleksibel, karena ini dapat digunakan untuk menangkal efek sekunder pendorong utama yang lemah.

Akhirnya, hingga 100 pendorong, solusi untuk LP cukup cepat untuk dilakukan per frame. Namun, karena solusinya tidak tergantung pada lokasi atau keadaan saat ini, Anda dapat melakukan prekomputasi solusi untuk setiap kombinasi input pengontrol yang masuk akal setiap kali perubahan bentuk (ini termasuk menambahkan non-pendorong yang mengubah momen inersia atau massa kapal, karena kemudian pendorong berada di lokasi yang berbeda relatif terhadap pusat massa!). Ini adalah 24 kemungkinan (mis. 8 arah kali {putaran kiri, tidak ada putaran, putaran kanan}).


sumber
Dijelaskan dengan sangat baik!
Kim
1
Apa Sum_iartinya dalam konteks ini?
S. Tarık Çetin
1

Pikiran pertama saya adalah solusi empiris murni, yaitu mensimulasikan rig di lingkungan kotak pasir untuk berbagai tingkat dorongan untuk mengetahui bagaimana perilakunya. Alih-alih menyeimbangkan banyak matematika kompleks dalam mencari solusi deterministik Anda dapat mencapainya secara numerik misalnya menggunakan metode newton. Contoh:

Rentang untuk dorong adalah 0 hingga 1000 di mana 1000 adalah ALOT.

Langkah 1

Simulasikan dengan kepercayaan (0 + 1000) / 2 = 500. Hasilnya: terlalu banyak kepercayaan

Langkah 2

Rentang sekarang adalah 0 hingga 500. Simulasi dengan kepercayaan (0 + 500) / 2 = 250. Hasilnya: terlalu banyak kepercayaan

Langkah # 3

Rentang sekarang 0 hingga 250 Simulasikan dengan kepercayaan (0 + 250) / 2 = 125 Hasil: terlalu sedikit kepercayaan

Langkah # 4

Rentang sekarang 125 hingga 250 Simulasikan dengan kepercayaan (125 + 250) /2=187,5. Hasilnya terlalu banyak kepercayaan

Langkah # 5 Rentang sekarang 125 hingga 187,5. Simulasi dengan kepercayaan (125 + 187,5) /2=156,25 Hasilnya terlalu sedikit kepercayaan

Langkah # 6 Kisaran sekarang 156.25 ke 187.5 Kisaran berada di bawah ambang batas 35 yang berarti bahwa itu adalah perkiraan yang cukup baik

Hasil akhir = (187.5 + 156.25) / 2 = 171.875

Lennart Rolland
sumber