การกำหนดเป้าหมายเสียงหึ่งๆ


9

ลองจินตนาการถึง "โดรน" และจุดเป้าหมายบนระนาบ 2d มีพารามิเตอร์ที่แปด:

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

(เราจะบอกว่าเป้าหมายคงที่)

งานของโดรนคือการไปถึงเป้าหมายให้เร็วที่สุดเท่าที่จะทำได้โดยเชื่อฟังแรงบิดสูงสุดและแรงขับสูงสุด มีเพียงสองวิธีในการใช้แรงบิดเนื่องจากเป็นเพียงในระนาบ 2d แรงขับถูก จำกัด ให้ไปในทิศทางเดียวเท่านั้นเมื่อเทียบกับทิศทางของยานและไม่สามารถเล็งได้หากไม่มีการหมุนเสียงพึมพำ ละเลยความต้านทานใด ๆ คุณสามารถทำเป็นว่ามันลอยอยู่ในอวกาศรอบนอก 2d สมมติว่าเสียงพึมพำจะตรวจสอบสมการในช่วงเวลาt(อาจจะเหมือนกับทุก ๆ 0.01 วินาที), เสียบพารามิเตอร์และปรับแรงบิดและแรงขับตาม สมการของแรงขับและแรงบิดควรเป็นอย่างไร


3
หากแรงผลักดันสามารถเพียงไปในทิศทางหนึ่งที่คุณไม่เคยไปทิศทางการเปลี่ยนแปลง
MichaelHouse

1
ฉันควรระบุให้ชัดเจนยิ่งขึ้น - คุณไม่สามารถแทงแรงขับได้เช่นแรงขับสามารถไปในทิศทางเดียวเมื่อเทียบกับทิศทางของยาน คุณยังสามารถหมุนยานและเปลี่ยนทิศทางของแรงขับ
กัส

2
คำถามนี้เกี่ยวข้องกับสมองหรือไม่?
เซทแบททิน

1
จากนั้นฉันคิดว่าฉันสามารถโพสต์ทางออกที่ดีให้กับคุณ (หลังจากนี้เล็กน้อย) :)
เซทแบททิน

1
คำถามนี้ต้องการชื่อที่มีความหมายมากกว่า แต่ฉันไม่สามารถนึกถึงชื่อที่ดีได้ Halp?
Anko

คำตอบ:


5

เนื่องจากบริบทของคำถามของคุณhttp://nodewar.com/มีข้อควรพิจารณาบางประการสำหรับโซลูชันของคุณ:

  1. คุณมีความเร็วเชิงมุมสูงสุด (ต่ำ) และแรงบิดสูงสุดเพียงพอที่จะไปถึงได้ในเวลาอันสั้น
  2. เสียงพึมพำและเป้าหมายของคุณแต่ละคนมีความเร็วและความเร่งภายนอกที่ไม่เกี่ยวข้องกับแรงขับ
  3. เป้าหมายที่คุณต้องการเปลี่ยนแปลงบ่อยครั้งมากที่พยายามตั้งเป้าหมายอย่างสมบูรณ์จะเป็นของเสีย คุณควรพยายามเข้าใกล้และแก้ไขมันทุกเฟรม

วิธีการเหล่านี้เป็นสิ่งที่ฉันตั้งใจจะทำงานเพื่อให้ได้อัตราเร่งที่ต้องการ

การเร่งความเร็วไม่ใช่ความเร็ว

เนื่องจากคุณมีความเร็วที่กำหนดไว้แล้วและเป้าหมายของคุณกำลังเคลื่อนที่คุณจึงไม่ต้องการแรงขับไปยังจุดใดจุดหนึ่ง คุณต้องการแรงผลักดันที่จะเปลี่ยนความเร็วของคุณเป็นสิ่งที่ควรจะเป็น ซึ่งหมายความว่าเรือของคุณต้องไม่ชี้ไปยังที่ที่มันกำลังแล่น แต่ไปในทิศทางที่มันควรเร่ง

// 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 ครั้งหลายครั้งต่อวินาที สิ่งนี้จะช่วยให้คุณมีแรงขับเพียงบางส่วนโดยไม่เปลี่ยนแปลงค่าจริง

