लक्ष्य ट्रैकिंग: एक घूमने वाले बुर्ज को तेज और कम करने के लिए कब?


24

कहो कि मेरे पास एक गतिमान परिपत्र है targetजो इस प्रकार है:

Vector2 position;
Vector2 velocity;
float radius;

और एक घूर्णन turret(किसी प्रकार के बढ़ते वाहन पर आरोहित) को इस प्रकार परिभाषित किया गया है:

Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second

(या उन पंक्तियों के साथ बहुत बढ़िया। ध्यान दें कि दोनों की स्थिति और वेग कहीं और नियंत्रित होते हैं - मान लें कि वेग स्थिर है और वेग के आधार पर स्थिति में परिवर्तन होता है।)

मैं दिए गए फ्रेम पर निर्धारित करने के लिए दो संबंधित एआई फ़ंक्शन लिखने की कोशिश कर रहा हूं:

  • लक्ष्य पर इशारा करते हुए बुर्ज के कोण को लागू करने के लिए कोणीय त्वरण (और किस दिशा में)?

  • यदि लक्ष्य वर्तमान में दृष्टिगोचर होता है, तो क्या इसे (इसकी त्रिज्या के भीतर का कोई भाग) xसेकंड के लिए दृष्टि में रखा जा सकता है , जहां xएक सेकंड का एक अंश है? (वैकल्पिक रूप से: क्या यह सुनिश्चित करने के लिए एक और रणनीति है कि वास्तव में "लॉक ऑन" है और न केवल दर्शनीय स्थलों में उड़ रहा है?)

और मैं कुछ मदद का उपयोग कर सकता है ...


1
घूर्णी त्वरण और मंदी के लिए आपके अलग-अलग मूल्य हो सकते हैं - वास्तविक दुनिया में, शायद एक मोटर और दूसरा ब्रेक।
e100

जवाबों:


19

पहले आपको बुर्ज का सामना करने की दिशा और लक्ष्य की दिशा के बीच के कोण में अंतर निर्धारित करने की आवश्यकता है।

Vector2 turretToTarget = target.position - turret.position;
float desiredAngle = atan2(turretToTarget.y, turretToTarget.x);
float angleDiff = desiredAngle - turret.angle;

// Normalize angle to [-PI,PI] range. This ensures that the turret
// turns the shortest way.
while (angleDiff < -PI) angleDiff += 2*PI;
while (angleDiff >= PI) angleDiff -= 2*PI;

एक बार आपके पास ये मात्राएँ होने के बाद आप बुर्ज कोण के लिए दूसरी डिग्री की अभिव्यक्ति स्थापित कर सकते हैं। आपको यह सुनिश्चित करने के लिए प्रत्येक अपडेट पर यह गणना करने की आवश्यकता है कि आप हमेशा पदों और वेग के नवीनतम डेटा का उपयोग करें।

// Compute angular acceleration.
const float C0 = // Must be determined.
const float C1 = // Must be determined.
float angularAcc = C0 * angleDiff - C1 * turret.angularVelocity;

यहां, एक्सप्रेशन एक्सप्रेशन में पहला शब्द (शून्य डिग्री) बुर्ज को लक्ष्य की ओर मोड़ना शुरू कर देगा। हालांकि यह समय में नहीं रुकेगा, बल्कि इसके ऊपर आगे पीछे होगा। इसे रोकने के लिए हमें दूसरे कार्यकाल (प्रथम डिग्री) की आवश्यकता होती है, जो एक उच्च त्वरण द्वारा विरोध करने के लिए एक उच्च मोड़ वेग का कारण बनता है।

अब सकारात्मक स्थिरांक (जरूरी नहीं कि कार्यक्रम स्थिरांक) प्रणाली को अच्छी तरह से व्यवहार करने के लिए निर्धारित और संतुलित होने की आवश्यकता है। C0प्रणाली की गति के लिए प्रमुख नियंत्रण है। के लिए एक उच्च मूल्य C0एक तीव्र मोड़ गति देगा और एक कम मूल्य एक कम मोड़ गति देगा। वास्तविक मूल्य कई कारकों पर निर्भर करता है इसलिए आपको यहां परीक्षण और त्रुटि का उपयोग करना चाहिए। C1भिगोना परिमाण को नियंत्रित करता है। द्विघात समीकरण का विभेदक बताता है कि यदि C1*C1 - 4*C0 >= 0हमारे पास गैर-दोलन प्रणाली है।

// New definition.
const float C1 = 2*sqrt(C0); // Stabilizes the system.

