पीआईडी ​​नियंत्रण: क्या अगले लूप से पहले एक अच्छा विचार जोड़ना देरी है?

Jan 11 2021

मैं सी ++ में पीआईडी ​​नियंत्रण को लागू कर रहा हूं ताकि एक अंतर ड्राइव रोबोट को सटीक संख्या में डिग्री मिल सके, लेकिन मुझे कई मुद्दे हैं।

फास्ट लूप रनटाइम के कारण नियंत्रण लूप जल्दी बाहर निकलना

यदि रोबोट अपनी त्रुटि को 5 डिग्री से कम मापता है, तो यह नियंत्रण लूप से बाहर निकलता है और "समाप्त" मोड़ पर विचार करता है (.5 एक यादृच्छिक मान है जो मैं किसी बिंदु पर बदल सकता हूं)। ऐसा प्रतीत होता है कि नियंत्रण लूप इतनी तेज़ी से चल रहा है कि रोबोट बहुत तेज़ गति से चालू हो सकता है, सेटपॉइंट को अतीत में बदल सकता है, और लूप / कट मोटर शक्तियों से बाहर निकल सकता है, क्योंकि यह एक छोटे पल के लिए सेटपॉइंट पर था। मुझे पता है कि यह पीआईडी ​​नियंत्रण का पूरा उद्देश्य है, ओवरसोइंग के बिना सेटपॉइंट तक सही तरीके से पहुंचना, लेकिन यह समस्या पीआईडी ​​स्थिरांक को ट्यून करना बहुत मुश्किल बना रही है। उदाहरण के लिए, मैं kp के मान को खोजने की कोशिश करता हूं, जैसे कि स्थिर दोलन है, लेकिन कभी कोई दोलन नहीं होता है क्योंकि रोबोट को लगता है कि यह सेटपॉइंट पास करने के बाद "समाप्त" हो गया है। इसे ठीक करने के लिए,मैंने एक ऐसी प्रणाली लागू की है जिसमें रोबोट को बाहर निकलने से पहले एक निश्चित समय के लिए सेटपॉइंट पर रहना पड़ता है, और यह प्रभावी रहा है, जिससे दोलन होने की अनुमति मिलती है, लेकिन लूप को जल्दी बाहर निकालने का मामला एक असामान्य समस्या और मेरे समाधान की तरह लगता है गलत हो सकता है।

तेजी से चलने के कारण डी टर्म का कोई प्रभाव नहीं है

एक बार जब मैंने रोबोट को केवल पी का उपयोग करके नियंत्रित तरीके से दोलन किया, तो मैंने ओवरशूट को रोकने के लिए डी को जोड़ने का प्रयास किया। हालांकि, यह समय के बहुमत के लिए कोई प्रभाव नहीं था, क्योंकि नियंत्रण लूप इतनी तेज़ी से चल रहा है कि 20 में से 19 लूप्स, त्रुटि के परिवर्तन की दर 0 है: रोबोट ने इसे स्थानांतरित नहीं किया था या इसके लिए पर्याप्त स्थानांतरित नहीं किया था उस समय में मापा जा सकता है। मैंने इसकी पुष्टि करने के लिए त्रुटि में परिवर्तन और प्रत्येक लूप को व्युत्पन्न किया और मैं देख सकता था कि ये दोनों एक उचित मूल्य लेने से पहले लगभग 20 लूप चक्रों के लिए 0 होंगे और फिर अन्य 20 चक्रों के लिए 0 पर वापस आ जाएंगे। जैसा कि मैंने कहा, मुझे लगता है कि यह इसलिए है क्योंकि लूप चक्र इतनी जल्दी होते हैं कि रोबोट शाब्दिक रूप से त्रुटि में किसी भी प्रकार के ध्यान देने योग्य परिवर्तन के लिए पर्याप्त रूप से स्थानांतरित नहीं हुआ है।यह एक बड़ी समस्या थी क्योंकि इसका मतलब था कि डी शब्द का अनिवार्य रूप से रोबोट आंदोलन पर कोई प्रभाव नहीं था क्योंकि यह लगभग हमेशा 0. था। इस समस्या को ठीक करने के लिए, मैंने किसी भी 0 मानों के स्थान पर व्युत्पन्न के अंतिम गैर-शून्य मान का उपयोग करने की कोशिश की। लेकिन यह अच्छी तरह से काम नहीं किया, और अगर पिछले व्युत्पन्न त्रुटि की वर्तमान दर का प्रतिनिधित्व नहीं करता था तो रोबोट बेतरतीब ढंग से दोलन करेगा।

नोट: मैं घर्षण के स्थिर गुणांक के लिए एक छोटे से फीडफ़ॉर्म का भी उपयोग कर रहा हूं, और मैं इस फीडफोवर्ड को "एफ" कहता हूं

क्या मुझे देरी से जोड़ना चाहिए?

मैंने महसूस किया कि मुझे लगता है कि इन दोनों मुद्दों का स्रोत बहुत जल्दी चलने वाला लूप है, इसलिए मैंने जो कुछ सोचा था वह लूप के अंत में एक प्रतीक्षा विवरण जोड़ रहा था। हालांकि, यह एक लूप को जानबूझकर धीमा करने के लिए एक समग्र खराब समाधान की तरह लगता है। यह एक अच्छा विचार है?

