मुख्य कंटेंट तक स्किप करें

विजुअल सर्वोइंग के साथ निशाना लगाना

  1. आप केवल एक लाइमलाइट और अपने ड्राइवट्रेन का उपयोग करके अपने रोबोट को सटीक और तेजी से निशाना लगा सकते हैं।
  2. यह सब 1 घंटे से कम समय में पूरा किया जा सकता है।

उच्च-फ्रेमरेट विजन ट्रैकिंग का उपयोग करके, अब आपके रोबोट या टरेट को गाइड करने के लिए PID कंट्रोल लूप में "सेंसर" के रूप में सीधे विजन पाइपलाइन का उपयोग करना संभव है। इस विचार का परीक्षण करने के लिए हमने अपने 2017 FRC रोबोट में एक लाइमलाइट जोड़ा और इसे केवल ड्राइवट्रेन और लाइमलाइट द्वारा रिपोर्ट किए गए नेटवर्क टेबल डेटा का उपयोग करके विजन टारगेट पर निशाना लगाने के लिए बनाया।

इस उदाहरण में, हमारा टेस्ट कैंडिडेट एक 2017 FRC रोबोट था जो कोलसन व्हील्स के साथ 6-व्हील ड्राइवट्रेन का उपयोग करता है। यहाँ एक तस्वीर है जिसमें हम इस परीक्षण को करने के लिए रोबोट पर एक लाइमलाइट जोड़ रहे हैं।

CS_aim_limelight_mounted

फिर हमने रोबोट में कुछ कोड जोड़ा जो तब चलेगा जब ड्राइवर जॉयस्टिक पर एक बटन दबाए रखता है। यह रोबोट "टैंक" स्टाइल ड्राइविंग का उपयोग करता था इसलिए ऑपरेटरकंट्रोल फंक्शन ड्राइवट्रेन के बाएं और दाएं साइड को नियंत्रित करने के लिए 'left_command' वैल्यू और 'right_command' वैल्यू जनरेट कर रहा था। सामान्य कंट्रोल कोड के बाद, हमने इस तरह का कोड ब्लॉक जोड़ा:

float Kp = -0.1f;  // प्रोपोर्शनल कंट्रोल कॉन्स्टेंट

std::shared_ptr<NetworkTable> table = NetworkTable::GetTable("limelight");
float tx = table->GetNumber("tx");

if (joystick->GetRawButton(9))
{
float heading_error = tx;
steering_adjust = Kp * tx;

left_command+=steering_adjust;
right_command-=steering_adjust;
}

शुरू से ही, यह काफी हद तक काम करता था। जब आप बटन दबाए रखते हैं तो रोबोट स्वचालित रूप से लक्ष्य की दिशा में मुड़ता है। यदि आप लक्ष्य को इधर-उधर ले जाते हैं, तो रोबोट लक्ष्य का अनुसरण करने के लिए मुड़ता है। हालांकि, डैशबोर्ड पर लाइव वीडियो फीड का उपयोग करते हुए, हम देख सकते थे कि एक बड़ी समस्या थी: रोबोट हमेशा लक्ष्य के साथ पूरी तरह से संरेखित नहीं हो रहा था। छोटे लक्ष्यों वाले कुछ गेम्स में (जैसे 2016 और 2017) यह पर्याप्त नहीं होगा।

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

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

float Kp = -0.1f;
float min_command = 0.05f;

std::shared_ptr<NetworkTable> table = NetworkTable::GetTable("limelight");
float tx = table->GetNumber("tx");

if (joystick->GetRawButton(9))
{
float heading_error = -tx;
float steering_adjust = 0.0f;
if (Math.abs(heading_error) > 1.0)
{
if (heading_error < 0)
{
steering_adjust = Kp*heading_error + min_command;
}
else
{
steering_adjust = Kp*heading_error - min_command;
}
}
left_command += steering_adjust;
right_command -= steering_adjust;
}

सावधान रहें, यदि आप Kp या min_command को बहुत अधिक सेट करते हैं, तो आपका रोबोट अस्थिर हो सकता है और लक्ष्य को पार करते समय आगे-पीछे दोलन कर सकता है:

CS_aim_bad

Kp और min_command पर कुछ ट्यूनिंग के बाद आपका रोबोट बहुत सटीक और तेजी से सीधे लक्ष्य पर निशाना लगा सकेगा।

CS_aim_good