function [y,u,t,p,UU,t_open,t_ppp,t_est,its_ppp,its_est] = ppp_nlin_run(system_name,i_ppp,i_par,A_u,w_s,N_ol,Q,extras) ## usage: [y,u,t,p,U,t_open,t_ppp,t_est,its_ppp,its_est] = ## ppp_nlin_run (system_name,i_ppp,i_par,A_u,w_s,N_ol[,extras]) ## ## y,u,t System output, input and corresponding time p ## Estimated parameters U PPP weight vector t_open The ## open-loop interval t_ppp Time for each ppp optimisation t_est ## Time for each estimation i_ppp Matrix of ppp gain indices: col. ## 1 Gain indices in sensitivity system col. 2 Gain sensitivity ## indices in sensitivity system col. 3 Gain indices in system ## i_par Matrix of indices of estimated parameters col. 1 Parameter ## indices in sensitivity system col. 2 Parameter sensitivity ## indices in sensitivity system col. 3 Parameter indices in system ## A_u Basis function generating matrix w_s w_star: That part ## of the moving horizon setpoint within the optimisation horizon. ## N_ol The number of open-loop intervals to be computed extras ## Extra parameters in a structure: extras.alpha ?? ## extras.criterion Optimisation convergence criterion ## extras.emulate_timing Simulate some real-time features ## extras.estimate Estimate parameters and states ## extras.max_iterations Maximum optimisation iterations ## extras.simulate 1 for simulation (not real-time) extras.vInitial Levenberg-Marquardt parameter ## extras.verbose 1 for extra info display ## ## Real-time implementatipn of nonlinear PPP Copyright (C) 2001,2002 ## by Peter J. Gawthrop ## Globals to pass details to simulation global system_name_sim i_ppp_sim x_0_sim y_sim u_sim A_u_sim simpar_sim ## Defaults if nargin<8 extras.alpha = 0.1; extras.criterion = 1e-5; extras.emulate_timing = 0; extras.max_iterations = 10; extras.simulate = 1; extras.v = 1e-5; extras.verbose = 0; extras.visual = 0; endif ##Estimate if we have some adjustable parameters estimating_parameters = (length(i_par)>0); ## Names s_system_name = sprintf("s%s", system_name); ## System details -- defines simulation within ol interval par = eval(sprintf("%s_numpar;", system_name)); simpar = eval(sprintf("%s_simpar;", system_name)); dt = simpar.dt; # Sample interval simpar_est = simpar; # Initial estimation simulation params simpar_model = simpar; # Initial internal model simulation params simpar_pred = simpar; # Initial prediction simulation params T_ol_0 = simpar.last; # The initial specified interval n_t = round(simpar.last/simpar.dt); # Corresponding length x_0 = eval(sprintf("%s_state(par);", system_name)); x_0_model = x_0; [n_x,n_y,n_u] = eval(sprintf("%s_def;", system_name)); if nargin<8 Q = ones(n_y,1); endif ## Sensitivity system details -- defines moving horizon simulation simpars = eval(sprintf("%s_simpar;", s_system_name)); pars = eval(sprintf("%s_numpar;", s_system_name)); x_0s = eval(sprintf("%s_state(pars);", s_system_name)); x_0_models = x_0s; ## Times ## -- within opt horizon n_Tau = round(simpars.last/simpars.dt); dtau = simpars.dt; Tau = [0:n_Tau-1]'*dtau; [n_tau,n_w] = size(w_s); tau = Tau(n_Tau-n_tau+1:n_Tau); w = w_s(n_tau,:); # Final value of setpoint ## Main simulation loop y = []; x = []; u = []; t = []; p = []; t_last = 0; UU = []; UU_l =[]; UU_c =[]; t_ppp = []; t_est = []; its_ppp = []; its_est = []; t_open = []; x_nexts = zeros(2*n_x,1); ## Initial U is zero [n_U,junk] = size(A_u); U = zeros(n_U,1); ## Create input basis functions u_star_tau = ppp_ustar(A_u,1,Tau',0,0,n_u-n_U); ## Reverse time to get "previous" U U_old = U; if (extras.simulate==1) ## Set up globals for simulation system_name_sim = system_name; i_ppp_sim = i_ppp; x_0_sim = x_0; y_sim = []; # Junk u_sim = []; # Junk A_u_sim = A_u; simpar_sim = simpar; T_total = simpar.last; endif for i = 0:N_ol # Main loop printf("%i",i); if (extras.simulate==1) [y_ol,u_ol] = ppp_RT_sim(U); # Simulate else [y_ol,u_ol] = ppp_RT(U); # Real thing endif t_start = time; # Initialise time if (i==0) # Data is rubbish at i=0 - ignore usleep(T_ol_0*1e6); # Hang about else ## Set up time information for the gathered data n_ol = length(y_ol); # How many data points? t_ol = [0:n_ol-1]'*dt; T_ol = n_ol*dt; # Length of ol interval t_open = [t_open;T_ol]; ## Generate input to actual system u_star_t = ppp_ustar(A_u,1,t_ol',0,0,n_u-n_U); ## Tune parameters/states if (estimating_parameters==1) ## Save up the estimated parameters par_est = pars(i_par(:,1)); p = [p; par_est']; ## Set up according to interval length if (T_ol>T_ol_0) ## Truncate data simpar_est.last = T_ol_0; y_est = y_ol(1:n_t+1,:); else simpar_est.last = T_ol; y_est = y_ol; endif simpar_pred.last = T_ol_0; # Predicted length of next interval pars(i_ppp(:,1)) = U_old; # Update the simulation ppp weights ## Optimise tick = time; [pars,Par,Error,Y,its] = \ ppp_optimise(s_system_name,x_0_models,pars,simpar_est,u_star_t,y_est,i_par,extras); if extras.visual figure(11); title("Parameter optimisation"); II = [1:length(y_est)]; plot(II,y_est,"*", II,Y); endif est_time = time-tick; t_est = [t_est;est_time]; its_est = [its_est; its-1]; endif ## Update internal model par(i_ppp(:,3)) = U_old; # Update the internal model ppp weights if (estimating_parameters==1) par(i_par(:,3)) = pars(i_par(:,1)); # Update the internal model params endif simpar_model.last = T_ol; [y_model,x_model] = eval(sprintf("%s_sim(x_0_model, par, simpar_model, \ u_star_t);",system_name)); x_0 = x_model(n_ol+1,:)'; # Initial state of next interval ## x_0 = x_model(n_ol-1,:)'; # Initial state of next interval x_0_model = x_0; x_0_models(1:2:(2*n_x)-1) = x_0_model; ## Compute U by optimisation tick = time; ## Predict state at start of next interval par(i_ppp(:,3)) = U; [y_next,x_next] = eval(sprintf("%s_sim(x_0, par, simpar, \ u_star_t);",system_name)); x_next = x_next(n_t+1,:)'; # Initial state for next time x_nexts(1:2:(2*n_x)-1) = x_next; # And for internal sensitivity model ## Optimize for next interval U_old = U; # Save previous value U = expm(A_u*T_ol)*U; # Initialise from continuation trajectory pars(i_ppp(:,1)) = U; # Put initial value of U into the parameter vector [U, U_all, Error, Y, its] = ppp_nlin(system_name,x_nexts,pars,simpars,u_star_tau,w_s,i_ppp,Q,extras); if extras.visual figure(12); title("PPP optimisation"); II = [1:length(w_s)]; plot(II,w_s,"*", II,Y); figure(1); endif ppp_time = time-tick; t_ppp = [t_ppp;ppp_time]; its_ppp = [its_ppp; its-1]; ## Total execution time T_total = time - t_start; if (extras.simulate==1)&&(extras.emulate_timing!=1) printf("."); T_diff = 0; # Always correct interval else T_diff = T_total - T_ol_0; # Compute difference if T_diff<0 printf("-"); usleep(-T_diff*1e6); T_total = time - t_start; else printf("+"); endif printf("%2.2f",T_total); endif T_total = simpar.dt*round(T_total/simpar.dt); # Whole no. of intervals pars(i_ppp(:,1)) = U; # Put final value of U into the parameter vector ## Save up data y_ol = y_ol(1:n_ol,:); y = [y; y_ol]; u = [u; u_ol]; UU = [UU; U']; t = [t; t_ol+t_last*ones(n_ol,1) ]; t_last = t_last + T_ol; endif if (extras.simulate==1) # Do the actual simulation if (extras.emulate_timing==1) # Emulate timing simpar_sim.last = T_total; # simulate for actual execution time endif ppp_RT_sim_compute (U_old); endif endfor printf("\n"); endfunction