آخرين ارسالهاي تالار

آموزش GUI (قسمت سوم) مشاهده در قالب PDF چاپ فرستادن به ایمیل
نوشته شده توسط مجتبی آیتی نیا   
یکشنبه, 21 شهریور 1389 ساعت 17:42

طراحی بدنه‌ی اصلی GUI ، در قسمت دوم آموزش GUI ، شرح داده شد. حال در این مرحله برنامه را Run کرده و با نام ControlTool ذخیره کرده‌ایم. اینک می‌خواهیم کدهای آن را بنویسیم.

برای شروع ابتدا به قسمت ControlTool_OpeningFcn بروید تا کدهای بازشدن GUI را بنویسید. کدهای زیر را وارد کنید:

g=tf(1,[1 3 2 4]);

step(handles.axes1,g);

rlocus(handles.axes2,g);

bode(handles.axes3,g);

این کدها نمودارهای سیستمی را که بصورت پیش‌فرض قرار داده‌ایم، رسم می‌کند. تابع تبدیل این سیستم، به قرار زیر است:

 

 

 

به Callback تمامی Edit Textها رفته، و کد زیر را وارد کنید:

input=get(hObject,'String');

if (isempty(input))

set(hObject,'String','Default')

end

guidata(hObject, handles);

فقط به‌جای عبارت Default ، مقدار پیش‌فرض آن Edit Text را قرار دهید. این کد مقدار واردشده در Edit Text را به‌صورت رشته‌ای می‌خواند، و اگر مقداری وارد نشده بود، Default را جایگزین می‌کند و در نهایت مقادیر آپدیت می‌شوند.

در ادامه‌ی کار به Callback دگمه‌ی فشاری Run رفته و قطعه کد زیر را وارد کنید:

if get(handles.radiobutton1,'Value') == get(handles.radiobutton1,'Max')

num=get(handles.edit1,'String');

num=str2num(num);

den=get(handles.edit2,'String');

den=str2num(den);

s1=size(num);

s2=size(den);

delay=get(handles.edit8,'String');

delay=str2num(delay);

if s1(1,2) > s2(1,2)

errordlg('Invalid input value!  size(num) <= size(den)','Error','modal');

end

if get(handles.checkbox1,'Value') == get(handles.checkbox1,'Max')

if delay < 0

errordlg('The value of the "OutputDelay" property must be a vector of nonnegative numbers.','Error','modal');

elseif mod(delay,1) ~= 0

errordlg('The value of the "OutputDelay" property must be integer valued for discrete-time models.','Error','modal');

else

h=tf(num,den,1,'outputdelay',delay);

g=tf(num,den,'outputdelay',delay);

end

else

g=tf(num,den);

end

else

z=get(handles.edit3,'String');

z=str2num(z);

p=get(handles.edit4,'String');

p=str2num(p);

s1=size(z);

s2=size(p);

delay=get(handles.edit8,'String');

delay=str2num(delay);

if s1(1,2) > s2(1,2)

errordlg('Invalid input value!  size(z) <= size(p)','Error','modal');

end

k=get(handles.edit5,'String');

k=str2num(k);

if get(handles.checkbox1,'Value') == get(handles.checkbox1,'Max')

if delay < 0

errordlg('The value of the "OutputDelay" property must be a vector of nonnegative numbers.','Error','modal');

elseif mod(delay,1) ~= 0

errordlg('The value of the "OutputDelay" property must be integer valued for discrete-time models.','Error','modal');

else

h=zpk(z,p,k,1,'outputdelay',delay);

g=zpk(z,p,k,'outputdelay',delay);

end

else

g=zpk(z,p,k);

end

end

if get(handles.radiobutton6,'Value') == get(handles.radiobutton6,'Max')...

&& get(handles.checkbox1,'Value') ~= get(handles.checkbox1,'Max')

g=feedback(g,1);

elseif get(handles.radiobutton6,'Value') == get(handles.radiobutton6,'Max')...

&& get(handles.checkbox1,'Value') == get(handles.checkbox1,'Max')

errordlg('Delay must be turn off in close loop.','Error','modal');

end

if (delay > 0) && (mod(delay,1) == 0)

%------------------------------------Response of LTI System

val1 = get(handles.popupmenu1,'Value');

if get(handles.radiobutton3,'Value') == get(handles.radiobutton3,'Max')

switch val1

case 1

step(handles.axes1,g);

case 2

impulse(handles.axes1,g);

end

else

time=get(handles.edit7,'String');

time=str2num(time);

t=0:time/1000:time;

switch val1

case 1

step(handles.axes1,g,t);

case 2

impulse(handles.axes1,g,t);

end

end

%-------------------------------------------Analysis roots

val2 = get(handles.popupmenu2,'Value');

switch val2

case 1

if get(handles.checkbox1,'Value') == get(handles.checkbox1,'Max')

rlocus(handles.axes2,h);

else

rlocus(handles.axes2,g);

