การปรับสมดุลแบบไดนามิกของยานอวกาศ


14

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

นี่คือตัวอย่างของเรือที่สมมาตรหันหน้าไปทางที่จุดสีแดงชี้บอกให้หมุนไปทางซ้าย

เรือ

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

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

สิ่งที่ฉันได้ทำมาในตอนนี้คือสูตรในการกำหนด "ประสิทธิภาพการเลี้ยว" เช่นการหมุนเกิดขึ้นเมื่อเทียบกับการเคลื่อนที่เชิงเส้น

a - position vector to thruster a b - ตำแหน่งเวกเตอร์ไปยัง thruster b v1 - แรงจาก thruster a v2 - แรงจาก thruster b

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

โดยทั่วไปแล้ว "a.cross (v1 * t) / | v1 |" ควรจะเป็นประสิทธิภาพการเปิด จากนั้นเราก็ลบมันออกด้วยประสิทธิภาพเทิร์นของ thrusters ที่รวมกันเพื่อดูว่าการยิง thruster ใหม่นั้นมีค่าหรือไม่

ปัญหาเกิดขึ้นเมื่อฉันตระหนักว่า thrusters ไม่ได้ถูกเปิด / ปิด แต่สามารถเปลี่ยนแปลง thrust ของพวกเขาจาก 0 ถึง 1 และจะทำอย่างไรเมื่อผู้เล่นต้องการให้เรือแล่นไปข้างหน้า แน่นอนว่าจะต้องมีความสมดุลว่าจะหมุน / ย้ายเท่าใด

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

ขอบคุณที่สละเวลา! / คิม


3
ฉันเริ่มต้นบนเส้นทางเดียวกัน แต่ด้วยการกำหนดค่าหลายอย่างมันเป็นไปไม่ได้ที่ทั้งหมุนและไม่แปล ดังนั้นคุณจะหมุนไปหรือไม่ หรือคุณอนุญาตการแปล ในที่สุดมันก็ขึ้นอยู่กับผู้ใช้ที่ออกแบบเรือ สำหรับตัวอย่างนี้ฉันแกล้งมัน ที่เกี่ยวข้อง: gamedev.stackexchange.com/questions/58216/… , gamedev.stackexchange.com/questions/40615/…
MichaelHouse

ฉันลงเส้นทางที่คล้ายกันและลงเอยด้วยการเขียนตัวอย่างในหน้านี้ ในขณะที่คุณเลื่อนเครื่องขับดันไปรอบ ๆ (ลากไปไว้บนเรือเพื่อกำหนดตำแหน่งและพลัง) มันจะดึงรูปทรงสามแบบ สัญชาตญาณคือคุณสามารถนึกถึงการเคลื่อนไหวที่เป็นไปได้ทั้งหมดว่าเป็นจุดในสเปซ 3 มิติ (x, y, การหมุน) และการ จำกัด ไว้ที่ 0-1 เป็นข้อ จำกัด ในพื้นที่นั้น ดังนั้นคุณจะได้รูปร่าง 3 มิติที่มีการเคลื่อนไหวที่เป็นไปได้ทั้งหมด หากคุณไม่ต้องการความเร็วเชิงเส้นคุณกำลังมองหาที่ (x = 0, y = 0) บรรทัดในพื้นที่นั้น (Q, W, E, S ทั้งหมด 0 ในการสาธิตของฉัน)
amitp

คำตอบ:


7

ฉันจะสมมติว่าคุณมีการเคลื่อนไหวที่ถูกต้องสำหรับเรือของคุณมิฉะนั้นการวิเคราะห์นี้จะไม่ถือ คุณต้องการบางสิ่งที่แข็งแกร่งกว่าประสิทธิภาพเพื่อแก้ไขปัญหานี้อย่างถูกต้อง

