IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème conversion code Scilab en C


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2019
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2019
    Messages : 36
    Par défaut Problème conversion code Scilab en C
    Bonjour,

    J’essaie de convertir ce programme scilab qui effectue une simulation de régulation et qui fonctionne:
    Code Scilab : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // essai MPC kindergarten ordre 1 ave perturbatio,
     
    clear; xdel(winsid());
    tf= 1500; w=1:1:tf; // uuree
    tech=1;
    // nitialisation
    u=zeros(1,tf);
    MV=u; CV=u; sm=u; DV=u; SP=u; r=200;
    // odele et process
    taum=35; am=exp(-tech/taum); bm=1-am; Km=1.7; // modele
    taup=35; ap=exp(-tech/taup); bp=1-ap; Kp=1.7; // process
    // acteur essentielle de reglage temps de reponse desire boucle ferme
    TRBF=45; lh=1-exp(-tech*3/TRBF); 
    //
    for ii=2+r:1:tf
        if ii<700 then DV(ii)=0; else DV(ii)=20; end; // erturbation
        SP(ii)=100; // consigne
        CV(ii)=ap*CV(ii-1)+bp*(Kp*MV(ii-1-r)+DV(ii)); // process
        sm(ii)=am*sm(ii-1)+bm*Km*MV(ii-1); // modele
        spred=CV(ii)+(sm(ii)-sm(ii-r))*1; // prediction
        d=(SP(ii)-spred)*lh+sm(ii)*bm;
        MV(ii)=d/(Km*bm); // ariable manipule
        // limites physique systeme
        if MV(ii)>70 then MV(ii)=70; end;
        if MV(ii)>MV(ii-1)+4 then MV(ii)=MV(ii-1)+4; end;
        if MV(ii)<MV(ii-1)-4 then MV(ii)=MV(ii-1)-4; end;
    end
    //
    scf(0);
    plot(w,MV,"b",w,CV,"r",w,SP,"k",w,DV,"m");
    a=gca(); a.grid=[1,1]; a.tight_limits="on"; a.data_bounds=[1,0;1500,150];
    xlabel("sec");
    title("MV bleu, CV rouge consigne noir, DV m, R=200 !, limites: abs=60 / itesse=4");

    en un programme en C. J’ai essayé de séparer la partie simulation du régulateur car maintenant que je l’ai testé en simulation, j’aimerai l’utiliser pour des applications réelles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    float PFC(int,int,int,float,float,float,float *);
     
    int main(void)
    {
      float sortie_precedente[200];//buffer= r*tech
      float SP=100;
      int tech=1;
      int trbf=45;
      int i=0;//variable de gestion de tableau
     
      //Simulation processus
      int t=0;//variable simulation temps
      //process
      int taup=35;
      float ap=exp(-tech/taup);
      float bp=1-ap;
      float Kp=1.7;
      int r=200;
      float PV[1500];
      float MV[1500];
     
      //initialisation tableau de sortie_modele sortie_precedente
      for (i=0;i<200;i++)
      {
        sortie_precedente[i]=0;
      }
     
      //initialisation PV
      for (i=0;i<200;i++)
      {
        PV[i]=0;
      }
     
      //initialisation MV
      for (i=0;i<200;i++)
      {
        MV[i]=0;
      }
     
      //Simulation regulation processus
      for(t=(2+r);t<=1500;t++)
      {
        PV[t]=ap*PV[t-1]+bp*(Kp*MV[t-1-r]); // process
        MV[t]=PFC(tech,trbf,r,PV[t],SP,MV[t-1],sortie_precedente);
      }
     
      //Affichage de quelques valeurs pour comparer avec simulation scilab
      for(i=0;i<1500;i+=100)
      {
        printf("PV[%d] = %f \n",i,PV[i]);
      }
      return 0;
    }
    float PFC(int tech,int trbf,int retard,float PV,float SP,float MV_1,float *sortie_precedente)
    {
     
      //initialisation variables
      int i=0;//Variable de gestion du tableau
      int temps=0;
      float d,MV,sm,spred=0;
      float taum=30.0;
      float km=1.0;
      float sm_r=0;
     
      //Paramètres du modèle
      float am=exp(-tech/taum);
      float bm=1-am;
      float lh=1-exp(-tech*3/trbf);
     
      //sortie modèle
      sm=am*sortie_precedente[0]+MV_1*bm*km;
     
      // prediction
      spred=PV+(sm-sortie_precedente[retard-1])*1;
     
      //Calcul de la MV
      d=(SP-spred)*lh+sm*bm;
      MV=d/(km*bm);
     
      //Mise a jour du buffer sortie_precedente
      for(i=199;i>0;i--)
      {
          sortie_precedente[i]=sortie_precedente[i-1];
      }
      sortie_precedente[0]=sm;
     
     
      //Contraintes liés à la vitesse réelle de l'actionneur
      if (MV>(MV_1+4))
      {
        MV=MV_1+4;
      }
      if (MV<(MV_1-4))
      {
        MV=MV_1-4;
      }
     
      return MV;
    }
    Malheureusement la sortie PV qui correspond à la variable à réguler reste à 0. Sauriez vous ce que j’ai fait de mal ?

    Merci d’avance pour votre aide

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Dès la ligne 19 : float ap=exp(-tech/taup); va calculer float ap=exp(-1/35);, mais 1/35 c'est 0. d'où ap vaut 1.0f.
    Il faut écrire float ap = exp( -(double)tech / taup ); pour forcer un calcul flottant.
    Peut-être y a-t-il d'autre problème plus loin.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2019
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2019
    Messages : 36
    Par défaut
    Bonjour,
    Merci pour votre aide, j'ai remplacer les types int posant problème par des flottants.
    J'ai aussi remplacer l'initialisation de PV et MV à 0 par une initialisation à 20.
    Le résultat varie maintenant mais n'est toujours pas bon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    PV[0] = 20.000000 
    PV[100] = 20.000000 
    PV[200] = 0.000000 
    PV[300] = 31.990671 
    PV[400] = 33.884636 
    PV[500] = 1.946083 
    PV[600] = 0.111769 
    PV[700] = 0.006419 
    PV[800] = 0.000369 
    PV[900] = 0.000021 
    PV[1000] = 0.000001 
    PV[1100] = 0.000000 
    PV[1200] = 0.000000 
    PV[1300] = 0.000000 
    PV[1400] = 0.000000
    Je pense qu'il doit y avoir une erreur dans le buffer sortie_precedente, je vais y jeter un oeil.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2019
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2019
    Messages : 36
    Par défaut
    Bonjour,
    J'ai trouvé la dernière erreur, il s'agissait du même problème que celui que vous aviez repéré, j'avais remplacé tous les types dans le main mais j'avais laissé les types en int dans la fonction PFC.
    En changeant cela, le problème a été résolu.

    Merci beaucoup pour votre aide

  5. #5
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,
    Citation Envoyé par Asterix20 Voir le message
    Bonjour,
    Merci pour votre aide, j'ai remplacer les types int posant problème par des flottants.
    J'ai aussi remplacer l'initialisation de PV et MV à 0 par une initialisation à 20.
    Le résultat varie maintenant mais n'est toujours pas bon:
    Peut-être qu'il est préférable de remplacer les float par des double, car certaines fonctions utilisées ici renvoient des doubles et non float exemple: double exp(double x); pour des variable double et float expf(float x); pour des variables float et long double expl(long double x); pour des variable long double sans oublier que les variables sm_r et temps ne sont pas utilisés et ne serve pas dans le cas actuel sauf s'ils ont une utilité future.

    à bientôt

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/11/2017, 12h56
  2. Problème conversion float vers double
    Par jhenaff dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/01/2006, 10h39
  3. Problème de code besoin d un petit depannage
    Par rakengoule dans le forum MFC
    Réponses: 3
    Dernier message: 10/10/2005, 16h25
  4. Probléme de code non portable
    Par Stany dans le forum Windows
    Réponses: 2
    Dernier message: 23/08/2005, 11h02
  5. Problème conversion date
    Par mat.M dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 30/03/2004, 15h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo