📄 mlp_tanker.m
字号:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Multilayer Perceptron for Tanker Ship Heading Regulation%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% By: Kevin Passino % Version: 4/4/00%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%clear % Clear all variables in memory% Initialize ship parameters % (can test two conditions, "ballast" or "full"):ell=350; % Length of the ship (in meters)u=5; % Nominal speed (in meters/sec)%u=3; % A lower speed where the ship is more difficult to controlabar=1; % Parameters for nonlinearitybbar=1;% The parameters for the tanker under "ballast" conditions % (a heavy ship) are:K_0=5.88;tau_10=-16.91;tau_20=0.45;tau_30=1.43;% The parameters for the tanker under "full" conditions (a ship% that weighs less than one under "ballast" conditions) are:%K_0=0.83;%tau_10=-2.88;%tau_20=0.38;%tau_30=1.07;% Some other plant parameters are:K=K_0*(u/ell);tau_1=tau_10*(ell/u);tau_2=tau_20*(ell/u);tau_3=tau_30*(ell/u);% Parameters for the multilayer perceptron% The first hidden layer is trivial, with unity weights and a zero bias % Weights/biases in the second hidden layer:w112=10;w122=10;b12=-200*pi/180;b22=+200*pi/180;% Weights/biases in the third hidden layer:w113=-80*pi/180;w223=-80*pi/180;b13=0;b23=80*pi/180;% The bias in the output layer is zero and the two% output layer weights are unity. % Now, you can proceed to do the simulation or simply view the nonlinear% surface generated by the neural controller. %flag1=input('\n Do you want to simulate the \n neural control system \n for the tanker? \n (type 1 for yes and 0 for no) ');%if flag1==1, % Next, we initialize the simulation:t=0; % Reset time to zeroindex=1; % This is time's index (not time, its index). tstop=4000; % Stopping time for the simulation (in seconds)step=1; % Integration step sizeT=10; % The controller is implemented in discrete time and % this is the sampling time for the controller. % Note that the integration step size and the sampling % time are not the same. In this way we seek to simulate % the continuous time system via the Runge-Kutta method and % the discrete time controller as if it were % implemented by a digital computer. Hence, we sample % the plant output every T seconds and at that time % output a new value of the controller output.counter=10; % This counter will be used to count the number of integration % steps that have been taken in the current sampling interval. % Set it to 10 to begin so that it will compute a controller % output at the first step. % For our example, when 10 integration steps have been % taken we will then we will sample the ship heading % and the reference heading and compute a new output % for the controller. x=[0;0;0]; % First, set the state to be a vector x(1)=0; % Set the initial heading to be zerox(2)=0; % Set the initial heading rate to be zero. % We would also like to set x(3) initially but this % must be done after we have computed the output % of the controller. In this case, by % choosing the reference trajectory to be % zero at the beginning and the other initial conditions % as they are, and the controller as designed, % we will know that the output of the controller % will start out at zero so we could have set % x(3)=0 here. To keep things more general, however, % we set the intial condition immediately after % we compute the first controller output in the % loop below.% Next, we start the simulation of the system. This is the main % loop for the simulation of the control system.while t <= tstop% First, we define the reference input psi_r (desired heading).if t<100, psi_r(index)=0; end % Request heading of 0 degif t>=100, psi_r(index)=45*(pi/180); end % Request heading of 45 degif t>2000, psi_r(index)=0; end % Then request heading of 0 deg%if t>4000, psi_r(index)=45*(pi/180); end % Then request heading of 45 deg%if t>6000, psi_r(index)=0; end % Then request heading of 0 deg%if t>8000, psi_r(index)=45*(pi/180); end % Then request heading of 45 deg%if t>10000, psi_r(index)=0; end % Then request heading of 0 deg%if t>12000, psi_r(index)=45*(pi/180); end % Then request heading of 45 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);s(index)=0; % This allows us to remove the noise.psi(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% Multilayer perceptron controller calculations:e(index)=psi_r(index)-psi(index); % Computes error (first layer of perceptron)xbar1(index)=b12+w112*e(index); % Compute inputs to activation functions in second hidden layerxbar2(index)=b22+w122*e(index);x11(index)=1/(1+exp(-xbar1(index))); % Compute output of activation functionsx21(index)=1/(1+exp(-xbar2(index)));delta(index)=(b13+w113*x11(index)+b23+w223*x21(index)); % Compute second hidden layer and output layer%% A conventinal proportional controller:%delta(index)=-e(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 neural 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); delta(index)=delta(index-1);end % This is the end statement for the "if counter=10" statement% 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, 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.%% First, we convert from rad. to degreespsi_r=psi_r*(180/pi);psi=psi*(180/pi);delta=delta*(180/pi);e=e*(180/pi);% Next, we provide plots of data from the simulationfigure(1)clfsubplot(311)plot(time,psi,'k-',time,psi_r,'k--')grid ontitle('Ship heading (solid) and desired ship heading (dashed), deg.')subplot(312)plot(time,e,'k-')grid ontitle('Ship heading error between ship heading and desired heading, deg.')subplot(313)plot(time,delta,'k-')grid onxlabel('Time (sec)')title('Rudder angle (\delta), deg.')zoom%end % 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 neural 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 neural \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 neural controller inputs e_input=(-pi/2):(pi/2)/100:(pi/2); % Next, compute the neural controller output for all these inputsfor jj=1:length(e_input) xbar1t(jj)=b12+w112*e_input(jj); xbar2t(jj)=b22+w122*e_input(jj); x11t(jj)=1/(1+exp(-xbar1t(jj))); x21t(jj)=1/(1+exp(-xbar2t(jj))); delta_output(jj)=b13+w113*x11t(jj)+b23+w223*x21t(jj); delta_output1(jj)=b13+w113*x11t(jj); % This line used to show only one path in the network delta_output2(jj)=b23+w223*x21t(jj); % This is used to show the second pathend% Convert from radians to degrees:delta_output=delta_output*(180/pi);e_input=e_input*(180/pi);delta_output1=delta_output1*(180/pi);delta_output2=delta_output2*(180/pi);figure(2)clf% Plot the two paths (from error to output)subplot(311)plot(e_input,delta_output1)gridylabel('Output (\delta), deg.')title('Top path multilayer perceptron mapping between error input and output')axis([min(e_input) max(e_input) -80 80])subplot(312)plot(e_input,delta_output2)gridylabel('Output (\delta), deg.')title('Bottom path multilayer perceptron mapping between error input and output')axis([min(e_input) max(e_input) -80 80])% Plot the controller map from error to deltasubplot(313)plot(e_input,delta_output)gridxlabel('Heading error (e), deg.')ylabel('Output (\delta), deg.')title('Multilayer perceptron mapping between error input and output')axis([min(e_input) max(e_input) -80 80])%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Next, plot the two-dimensional surface of the multilayer perceptron:psi_r_input=(-pi/2):(pi/2)/50:(pi/2); psi_input=(-pi/2):(pi/2)/50:(pi/2); % Next, compute the neural controller output for all these inputsfor jj=1:length(psi_r_input) for ii=1:length(psi_input) e_input2(ii,jj)=psi_r_input(jj)-psi_input(ii); xbar1t2(ii,jj)=b12+w112*e_input2(ii,jj); xbar2t2(ii,jj)=b22+w122*e_input2(ii,jj); x11t2(ii,jj)=1/(1+exp(-xbar1t2(ii,jj))); x21t2(ii,jj)=1/(1+exp(-xbar2t2(ii,jj))); delta_outputt(ii,jj)=b13+w113*x11t2(ii,jj)+b23+w223*x21t2(ii,jj); endend% Convert from radians to degrees:delta_outputt=delta_outputt*(180/pi);psi_r_input=psi_r_input*(180/pi);psi_input=psi_input*(180/pi);% Plot the controller mapfigure(3)clfsurf(psi_r_input,psi_input,delta_outputt);view(30,30)colormap(white);xlabel('Reference input (\psi_r), deg.');ylabel('Heading angle (\psi), deg.');zlabel('Controller output (\delta), deg.');title('Multilayer perceptron controller mapping between inputs and output');%end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -