Sistemas de circuito cerrado - discrepancia entre Simulink y Arduino

1

Estoy tratando de descubrir cómo reproducir sistemas de circuito cerrado en Arduino que fueron diseñados inicialmente en Simulink.

Tome el siguiente sistema de circuito cerrado con retroalimentación de unidad y ganancia:

DondeGp(z)esunafuncióndetransferenciadiscreta,quetomalaformade:

\$Gp(z)=\frac{0.1288z-0.06234}{z^2-0.7813z+0.1817}\$

ElsistemadecircuitocerradosereplicóenArduinoconelsiguientecódigo:

intiteration(0);doubley(0),e(0);doubleGp_y_0(0),Gp_y_1(0),Gp_y_2(0),Gp_x_0(0),Gp_x_1(0),Gp_x_2(0);voidsetup(){Serial.begin(115200);}doubleGp_z(doubleGp_x_0){Gp_y_0=(0.128767938742003*Gp_x_1)+(-0.062336933973903*Gp_x_2)-(-0.781272292546052*Gp_y_1)-(0.181746970098960*Gp_y_2);Gp_x_2=Gp_x_1;Gp_x_1=Gp_x_0;Gp_y_2=Gp_y_1;Gp_y_1=Gp_y_0;returnGp_y_0;}voidloop(){delay(500);e=20.0-y;y=Gp_z(e);Serial.print(iteration);Serial.print('\t');Serial.print(e,9);Serial.print('\t');Serial.print(y,9);Serial.println();iteration++;}

Laplanta,Gp,seimplementacorrectamenteenArduino.Probéquesurespuestadebucleabiertoseprobóconunpasodeentrada:losvaloresadquiridoscoincidíanconMATLABcon12dígitosdeprecisión.

Sinembargo,cuandocierroelbucle,observoquedespuésdelaprimeraiteraciónlasalidaesdiferentealasalidaenSimulink.ArduinomuestramásoscilacionesenlarespuestaalescalónquelasmostradasenSimulink.Estoyconvencidodequeelrazonamientoparaestoeselordendelasoperaciones.MiobjetivoeshacercoincidirlasalidadeArduinoconlassimulacionesqueobtengodeSimulink.Parecequenopuedohacerlascoincidir.

Aquíestánlas10primerasmuestras(númerodeinteración,error,salida):

Arduino

020.0000000000.000000000120.0000000002.575358775217.4246412253.340676550316.6593234503.138910827416.8610891732.904174249517.0958257512.831139893617.1688601072.834391925717.1656080752.844978145817.1550218552.847686323917.1523136772.846717691

Simulink

020.0000000000000000117.4246412251599352.575358774840067216.9909470914473963.009052908552605317.0154834653193242.984516534680677417.0832809882711592.916719011728840517.1245892778839382.875410722116062617.1434474120396102.856552587960392717.1508198023258742.849180197674125817.1533784686048282.846621531395171917.1541676721013662.845832327898634

Almirarlosnúmeros,puedequenoparezcaunagrandiferencia,peroaldiseñaruncontrolador,esMUYimportante,casihacequelasherramientasdediseñodeSimulinkseaninútilescuandoseimplementanenArduino.

Gracias,

EDITAR:AclaracióndelafunciónGp_z()enArduino.Paraimplementarunafuncióndetransferenciadiscreta,comoGp(z)enArduino.RealicéunatransformadaZinversaenGp(z):

  1. MultiplicaGp(z)por\$\frac{z^{-2}}{z^{-2}}\$:

\$\frac{Y(z)}{X(z)}=\frac{0.1288z^{-1}-0.06234z^{-2}}{1-0.7813z^{-1}+0.1817z^{-2}}\$

  • Aísle Y (z):
  • \ $ Y (z) = X (z) 0.1288z ^ {- 1} - X (z) 0.06234z ^ {- 2} + Y (z) 0.7813z ^ {- 1} - Y (z) 0.1817z ^ {- 2} \ $

    1. Transformada Z inversa:

    \ $ y [n] = 0.1288x [n-1] - 0.06234x [n-2] + 0.7813y [n-1] - 0.1817y [n-2] \ $

    Esta fórmula se implementó en la función Gp_z ().

    ACTUALIZACIÓN: cambiando el orden de ejecución de e y y en Arduino:

    void loop() {
      delay(500);
      y = Gp_z(e);
      e = 20.0 - y;
      Serial.print(iteration); Serial.print('\t');
      Serial.print(e, 9); Serial.print('\t');
      Serial.print(y, 9); Serial.print('\t');
      Serial.println();
      iteration++;
    }
    

    Aquí está la salida resultante:

    0   20.000000000    0.000000000 
    1   20.000000000    0.000000000 
    2   17.424641225    2.575358775 
    3   16.659323450    3.340676550 
    4   16.861089173    3.138910827 
    5   17.095825751    2.904174249 
    6   17.168860107    2.831139893 
    7   17.165608075    2.834391925 
    8   17.155021855    2.844978145 
    9   17.152313677    2.847686323 
    

    Hay una iteración adicional de las condiciones iniciales y los números se ven mejor pero aún con un exceso importante en comparación con Simulink. No creo que esta sea la solución al problema.

        
    pregunta Danny Gelman

    0 respuestas

    Lea otras preguntas en las etiquetas