แต่ละทรัสเตอร์จะสร้างเอฟเฟกต์สองอย่างต่อการเคลื่อนไหวของเรือ: แบบเชิงเส้นและเชิงมุม สิ่งเหล่านี้สามารถพิจารณาได้อย่างอิสระ หากทรัสเตอร์สร้างแรงไปfในทิศทางdirหนึ่งและถูกชดเชยจากจุดศูนย์กลางมวลโดยเวกเตอร์r(ไม่ใช่ศูนย์กลางเรขาคณิตหรือศูนย์กลางของสไปรต์!) ดังนั้นเอฟเฟกต์ต่อองค์ประกอบเชิงเส้นจะเป็น:

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

ผลกระทบของความเร็วเชิงมุมนั้นเกิดจากแรงบิด:

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

tเป็นเวกเตอร์แรง (เช่นแรงผลักดันเชิงเส้น) tauเป็นเซนต์คิตส์และเนวิสซึ่งเมื่อหารด้วยโมเมนต์ความเฉื่อยจะทำให้ความเร่งเชิงมุมเพิ่มขึ้น สิ่งสำคัญคือdirและrอยู่ในพื้นที่พิกัดเดียวกันนั่นคือทั้งในพิกัดท้องถิ่นหรือทั้งสองในพิกัดโลก

การเร่งความเร็วเชิงเส้นโดยรวมของเรือนั้นได้มาจากผลรวมของt's สำหรับแต่ละทรัสเตอร์หารด้วยมวลของเรือ ในทำนองเดียวกันการเร่งความเร็วเชิงมุมเป็นเพียงผลรวมของแรงบิดหารด้วยโมเมนต์ความเฉื่อย (ซึ่งเป็นสเกลาร์อื่น) เรือจะไม่หมุนหากแรงบิดทั้งหมดเป็นศูนย์ ในทำนองเดียวกันมันจะไม่เคลื่อนที่ถ้าแรงขับรวมเป็นศูนย์ Recall บิดเป็นสเกลาร์ แต่แรงขับ (ผลรวมของt) เป็นเวกเตอร์ 2 มิติ

จุดของการแสดงออกนี้ก็คือว่าตอนนี้เราสามารถเขียนปัญหาของเราเป็นโปรแกรมเชิงเส้น พูดแรกที่เราต้องการเรือของเราที่จะเปิดโดยไม่ต้องเคลื่อนย้าย เรามีตัวแปรสำหรับแต่ละ thruster, $ x_1, x_2, ... $, ซึ่งเป็นจำนวนของ thrust ที่ thruster จะให้ ข้อ จำกัด หนึ่งชุดคือ:

0 <= x_i < fmax_i  //for each i

ที่fmaxเป็นแรงสูงสุดสำหรับรัสที่ (นี้จะช่วยให้เรามีคนที่แข็งแกร่งหรืออ่อนแอ) ต่อไปเราจะพูดว่าความเท่าเทียมกันทั้งสอง:

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

นี่เป็นการเข้ารหัสข้อ จำกัด ที่เราจะไม่ใช้การเร่งความเร็วเชิงเส้นโดยบอกว่าแรงขับทั้งหมดเป็นศูนย์ (แรงขับคือเวกเตอร์ดังนั้นเราบอกว่าแต่ละส่วนเป็นศูนย์)

ตอนนี้เราต้องการให้เรือของเราเลี้ยว สมมุติว่าเราต้องการให้เร็วที่สุดเท่าที่จะทำได้ดังนั้นเราจึงต้องการ:

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>

การแก้เพื่อความx_iพึงพอใจในความไม่เท่าเทียมกันและความเสมอภาคด้านบนในขณะที่การเพิ่มผลรวมสูงสุดข้างต้นจะทำให้เราได้แรงขับที่ต้องการ ภาษาโปรแกรมส่วนใหญ่มีไลบรารี่ LP สำหรับพวกเขา เพียงแค่ใส่ปัญหาข้างต้นลงไปและมันจะสร้างคำตอบของคุณ

ปัญหาที่คล้ายกันจะช่วยให้เราเคลื่อนไหวได้โดยไม่ต้องเลี้ยว สมมติว่าเราเขียนปัญหาของเราอีกครั้งในระบบพิกัดที่เราต้องการเคลื่อนไปในทิศทางบวก x ดังนั้นข้อ จำกัด คือ:

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

