Skip to content

Commit cfd8a6d

Browse files
committed
Merge branch 'Asservissement'
2 parents 7765d1d + d9b1206 commit cfd8a6d

15 files changed

Lines changed: 591 additions & 4 deletions

File tree

.DS_Store

6 KB
Binary file not shown.

Licence

100644100755
File mode changed.

README.md

100644100755
File mode changed.

docs/Asservissement.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Page asservissement

mkdocs.yml

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ nav:
55
- Lidar.md
66
- Simulateur.md
77
- IA.md
8+
- Asservissement.md
89
- How to create documentation: building_docs.md
910
- Déroulement de la course: Deroulement_course.md
1011
- Regle de la course: https://ajuton-ens.github.io/CourseVoituresAutonomesSaclay/

scripts/sender.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from time import sleep
2+
import smbus #type: ignore #ignore the module could not be resolved error because it is a linux only module
3+
import struct
4+
5+
SLAVE_ADDRESS = 0x08
6+
# Create an SMBus instance
7+
bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1
8+
9+
def write_data(float_data):
10+
# Convert the float to bytes
11+
print(float_data)
12+
byte_data = struct.pack('f', float_data)
13+
# Convert the bytes to a list of integers
14+
int_data = list(byte_data)
15+
print(int_data)
16+
int_data.append(0)
17+
# Write the data to the I2C bus
18+
bus.write_i2c_block_data(SLAVE_ADDRESS, int_data[0], int_data[1:4])
19+
20+
def read_data(num_floats=3):
21+
22+
# Each float is 4 bytes
23+
length = num_floats * 4
24+
# Read a block of data from the slave
25+
data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length)
26+
# Convert the byte data to floats
27+
if len(data) >= length:
28+
float_values = struct.unpack('f' * num_floats, bytes(data[:length]))
29+
return list(float_values)
30+
else:
31+
raise ValueError("Not enough data received from I2C bus")
32+
33+
def read_data(num_floats=3):
34+
# Each float is 4 bytes
35+
length = num_floats * 4
36+
# Read a block of data from the slave
37+
data = bus.read_i2c_block_data(SLAVE_ADDRESS, 0, length)
38+
# Convert the byte data to floats
39+
if len(data) >= length:
40+
float_values = struct.unpack('f' * num_floats, bytes(data[:length]))
41+
return list(float_values)
42+
else:
43+
raise ValueError("Not enough data received from I2C bus")
44+
45+
i=0.56
46+
while True :
47+
write_data(i)
48+
sleep(0.5)
49+
i+=1
50+

src/HL/Car.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
import numpy as np
66
from gpiozero import LED, Button
77
import logging as log
8+
import smbus # type: ignore #ignore the module could not be resolved error because it is a linux only module
9+
import struct
10+
11+
SLAVE_ADDRESS = 0x08
12+
# Create an SMBus instance
13+
bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1
814

915

1016
# Import constants from HL.Autotech_constant to share them between files and ease of use

src/HL/main.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,16 @@ def display_combined_im(text):
6565
with canvas(device) as draw:
6666
draw.bitmap((0, 0), im, fill="white")
6767

68-
def write_data(data):
69-
# Convert string to list of ASCII values
70-
data_list = [ord(char) for char in data]
71-
bus.write_i2c_block_data(SLAVE_ADDRESS, 0, data_list)
68+
def write_data(float_data):
69+
# Convert the float to bytes
70+
print(float_data)
71+
byte_data = struct.pack('f', float_data)
72+
# Convert the bytes to a list of integers
73+
int_data = list(byte_data)
74+
print(int_data)
75+
int_data.append(0)
76+
# Write the data to the I2C bus
77+
bus.write_i2c_block_data(SLAVE_ADDRESS, int_data[0], int_data[1:4])
7278

7379
def read_data(num_floats=3):
7480

src/LL/Asserv2/.DS_Store

6 KB
Binary file not shown.

