Skip to content

Commit 5c646df

Browse files
authored
Merge pull request #31 from Association-INTech/LL
Ll
2 parents b3d1153 + 87ce469 commit 5c646df

1 file changed

Lines changed: 133 additions & 140 deletions

File tree

src/LL/Asserv2bazar/Asserv2bazar.ino

Lines changed: 133 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,32 @@ volatile int vieuxCount=0; //stocke l'ancienne valeur de count pour ensuite fair
4747
volatile byte state=LOW;
4848
float mesures[3]; // tableau de mesures pour lisser
4949

50-
////I2C
50+
//I2C
5151
union floatToBytes {
5252
byte valueBuffer[4];
5353
float valueReading;
5454
} converter;
5555

56-
////Voltage
56+
//struct pour la fréquence d'éxécution des fonctions
57+
struct Task {
58+
unsigned long period;
59+
unsigned long last;
60+
void (*run)();
61+
};
62+
63+
enum DriveState {
64+
DRIVE_STOP,
65+
DRIVE_FORWARD,
66+
DRIVE_REV_ARM_1, // neutre
67+
DRIVE_REV_ARM_2, // reverse fort
68+
DRIVE_REV_ARM_3, // retour neutre
69+
DRIVE_REVERSE
70+
};
71+
72+
DriveState driveState = DRIVE_STOP;
73+
unsigned long driveTimer = 0;
74+
75+
//Voltage
5776
volatile bool dataReceived = false;
5877
volatile char receivedData[32]; // Buffer to hold received data
5978
volatile int receivedLength = 0;
@@ -70,9 +89,8 @@ float voltage_NiMh = 0; // variable to store the value read
7089

7190
int out;
7291
int marche_avant = 1; //on initie la marche avant au début (0 étant la marche arriérer)
73-
float marche_arriere_time = 0;
7492