end

case 2

pzmap(handles.axes2,g);

end

%---------------------------------------Frequency response

val3 = get(handles.popupmenu3,'Value');

switch val3

case 1

bode(handles.axes3,g);

case 2

nyquist(handles.axes3,g);

case 3

nichols(handles.axes3,g);

end

end

guidata(hObject, handles);

 

توضیح کد:

این کد درابتدا بررسی می‌کند که کدام روش برای معرفی سیستم، وارد شده است. اگر روش ضرایب چندجمله‌ای وارد شده بود، مقادیر num و den را به‌صورت رشته‌ای خوانده و به عدد تبدیل می‌کند. مقدار Delay را هم به‌همین ترتیب خوانده و به عدد تبدیل می‌کند تا در صورت نیاز از آن استفاده شود. در ادامه سایزهای num و den خوانده شده و در صورتیکه سایز num بزرگتر از den باشد، بوسیله‌ی تابع errordlg ، پیغام خطایی صادر می‌شود(در تمام توابع تبدیل سیستم‌های کنترلی، منطقی آن است که سایز num از سایز den کوچکتر و یا مساوی باشد). این دیالوگ به‌صورت زیر است:

 

 

 

 

 

 

نکته: این خطا از نوع modal است، و تا زمانی که OK نشود، کاربر نمی‌تواند به ادامه‌ی کار بپردازد.

در ادامه‌ی کد بررسی می‌شود که آیا Delay فعال است یا نه؟ اگر فعال باشد، بررسی می‌کند که مقدار وارد شده برای Delay ، منفی و یا اعشاری نباشد، و برای رخداد هرکدام پیغام خطایی از نوع modal صادر می‌کند. سپس درصورتی‌که مشکلی در عدد وارد شده برای Delay نبود، تابع تبدیل سیستم را به‌همراه Delay تشکیل می‌دهد و اگرهم Delay فعال نبود، که تابع تبدیل را بدون Delay تشکیل می‌دهد.

در ادامه‌ی کد به قسمتی می‌رسیم که مربوط به معرفی سیستم با صفرها و قطب‌ها و گین می‌باشد. این کد درابتدا صفرها و قطب‌ها و گین و تأخیر سیستم را خوانده و به عدد تبدیل می‌کند. سپس بررسی می‌کند که تعداد صفرهای سیستم از تعداد قطب‌های آن بیشتر نباشد، که دراین‌صورت پیغام خطایی صادر می‌کند. سپس در صورت فعال بودن Delay، همان شروط ذکر شده را برای عدد وارد شده، چک می‌نماید. درصورتی‌که مشکلی وجود داشت، خطایی صادر می‌کند و درغیراین‌صورت تابع تبدیل را به‌همراه Delay ، تشکیل می‌دهد و در صورتی‌که تأخیری در کار نباشد، تابع تبدیل بدون تأخیر را تشکیل می‌دهد.

سپس درصورتی‌که نوع سیستم، حلقه‌بسته انتخاب شده باشد(و Delay هم فعال نباشد)، سیستم حلقه‌بسته با استفاده از دستور feedback ، تشکیل می‌شود.

در ادامه‌ی کد بررسی می‌شود که تأخیر وارد شده، مشکلی نداشته باشد که اگر چنین باشد، هیچ پاسخی رسم نمی‌شود. سپس بررسی می‌شود که در قسمت پاسخ زمانی سیستم، حالت پیش‌فرض قرار داده شده‌است و یا انتخابی؟ در صورت فعال بودن حالت انتخابی، زمان واردشده در کادر مربوطه، خوانده شده و به عدد تبدیل می‌شود سپس برداری از صفر تا عدد واردشده و با گام یک‌هزارم عدد واردشده، تشکیل می‌شود تا پاسخ سیستم به ازای آن بردار ترسیم شود. نحوه‌ی تشخیص فعال‌بودن کدام پاسخ نیز بوسیله‌ی دستور switch ، کاملا واضح است.

ادامه‌ی این کد نیز مربوط به رسم نمودارهای آنالیز ریشه‌های سیستم و پاسخ فرکانسی آن می‌باشد که با توجه به توضیحات ذکر شده، مطلب خاصی باقی نمی‌ماند.

در ادامه‌ی کار به Callback دگمه‌ی فشاری Reset رفته و قطعه کد زیر را وارد کنید:

g=tf(1,[1 3 2 4]);

step(handles.axes1,g);

rlocus(handles.axes2,g);

bode(handles.axes3,g);

set(handles.radiobutton1,'Value',1);

set(handles.radiobutton3,'Value',1);

set(handles.radiobutton5,'Value',1);

set(handles.edit1,'String','1');

set(handles.edit2,'String','[1 3 2 4]');

set(handles.edit3,'String','[]');

set(handles.edit4,'String','[-1 -2]');

set(handles.edit5,'String','1');

set(handles.edit7,'String','10');

set(handles.edit8,'String','2');

set(handles.popupmenu1,'Value',1);

set(handles.popupmenu2,'Value',1);

set(handles.popupmenu3,'Value',1);

set(handles.checkbox1,'Value',0);

guidata(hObject, handles);

 

توضیح کد:

این کد تمامی تغییرات را به حالت پیش‌فرض خود بازمی‌گرداند.

 

اگر سؤالي داشتيد مي‌توانيد در بخش نظرات آن را مطرح كنيد.

براي رفتن به قسمت بعد، به‌روي لينك زير كليك كنيد:

آموزش GUI (قسمت چهارم)

 

براي رفتن به ديگر قسمت‌ها، به‌روي لينك‌هاي زير كليك كنيد:

آموزش GUI (قسمت اول)

آموزش GUI (قسمت دوم)

آموزش GUI (قسمت سوم)

آموزش GUI (قسمت چهارم)


نظر ها (40)
  • وحید  - تشکر و سوال
    با تشکر از زحمات شما چند تا سوال داشتم
    دستور tf چیکار می کنه ؟
    در مورد دستور guidata اگر امکانش هست یه توضیحی بدید
  • moj1001
    سلام دوست عزیز
    tf که transfer function هستش. یعنی با گرفتن ضرایب چندجمله‌ای صورت و مخرج، تابع تبدیل رو ایجاد می کنه.
    guidata هم برای آپدیت کردن دیتاهای ذخیره شده به کار می‌ره. مثلا زمانی که در متغییر handles دیتا ذخیره می‌کنی باید از این دستور استفاده کنی تا اگه دیتا تغییر کرد، دیتای به‌روز شده مورد استفاده قرار بگیره.
  • omid  - ice
    با سلام و عرض خسته نباشید.من می خواستم بدونم راجب دستور (ice)در متلب چیزی هست که بتونم ازش استفاده کنم مخصوصا راجب فایلی با پسوند fig. چطوری می تونم این فایلو پیدا کنم .با تشکر
  • moj1001
    سلام دوست عزیز
    منظورت از ice چیه؟
    فایل fig مگه کجاست که می خای اون رو پیدا کنی؟
  • ناشناس
    با سلام .من برنامه رو دانلودکردم ولی متاسفانه اجرا نشد و ارور داد.ورژن متلب 2009بود.بهرحال از سایت خوبتون تشکر می کنم
  • moj1001
    سلام دوست عزیز
    برنامه فکر نکنم توی ورژن 2009 ارور بده!
    شاید برنامه رو درست اجرا نکردی!
    با این حال بگو چه اروری داده تا بتونم کمکت کنم.
  • ناشناس
    ALI BUD
  • gunash
    سلام دوست عزیز
    با تشکر از مطالب ارزشمندتون.
    ادامه نداشت؟ من نتونستم فسمت چهارم رو بیابم!!!
  • moj1001
    سلام
    شرمنده لينكش رو يادم رفته بود بزارم الان مي‌تونيد وارد بشيد.
  • vahid  - سوال و تشکر
    آز آموزش و مثال خوبی که برای GUI نوشتی، ممنون :twisted:
    میشه hObject توضیح بدی ؟ یا تفاوت بین دو دستور زیر را برام مشخص کنی؟
    get(hObject,'String');%a
    get(handles.text1.'string');%b
  • moj1001
    سلام
    ممنون
    دستور get(handles.edit3,'String') آنچه را كه درون edit3 نوشته شده است، به صورت رشته‌اي مي‌گيرد.
    دستور get(hObject,'String') فكر نمي‌كنم كاربردي داشته باشد.
  • vahid  - سوال
    پس کاربرد این دستور در برنامه بالا چیه؟
    پایین خط
    ""به Callback تمامی Edit Textها رفته، و کد زیر را وارد کنید:"" :)

  • moj1001
    ok :idea:
    دستور get(hObject,'String') براي زماني هست كه مي‌خاي مقدار Edit Text رو در Callback خودش بخوني و دستور get(handles.edit3,'String') براي فراخواني مقدار edit3 در Callback‌هاي ديگر.
    ok :?:
  • vahid  - ممنون
    :lol: :lol: :lol: :lol: :lol:
  • جواد  - استفاده از دستور plot
    سلام: ممنون ، واقعاً مفید بود.
    میشه بگین چجوری میشه از دستور plot برای رسم شکل در axes استفاده کرد؟
  • moj1001
    سلام ممنون
    plot(handles.axes1,x,y)
  • میثم
    سلام آقا عالی بود، خیلی زحمت کشیدی :wink:
    فقط نحوه کدنویسی وابسته به شماره گذاری radiobutton ها بود که نیاز به فهم کامل کد هست و
    ولی خوب خیلی توپ بود دستت درد نکنه
تنها کاربران عضو شده می توانند نظر ارسال کنند!
آخرین بروز رسانی در یکشنبه, 04 تیر 1396 ساعت 04:02
 
logo-samandehi