در این مطلب می خواهم کمی در مورد PID صحبت کنم. وقتی میگم کمی، یعنی قرار نیست تاریخچه و کلی فرمول براتون ردیف کنم. و فقط میخواهم یک توضیح مختصر بدم و کد برنامه را براتون بنویسم.
طبق معمول پروژهای را انجام میدادم که احتیاج به PID داشت. یک کتابخانهی خوب هم در آردوینو هست براش. ولی طبق معمول تا نفهمم که این PID چطوری کار میکنه و مفهومش چیه اصلا برام جالب نیست. برای همین اول یک خلاصه در مورد PID صحبت کنیم.
پیش از PID
ساده ترین روش کنترل یک فرایند نوشتن یک کد شرطی است. برای مثال فرض کنید یک دستگاه تولید جوجه داریم و میخواهیم که دمای داخل آن از 30 درجه پایین تر نیاید. برای این کار ما یک هیسترسیز برای دمای مورد نظر در نظر میگرفتیم. مثلا 29 و 31. می گفتیم اگر دما از 29 کمتر شد المنت روشن شود و اگر از 31 بیشتر شد المنت خاموش شود. این سادهترین روش بود ولی دما دارای یک نوسان میشود و ما بین 29 و 31 در حال نوسان است. ولی شاید ما بخواهیم که دما دقیقا روی 30 درجه ثابت بماند. اگر هیسترسیز را حذف کنیم المنت خیلی سریع خاموش روشن میشود. و از نظر مکانیکی امکان پذیر نیست.
PID
PID یک روش کنترل فرآیند است. که برعکس روش قبلی، برای کنترلهای آنالوگ کاربرد دارد. مثلا وقتی که المنت ما بجای اینکه فقط امکان خاموش و روشن شدن داشته باشد. امکان تنظیم درجه و شدت داشته باشد. یا برای کنترل شیر آب که در روش قبلی فقط امکان خاموش و روشن کردن بود مثل شیربرقی، در اینجا امکان کم و زیاد کردن شیر وجود داشته باشد.
موردی که من خودم تجربه کردم و بررسی لازم داشت، انتظار ما از کنترل است. در پروژهی من فقط کنترل برای افزایش نیافتن دما بود و اگر دما به هر دلیلی پایینتر از دمای مورد نظر ما بود لازم نبود کاری صورت گیرد. فرض کنید با یک فن می خواهیم دمای اطاقی را کنترل کنیم تا دما از 30 بالاتر نرود. ولی اگر پایینتر رفت مثلا شبها لازم نیست کاری صورت گیرد. فقط لازم است از 30 درجه بالاتر نرود. این قسمت را بعدا بیشتر توضیح خواهم داد.
حالا بر می گردیم به توضیح PID. فرض کنید منبع آبی داریم و می خواهیم که سطح آب داخل آن روی سطح مشخصی ثابت بماند، در صورتی که خروجی آب از منبع میزان ثابتی نیست و در بازه های زمانی کم و زیاد میشود. شیر ورودی از صفر تا 180 قابل بسته و باز شدن است. اگر بخواهیم بصورت دستی کنترل کنیم. وقتی مصرف آب زیاد میشود و سطح آب پایین میآید. اول لازم است شیر ورودی بیشتر از شیر خروجی باز شود تا وقتی که سطح آب به حد انتظار برگردد. و بعد با نزدیک شدن به آن شیر را کمی ببیندیم تا سطح آب با وجود خروج آب از منبع، ثابت بماند. حال میخواهیم این کار را PID برای ما انجام دهد.
فرمول PID
PID از سه بخش یا پارامتر قابل تنظیم تشکیل شده است. شکل کلی فرمول PID به صورت زیر است.
شرح فرمول PID
- P اول کلمهی Proportional به معنای متناسب است. P قسمت اول فرمول است که در فرمول دارای یک ضریب به نام Kp است، که از طرف ما مشخص میشود. این ضریب در ارور(اختلاف سطح آب با مقدار مد نظر ما) ضرب میشود و باعث میشود قسمت اول فرمول ما متناسب با ارور افزایش و کاهش یابد. فرض کنید Kp را 2 قرار دادهایم و سطح آب 30 سانت پایینتر از سطح مورد نظر ما قرار دارد. پس ارور ما میشود 30 که در 2 ضرب شده و حاصل 60 میشود. پس خروجی تابع ما میشود 60. تا اینجا شیر آب ورودی روی 60 درجه قرار میگیرد. فرض کنید مقدار آب ورودی از خروجی بیشتر است و ارور ما در حال کم شدن. همینطور که ارور کم میشود به جایی میرسیم که آب ورودی با خروجی دقیقا برابر میشود. مثلا درجه شیر خروجی روی 50 است و وقتی ارور ما به 25 برسد، شیر ورودی هم روی 50 قرار میگیرد. از اینجا به بعد بخش P کاربرد خود را از دست میدهد. چرا؟ چون اگر ارور بخواهد کمتر بشود پس درجه شیر ورودی هم کمتر شده و دوباره سطح آب پایینتر میرود و ارور افزایش پیدا میکند. شاید بگویید خب کاری نداره ضریب Kp را یک عدد بیشتر میگذاریم. مثلا 10 خوبه؟ باز هم اگر در فرمول جایگزین کنیم، میبینیم که وقتی ارور به 5 برسد درجهی شیر ورودی با خروجی برابر شده و ارور ما همچنان باقی میماند. در اینجا است که بخش دوم یا “I” به کمک ما میآید.
- I اول کلمهی Integral است.که در فرمول قسمت دوم است. انتگرال ارور در یک ضریب که با Ki نشان داده شده است و ما تنظیم میکنیم، ضرب میشود. همانطور که میدانید انتگرال اندازهی سطح زیر نمودار است. تا اینجا ارور ما 25 بود. فرض کنید ضریب Ki را هم روی 0.5 تنظیم کرده ایم و بازه زمانی نمونه گیری ما هم دقیقه است. در دقیقه اول ارور ما 25 است که اگر در نیم ضرب کنیم میشود 12.5، و این مقدار با مقدار اول فرمول ما یا همان P جمع میشود. حاصل میشود 62.5 . پس درجه شیر ورودی ما روی 62.5 قرار میگیرد. پس مقدار ورودی آب از خروجی بیشتر شده. پس انتظار داریم در دقیقهی دوم مقدار ارور ما باز هم کمتر شود. فرض کنید ارور ما در دقیقه دوم به 10 رسیده باشد. انتگرال نمودار ارور ما میشود 25 که از قبل بود بعلاوهی 10 که میشود 35، ضربدر 0.5 میشود 17.5. پس در دقیقهی دوم درجه شیر ما روی 67.5 قرار می گیرد. و همینطور که مشخص است در دقیقه سوم انتظار میره که خطای ما منفی شود و سطح آب از مقدار مد نظر ما بیشتر شود. در اینجاست که مقدار انتگرال ما هم کاهش پیدا می کند. این نوسان در اطراف سطح مورد نظر ما آنقدری ادامه پیدا می کند تا به ثبات برسد. ولی برای اینکه سریعتر به ثبات برسیم به بخش سوم نیاز پیدا میکنیم.
- اول کلمهی Derivative به معنای مشتق است. که در فرمول قسمت سوم میباشد. مشتق هم در یک ضریب به اسم Kd که توسط ما تنظیم میشود، ضرب میشود. همانطور که میدانید مشتق شیب نمودار است و در اینجا شیب نمودار ارور ما میباشد. کار اصلی این بخش این است که از نوسانات شدید جلوگیری کند. وقتی ارور ما از 25 در دقیقه اول به 10 در دقیقهی دوم رسید مشتق آن میشود 15-. که اگر ضریب Ki را یک در نظر گرفته باشیم. مقدار خروجی فرمول ما میشود 67.5 منهای 15 که میشود 52.5. میبینید که باز شدن شیر کمی آرامتر شد و از شدت آن جلوگیری شد. پس نمودار ارور ما با شیب و شتاب بهتری به سمت صفر میرود.
اینکه این سه پارامتر را چه اعدادی بگذاریم بسته به نوع فرآیند ما متفاوت است و باید تجربه کسب کرد.
کد PID
در ادامه کد PID را پیاده کردهام.
unsigned long currentTime, previousTime; double lastError; double setPoint = 30; double cumError, rateError; float kP = 2,kI = 0.5,kD = 1; float computePID(float inp){ currentTime = millis(); //get current time float elapsedTime = (float)(currentTime - previousTime); //compute time elapsed from previous computation float error = setPoint - inp; // determine error cumError += error * elapsedTime; // compute integral rateError = (error - lastError)/elapsedTime; // compute derivative float out = kP*error + kI*cumError + kD*rateError; //PID output lastError = error; //remember current error previousTime = currentTime; //remember current time return out; //have function return the PID output }
شرح کد
در قسمت اول متغیر های مورد نیاز را تعریف میکنیم.
در ادامه تابع محاسبه PID را نوشتم، که زمان سپری شده را حساب میکند. سپس ارور را بدست میآورد و از روی ارور انتگرال و مشتق را بدست آورده. هر سه را با هم جمع کرده و به عنوان خروجی بر میگرداند.
امیدوارم این آموزش مفید بوده باشه.
دیدگاه ها :