आपको शायद चुनना चाहिए C1 संख्यात्मक कारणों से इससे थोड़ा बड़ा , लेकिन बहुत बड़ा नहीं है क्योंकि इसके बजाय प्रतिक्रिया करने के लिए बहुत अधिक नम और धीमा हो सकता है। फिर से, आपको ट्वीक करने की आवश्यकता है।

यह भी ध्यान रखना महत्वपूर्ण है कि यह कोड केवल कोणीय त्वरण की गणना करता है। कोण और कोणीय वेग को कहीं और से अद्यतन करने की आवश्यकता है, किसी प्रकार का उपयोग और इंटीग्रेटर। सवाल से मुझे लगता है कि यह कवर किया गया है।

अंत में लैगिंग के बारे में कुछ कहना है, क्योंकि तेजी से लक्ष्य को ट्रैक करते समय बुर्ज शायद हमेशा पीछे रहेगा। इससे निपटने का एक सरल तरीका यह है कि लक्ष्य की स्थिति में एक रैखिक भविष्यवाणी जोड़ दी जाए, यानी लक्ष्य की आगे की दिशा में हमेशा थोड़ा आगे बढ़ें।

// Improvement of the first lines above.
const float predictionTime = 1; // One second prediction, you need to experiment.
Vector2 turretToTarget = target.position + predictionTime * target.velocity - turret.position;
/// ...

कुछ समय के लिए लक्ष्य की त्रिज्या के भीतर बुर्ज रखने के लिए के रूप में, यह इस तरह की प्रणाली पर सीधे लागू करने के लिए एक कठिन आवश्यकता हो सकती है। आप निश्चित हो सकते हैं कि यह नियंत्रक हर समय लक्ष्य (या बल्कि अनुमानित स्थिति) पर बुर्ज रखने का प्रयास करेगा। यदि परिणाम संतोषजनक नहीं निकला तो आपको मापदंडों को संशोधित करना होगा predictionTime, C0और C1(स्थिर सीमा के भीतर)।


मैं यह कहने के लिए योग्य नहीं हूं कि यह सही है या नहीं, लेकिन यह कुछ चतुर सामान जैसा लगता है! मैंने पूर्व में इस प्रकार की समस्याओं को हल किया है, आगे बढ़ने के लिए त्वरण के प्रभाव की भविष्यवाणी करते हुए कि कब तेजी लाने के लिए और कब "ब्रेक लागू करें"। क्या इसका मतलब है कि मैं इसे गलत कर रहा हूं?
इयान

Atan2 इस विधि को एक पूर्वसूचक प्रणाली के अनुकूल बनाना मुश्किल बनाता है क्योंकि x और y पैरामीटर से atan2 t पर निर्भर हो जाता है।
स्किज़ जूल

यह ठीक समाधान है जो मैं नीचे अपने जवाब में इशारा कर रहा था। उत्कृष्ट विस्तार और प्रस्तुति!
drxzcl

@ मुख्य: नहीं, यहाँ कोई सही और गलत नहीं है। जबकि मुझे लगता है कि आपकी विधि में दो असतत अवस्थाएँ होंगी: गति / मंदी, यह विधि नियंत्रण सिद्धांत के एक नियामक से प्रेरित है, ओवरशूट और दोलनों को कम करते हुए तेजी से प्रतिक्रिया करने के लिए त्वरण को मापता है।
स्टाफ़ ई ई

1
अन्य टिप्पणियों के साथ, यह एक स्थिर लक्ष्य के लिए काम करेगा लेकिन संभवतः किसी भी गतिशील लक्ष्य के लिए अस्वीकार्य होगा। C0 और C1 शब्द पारंपरिक नम वसंत सामग्री है, जहां C0 वसंत की ताकत (आमतौर पर कहा जाता है k) का प्रतिनिधित्व करता है और C1 भिगोना कारक है (आमतौर पर 'B' या 'c')। तो हाँ, आप भिगोना कम करके दोलन को कम कर सकते हैं लेकिन समस्या यह है कि यह अनुमान लगाने की कोशिश नहीं करता है कि लक्ष्य कहाँ होगा, इसलिए वांछित लक्ष्य को पिछड़ने के लिए बर्बाद किया जाता है।
डैश-टॉम-बैंग

3

आपके पास यहां जो है वह एक बुनियादी है नियंत्रण समस्या है । बुर्ज प्रणाली है, त्वरण नियंत्रण है और सेंसर स्थिति / वेग को मापता है। इन समस्याओं से निपटने के कई तरीके हैं, क्योंकि यह इंजीनियरिंग में बहुत अच्छी तरह से अध्ययन की जाने वाली समस्या है।

कुंजी एक स्थिर प्रणाली के साथ समाप्त हो रही है, अर्थात ऐसी प्रणाली जो दोलनों को उत्पन्न नहीं करती है। यह आमतौर पर भिगोना जोड़कर किया जाता है। विकिपीडिया पृष्ठ आपको आरंभ करना चाहिए।


2

सबसे पहले, टारगेट से लक्ष्य तक वेक्टर की गणना करें। फिर बुर्ज के वर्तमान वेक्टर के साथ इसकी तुलना करें। फिर एक निश्चित समय के भीतर सही दिशा में इंगित करने के लिए बुर्ज प्राप्त करने के लिए आवश्यक कोणीय त्वरण और कोणीय वेग को बाहर करने के लिए दोनों के बीच के अंतर का उपयोग करें।

ठीक है, यह आसान लग रहा था। हालाँकि, आपको वास्तव में लक्ष्य की स्थिति का अनुमान लगाने का प्रयास करना चाहिए क्योंकि लक्ष्य उस समय तक आगे बढ़ने वाला है जब आप बुर्ज को बदल चुके हैं। यह करने के लिए:-

Pd' = Pd + t.Vd
Ps' = Ps + t.Vs

जहां P स्थिति है और V वेग है और सबस्क्रिप्ट गंतव्य (लक्ष्य) और स्रोत (बुर्ज) के लिए है, जो एक दिशा वेक्टर देता है: -

Dsd' = Pd' - Ps' = Pd + t.Vd - (Ps + t.Vs) = Pd - Ps + (Vd - Vs).t

जहाँ D एक दिशा सदिश है और Dsd 'समय t पर आवश्यक दिशा है। अब, वर्तमान स्थिति और एक निश्चित समय के लिए अधिकतम वेग और त्वरण के आधार पर बुर्ज की दिशा का काम करें: -

Ds' = t.Ds.Rs -> this is a vector rotation

डीएस और डीएस 'स्रोत दिशाएं हैं और रुपये घूर्णी वेग है। इन सब के साथ, आप Dsd '== Ds' और इस प्रकार रु। के लिए t खोजना चाहते हैं, जो आवश्यक घूर्णी वेग है। मत भूलो कि सभी पी, डी और वी के एक्स और वाई घटक हैं।

मैंने यहाँ त्वरण को ध्यान में नहीं रखा है - जो जटिलता के लिए बहुत अधिक जोड़ता है। एक बार जब आप रु।


यह अवरोधन गणना के लिए एक अच्छे उत्तर की तरह दिखता है, लेकिन दुर्भाग्य से ऐसे लोगों के बीच एक बड़ा अंतर है जो इस तरह के गणित संकेतन को पढ़ सकते हैं और इसे प्रोग्राम कोड में बदल सकते हैं, और अधिकांश लोग ऐसे गेम बना रहे हैं जो पहले से ही इसका जवाब नहीं जानते हैं प्रश्न। दूसरे शब्दों में, मुझे लगता है कि खेल देव जो उस गणित संकेतन को पढ़ सकते हैं, शायद पहले से ही यह पता लगा सकते हैं कि फायरिंग समाधान कैसे प्रोग्राम किया जाए। यदि आप अपने शब्दों का अर्थ बताते हैं तो इससे मुझे आपके सूत्रों को समझने में मदद मिलेगी।
ड्रोनज

2

आप शायद यहाँ जो देख रहे हैं वह एक PID नियंत्रक है , जो इस SO प्रश्न पर स्वीकृत उत्तर के समान है

मैंने शुरू में उस सवाल का जवाब "अपना खुद का रोल" करके दिया था, लेकिन यह जवाब काफी अधिक पूर्ण और सुरुचिपूर्ण है।


0

पहली बात यह है कि समतल और ट्रैक की गई वस्तु के बीच के कोण की गणना करना।
अगली बात यह है कि अगर वर्तमान धार गति का उपयोग करके और अधिकतम त्वरण को पीछे की ओर (टोरेंट को रोककर) ट्रैक की गई वस्तु से पहले या बाद में रोका जाएगा, तो जांच लें।
यदि उत्तर है कि ट्रैक की गई वस्तु से पहले धार बंद हो जाएगी, तो अधिकतम त्वरण आगे (बढ़ती गति) लागू करें।
यदि उत्तर यह है कि ट्रैक किए गए ऑब्जेक्ट के बाद धार बंद हो जाएगी, तो अधिकतम त्वरण पिछड़े (टोरेंट को रोकना) लागू करें।
इस तरह टोरेंट अलविस सबसे तेजी से आएगा और सही बिंदु (या उसके बाद एक अंश) पर रुकेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.