turnHeading(double finalAngle, double kp, double ki, double kd, double f){
    std::clock_t timer;
    timer = std::clock();

    double pastTime = 0;
    double currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);

    const double initialHeading = getHeading();
    finalAngle = angleWrapDeg(finalAngle);

    const double initialAngleDiff = initialHeading - finalAngle;
    double error = angleDiff(getHeading(), finalAngle);
    double pastError = error;

    double firstTimeAtSetpoint = 0;
    double timeAtSetPoint = 0;
    bool atSetpoint = false;

    double integral = 0;
    double derivative = 0;
    double lastNonZeroD = 0;

    while (timeAtSetPoint < .05)
    {
        updatePos(encoderL.read(), encoderR.read());
        error = angleDiff(getHeading(), finalAngle);

        currentTime = ((std::clock() - timer) / (double)CLOCKS_PER_SEC);
        double dt = currentTime - pastTime;

        double proportional = error / fabs(initialAngleDiff);
        integral += dt * ((error + pastError) / 2.0);
        double derivative = (error - pastError) / dt;
        
        //FAILED METHOD OF USING LAST NON-0 VALUE OF DERIVATIVE
        // if(epsilonEquals(derivative, 0))
        // {
        //     derivative = lastNonZeroD;
        // }
        // else
        // {
        //     lastNonZeroD = derivative;
        // }

        double power = kp * proportional + ki * integral + kd * derivative;

        if (power > 0)
        {
            setMotorPowers(-power - f, power + f);
        }
        else
        {
            setMotorPowers(-power + f, power - f);
        }

        if (fabs(error) < 2)
        {
            if (!atSetpoint)
            {
                atSetpoint = true;
                firstTimeAtSetpoint = currentTime;
            }
            else //at setpoint
            {
                timeAtSetPoint = currentTime - firstTimeAtSetpoint;
            }
        }
        else //no longer at setpoint
        {
            atSetpoint = false;
            timeAtSetPoint = 0;
        }
        pastTime = currentTime;
        pastError = error;
    }
    setMotorPowers(0, 0);
}

turnHeading(90, .37, 0, .00004, .12);

जवाब

3 UgoPattacini Jan 12 2021 at 05:14

अपने नियंत्रक को न दें।

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

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

यह काफी संबंधित संसाधन है: https://robotics.stackexchange.com/a/19198/6941।

व्युत्पन्न छोड़ दें।

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

  • https://robotics.stackexchange.com/a/21556/6941।
  • https://robotics.stackexchange.com/a/21555/6941।

एक बार जब मैंने रोबोट को केवल पी का उपयोग करके नियंत्रित तरीके से दोलन किया, तो मैंने ओवरशूट को रोकने के लिए डी को जोड़ने का प्रयास किया।

खैर, ऐसा लगता है कि आप अपने नियंत्रक को ट्यून करने के लिए ज़िग्लर-निकोल्स के नुस्खे का पालन कर रहे हैं। ऐसी तालिकाएँ हैं जिन्हें आपको हासिल करने की आवश्यकता है ताकि आप लाभ के लिए अनुमान लगा सकें। हालाँकि, ये विधर्मी हैं और यह संभावना है कि आपके मामले में काम नहीं करेगा।

बस डी भाग को छोड़ दें और पीआई नियंत्रक पर ध्यान केंद्रित करें। एक अन्य ZN संस्करण भी है जो जानबूझकर उत्पन्न दोलनों पर निर्भर नहीं करता है:https://robotics.stackexchange.com/a/21616/6941।

कभी भी सिस्टम में देरी न करें।

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

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

इस संबंध में, यदि आप अभिन्न शब्द I सम्मिलित करते हैं, तो आपको नमूना समय के बारे में तर्क करने की आवश्यकता होगी $T_s$ भी।

1 TimWescott Jan 12 2021 at 08:36

अपने नियंत्रक के लिए एक निश्चित नमूना दर निर्धारित करना बेहतर होगा। अंगूठे का एक बहुत मोटा नियम यह है कि लीनियर रिजीम में काम करने के बाद आपको जो भी बसने का समय चाहिए, वह लूप से बाहर हो जाएगा, आपका सैंपल इंटरवल सेटल होने के समय से 10 गुना से 100 गुना कम होना चाहिए। दूसरा तरीका रखो, नमूना दर वांछित लूप बैंडविड्थ की तुलना में 10 से 100 गुना तेज होना चाहिए।

एक छोटे से जोड़ा बोनस के रूप में, इसका मतलब है कि आप लूप के बाहर डीटी की गणना कर सकते हैं

वरीयता के अनुसार, नमूना दर को हार्डवेयर द्वारा तय किया जाना चाहिए, जैसे कि हार्डवेयर टाइमर द्वारा, और इससे भी बेहतर स्थिति का नमूना हार्डवेयर द्वारा किया जाना चाहिए, एक टाइमर से ट्रिगर किया गया। यह सॉफ्टवेयर पर वास्तविक समय की बाधाओं को काफी कम करता है।

यदि आप एक उचित नमूना दर का उपयोग कर रहे हैं और आप ज्यादातर अपने एनकोडर में परिवर्तन दर्ज नहीं कर रहे हैं, तो आपके एनकोडर के पास पर्याप्त कदम नहीं हैं।

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

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