src/LL/Asserv2/Asserv2.ino

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#include <Servo.h>
2+
#include <EnableInterrupt.h>
3+
#include "I2Cslave.hpp"
4+
5+
#define PIN_DIR 10
6+
#define PIN_MOT 9
7+
#define PIN_FOURCHE 14
8+
9+
10+
Servo moteur;
11+
Servo direction;
12+
13+
14+
15+
//declaration des broches des differents composants
16+
const int pinMoteur=PIN_MOT;
17+
const int pinDirection=PIN_DIR;
18+
const int pinFourche=PIN_FOURCHE;
19+
20+
//constantes utiles
21+
const int nb_trous=16*2; //nb de trous dans la roue qui tourne devant la fourche optique
22+
const int distanceUnTour=79; //distance parcourue par la voiture apres un tour de roue en mm
23+
24+
//variables
25+
char command;
26+
float Vcons=0;
27+
float old_Vcons ;//consigne
28+
float vitesse=0; //vitesse de la voiture
29+
30+
//PID
31+
float vieuxEcart=0;
32+
float vieuxTemps=0; //variable utilisee pour mesurer le temps qui passe
33+
float Kp=0.05; //correction prop
34+
float Ki=0.1; //correction integrale
35+
float Kd=0.; //correction derivee
36+
float integral=0;//valeur de l'integrale dans le PID
37+
float derivee=0; //valeur de la derivee dans le PID
38+
39+
//mesures
40+
volatile int count=0; //variable utilisee pour compter le nombre de fronts montants/descendants
41+
volatile int vieuxCount=0; //stocke l'ancienne valeur de count pour ensuite faire la difference
42+
volatile byte state=LOW;
43+
float mesures[10]; // tableau de mesures pour lisser
44+
45+
float getMeanSpeed(float dt){
46+
int length = sizeof(mesures)/sizeof(mesures[0]);
47+
//ajout d'une nouvelle mesure et suppression de l'ancienne
48+
for (int i=length-1;i>0;i--){
49+
mesures[i]=mesures[i-1];
50+
}
51+
mesures[0] = getSpeed(dt);
52+
53+
//Calcul d'une moyenne pour lisser les mesures qui sont trop dipersées sinon
54+
float sum=0;
55+
for (int i=0;i<length;i++){
56+
sum+=mesures[i];
57+
}
58+
59+
//affichage debug
60+
#if 0
61+
for(int i=0;i<length;i++){
62+
Serial.print(mesures[i]);
63+
Serial.print(" , ");
64+
}
65+
Serial.println(sum/length);
66+
#endif
67+
68+
return sum/length;
69+
}
70+
71+
float getSpeed(float dt){
72+
int N = count - vieuxCount; //nombre de fronts montant et descendands après chaque loop
73+
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
74+
vieuxCount=count;
75+
vieuxTemps=millis();
76+
return V;
77+
}
78+
void blink(){ //on compte tous les fronts
79+
//Serial.print(count);
80+
count++;
81+
}
82+
float PID(float cons, float mes, float dt) {
83+
// Adjust the measured speed based on the sign of the desired speed
84+
float adjustedMes = (cons < 0) ? -mes : mes;
85+
86+
// Calculate the error
87+
float e = cons - adjustedMes;
88+
89+
// Proportional term
90+
float P = Kp * e;
91+
92+
// Integral term
93+
integral = integral + e * dt;
94+
float I = Ki * integral;
95+
96+
#if 0
97+
// Derivative term
98+
derivee = (e - vieuxEcart) / dt;
99+
vieuxEcart = e;
100+
float D = Kd * derivee;
101+
#endif
102+
103+
return P + I;
104+
}
105+
void setup() {
106+
I2Cslave::setup();
107+
Serial.begin(115200);
108+
109+
pinMode(pinMoteur,OUTPUT);
110+
moteur.attach(pinMoteur,0,2000);
111+
112+
pinMode(pinDirection,OUTPUT);
113+
direction.attach(pinDirection,0,2000);
114+
115+
pinMode(pinFourche,INPUT_PULLUP);
116+
enableInterrupt(PIN_FOURCHE, blink, CHANGE); //on regarde a chaque fois que le signal de la fourche change (Montants et Descendants)
117+
118+
moteur.writeMicroseconds(1500);
119+
delay(2000);
120+
moteur.writeMicroseconds(1590);
121+
122+
123+
delay(10);
124+
Serial.println("init");
125+
}
126+
void loop() {
127+
// Commandes pour debugger
128+
command=Serial.read();
129+
switch (command){ //pour regler les parametres
130+
case 'a':
131+
Vcons+=200;
132+
break;
133+
case 'z':
134+
Vcons-=200;
135+
break;
136+
case 's':
137+
Vcons=-1000;
138+
break;
139+
case 'd':
140+
Vcons=2000;
141+
break;
142+
case 'q':
143+
Vcons=0;
144+
break;
145+
}
146+
147+
//lecture depuis l'I2C
148+
Vcons = I2CSlave::getReadValue();
149+
150+
int deltaT = millis()-vieuxTemps; //temps qui est passé pendant un loop (en millisecondes)
151+
vitesse=getMeanSpeed(deltaT); // on recup la vitesse lissée
152+
153+
int out;
154+
155+
if (Vcons>=0){
156+
157+
out = PID(Vcons,vitesse,float(deltaT)/1e3);
158+
moteur.writeMicroseconds(constrain(1500 + out,1500,2000));
159+
160+
} else if ( Vcons<0 && old_Vcons>=0 ){
161+
162+
out = PID(-8000,vitesse,float(deltaT)/1e3);
163+
moteur.writeMicroseconds(constrain(1500 + out,500,1500));
164+
delay(200);
165+
out = PID(0,vitesse,float(deltaT)/1e3);
166+
moteur.writeMicroseconds(constrain(1500 + out,1500,2000));
167+
delay(10);
168+
169+
} else {
170+
171+
out = PID(Vcons,vitesse,float(deltaT)/1e3);
172+
moteur.writeMicroseconds(constrain(1500 + out,500,1500));
173+
}
174+
175+
old_Vcons = Vcons;
176+
177+
//print debug
178+
#if 0
179+
Serial.print("");
180+
Serial.print(Vcons);
181+
Serial.print(", ");
182+
Serial.print(vitesse);
183+
Serial.print(", ");
184+
Serial.print(Ki);
185+
Serial.print(", ");
186+
Serial.print(Kp);
187+
Serial.print(", ");
188+
Serial.print("out=");
189+
Serial.println(out);
190+
#endif
191+
delay(10);
192+
}

0 commit comments

Comments
 (0)