75-
float dernier_input = millis();
93+
unsigned long dernier_input = millis();
7694
//direction millieu 1851
7795
// tout a gaucge 1231
7896
// tout a droite 2471
@@ -105,50 +123,33 @@ float getMeanSpeed(float dt){
105123

106124
float getSpeed(float dt){
107125
int N = count - vieuxCount; //nombre de fronts montant et descendands après chaque loop
108-
float V = ((float)N/(float)nb_trous)*distanceUnTour/(dt*1e-3); //16 increments -> 1 tour de la roue et 1 tour de roue = 79 mm
109126
vieuxCount=count;
110-
vieuxTemps=millis();
111-
return V;
127+
return ((float)N/(float)nb_trous)*distanceUnTour/(dt*1e-3); //16 increments -> 1 tour de la roue et 1 tour de roue = 79 mm ;
112128
}
113129

114130

115131
void blink(){ //on compte tous les fronts
116-
//Serial.print(count);
117132
count++;
118133
}
119134

120135

121136
float PID(float cons, float mes, float dt,float old_out) {
122137

123-
124138
if ( old_out <= 0 && cons > 0){ // pour pouvoir sauter directement dans la plage de pwm ou la roue bouge et une transition plus fluide entre marche arriere et avant
125139
integral = 2500; // valeur experimentale
126140
}
127141
else if (old_out >= 0 && cons <0 ){ // pour pouvoir sauter directement dans la plage de pwm où la roue bouge et une transition plus fluide entre marche avant et arriere
128142
integral = -5000; // valeur experimentale
129143
}
130144

131-
132-
// Adjust the measured speed based on the sign of the desired speed
133-
float adjustedMes = (cons < 0) ? -mes : mes;
134-
135-
// Calculate the error
136-
float e = cons - adjustedMes;
137-
138-
// Proportional term
139-
float P = Kp * e;
140-
141-
// Integral term
142-
integral = integral + e * dt;
143-
float I = Ki * integral;
144-
145-
// Derivative term
146-
derivee = (e - vieuxEcart) / dt;
145+
float adjustedMes = (cons < 0) ? -mes : mes; // Adjust the measured speed based on the sign of the desired speed
146+
float e = cons - adjustedMes; // Calculate the error
147+
float P = Kp * e; // Proportional term
148+
integral = integral + e * dt; // Integral term
149+
float I = Ki * integral;
150+
derivee = (e - vieuxEcart) / dt; // Derivative term
147151
vieuxEcart = e;
148152
float D = Kd * derivee;
149-
150-
// Garde en mémoir pour passer out à 0 directe lorsque l'on change de sens pour ne pas attendre qu'elle change de sens tout seul (que c'est long mdr
151-
152153
return P + I + D;
153154
}
154155

@@ -164,114 +165,93 @@ void calculateVoltage(){
164165
//Serial.println(voltage_NiMh);
165166
}
166167

167-
/*
168-
float direction_compensation(float dir_recue, float anciene_dir){
169-
if (anciene_dir > )
170-
}*/
171-
172-
void programme_principal(){
173-
calculateVoltage();
174-
// Commandes pour debugger
175-
#if 0
176-
command=Serial.read();
177-
switch (command){ //pour regler les parametres
178-
case 'a':
179-
Vcons+=200;
180-
break;
181-
case 'z':
182-
Vcons-=200;
183-
break;
184-
case 's':
185-
Vcons=-1000;
186-
break;
187-
case 'd':
188-
Vcons=2000;
189-
break;
190-
case 'q':
191-
Vcons=0;
192-
break;
193-
case 'b':
194-
dir+=10;
195-
break;
196-
case 'n':
197-
dir-=100;
198-
break;
199-
case 'j':
200-
dir+=10;
201-
break;
202-
case 'k':
203-
dir-=10;
204-
break;
205-
}
206-
#endif
207-
208-
209-
// Propulsion de la voiture
210-
int deltaT = millis()-vieuxTemps; //temps qui est passé pendant un loop (en millisecondes)
211-
vitesse=getMeanSpeed(deltaT); // on recup la vitesse lissée
212-
168+
void updateDirection(){
169+
// Update direction
170+
dir = map(dir_recue,-dir_max,dir_max,dir_min_pwm,dir_max_pwm); // remape en degré
171+
direction.writeMicroseconds(dir);
172+
}
213173

214-
if (Vcons == 0){
215-
out = 0;
216-
moteur.writeMicroseconds(out+1500);
217-
/*
218-
Serial.print("out:");
219-
Serial.print(out);
220-
*/
221-
marche_arriere_time = millis();
174+
void updateSpeed() {
175+
unsigned long now = millis();
176+
float dt = (now - vieuxTemps) * 0.001f;
177+
if (dt <= 0) dt = 0.001f;
178+
179+
vitesse = getMeanSpeed(now - vieuxTemps);
180+
vieuxTemps = now;
181+
182+
switch (driveState) {
183+
184+
case DRIVE_STOP:
185+
moteur.writeMicroseconds(1500);
186+
integral = 0;
187+
out = 0;
188+
189+
if (Vcons > 0) {
190+
driveState = DRIVE_FORWARD;
191+
}
192+
else if (Vcons < 0) {
193+
driveState = DRIVE_REV_ARM_1;
194+
driveTimer = now;
195+
}
196+
break;
197+
198+
case DRIVE_FORWARD:
199+
out = PID(Vcons, vitesse, dt, out);
200+
moteur.writeMicroseconds(constrain(1500 + out, 1500, 2000));
201+
202+
if (Vcons == 0) {
203+
driveState = DRIVE_STOP;
204+
}
205+
else if (Vcons < 0) {
206+
driveState = DRIVE_REV_ARM_1;
207+
driveTimer = now;
208+
}
209+
break;
210+
211+
case DRIVE_REV_ARM_1: // neutre court
212+
moteur.writeMicroseconds(1500);
213+
if (now - driveTimer >= 10) {
214+
driveState = DRIVE_REV_ARM_2;
215+
driveTimer = now;
216+
}
217+
break;
218+
219+
case DRIVE_REV_ARM_2: // reverse fort (armement ESC)
220+
moteur.writeMicroseconds(1000);
221+
if (now - driveTimer >= 150) {
222+
driveState = DRIVE_REV_ARM_3;
223+
driveTimer = now;
224+
}
225+
break;
226+
227+
case DRIVE_REV_ARM_3: // retour neutre
228+
moteur.writeMicroseconds(1500);
229+
if (now - driveTimer >= 10) {
230+
driveState = DRIVE_REVERSE; // marche arrière ENGAGÉE
231+
}
232+
break;
233+
234+
case DRIVE_REVERSE:
235+
float cons = abs(Vcons);
236+
out = PID(cons, vitesse, dt, out);
237+
moteur.writeMicroseconds(constrain(1430 - out, 500, 1500));
238+
239+
if (Vcons == 0){
240+
moteur.writeMicroseconds(1500);
241+
integral = 0;
242+
out = 0;
243+
}
244+
else if (Vcons > 0) {
245+
driveState = DRIVE_FORWARD;
246+
}
247+
break;
222248
}
223-
else if (Vcons>0){
224-
225-
out = PID(Vcons,vitesse,float(deltaT)/1e3,out);
226-
moteur.writeMicroseconds(constrain(1500 + out,1500,2000));
227-
/*
228-
Serial.print("out:");
229-
Serial.print(constrain(1500 + out,500,2000));
230-
*/
231-
marche_avant = 1; // on est en marche avant
232-
233-
} else if ( Vcons<0 && old_Vcons>=0 && marche_avant == 1){ //on vériefie si il faut enclencher la marche arrière
234-
out = PID(-8000,vitesse,float(deltaT)/1e3,out);
235-
moteur.writeMicroseconds(constrain(1500 + out,500,1500));
236-
delay(150);
237-
out = PID(0,vitesse,float(deltaT)/1e3,out);
238-
moteur.writeMicroseconds(constrain(1500 + out,1500,2000));
239-
delay(10);
240-
marche_avant = 0; //on est passée en marche arrière
241-
marche_arriere_time = millis();
242249

243-
} else {
244-
if (vitesse==0 && Vcons<0 && millis()- marche_arriere_time > 500){ //vérifie si on est bien passée en marche arrière car bug parfois et si non on passe en marche arriere
245-
246-
247-
out = PID(-8000,vitesse,float(deltaT)/1e3,out);
248-
moteur.writeMicroseconds(constrain(1500 + out,500,1500));
249-
delay(150);
250-
out = PID(0,vitesse,float(deltaT)/1e3,out);
251-
moteur.writeMicroseconds(constrain(1500 + out,1500,2000));
252-
delay(10);
253-
}
254-
255-
out = PID(Vcons,vitesse,float(deltaT)/1e3,out);
256-
moteur.writeMicroseconds(constrain(1500 + out,500,1500));
257-
/*
258-
Serial.print("out:");
259-
Serial.print(constrain(1500 + out,500,2000));
260-
*/
261-
}
262250

263-
old_Vcons = Vcons;
264251

265252

266-
// Direction de la voiture
267-
dir = map(dir_recue,-dir_max,dir_max,dir_min_pwm,dir_max_pwm); // remape en degré
268-
direction.writeMicroseconds(dir);
269-
270253

271-
//print debug
272-
#if 1
273-
Serial.print("temps en marche arriere: ");
274-
Serial.print(millis()- marche_arriere_time);
254+
#if 0
275255
Serial.print(",integrale");
276256
Serial.print(integral);
277257
Serial.print(",const:");
@@ -282,16 +262,11 @@ void programme_principal(){
282262
Serial.print(vitesse);
283263
Serial.print(",Directino en degré:");
284264
Serial.print(dir_recue);
285-
// Serial.print(", Ki : ");
286-
// Serial.print(Ki);
287-
// Serial.print(", Kp: ");
288-
// Serial.print(Kp);
289-
// Serial.print(", ");
290265
Serial.print(",out2:");
291266
Serial.println(out);
292267
#endif
293-
delay(10);
294268
}
269+
295270
void receiveEvent(int byteCount){
296271
// Ignorer le premier octet "commande" du Raspberry
297272
if (Wire.available()) Wire.read(); // skip cmd byte
@@ -305,9 +280,11 @@ void receiveEvent(int byteCount){
305280
buffer[i] = Wire.read();
306281
}
307282

308-
float* vals = (float*)buffer;
309-
Vcons = vals[0]; // reçue en milimetre par secondes
310-
dir_recue = vals[1]; //reçue en degré.
283+
float v, d;
284+
memcpy(&v, buffer, 4);
285+
memcpy(&d, buffer + 4, 4);
286+
Vcons = v; // reçue en milimetre par secondes
287+
dir_recue = d; //reçue en degré.
311288
} else {
312289
while (Wire.available()) Wire.read(); // vide le buffer
313290
}
@@ -339,14 +316,30 @@ void setup() {
339316
}
340317

341318

319+
Task tasks[] = {
320+
{5, 0, updateDirection}, // 200 Hz
321+
{20, 0, updateSpeed}, // 50 Hz
322+
{500, 0, calculateVoltage} // 2 Hz
323+
};
324+
342325
void loop() {
343-
if(millis()-dernier_input < 150){ // on vérifie si on a recue une commande dans les 100 dernière millisecondes sinon on arrete
344-
programme_principal();
326+
unsigned long now = millis();
327+
328+
if(now - dernier_input < 150){ // on vérifie si on a recue une commande dans les 100 dernière millisecondes sinon on arrete
329+
for (auto &t : tasks) {
330+
if (now - t.last >= t.period) {
331+
t.last = now;
332+
t.run();
333+
}
334+
}
345335
}
346336
else {
347337
moteur.writeMicroseconds(1500);
348338
dir = map(0,-dir_max,dir_max,dir_min_pwm,dir_max_pwm);
349339
direction.writeMicroseconds(dir);
340+
driveState = DRIVE_STOP;
341+
integral=0;
342+
out=0;
350343
}
351344
}
352345

0 commit comments

Comments
 (0)