โชคดี!


เยี่ยมมากขอบคุณมันช่วยได้มาก ฉันจะต้องแก้ไขมันเล็กน้อยฉันคิดว่า เผ่าพันธุ์ของคุณชื่ออะไร
กัส

ฉันไม่ได้ผลักพวกเขาไปที่บันได พวกเขาไม่มีวิธีการโจมตี :)
Seth Battin

3

คำถามที่คล้ายกันพร้อมด้วยคำตอบที่ดีรวมถึงชื่อที่ชัดเจนของเรื่องทั้งหมด "การวางแผนการเคลื่อนไหว":
/programming/2560817/2d-trajectory-planning-of-a-spaceship-with-physics

ในฐานะโปรแกรมเมอร์ฉันชอบการปฏิบัติตามคำแนะนำของ user470365 อย่างไรก็ตามฉันจะใช้วิธีแทงอย่างเข้มงวดมากขึ้น ข้อเสนอแนะของฉันที่นี่คำนวณแผนเต็มเมื่อเริ่มต้น แต่ฉันคิดว่าคุณสามารถประเมินได้บ่อยครั้งตามที่ต้องการหากพารามิเตอร์มีการเปลี่ยนแปลง

แผนการ

  1. หันไปทิศทางหนึ่ง, dและถือเป็นทิศทางนั้น
  2. รอจนกว่าจะถึงเวลาที่กำหนดtจากนั้นให้ทำอย่างใดอย่างหนึ่งแทงอย่างยั่งยืนจนกว่าจะถึงเป้าหมาย

รายละเอียด

ฉันแนะนำวิธีการวนซ้ำเพื่อค้นหาdและt :

  1. ถ้าไม่มีแรงขับให้ข้ามแนววิถีในอนาคตของโดรนโดยใช้ลูปและการประทับเวลาเล็กน้อย:

    • สำหรับตำแหน่งและความเร็วของโดรนในเวลานี้ในอนาคตค้นหาทิศทางdเช่นแรงขับที่ต่อเนื่องจะนำเสียงหึ่งๆไปยังเป้าหมาย ทำได้โดยการสุ่มเลือกทิศทางระหว่าง 0 ถึง 360 องศาและค้นหาทิศทางที่จะนำเสียงพึมพำเข้ามาใกล้เป้าหมายในเวลาอันสั้น
    • ตรวจสอบเพื่อดูว่าเรามีเวลาเพียงพอในระหว่างนี้และเวลานี้ในอนาคตจะหันไปd (การกลึงเป็นเรื่องไม่สำคัญดูการสนทนาในตอนท้าย)
    • หากเรามีเวลาเพียงพอการค้นหาของเราก็เสร็จสมบูรณ์ดังนั้นจงแยกวงนี้ออก
  2. ตอนนี้เราพบdและtแล้ว

  3. เปลี่ยนเป็นdโดยเร็วที่สุด (อีกครั้งดูการสนทนาด้านล่าง)
  4. รอจนกระทั่งtจากนั้นเริ่มแรงขับที่ยั่งยืน
  5. เสียงพึมพำในที่สุดควรถึงเป้าหมาย

การหมุน

เมื่อฉันบอกว่า "หันไปd " ผมหมายถึงจริงๆ "ทำลำดับของแรงบิดดังกล่าวว่าเราหมุนไปdเร็วที่สุดเท่าที่เป็นไปได้ในขณะที่ยังนำความเร็วเชิงมุมเป็นศูนย์" อาจมีสมการสำหรับสิ่งนี้ที่เกี่ยวข้องกับทิศทางปัจจุบันความเร็วเชิงมุมในปัจจุบันและความเร่งเชิงมุมสูงสุด แต่มันซับซ้อนโดยพฤติกรรมการห่อของมุม


แนวทางที่น่าสนใจ ดังนั้นสิ่งที่ควบคุมการเลือกเวลาในอนาคตของเรา? ดูเหมือนว่าเทคนิคใด ๆ ในการตรวจสอบว่ามีปัญหาอยู่แล้วดังนั้นการทำซ้ำอาจมีความจำเป็นเช่นกัน
กัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.