Penargetan drone

9

Bayangkan sebuah "drone" dan titik target di pesawat 2d. Ada delapan parameter:

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

(Kami hanya akan mengatakan targetnya diam)

Tugas drone adalah untuk mencapai target secepat mungkin, mematuhi torsi maksimum dan dorongan maksimum. Hanya ada dua cara untuk menerapkan torsi, karena ini hanya di pesawat 2d. Daya dorong terbatas untuk hanya bergerak dalam satu arah relatif terhadap orientasi pesawat, dan tidak dapat diarahkan tanpa memutar drone. Abaikan perlawanan, Anda bisa berpura-pura melayang di luar angkasa 2d. Katakanlah drone memeriksa persamaan pada interval waktu t(mungkin sekitar 0,01 detik), menyambungkan parameter, dan menyesuaikan torsi dan dorong sesuai. Seperti apa persamaan untuk dorong dan torsi?

Gus
sumber
3
Jika dorong hanya bisa bergerak ke satu arah, Anda tidak akan pernah mengubah arah.
MichaelHouse
1
Saya seharusnya telah menentukan lebih jelas - Anda tidak dapat gimbal dorong, yaitu dorong hanya bisa pergi dalam satu arah relatif terhadap orientasi kerajinan. Anda masih bisa memutar pesawat dan mengubah arah dorong.
Gus
2
Apakah pertanyaan ini terkait dengan nodewar?
Seth Battin
1
Maka saya pikir saya dapat memposting solusi yang baik untuk Anda (sedikit malam nanti). :)
Seth Battin
1
Pertanyaan ini membutuhkan judul yang lebih deskriptif, tetapi saya tidak bisa memikirkan yang bagus. Berhenti?
Anko

Jawaban:

5

Mengingat konteks pertanyaan Anda, http://nodewar.com/ , ada beberapa pertimbangan khusus untuk solusi Anda:

  1. Anda memiliki kecepatan sudut maksimum (rendah), dan torsi maksimum yang cukup untuk mencapainya dalam waktu yang sangat singkat.
  2. Drone dan target Anda masing-masing memiliki kecepatan dan akselerasi eksternal yang tidak terkait dengan daya dorong (gravitasi berlimpah).
  3. Target yang Anda inginkan berubah begitu sering sehingga berusaha membidik dengan sempurna akan sia-sia. Anda harus mencoba mendekat, dan memperbaikinya setiap frame.

Metode ini adalah apa yang saya tekankan untuk bekerja untuk mencapai akselerasi yang diinginkan.

Akselerasi, bukan kecepatan

Karena Anda sudah memiliki kecepatan tertentu, dan target Anda bergerak, Anda tidak perlu didorong ke suatu titik. Anda perlu dorongan untuk mengubah kecepatan Anda menjadi seperti seharusnya. Ini berarti bahwa kapal Anda perlu menunjuk bukan ke arah ke mana ia pergi, tetapi ke arah di mana ia harus mempercepat.

// 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)  
);

Kemudi ke arah kanan

Anda memiliki vektor percepatan, sekarang Anda ingin menerapkannya. Tentukan seberapa jauh Anda perlu memutar. Saya mungkin menggunakan lebih banyak langkah daripada yang diperlukan di sini, tetapi koordinat rotasi membingungkan saya, dan saya pikir nilai rotasi kapal yang belum dibuka adalah bug di 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;
}

Formula sederhana. Tidak ada salahnya memutar sepanjang waktu, jadi jangan repot-repot menerapkan nilai torsi parsial. Jika Anda memerlukan koreksi kecil dalam kecepatan sudut, Anda harus membuat penentuan ini berkali-kali per detik.

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

Formula yang kurang sederhana. Akan ada titik di mana Anda tidak ingin terus berputar, karena Anda akhirnya ingin berhenti. Untungnya, tutup kecepatan sudut itu berarti Anda dapat dengan cepat memperlambat dari kecepatan sudut maks ke nol. Anda hanya perlu menghitung kapan melakukannya.

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;
}

Setelah mengubah kode di atas sesuai dengan kebutuhan Anda, kapal Anda harus berputar dengan cepat dan tepat ke sudut mana pun yang Anda berikan untuk ditargetkan.

Kecepatan serudukan

Jadi, kapan harus disodorkan? Sekali lagi, perubahan yang cepat dari target dan faktor-faktor lain menciptakan kesulitan besar dalam menyelesaikan solusi yang tepat. Jangan coba-coba.

// 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;
  } 
}

Untuk kasus-kasus di mana Anda memerlukan dorongan parsial, Anda dapat kembali mengandalkan fakta bahwa Anda dapat memilih antara 0 dan 1 dorongan berkali-kali per detik. Ini memberi Anda dorongan parsial yang efektif tanpa memvariasikan nilai sebenarnya.

Semoga berhasil!

Seth Battin
sumber
Hebat, terima kasih, ini sangat membantu. Saya harus mengubahnya sedikit saya pikir. Siapa nama spesies Anda?
Gus
Saya belum mendorong mereka ke tangga. Mereka tidak memiliki metode untuk menyerang. :)
Seth Battin
3

Pertanyaan serupa, dengan beberapa jawaban yang baik, termasuk nama nyata dari seluruh subjek ini, "perencanaan gerak":
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

Sebagai seorang programmer, saya menyukai kepraktisan dari saran user470365. Namun, saya akan mencoba pendekatan yang lebih keras. Saran saya di sini menghitung rencana lengkap di awal, tetapi saya kira Anda dapat mengevaluasi kembali sesering yang diinginkan jika parameter berubah.

Rencana

  1. Putar ke arah tertentu, d , dan tahan arah itu.
  2. Tunggu sampai waktu tertentu, t , lalu lakukan satu, dorong berkelanjutan sampai target tercapai.

Detail

Saya menyarankan metode berulang untuk menemukan d dan t :

  1. Dengan asumsi tidak ada dorongan, lintasi sepanjang lintasan drone di masa depan menggunakan loop dan catatan waktu kecil:

    • Untuk posisi dan kecepatan drone di waktu mendatang, temukan arah, d , sedemikian rupa sehingga dorongan yang berkelanjutan akan membawa drone ke target. Lakukan ini dengan mengambil sampel banyak arah antara 0 dan 360 derajat dan temukan yang akan membuat drone mendekati target dalam waktu singkat.
    • Periksa untuk melihat apakah kita memiliki cukup waktu antara sekarang dan waktu mendatang untuk beralih ke d . (Berpaling itu tidak sepele. Lihat diskusi di akhir.)
    • Jika kita punya cukup waktu, maka pencarian kita sudah selesai, jadi keluarlah dari loop ini.
  2. Kami sekarang telah menemukan d dan t .

  3. Beralih ke d secepat mungkin (lagi, lihat diskusi di bawah).
  4. Tunggu sampai t , lalu mulai desakan berkelanjutan.
  5. Drone akhirnya harus mengenai target.

Berputar

Ketika saya mengatakan "belok ke d ", maksud saya benar-benar, "lakukan urutan torsi sedemikian rupa sehingga kami memutar ke d secepat mungkin sambil juga membawa kecepatan sudut ke nol". Mungkin ada persamaan untuk ini yang melibatkan arah arus, kecepatan sudut saat ini, dan percepatan sudut maksimal, tetapi rumit dengan perilaku pembungkus sudut.

Eric Undersander
sumber
Pendekatan yang menarik. Jadi, apa yang mengatur pemilihan waktu mendatang kita? Sepertinya teknik apa pun untuk menentukan itu memiliki masalah, jadi iterasi mungkin diperlukan juga.
Gus