%
% ESE - stima dei parametri di un sistema meccanico con il PEM:
%
% - consideriamo il sistema con le tre masse visto durante il corso e costruiamo il relativo modello state-space,
%   supponendo sia sottoposto ad un solo ingresso e si possa misurare una sola uscita.
% - facciamo una simulazione del modello, dando un segnale arbitrario in ingresso; 
%   consideriamo i dati prodotti dalla simulazione come fossero dati sperimentali sul sistema vero.
% - supponiamo che uno dei parametri fisici del sistema sia ignoto (es. la
%   massa M1) e cerchiamo di stimarne il valore, partendo da un'ipotesi
%   iniziale che può essere ad esempio un valore arbitrario, utilizzando:
%     - la struttura (nota) del modello di riferimento, rappresentata in forma state-space;
%     - i valori dei parametri fisici noti;
%     - l'algoritmo PEM.
% 
% NOTE:
% - il parametro incognito deve diventare una variabile, in modo da poter
%   ri-costruire il modello di simulazione ad ogni approssimazione successiva
%   del suo valore; supponiamo che i parametri ignoti stiano in un vettore
%   "e_coeff" (qui di lunghezza==1).
%

Ts = 0.0002;
dpt=???; max_iter=???; iter=0;
N=20; lbuf_perr=N;
range_Itheta=1;
perc_VN=???;
load=sin((1:N)*8*pi/N);
delta_coeff=inf;
e_coeff=10;
disp(['[0] m_est=',num2str(e_coeff)]);
%
% genero i dati "sperimentali":
[A,B,C,D] = build_sistema_meccanico_3gdl();
dati_sperim=simula_sistema_meccanico_3gdl(A,B,C,D,load,Ts);


while iter<max_iter & abs(delta_coeff)>0.1
  iter=iter+1;
  [A,B,C,D]=build_sistema_meccanico_3gdl(e_coeff);
  perr_temp=simula_sistema_meccanico_3gdl(A,B,C,D,load,Ts)-dati_sperim;
  VN_temp = (1/lbuf_perr) * sum(perr_temp.^2);
  psi_temp = [];
  for Itheta_temp = range_Itheta
    %
    store_coeff = e_coeff(Itheta_temp);
    e_coeff(Itheta_temp) = e_coeff(Itheta_temp)*(1-dpt/2);
    [A,B,C,D,Ts]=build_???;
    ypred1=simula_???;
    e_coeff(Itheta_temp) = store_coeff;
    %
    store_coeff = e_coeff(Itheta_temp);
    ???
    e_coeff(Itheta_temp) = store_coeff;
    %
    psi_temp = [psi_temp; ???];
  end;
  VNder_temp = (2/lbuf_perr) * sum( psi_temp .* perr_temp );
  VNder2_temp = (2/lbuf_perr) * sum( psi_temp .* psi_temp);
  delta_theta_temp = VNder2_temp \ VNder_temp;
  %
  %  scelta adattativa di "mu" :
  %
  mu_temp = 1.0;
  tempVN_temp = VN_temp;
  store_coeff = e_coeff(Itheta_temp);
  delta_coeff = 0;
  while (tempVN_temp >= VN_temp*(1-perc_VN))  &  (mu_temp > 0) & (abs(delta_theta_temp) > 0)
    e_coeff(Itheta_temp) = store_coeff;
    delta_coeff = - mu_temp * delta_theta_temp;
    e_coeff(Itheta_temp) = e_coeff(Itheta_temp) + delta_coeff;   % metodo di Newton
    [A,B,C,D,Ts]=build_sistema_meccanico_3gdl(e_coeff(Itheta_temp));
    perr_temp2=simula_sistema_meccanico_3gdl(A,B,C,D,load,Ts)-dati_sperim;
    tempVN_temp = (1/lbuf_perr) * sum(perr_temp2.^2);
    if mu_temp > 1e-3
      mu_temp = ???;
    else
      mu_temp = 0;
    end
  end
  disp(['[',num2str(iter),'] m_est=',num2str(e_coeff)]);
end

