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> |