ด้วยข้อ จำกัด ที่ thrusters สามารถสร้างแรงขับในทิศทางเดียวเท่านั้นจึงจะมีข้อ จำกัด เกี่ยวกับชนิดของการหมุนและความเร็วเชิงเส้นที่คุณจะสามารถบรรลุได้ สิ่งนี้จะแสดงให้เห็นว่าเป็นวิธีการแก้ปัญหา0 = x_1 = x_2 = ... = x_nซึ่งหมายความว่าคุณจะไม่เคยไปไหนมาไหน เพื่อลดสิ่งนี้ฉันแนะนำให้เพิ่มคู่ขับดันขนาดเล็กที่อ่อนแอ (พูด 5% หรือ 10%) สำหรับผู้เล่นแต่ละคนวางทรัสเตอร์ที่ 45 องศาทั้งสองด้าน สิ่งนี้จะช่วยให้การแก้ปัญหามีความยืดหยุ่นมากขึ้นเพราะสิ่งเหล่านี้สามารถใช้ในการตอบโต้ผลกระทบทุติยภูมิที่อ่อนแอของเครื่องขับดันหลัก

ในที่สุดอาจถึง 100 thrusters ทางออกของ LP นั้นเร็วพอที่จะทำต่อเฟรม อย่างไรก็ตามเนื่องจากวิธีการแก้ปัญหาไม่ได้ขึ้นอยู่กับสถานที่หรือสถานะปัจจุบันคุณสามารถคำนวณวิธีการแก้ปัญหาสำหรับการรวมอินพุตคอนโทรลเลอร์ที่เหมาะสมแต่ละชุดเมื่อใดก็ตามที่มีการเปลี่ยนแปลงรูปร่าง (รวมถึงการเพิ่มที่ไม่ใช่ขับดัน เพราะเมื่อนั้นเครื่องขับดันจะอยู่ในตำแหน่งที่ต่างกันเมื่อเทียบกับศูนย์กลางของมวล!) นี่คือ 24 ความเป็นไปได้ (เช่น 8 ทิศทางครั้ง {หมุนซ้ายไม่มีการหมุนหมุนขวา})


อธิบายได้ดีมาก!
Kim

1
อะไรSum_iหมายถึงในบริบทนี้?
S. TarıkÇetin

1

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

ช่วงสำหรับแรงขับคือ 0 ถึง 1,000 โดยที่ 1000 คือจำนวนมาก

ขั้นตอนที่ 1

จำลองด้วยความน่าเชื่อถือ (0 + 1,000) / 2 = 500 ผลลัพธ์: เชื่อใจมากเกินไป

ขั้นตอนที่ 2

ช่วงคือตอนนี้ 0 ถึง 500 จำลองด้วยความน่าเชื่อถือ (0 + 500) / 2 = 250 ผลลัพธ์: เชื่อใจมากเกินไป

ขั้นตอนที่ # 3

ช่วงคือตอนนี้ 0 ถึง 250 จำลองด้วยความน่าเชื่อถือ (0 + 250) / 2 = 125 ผลลัพธ์: ความเชื่อใจน้อยเกินไป

ขั้นตอนที่ # 4

ช่วงนี้คือ 125 ถึง 250 จำลองด้วยความน่าเชื่อถือ (125 + 250) /2=187.5 ผลความน่าเชื่อถือมากเกินไป

ขั้นตอนที่ # 5 ช่วงคือ 125 ถึง 187.5 จำลองด้วยความน่าเชื่อถือ (125 + 187.5) /2=156.25 ผลลัพธ์ที่ได้คือความไว้วางใจที่น้อยเกินไป

Step # 6 Range คือ 156.25 ถึง 187.5 Range อยู่ต่ำกว่า threshold ที่ 35 ซึ่งหมายความว่าเป็นการประมาณการที่ดีพอ

ผลสุดท้าย = (187.5 + 156.25) / 2 = 171.875

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