Projet

Général

Profil

Asservissement » Historique » Version 1

Anonyme, 08/12/2015 16:47

1 1 Anonyme
h1. Asservissement
2
3
<pre>
4
5
/*
6
Travail du Club Robot de l'école Centrale Marseille
7
****************************************************************************************
8
Programme d'asservissement de moteurs
9
Version du 07/12/2015
10
11
Définition des constantes:
12
13
Constantes Physiques*/
14
float const d=10;//distance entre les roues en cm
15
float const Vmax=12.5;//vitesse max en cm/s
16
float const conversion=0.0486; //permet de transformer le nombre de ticks en vitesse par seconde
17
18
/* Définition des constantes pour la correction */
19
float const decalage=1;//le compteur G délivre moins de ticks que le droit pour une même vitesse
20
float const correctionRegulationMAv=251.0/200.0;//compense l'erreur de régulation en marche avant - Moteur Gauche trop rapide
21
float const correctionRegulationMAr=233.0/200.0;//compense l'erreur de régulation en marche arrière - Moteur gauche trop rapide
22
float const KiG=2.0;// correcteur intégrale du moteur gauche
23
float const KpG=18.0;// correcteur proportionnel du moteur gauche
24
float const KiD=2.0;
25
float const KpD=18.0;
26
/*
27
Méthode de calcul de la conversion
28
tick en 200ms -> tick/s -> tour/s -> cm/s
29
               5       1/1938    6*Pi
30
*/
31
32
/*Définition des variables globales du moteur Gauche*/
33
int PWMG = 3; //pin du pwm du moteur gauche
34
int sensG=12;//pin du sens de rotation du moteur. Si sensG à LOW => marche avance. Si sensG à HIGH => marche arrière.
35
int entreeG = A5;// pin du capteur à effet haul du moteur
36
boolean etatG;
37
float consigneG=0;//en cm/s
38
float integraleG;
39
40
/*Définition des variables globales du moteur Droit*/
41
int PWMD=11;
42
int sensD=13;//Si sensD à LOW => marche avant. Si sensD à HIGH => marche arrière.
43
int entreeD=A3;// pin du capteur à effet haul du moteur
44
boolean etatD;
45
float consigneD=0;//en cm/s
46
float integraleD;
47
48
#include <Wire.h>
49
50
void setup() {
51
  Wire.begin(); //join i2c bus (address optional for master)
52
  pinMode(PWMG, OUTPUT);
53
  pinMode(sensG, OUTPUT);
54
  pinMode(PWMD, OUTPUT);
55
  pinMode(sensD, OUTPUT);
56
  pinMode(entreeG, INPUT);
57
  pinMode(entreeD, INPUT);
58
  Serial.begin(9600);
59
  integraleG=0;
60
  integraleD=0;
61
  AdaptationConsigneRobot(7.0, 0);
62
}
63
64
void loop() {
65
  int ticks[3];
66
  int commandeSortie[3];
67
  float vitesse[3];
68
  
69
  AcquisitionTicks(ticks);
70
71
  TraitementTicks(ticks,commandeSortie,vitesse);
72
  
73
 /* Adaptation à l'alimentation par générateur*/
74
 if(consigneG !=0 && consigneD != 0 && ticks[0]==0 && ticks[1]==0) {
75
   analogWrite(PWMG,0);
76
   analogWrite(PWMD, 255);//envoie de la commande au moteur droit
77
   delay(100);
78
   analogWrite(PWMG, 255);
79
 } else{
80
    //Envoi des commandes aux moteurs
81
    analogWrite(PWMD, commandeSortie[1]);//envoie de la commande au moteur droit
82
    analogWrite(PWMG, commandeSortie[0]);//envoie de la commande au moteur gauche
83
  }
84
  //Envoi de données pour correction du code
85
  Serial.print(commandeSortie[0]);//Gauche
86
  Serial.print(" ");
87
  Serial.print(commandeSortie[1]);//Droit
88
  Serial.print(" ");
89
  Serial.print(consigneG);
90
  Serial.print(" ");
91
  Serial.print(consigneD);
92
  Serial.print(" ");
93
  Serial.print(vitesse[0]);//gauche
94
  Serial.print(" ");
95
  Serial.println(vitesse[1]);//droit
96
97
  //Gestion de la communication i2c
98
  communication(vitesse);
99
}
100
// Permet le comptage des ticks effectués lors de la rotation du moteur
101
void AcquisitionTicks(int ticks[3]) {
102
  unsigned long timeInit=millis();
103
  boolean UpG;
104
  boolean UpD;
105
  int tickG=0;
106
  int tickD=0;
107
  /*
108
  Acquisition des ticks des deux moteurs
109
  */
110
  while(millis()-timeInit < 100) {
111
    //Détection des ticks pour le moteur de Gauche par détection de fronts descendants
112
    if(analogRead(entreeG)*5.0/1024.0>2.0) {
113
      UpG=true;
114
    }
115
    if(analogRead(entreeG)*5.0/1024.0<2.0 && UpG==true) {
116
      UpG=false;
117
      tickG++;
118
    }
119
    //Détection des ticks pour le moteur de Droite par détection de fronts descendants
120
    if(analogRead(entreeD)*5.0/1024.0>2.0) {
121
      UpD=true;
122
    }
123
    if(analogRead(entreeD)*5.0/1024.0<2.0 && UpD==true) {
124
      UpD=false;
125
      tickD++;
126
    }
127
  }
128
  ticks[0]=tickG;
129
  ticks[1]=tickD;
130
  /*
131
  Fin de la détection
132
  ****************************
133
  */
134
}
135
//permet de faire une rectification de la commande du moteur à partir du nombre de ticks
136
void TraitementTicks(int ticks[3], int commandeSortie[3], float vitesse[3]) {
137
  int tickG=ticks[0];
138
  int tickD=ticks[1];
139
  int commandeSortieD;
140
  int commandeSortieG;
141
  float erreurG;
142
  float erreurD;
143
  float proportionnelleD;
144
  float proportionnelleG;
145
  float vitesseG;
146
  float vitesseD;
147
  tickG=tickG*decalage;
148
  if(consigneG != 0 && tickG == 0) {//permet de vite faire démarrer le moteur en cas de faible vitesse
149
    integraleG=200;
150
    commandeSortieG=255;
151
  } else {//cas normal
152
    vitesseG=tickG*conversion;
153
    erreurG = (consigneG - vitesseG);//application du correcteur;
154
    integraleG =integraleG+ KiG*erreurG;
155
    proportionnelleG = KpG*erreurG;
156
    commandeSortieG = int(integraleG + proportionnelleG);
157
    commandeSortieG = constrain(commandeSortieG, 0, 255);
158
  }
159
 
160
  /*
161
  La fonction commande s'occupe de la commande a envoyé au moteur droit pour atteindre la consigne
162
  */
163
  if(consigneD != 0 && tickD == 0) {//permet de vite faire démarrer le moteur en cas de faible vitesse
164
    integraleD=200;
165
    commandeSortieD=255;
166
  } else {//cas normal
167
    vitesseD=tickD*conversion;
168
    erreurD = (consigneD - vitesseD);//application du correcteur;
169
    integraleD =integraleD+ KiD*erreurD;
170
    proportionnelleD = KpD*erreurD;
171
    commandeSortieD = int(integraleD + proportionnelleD);
172
    commandeSortieD = constrain(commandeSortieD, 0, 255);
173
  }
174
  //mise à jour des tableaux
175
  ticks[0]=tickG;
176
  ticks[1]=tickD;
177
  commandeSortie[0]=commandeSortieG;
178
  commandeSortie[1]=commandeSortieD;
179
  vitesse[0]=vitesseG;
180
  vitesse[1]=vitesseD;
181
  //Fin du traitement du nombre de ticks pour déduire la commande des moteurs.
182
}
183
184
void AdaptationConsigneMoteur(boolean AvG, float consignePourMG, boolean AvD, float consignePourMD) {
185
 
186
  //Mise à jour des consignes de vitesse des moteurs
187
  consigneG=consignePourMG;
188
  consigneD=consignePourMD;
189
  int commandeSortieG;
190
  int commandeSortieD;
191
  //Redéfinition des sens de rotation du moteur gauche
192
  if(AvG==false&&etatG != LOW) {
193
    etatG=LOW;
194
    integraleG=50;
195
    commandeSortieG=255;
196
  } else if(AvG==true&&etatG != HIGH) {
197
    etatG=HIGH;
198
    integraleG=50;
199
    commandeSortieG=255;
200
  }
201
 
202
  //Redéfinition des sens de rotation du moteur droit
203
  if(AvD==false&&etatD != LOW) {
204
    etatD=LOW;
205
    integraleD=50;
206
    commandeSortieD=255;
207
  } else if(AvD==true&&etatD != HIGH) {
208
    etatD=HIGH;
209
    integraleD=50;
210
    commandeSortieD=255;
211
  }
212
  
213
  //Correction de la consigne pour l'adapter à la réalité - f(consigne)=rotation différent pour les deux moteurs-
214
  if(etatD==false){
215
    consigneD=consigneD*correctionRegulationMAv;
216
  } else {
217
    consigneD=consigneD*correctionRegulationMAr;
218
  }
219
  // Correction des consignes pour ne pas saturer les moteurs et obtenir n'importe quoi
220
  if(consigneG>Vmax && consigneG>consigneD) {
221
    consigneD=consigneD*Vmax/consigneG;
222
    consigneG=Vmax;
223
  } else if(consigneD>Vmax) {
224
    consigneG=consigneG*Vmax/consigneD;
225
    consigneD=Vmax;
226
  }
227
 
228
  /*
229
  Transmission des consignes aux moteurs
230
    *  En cas de changement de sens, on transmet le dirac afin de faire changer le sens des moteurs.
231
    *  En cas de maintient du sens des moteurs, la valeur envoyé aux moteurs ne change pas et l'asservissement va se charger d'atteindre la consigne de vitesse
232
  */
233
  digitalWrite(sensG, etatG);//envoie de la commande au moteur
234
  digitalWrite(sensD, etatD);//envoie de la commande au moteur
235
 
236
  analogWrite(PWMG, commandeSortieG);//envoie de la commande au moteur
237
  analogWrite(PWMD, commandeSortieD);//envoie de la commande au moteur
238
 
239
}  
240
241
void AdaptationConsigneRobot(float vitesseTranslation, float vitesseRotation) {
242
  //vitesse en cm/s et vitesseRotation en rad/s
243
  float vg=vitesseTranslation-vitesseRotation*d/2;
244
  float vd=vitesseTranslation+vitesseRotation*d/2;
245
  boolean etmg=false;
246
  boolean etmd=false;
247
  //mise en forme pour utilisation d'AdaptationConsigneMoteur(boolean AvG, float consignePourMG, boolean AvD, float consignePourMD);
248
  if(vg<0) {
249
    etmg=true;
250
    vg=-vg;
251
  }
252
  if(vd<0) {
253
    etmd=true;
254
    vd=-vd;
255
  }
256
  AdaptationConsigneMoteur(etmg,vg,etmd,vd);
257
}
258
259
//Intégration de la variation de position
260
void VariationPosition(float vitesseG, float vitesseD, float tab[3]) {
261
  tab[0]=0.2*vitesseG;
262
  tab[1]=0.2*vitesseD;
263
}
264
265
void communication(float vitesse[3]) {
266
  float tabPosition[3];
267
  int tabPositionInt[3];
268
  float vitesseG;
269
  float vitesseD;
270
  vitesseG=vitesse[0];
271
  vitesseD=vitesse[1];
272
  float vitesseTranslation;
273
  float vitesseRotation;
274
  VariationPosition(vitesseG, vitesseD, tabPosition);
275
  tabPositionInt[0]=(int)(tabPosition[0]*10.0);
276
  tabPositionInt[1]=(int)(tabPosition[1]*10.0); // !!!!!!!vérifier l'ajustement pour avoir une bonne précision, si besoin, changer de méthode
277
  Wire.beginTransmission(8); // transmit to device #8
278
  Wire.write(tabPositionInt[0]);        // sends speed of left motor
279
  Wire.write(tabPositionInt[1]);        // sends speed of right motor
280
  Wire.endTransmission(); // stop transmitting
281
  
282
  Wire.requestFrom(8, 1); //request vitesseTranslation
283
  while (Wire.available()) { // slave may send less than requested
284
    int c = Wire.read(); // receive a byte as int
285
    //Serial.print(c);
286
    //Serial.print(" ");
287
    vitesseTranslation=((float) c)/10.0;
288
  }
289
  Wire.requestFrom(8, 1); //request vitesseRotation
290
  while (Wire.available()) { // slave may send less than requested
291
    int c = Wire.read(); // receive a byte as int
292
    //Serial.print(c);
293
    //Serial.print(" ");
294
    vitesseRotation=((float) c)/100.0;
295
  }
296
  //Serial.println("Et on repart");
297
  AdaptationConsigneRobot( vitesseTranslation, vitesseRotation);
298
}
299
300
</pre>