⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fc_tanker.m

📁 一个用MATLAB编写的优化控制工具箱
💻 M
📖 第 1 页 / 共 2 页
字号:
	end% The next two loops calculate the crisp output using only the non-% zero premise of error,e, and c.  This cuts down computation time % since we will only compute the contribution from the rules that % are on (i.e., a maximum of four rules for our case).  The minimum% is used for the premise (and implication for the center-of-gravity% defuzzification case).num=0;den=0;     	for k=(e_int-e_count+1):e_int  						% Scan over e indices of mfs that are on		for l=(c_int-c_count+1):c_int							% Scan over c indices of mfs that are on		  prem=min([mfe(k) mfc(l)]); 		  				% Value of premise membership function% This next calculation of num adds up the numerator for the % center of gravity defuzzification formula. rules(k,l) is the output center % for the rule.  base*(prem-(prem)^2/2) is the area of a symmetric% triangle that peaks at one with base width "base" and that is chopped off at % a height of prem (since we use minimum to represent the % implication). Computation of den is similar but without % rules(k,l).		  num=num+rules(k,l)*base*(prem-(prem)^2/2);		  den=den+base*(prem-(prem)^2/2);		% To do the same computations, but for center-average defuzzification,% use the following lines of code rather than the two above (notice% that in this case we did not use any information about the output% membership function shapes, just their centers; also, note that% the computations are slightly simpler for the center-average defuzzificaton):%		num=num+rules(k,l)*prem;%		den=den+prem;		end	end   delta(index)=num/den;      			% Crisp output of fuzzy controller that is the input   			% to the plant.else % This goes with the "if" statement to check if the counter=10     % so the next lines up to the next "end" statement are executed     % whenever counter is not equal to 10% Now, even though we do not compute the fuzzy controller at each% time instant, we do want to save the data at its inputs and output at% each time instant for the sake of plotting it.  Hence, we need to % compute these here (note that we simply hold the values constant):e(index)=e(index-1);	c(index)=c(index-1); delta(index)=delta(index-1);end % This is the end statement for the "if counter=10" statement% Now, for the first step, we set the initial condition for the% third state x(3).if t==0, x(3)=-(K*tau_3/(tau_1*tau_2))*delta(index); end% Next, the Runge-Kutta equations are used to find the next state. % Clearly, it would be better to use a Matlab "function" for% F (but here we do not, so we can have only one program).  	time(index)=t;% First, we define a wind disturbance against the body of the ship% that has the effect of pressing water against the rudder%w(index)=0.5*(pi/180)*sin(2*pi*0.001*t);  % This is an additive sine disturbance to 										% the rudder input.  It is of amplitude of										% 0.5 deg. and its period is 1000sec.%delta(index)=delta(index)+w(index);% Next, implement the nonlinearity where the rudder angle is saturated% at +-80 degreesif delta(index) >= 80*(pi/180), delta(index)=80*(pi/180); endif delta(index) <= -80*(pi/180), delta(index)=-80*(pi/180); end% Next, we use the formulas to implement the Runge-Kutta method% (note that here only an approximation to the method is implemented where% we do not compute the function at multiple points in the integration step size).F=[ x(2) ;    x(3)+ (K*tau_3/(tau_1*tau_2))*delta(index) ;    -((1/tau_1)+(1/tau_2))*(x(3)+ (K*tau_3/(tau_1*tau_2))*delta(index))-...        (1/(tau_1*tau_2))*(abar*x(2)^3 + bbar*x(2)) + (K/(tau_1*tau_2))*delta(index) ];        	k1=step*F;	xnew=x+k1/2;F=[ xnew(2) ;    xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index) ;    -((1/tau_1)+(1/tau_2))*(xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index))-...        (1/(tau_1*tau_2))*(abar*xnew(2)^3 + bbar*xnew(2)) + (K/(tau_1*tau_2))*delta(index) ];   	k2=step*F;	xnew=x+k2/2;F=[ xnew(2) ;    xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index) ;    -((1/tau_1)+(1/tau_2))*(xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index))-...        (1/(tau_1*tau_2))*(abar*xnew(2)^3 + bbar*xnew(2)) + (K/(tau_1*tau_2))*delta(index) ];   	k3=step*F;	xnew=x+k3;F=[ xnew(2) ;    xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index) ;    -((1/tau_1)+(1/tau_2))*(xnew(3)+ (K*tau_3/(tau_1*tau_2))*delta(index))-...        (1/(tau_1*tau_2))*(abar*xnew(2)^3 + bbar*xnew(2)) + (K/(tau_1*tau_2))*delta(index) ];   	k4=step*F;	x=x+(1/6)*(k1+2*k2+2*k3+k4); % Calculated next statet=t+step;  			% Increments timeindex=index+1;	 	% Increments the indexing term so that 					% index=1 corresponds to time t=0.counter=counter+1;	% Indicates that we computed one more integration stepend % This end statement goes with the first "while" statement     % in the program so when this is complete the simulation is done.%% Next, we provide plots of the input and output of the ship % along with the reference heading that we want to track.% Also, we plot the two inputs to the fuzzy controller.%% First, we convert from rad. to degreespsi_r=psi_r*(180/pi);psi=psi*(180/pi);delta=delta*(180/pi);e=e*(180/pi);c=c*(180/pi);% Next, we provide plots of data from the simulationfigure(1)clfsubplot(211)plot(time,psi,'k-',time,psi_r,'k--')grid onxlabel('Time (sec)')title('Ship heading (solid) and desired ship heading (dashed), deg.')subplot(212)plot(time,delta,'k-')grid onxlabel('Time (sec)')title('Rudder angle (\delta), deg.')zoomfigure(2)clfsubplot(211)plot(time,e,'k-')grid onxlabel('Time (sec)')title('Ship heading error between ship heading and desired heading, deg.')subplot(212)plot(time,c,'k-')grid onxlabel('Time (sec)')title('Change in ship heading error, deg./sec')zoomend % This ends the if statement (on flag1) on whether you want to do a simulation    % or just see the control surface 	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Next, provide a plot of the fuzzy controller surface:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Request input from the user to see if they want to see the % controller mapping:flag2=input('\n Do you want to see the nonlinear \n mapping implemented by the fuzzy \n controller? \n (type 1 for yes and 0 for no) ');if flag2==1,	% First, compute vectors with points over the whole range of % the fuzzy controller inputs plus 20% over the end of the range% and put 100 points in each vectore_input=(-(1/g1)-0.2*(1/g1)):(1/100)*(((1/g1)+0.2*(1/g1))-(-(1/g1)-...     0.2*(1/g1))):((1/g1)+0.2*(1/g1)); ce_input=(-(1/g2)-0.2*(1/g2)):(1/100)*(((1/g2)+0.2*(1/g2))-(-(1/g2)-...     0.2*(1/g2))):((1/g2)+0.2*(1/g2));% Next, compute the fuzzy controller output for all these inputsfor jj=1:length(e_input) 	for ii=1:length(ce_input) c_count=0;,e_count=0;   % These are used to count the number of 						% non-zero mf certainities of e and c% The following if-then structure fills the vector mfe % with the certainty of each membership fucntion of e for the % current input e.  We use triangular membership functions.	if e_input(jj)<=ce(1)		% Takes care of saturation of the left-most 					            % membership function         mfe=[1 0 0 0 0 0 0 0 0 0 0]; % i.e., the only one on is the          							  % left-most one	 e_count=e_count+1;,e_int=1; 	  %  One mf on, it is the 	 								  % left-most one.	elseif e_input(jj)>=ce(nume)				  % Takes care of saturation 									  % of the right-most mf	 mfe=[0 0 0 0 0 0 0 0 0 0 1];	 e_count=e_count+1;,e_int=nume; % One mf on, it is the 	 								% right-most one	else      % In this case the input is on the middle part of the 			  % universe of discourse for e			  % Next, we are going to cycle through the mfs to 			  % find all that are on	   for i=1:nume		 if e_input(jj)<=ce(i)		  mfe(i)=max([0 1+(e_input(jj)-ce(i))/we]);   		  				% In this case the input is to the 		  				% left of the center ce(i) and we compute						% the value of the mf centered at ce(i)						% for this input e			if mfe(i)~=0					% If the certainty is not equal to zero then say 				% that have one mf on by incrementing our count			 e_count=e_count+1;			 e_int=i;	% This term holds the index last entry 			 			% with a non-zero term			end		 else 		  mfe(i)=max([0,1+(ce(i)-e_input(jj))/we]); 		  						% In this case the input is to the		  						% right of the center ce(i)			if mfe(i)~=0			 e_count=e_count+1;   			 e_int=i;  % This term holds the index of the 			 		   % last entry with a non-zero term			end		 end		end	end% The following if-then structure fills the vector mfc with the % certainty of each membership fucntion of the c% for its current value.	if ce_input(ii)<=cc(1)	% Takes care of saturation of left-most mf         mfc=[1 0 0 0 0 0 0 0 0 0 0];	 c_count=c_count+1;	 c_int=1;   	elseif ce_input(ii)>=cc(numc)					        % Takes care of saturation of the right-most mf	 mfc=[0 0 0 0 0 0 0 0 0 0 1];	 c_count=c_count+1; 	 c_int=numc;	else		for i=1:numc		 if ce_input(ii)<=cc(i)  		  mfc(i)=max([0,1+(ce_input(ii)-cc(i))/wc]);			if mfc(i)~=0			 c_count=c_count+1;			 c_int=i;  	    % This term holds last entry 			 		     	% with a non-zero term			end		 else 		  mfc(i)=max([0,1+(cc(i)-ce_input(ii))/wc]);			if mfc(i)~=0			 c_count=c_count+1;			 c_int=i;	% This term holds last entry 			 			% with a non-zero term			end		 end		end	end% The next loops calculate the crisp output using only the non-% zero premise of error,e, and c.  num=0;den=0;     	for k=(e_int-e_count+1):e_int  						% Scan over e indices of mfs that are on		for l=(c_int-c_count+1):c_int							% Scan over c indices of mfs that are on		  prem=min([mfe(k) mfc(l)]); 		  				% Value of premise membership function% This next calculation of num adds up the numerator for the % center of gravity defuzzification formula. 		  num=num+rules(k,l)*base*(prem-(prem)^2/2);		  den=den+base*(prem-(prem)^2/2);		% To do the same computations, but for center-average defuzzification,% use the following lines of code rather than the two above:%		num=num+rules(k,l)*prem;%		den=den+prem;		end	end   delta_output(ii,jj)=num/den;      			% Crisp output of fuzzy controller that is the input   			% to the plant.				endend% Convert from radians to degrees:delta_output=delta_output*(180/pi);e_input=e_input*(180/pi);ce_input=ce_input*(180/pi);% Plot the controller mapfigure(3)clfsurf(e_input,ce_input,delta_output);view(145,30);colormap(white);xlabel('Heading error (e), deg.');ylabel('Change in heading error (c), deg.');zlabel('Fuzzy controller output (\delta), deg.');title('Fuzzy controller mapping between inputs and output');end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -