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

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

  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