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

📄 spsa_pd_tanker.m

📁 一个用MATLAB编写的优化控制工具箱
💻 M
📖 第 1 页 / 共 2 页
字号:
if t>=15000, psi_r(index)=45*(pi/180); end     % Request heading of 45 degif t>=16500, psi_r(index)=0; end    			% Request heading of 0 degif t>=18000, psi_r(index)=45*(pi/180); end     % Request heading of 45 degif t>=19500, psi_r(index)=0; end    			% Request heading of 0 deg% Next, suppose that there is sensor noise for the heading sensor with that is% additive, with a uniform distribution on [- 0.01,+0.01] deg.s(index)=0.01*(pi/180)*(2*rand-1); %else%s(index)=0;					  % This allows us to remove the noise.%endpsi(index)=x(1)+s(index);     % Heading of the ship (possibly with sensor noise).if counter == 10,  % When the counter reaches 10 then execute the 				   % controllercounter=0; 			% First, reset the counter% Reference model calculations:% The reference model is part of the controller and to simulate it% we take the discrete equivalent of the% reference model to compute psi_m from psi_r (if you use% a continuous-time reference model you will have to augment % the state of the closed-loop system with the state(s) of the % reference model and hence update the state in the Runge-Kutta % equations).%% For the reference model we use a first order transfer function % k_r/(s+a_r) but we use the bilinear transformation where we % replace s by (2/step)(z-1)/(z+1), then find the z-domain % representation of the reference model, then convert this % to a difference equation:ym(index)=(1/(2+a_r*T))*((2-a_r*T)*ymold+...                                    k_r*T*(psi_r(index)+psi_r_old));ymold=ym(index);  psi_r_old=psi_r(index);	% This saves the past value of the ym and psi_r so that we can use it	% the next time around the loop	% Controller calculations:e(index)=psi_r(index)-psi(index); % Computes error (first layer of perceptron)c(index)=(e(index)-eold)/T; % Sets the value of ceold=e(index);   % Save the past value of e for use in the above				 % computation the next time around the loop%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% A proportional-derivative controller:delta(index)=Kpbest*e(index)+Kdbest*c(index);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%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 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);ym(index)=ym(index-1);end % This is the end statement for the "if counter=10" statement% 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%if flag==0, 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);%end% 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% The next line is used in place of the line following it to% change the speed of the ship%if t>=1000000,%if t>=9000,      % This switches the ship speed (unrealistically fast)%if flag==0,%u=3; % A lower speed%elseu=5;%end% Next, we change the parameters of the ship to tanker to reflect% changing loading conditions (note that we simulate as if% the ship is loaded while moving, but we only change the parameters% while the heading is zero so that it is then similar to re-running% the simulation, i.e., starting the tanker operation at different % times after loading/unloading has occurred).% The next line is used in place of the line following it to keep% "ballast" conditions throughout the simulation%if t>=1000000,%if t>=9000,      % This switches the parameters in the middle of the simulationif flag==0,K_0=0.83;  		% These are the parameters under "full" conditionstau_10=-2.88;tau_20=0.38;tau_30=1.07;elseK_0=5.88;		% These are the parameters under "ballast" conditionstau_10=-16.91;tau_20=0.45;tau_30=1.43;end% The following parameters are used in the definition of the tanker model:K=K_0*(u/ell);tau_1=tau_10*(ell/u);tau_2=tau_20*(ell/u);tau_3=tau_30*(ell/u);% Next, comes the plant:% 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, 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 data from the simulation%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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);ym=ym*(180/pi);% Next, we provide plots showing the performance of the best designfigure(3)clfsubplot(211)plot(time,psi,'k-',time,ym,'k--',time,psi_r,'k-.')zoomgrid ontitle('Ship heading (solid) and desired ship heading (dashed), deg.')subplot(212)plot(time,delta,'k-')zoomgrid ontitle('Rudder angle, output of controller (input to the ship), deg.')xlabel('Time, sec')figure(4)clfplot(time,psi-ym,'k-')zoomgrid ontitle('Ship heading error between ship heading and reference model heading, deg.')xlabel('Time, sec')%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Just repeat above code, but for off-nominal case%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

⌨️ 快捷键说明

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