www.gusucode.com > ident_featured 案例代码 matlab源码程序 > ident_featured/idnlgreydemo12.m
%% Modeling an Aerodynamic Body % This example shows the grey-box modeling of a large and complex % nonlinear system. The purpose is to show the ability to use the IDNLGREY % model to estimate a large number of parameters (16) in a system having % many inputs (10) and outputs (5). The system is an aerodynamic body. We % create a model that predicts the acceleration and velocity of the body % using the measurements of its velocities (translational and angular) and % various angles related to its control surfaces. % Copyright 2005-2015 The MathWorks, Inc. %% Input-Output Data % We load the measured velocities, angles and dynamic pressure from a data % file named aerodata.mat: load(fullfile(matlabroot, 'toolbox', 'ident', 'iddemos', 'data', 'aerodata')); %% % This file contains a uniformly sampled data set with 501 samples in the % variables |u| and |y|. The sample time is 0.02 seconds. This data % set was generated from another more elaborate model of the aerodynamic % body. % % Next, we create an IDDATA object to represent and store the data: z = iddata(y, u, 0.02, 'Name', 'Data'); z.InputName = {'Aileron angle' 'Elevator angle' ... 'Rudder angle' 'Dynamic pressure' ... 'Velocity' ... 'Measured angular velocity around x-axis' ... 'Measured angular velocity around y-axis' ... 'Measured angular velocity around z-axis' ... 'Measured angle of attack' ... 'Measured angle of sideslip'}; z.InputUnit = {'rad' 'rad' 'rad' 'kg/(m*s^2)' 'm/s' ... 'rad/s' 'rad/s' 'rad/s' 'rad' 'rad'}; z.OutputName = {'V(x)' ... % Angular velocity around x-axis 'V(y)' ... % Angular velocity around y-axis 'V(z)' ... % Angular velocity around z-axis 'Accel.(y)' ... % Acceleration in y-direction 'Accel.(z)' ... % Acceleration in z-direction }; z.OutputUnit = {'rad/s' 'rad/s' 'rad/s' 'm/s^2' 'm/s^2'}; z.Tstart = 0; z.TimeUnit = 's'; %% % View the input data: figure('Name', [z.Name ': input data'],... 'DefaultAxesTitleFontSizeMultiplier',1,... 'DefaultAxesTitleFontWeight','normal',... 'Position',[50, 50, 850, 620]); for i = 1:z.Nu subplot(z.Nu/2, 2, i); plot(z.SamplingInstants, z.InputData(:,i)); title(['Input #' num2str(i) ': ' z.InputName{i}],'FontWeight','normal'); xlabel(''); axis tight; if (i > z.Nu-2) xlabel([z.Domain ' (' z.TimeUnit ')']); end end %% % *Figure 1:* Input signals. %% % View the output data: figure('Name', [z.Name ': output data']); h_gcf = gcf; Pos = h_gcf.Position; h_gcf.Position = [Pos(1), Pos(2)-Pos(4)/2, Pos(3), Pos(4)*1.5]; for i = 1:z.Ny subplot(z.Ny, 1, i); plot(z.SamplingInstants, z.OutputData(:,i)); title(['Output #' num2str(i) ': ' z.OutputName{i}]); xlabel(''); axis tight; end xlabel([z.Domain ' (' z.TimeUnit ')']); %% % *Figure 2:* Output signals. %% % At a first glance, it might look strange to have measured variants of % some of the outputs in the input vector. However, the model used for % generating the data contains several integrators, which often result in % an unstable simulation behavior. To avoid this, the measurements of some % of the output signals are fed back via a nonlinear observer. These are % the input 6 to 8 in the dataset |z|. Thus, this is a system operating in % closed loop and the goal of the modeling exercise is to predict "future" % values of those outputs using measurements of current and past behavior. %% Modeling the System % To model the dynamics of interest, we use an IDNLGREY model object to % represent a state space structure of the system. A reasonable structure % is obtained by using Newton's basic force and momentum laws (balance % equations). To completely describe the model structure, basic aerodynamic % relations (constitutive relations) are also used. %% % The C MEX-file, aero_c.c, describes the system using the state and output % equations and initial conditions, as described next. Omitting the % derivation details for the equations of motion, we only display the final % state and output equations, and observe that the structure is quite % complex as well as nonlinear. % % /* State equations. */ % void compute_dx(double *dx, double *x, double *u, double **p) % { % /* Retrieve model parameters. */ % double *F, *M, *C, *d, *A, *I, *m, *K; % F = p[0]; /* Aerodynamic force coefficient. */ % M = p[1]; /* Aerodynamic momentum coefficient. */ % C = p[2]; /* Aerodynamic compensation factor. */ % d = p[3]; /* Body diameter. */ % A = p[4]; /* Body reference area. */ % I = p[5]; /* Moment of inertia, x-y-z. */ % m = p[6]; /* Mass. */ % K = p[7]; /* Feedback gain. */ % % /* x[0]: Angular velocity around x-axis. */ % /* x[1]: Angular velocity around y-axis. */ % /* x[2]: Angular velocity around z-axis. */ % /* x[3]: Angle of attack. */ % /* x[4]: Angle of sideslip. */ % dx[0] = 1/I[0]*(d[0]*A[0]*(M[0]*x[4]+0.5*M[1]*d[0]*x[0]/u[4]+M[2]*u[0])*u[3]-(I[2]-I[1])*x[1]*x[2])+K[0]*(u[5]-x[0]); % dx[1] = 1/I[1]*(d[0]*A[0]*(M[3]*x[3]+0.5*M[4]*d[0]*x[1]/u[4]+M[5]*u[1])*u[3]-(I[0]-I[2])*x[0]*x[2])+K[0]*(u[6]-x[1]); % dx[2] = 1/I[2]*(d[0]*A[0]*(M[6]*x[4]+M[7]*x[3]*x[4]+0.5*M[8]*d[0]*x[2]/u[4]+M[9]*u[0]+M[10]*u[2])*u[3]-(I[1]-I[0])*x[0]*x[1])+K[0]*(u[7]-x[2]); % dx[3] = (-A[0]*u[3]*(F[2]*x[3]+F[3]*u[1]))/(m[0]*u[4])-x[0]*x[4]+x[1]+K[0]*(u[8]/u[4]-x[3])+C[0]*pow(x[4],2); % dx[4] = (-A[0]*u[3]*(F[0]*x[4]+F[1]*u[2]))/(m[0]*u[4])-x[2]+x[0]*x[3]+K[0]*(u[9]/u[4]-x[4]); % } %% % /* Output equations. */ % void compute_y(double *y, double *x, double *u, double **p) % { % /* Retrieve model parameters. */ % double *F, *A, *m; % F = p[0]; /* Aerodynamic force coefficient. */ % A = p[4]; /* Body reference area. */ % m = p[6]; /* Mass. */ % % /* y[0]: Angular velocity around x-axis. */ % /* y[1]: Angular velocity around y-axis. */ % /* y[2]: Angular velocity around z-axis. */ % /* y[3]: Acceleration in y-direction. */ % /* y[4]: Acceleration in z-direction. */ % y[0] = x[0]; % y[1] = x[1]; % y[2] = x[2]; % y[3] = -A[0]*u[3]*(F[0]*x[4]+F[1]*u[2])/m[0]; % y[4] = -A[0]*u[3]*(F[2]*x[3]+F[3]*u[1])/m[0]; % } %% % We must also provide initial values of the 23 parameters. We specify some % of the parameters (aerodynamic force coefficients, aerodynamic momentum % coefficients, and moment of inertia factors) as vectors in 8 different % parameter objects. The initial parameter values are obtained partly by % physical reasoning and partly by quantitative guessing. The last 4 % parameters (A, I, m and K) are more or less constants, so by fixing these % parameters we get a model structure with 16 free parameters, distributed % among parameter objects F, M, C and d. Parameters = struct('Name', ... {'Aerodynamic force coefficient' ... % F, 4-by-1 vector. 'Aerodynamic momentum coefficient' ... % M, 11-by-1 vector. 'Aerodynamic compensation factor' ... % C, scalar. 'Body diameter' ... % d, scalar. 'Body reference area' ... % A, scalar. 'Moment of inertia, x-y-z' ... % I, 3-by-1 vector. 'Mass' ... % m, scalar. 'Feedback gain'}, ... % K, scalar. 'Unit', ... {'1/(rad*m^2), 1/(rad*m^2), 1/(rad*m^2), 1/(rad*m^2)' ... ['1/rad, 1/(s*rad), 1/rad, 1/rad, ' ... '1/(s*rad), 1/rad, 1/rad, 1/rad^2, ' ... '1/(s*rad), 1/rad, 1/rad'] ... '1/(s*rad)' 'm' 'm^2' ... 'kg*m^2, kg*m^2,kg*m^2' 'kg' '-'}, ... 'Value', ... {[20.0; -6.0; 35.0; 13.0] ... [-1.0; 15; 3.0; -16.0; -1800; -50; 23.0; -200; -2000; -17.0; -50.0] ... -5.0, 0.17, 0.0227 ... [0.5; 110; 110] 107 6}, ... 'Minimum',... {-Inf(4, 1) -Inf(11, 1) -Inf -Inf -Inf -Inf(3, 1) -Inf -Inf}, ... % Ignore constraints. 'Maximum', ... {Inf(4, 1) Inf(11, 1) Inf Inf Inf Inf(3, 1) Inf Inf}, ... % Ignore constraints. 'Fixed', ... {false(4, 1) false(11, 1) false true true true(3, 1) true true}); %% % We also define the 5 states of the model structure in the same % manner: InitialStates = struct('Name', {'Angular velocity around x-axis' ... 'Angular velocity around y-axis' ... 'Angular velocity around z-axis' ... 'Angle of attack' 'Angle of sideslip'}, ... 'Unit', {'rad/s' 'rad/s' 'rad/s' 'rad' 'rad'}, ... 'Value', {0 0 0 0 0}, ... 'Minimum', {-Inf -Inf -Inf -Inf -Inf},... % Ignore constraints. 'Maximum', {Inf Inf Inf Inf Inf},... % Ignore constraints. 'Fixed', {true true true true true}); %% % The model file along with order, parameter and initial states data are % now used to create an IDNLGREY object describing the system: FileName = 'aero_c'; % File describing the model structure. Order = [5 10 5]; % Model orders [ny nu nx]. Ts = 0; % Time-continuous system. nlgr = idnlgrey(FileName, Order, Parameters, InitialStates, Ts, ... 'Name', 'Model', 'TimeUnit', 's'); %% % Next, we use data from the IDDATA object to specify the input and output % signals of the system: nlgr.InputName = z.InputName; nlgr.InputUnit = z.InputUnit; nlgr.OutputName = z.OutputName; nlgr.OutputUnit = z.OutputUnit; %% % Thus, we have an IDNLGREY object with 10 input signals, 5 states, and % 5 output signals. As mentioned previously, the model also contains 23 % parameters, 7 of which are fixed and 16 of which are free: nlgr %% Performance of the Initial Model % Before estimating the 16 free parameters, we simulate the system using % the initial parameter vector. Simulation provides useful information % about the quality of the initial model: clf compare(z, nlgr); % simulate the model and compare the response to measured values %% % *Figure 3:* Comparison between measured outputs and the simulated outputs % of the initial model. %% % From the plot, we see that the measured and simulated signals match each % other closely except for the time span 4 to 6 seconds. This fact is % clearly revealed in a plot of the prediction errors: figure; h_gcf = gcf; Pos = h_gcf.Position; h_gcf.Position = [Pos(1), Pos(2)-Pos(4)/2, Pos(3), Pos(4)*1.5]; pe(z, nlgr); %% % *Figure 4:* Prediction errors of the initial model. %% Parameter Estimation % The initial model as defined above is a plausible starting point for % parameter estimation. Next, we compute the prediction error estimate of % the 16 free parameters. This computation will take some time. duration = clock; nlgr = nlgreyest(z, nlgr, nlgreyestOptions('Display', 'on')); duration = etime(clock, duration); %% Performance of the Estimated Aerodynamic Body Model % On the computer used, estimation of the parameters took the following % amount of time to complete: disp(['Estimation time : ' num2str(duration, 4) ' seconds']); disp(['Time per iteration: ' num2str(duration/nlgr.Report.Termination.Iterations, 4) ' seconds.']); %% % To evaluate the quality of the estimated model and to illustrate the % improvement compared to the initial model, we simulate the estimated % model and compare the measured and simulated outputs: clf compare(z, nlgr); %% % *Figure 5:* Comparison between measured outputs and the simulated outputs % of the estimated model. %% % The figure clearly indicates the improvement compared to the simulation % result obtained with the initial model. The system dynamics in the time % span 4 to 6 seconds is now captured with much higher accuracy than % before. This is best displayed by looking at the prediction errors: figure; h_gcf = gcf; Pos = h_gcf.Position; h_gcf.Position = [Pos(1), Pos(2)-Pos(4)/2, Pos(3), Pos(4)*1.5]; pe(z, nlgr); %% % *Figure 6:* Prediction errors of the estimated model. %% % Let us conclude the case study by displaying the model and the % estimated uncertainty: present(nlgr); %% Concluding Remarks % The estimated model is a good starting point for investigating the % fundamental performance of different control strategies. High-fidelity % models that preferably have a physical interpretation are, for example, % vital components of so-called "model predictive control systems". %% Additional Information % For more information on identifying dynamic systems with System % Identification Toolbox(TM), see the % <http://www.mathworks.com/products/sysid/ System Identification Toolbox> % product page.