Découvrez notre Chaîne YouTube "Devenir Ingénieur"

Objectifs

  1. Implémentation d’un système du 2nd ordre: y(n)=> {x(n-1), y(n-1), y(n-2)}
  2. Définition de la fonction Sys2()
  3. La réponse indicielle d’un système en 2nd ordre
  4. Etc.

Paramètre du système du second ordre

#define   Fn      10.00

#define   Zeta    0.2

#define   K       1.0

#define   T_ms    10  // 100 Hz

Paramètres de l’échelon

#define   A_step  5.0 // Amplitude

#define   c_step  200  // Période = 2*c_step*T_ms

Génération de l’entrée x(n) d’amplitude A_step

  c++; c=c%c_step;

  if(!c)

  {

    Step=!Step;

    c=0;

  }

  x_nn=A_step*(double)Step;

Calcul de la sortie

  y_nn=Sys2(x_nn, 0.1, Wn, K, T_s);

Affichage de l’entrée x(n) et la sortie y(n)

  Serial.print(x_nn); Serial.print(",");

  Serial.println(y_nn); 

La fonction Sys2()

La fonction Sys2() permet de calculer la sortie y(n) en fonction de l’entrée x(n) d’un système du second ordre ne boucle ouverte. Elle prend en entrée l’échantillon actuel d l’entrée x(n), la coefficient d’amortissement zêta, la pulsation normale wn, le gain statique k et la période d’échantillonnage T en seconde. Puis elle retourne la sortie y(n). Ci-dessous la définition de la fonction.

double Sys2(double x_nn, double zeta, double wn, double k, double T)

{

  // Paramètre du système

  double a1=2.0*zeta/wn;

  double a2=1.0/(wn*wn);




  const double b0=(a1/(2.0*T))+(a2/(T*T));

  const double b1=-2.0*a2/(T*T);

  const double b2=(-1.0*a1/(2.0*T))+(a2/(T*T));

  const double b[3]={b0,b1,b2};




  // Variables de l'entrée et la sortie

  static double y[2];

  static double x;

  double y_nn=0.0;




  // Calcul de la nouvelle sortie

  y_nn= -(y[0]*(1.0+b[1]))-(y[1]*b[2])+(k*x); // y[1]: y(n-2), y[0]: y(n-1)

  y_nn/=b[0];




  // Mise à jour de la sortie

  y[1]=y[0];

  y[0]=y_nn;




  // Mise à jour de l'entrée

  x=x_nn;




  // Renvoie du résultat

  return y_nn;

}

Le programme complet


/*
               -------------
               -           -
 x(n) ----------   SYS2    ---------- y(n)  
               -           -
               -------------
              
 * 1. Implémentation d'un système du 2nd ordre  
 *    y(n)=> {x(n-1), y(n-1), y(n-2)} 
 * 2. Définition de la fonction Sys2()
 * 3. La réponse indicielle d'un système en 2nd ordre 
 * 4. Etc.
 * 
*/

 
#define   Fn      10.00
#define   Zeta    0.2
#define   K       1.0
#define   T_ms    10  // 100 Hz 

#define   A_step  5.0 // Amplitude
#define   c_step  200  // Période = 2*c_step*T_ms

double Wn=2.0*PI*Fn;
double T_s=(double)T_ms/1000.0;
double x_nn=0.0,y_nn=0.0; 


// Paramètres de l'échelon
unsigned long c=0; // Compteur (période)  
bool Step=false; 


void setup()
{
  // Port série de la réponse du système 
  Serial.begin(9600); 
}

void loop()
{ 
  // Le signal échelon x(n) => [0, A_step]
  c++; c=c%c_step; 
  if(!c) 
  {
    Step=!Step;
    c=0; 
  }
  x_nn=A_step*(double)Step; 
  
  // Calcul de la sortie  
  y_nn=Sys2(x_nn, 0.1, Wn, K, T_s);

  // Affichage x(n)/y(n)
  Serial.print(x_nn); Serial.print(","); 
  Serial.println(y_nn);  

  // Période d'échantillonnage 
  delay(T_ms);
}



double Sys2(double x_nn, double zeta, double wn, double k, double T)
{
  // Paramètre du système 
  double a1=2.0*zeta/wn;
  double a2=1.0/(wn*wn);

  const double b0=(a1/(2.0*T))+(a2/(T*T)); 
  const double b1=-2.0*a2/(T*T); 
  const double b2=(-1.0*a1/(2.0*T))+(a2/(T*T)); 
  const double b[3]={b0,b1,b2};

  // Variables de l'entrée et la sortie 
  static double y[2]; 
  static double x; 
  double y_nn=0.0;
  
  // Calcul de la nouvelle sortie 
  y_nn= -(y[0]*(1.0+b[1]))-(y[1]*b[2])+(k*x); // y[1]: y(n-2), y[0]: y(n-1)
  y_nn/=b[0];
  
  
  // Mise à jour de la sortie  
  y[1]=y[0];
  y[0]=y_nn;
  

  // Mise à jour de l'entrée
  x=x_nn; 
  
  // Renvoie du résultat 
  return y_nn;
}

Accueil Asservissement avec Arduino

Click to rate this post!
[Total: 2 Average: 5]

2 commentaires

  • JP-SU · 2021-06-02 à 1:26

    Bonjour
    Très bien ce programme, juste une petite erreur : vous appelez la fonction Sys2 avec 0.1 au lieu de mettre la variable Zeta (qui est définie à 0.2), du coup lorsque l’on change la valeur de Zeta au début du programme pour faire une petite étude paramétrique, cela ne change rien à la sortie.
    En tout cas j’aime bien ce que vous faites, merci.

      admin · 2021-06-03 à 9:32

      Merci pour la remarque!

  • Répondre à JP-SU Annuler la réponse

    Avatar placeholder

    Votre adresse e-mail ne sera pas publiée.

    Anti-Robot *

    You have successfully subscribed to the newsletter

    There was an error while trying to send your request. Please try again.

    FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.