CARIA.2.2

Update for the final presentation
huge change with previous version
This commit is contained in:
ccunatbrule
2024-09-03 12:17:44 +02:00
parent ebcb596a4f
commit 2ddf2360e6
44 changed files with 7080 additions and 657 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
Thumbs.db
.DS_Store

View File

@@ -25,69 +25,71 @@ def run_shell_fct(script):
script_name = os.path.basename(script)
# Se déplacer vers le répertoire du script et exécuter le script shell
return subprocess.Popen(["sudo", "./" + script_name], cwd=script_dir)
def main():
python_scripts = [
"apps/infrared_tracking_objects.py",
"apps/infrared_obstacle_avoidance.py",
"tests/servo_motor.py",
"tests/motor_speed_move.py",
"tests/rfid_read_write_module.py",
"tests/infrared_obstacle_module.py",
"tests/lidar_module.py"
]
python_fct = [
"WebControl/main.py"
]
shell_fct = [
]
# Liste pour stocker les PID des processus en cours d'exécution
running_processes = []
all_scripts = python_scripts + python_fct + shell_fct
display_menu(all_scripts)
choice = input("Votre choix (entrez le numéro du script) : ")
try:
choice_index = int(choice) - 1
if choice_index < 0 or choice_index >= len(all_scripts):
raise ValueError()
selected_script = all_scripts[choice_index]
# Vérifie si le script est Python ou Shell et l'exécute en conséquence
if selected_script in python_scripts:
process = run_python_script(selected_script)
elif selected_script in python_fct:
process = run_python_fct(selected_script)
elif selected_script in shell_fct:
process = run_shell_fct(selected_script)
# Ajouter le PID du processus à la liste
running_processes.append(process.pid)
except (ValueError, IndexError):
print("Choix invalide.")
sys.exit(1)
# Afficher les PID des processus en cours d'exécution
print("PID des processus en cours d'exécution :")
for pid in running_processes:
print(pid)
# Attente de l'arrêt du programme
input("Appuyez sur Entrée pour quitter...")
# Boucle pour terminer tous les processus en cours d'exécution
print("Termination des processus en cours...")
for pid in running_processes:
try:
os.kill(pid, signal.SIGTERM)
print(f"Processus {pid} terminé.")
except ProcessLookupError:
print(f"Le processus {pid} n'existe plus.")
if __name__ == "__main__":
main()
while True:
python_scripts = [
"apps/scenario_rfid.py",
"apps/rfid_read_write_module.py",
"apps/lidar_speed_move.py",
"apps/infrared_obstacle_avoidance.py",
"tests/servo_motor.py",
"tests/rfid_open_door.py",
"tests/motor_speed_move.py",
"tests/lidar_module.py",
"tests/infrared_obstacle_module.py"
]
python_fct = [
# "WebControl/main.py"
]
shell_fct = [
# "fixs/reboot.sh"
# "fixs/fix_rfid.sh",
# "fixs/fix_motion.sh",
]
# Liste pour stocker les PID des processus en cours d'exécution
running_processes = []
all_scripts = python_scripts + python_fct + shell_fct
display_menu(all_scripts)
choice = input("Votre choix (entrez le numéro du script) : ")
try:
choice_index = int(choice) - 1
if choice_index < 0 or choice_index >= len(all_scripts):
raise ValueError()
selected_script = all_scripts[choice_index]
# Vérifie si le script est Python ou Shell et l'exécute en conséquence
if selected_script in python_scripts:
process = run_python_script(selected_script)
elif selected_script in python_fct:
process = run_python_fct(selected_script)
elif selected_script in shell_fct:
process = run_shell_fct(selected_script)
# Ajouter le PID du processus à la liste
running_processes.append(process.pid)
except (ValueError, IndexError):
print("Choix invalide.")
sys.exit(1)
# Afficher les PID des processus en cours d'exécution
print("PID des processus en cours d'exécution :")
for pid in running_processes:
print(pid)
# Attente de l'arrêt du programme
input("Appuyez sur Entrée pour quitter...\n")
# Boucle pour terminer tous les processus en cours d'exécution
print("Fermeture des processus en cours...")
for pid in running_processes:
try:
os.kill(pid, signal.SIGTERM)
print(f"Processus {pid} terminé.\n")
except ProcessLookupError:
print(f"Le processus {pid} n'existe plus.")

View File

@@ -1,3 +1,12 @@
crontab -e
@reboot sudo /usr/bin/motion
@reboot sh /home/christian/WebControl/webcontrol-launch.sh > /home/christian/WebControl/logs/log.txt 2>&1
@reboot /usr/bin/motion
@reboot /usr/bin/motion >> /home/christian/WebControl/logs/motionlogs.txt 2>&1
@reboot sh /home/christian/WebControl/webcontrol-launch.sh >> /home/christian/WebControl/logs/log.txt 2>&1
-----------
sudo visudo
christian ALL=(ALL) NOPASSWD: /sbin/reboot
christian ALL=(ALL) NOPASSWD: /usr/bin/pkill
christian ALL=NOPASSWD: /usr/bin/python3 /home/christian/WebControl/main.py
christian ALL=NOPASSWD: /usr/bin/motion

View File

@@ -1,38 +1,36 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import sys
import time, sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
speed = 100
DR = 16
DL = 19
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(DR,GPIO.IN,GPIO.PUD_UP)
GPIO.setup(DL,GPIO.IN,GPIO.PUD_UP)
status = "initialization"
duration = 0.1
speed = 20
try:
while True:
DR_status = GPIO.input(DR)
DL_status = GPIO.input(DL)
if((DL_status == 1) and (DR_status == 1)):
Ab.forward(speed)
elif((DL_status == 1) and (DR_status == 0)):
Ab.left(speed)
elif((DL_status == 0) and (DR_status == 1)):
Ab.right(speed)
else:
Ab.backward(speed)
time.sleep(0.2)
Ab.left(speed)
time.sleep(0.2)
Ab.stop()
start_time = time.time() # Enregistrer l'heure de début
while time.time() - start_time < 10: # Boucle pendant 5 seconde
OBSTACLE_PIN_status = GPIO.input(Ab.OBSTACLE_PIN)
if OBSTACLE_PIN_status == 1:
Ab.forward(duration, speed)
status = "operation successful"
else:
Ab.emergencystop()
status = "emergency stop successful"
except KeyboardInterrupt:
GPIO.cleanup();
print("Interruption par l'utilisateur.")
status = "interrupted"
finally:
Ab.cleanup()
# Vérification finale et affichage du statut
if status == "operation successful" or status == "emergency stop successful":
print(f"Le composant fonctionne correctement: {status}.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -1,35 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
DR = 16
DL = 19
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(DR,GPIO.IN,GPIO.PUD_UP)
GPIO.setup(DL,GPIO.IN,GPIO.PUD_UP)
Ab.stop()
speed=100
try:
while True:
DR_status = GPIO.input(DR)
DL_status = GPIO.input(DL)
if((DL_status == 0) and (DR_status == 0)):
Ab.forward(speed)
elif((DL_status == 1) and (DR_status == 0)):
Ab.right(speed)
elif((DL_status == 0) and (DR_status == 1)):
Ab.left(speed)
else:
Ab.stop()
except KeyboardInterrupt:
GPIO.cleanup();

View File

@@ -0,0 +1,59 @@
import requests, json, time
def get_directions(origin, destination, api_key):
url = f"https://maps.googleapis.com/maps/api/directions/json?origin={origin}&destination={destination}&key={api_key}"
response = requests.get(url)
if response.status_code == 200:
directions = response.json()
return directions
else:
return None
def save_steps_to_file(directions, filename):
if directions and 'routes' in directions and len(directions['routes']) > 0:
steps = []
for route in directions['routes']:
for leg in route['legs']:
for step in leg['steps']:
steps.append(step)
with open(filename, 'w', encoding='utf-8') as f:
json.dump(steps, f, indent=2, ensure_ascii=False)
def save_selected_steps_to_file(directions, filename):
selected_steps = []
if directions and 'routes' in directions and len(directions['routes']) > 0:
for route in directions['routes']:
for leg in route['legs']:
for step in leg['steps']:
selected_step = {
'distance_value': step['distance']['value'],
'maneuver': step.get('maneuver', 'maneuver-unspecified')
}
selected_steps.append(selected_step)
with open(filename, 'w', encoding='utf-8') as f:
json.dump(selected_steps, f, indent=2, ensure_ascii=False)
# Paramètres
origin = "48.8224, 2.2748" # Coordonnées pour Paris (latitude, longitude)
destination = "48.67912602858551, 2.3860270345466024" # Coordonnées pour Lyon (latitude, longitude)
api_key = "AIzaSyD6WRlNBTn27rEoYbIAlxw9U_Nr_iNqLJc"
# Obtenir les directions
directions = get_directions(origin, destination, api_key)
print("Préparons ensemble votre itinéraire !")
time.sleep(2)
print("Veuillez saisir l'adresse de départ et l'adresse d'arrivée.")
time.sleep(2)
print("Calcul de l'itinéraire en cours : de Paris à Lyon.")
time.sleep(2)
# Sauvegarder les étapes complètes dans un fichier JSON
steps_filename = '/home/christian/WebControl/logs/steps.json'
save_steps_to_file(directions, steps_filename)
# print(f"Les étapes complètes de l'itinéraire ont été sauvegardées dans le fichier {steps_filename}")
# Sauvegarder les étapes sélectionnées dans un fichier JSON
selected_steps_filename = '/home/christian/WebControl/logs/selected_steps.json'
save_selected_steps_to_file(directions, selected_steps_filename)
# print(f"Les étapes sélectionnées de l'itinéraire ont été sauvegardées dans le fichier {selected_steps_filename}")

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json, time, sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
speed = 20
# Fonction pour calculer la durée en fonction de la distance
def calculate_duration(distance_value):
# Réglez la vitesse de traitement selon vos besoins
speed_factor = 0.001 # Exemple 0.01/100m:s | 0.001/1km/s
return distance_value * speed_factor
# Lecture du fichier selected_steps.json et traitement des manoeuvres
def process_selected_steps(filename):
with open(filename, 'r', encoding='utf-8') as f:
selected_steps = json.load(f)
for step in selected_steps:
maneuver = step['maneuver']
distance_value = step['distance_value']
# Calcul de la durée en fonction de la distance
duration = calculate_duration(distance_value)
if maneuver == "maneuver-unspecified":
Ab.maneuver_unspecified(duration)
elif maneuver == "turn-slight-left":
Ab.turn_slight_left(duration, speed)
elif maneuver == "turn-sharp-left":
Ab.turn_sharp_left(duration, speed)
elif maneuver == "u-turn-left":
Ab.u_turn_left(duration, speed)
elif maneuver == "turn-left":
Ab.left(duration, speed)
elif maneuver == "turn-slight-right":
Ab.turn_slight_right(duration, speed)
elif maneuver == "turn-sharp-right":
Ab.turn_sharp_right(duration, speed)
elif maneuver == "u-turn-right":
Ab.u_turn_right(duration, speed)
elif maneuver == "turn-right":
Ab.right(duration, speed)
elif maneuver == "straight":
Ab.forward(duration, speed)
elif maneuver == "ramp-left":
Ab.ramp_left(duration, speed)
elif maneuver == "ramp-right":
Ab.ramp_right(duration, speed)
elif maneuver == "merge":
Ab.merge(duration, speed)
elif maneuver == "fork-left":
Ab.fork_left(duration, speed)
elif maneuver == "fork-right":
Ab.fork_right(duration, speed)
elif maneuver == "ferry":
Ab.stop(duration)
elif maneuver == "ferry-train":
Ab.stop(duration)
elif maneuver == "roundabout-left":
Ab.roundabout_left(duration, speed)
elif maneuver == "roundabout-right":
Ab.roundabout_right(duration, speed)
else:
print(f"Manoeuvre inconnue : {maneuver}")
# Nom du fichier contenant les étapes sélectionnées
selected_steps_filename = '/home/christian/WebControl/logs/selected_steps_short.json'
# Appel de la fonction pour traiter les étapes sélectionnées
print("Le départ est prévu dans 10 secondes...")
time.sleep(10)
print("Départ imminent !")
process_selected_steps(selected_steps_filename)

View File

@@ -0,0 +1,170 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import json, time, sys, threading
from threading import Thread
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
base_speed = 20 # Vitesse fixe de 20
current_step_index = 0
emergency_stop = False
remaining_duration = 0
stop_event_obstacle = threading.Event()
# Fonction pour calculer la durée en fonction de la distance
def calculate_duration(distance_value):
speed_factor = 0.001 # Exemple 0.01/100m:s | 0.001/1km/s
return distance_value * speed_factor
# Fonction pour surveiller les obstacles en arrière-plan
def monitor_obstacles():
global emergency_stop, remaining_duration
while not stop_event_obstacle.is_set():
DR_status = GPIO.input(Ab.OBSTACLE_PIN)
if DR_status == 0: # Obstacle détecté
Ab.emergencystop()
emergency_stop = True
while GPIO.input(Ab.OBSTACLE_PIN) == 0: # Attendre que l'obstacle soit dégagé
time.sleep(2)
print("Obstacle dégagé. Attente de 2 secondes avant de reprendre.")
emergency_stop = False
# Fonction pour exécuter une manoeuvre avec arrêt d'urgence possible
def execute_maneuver(maneuver_function, duration, speed=None):
global remaining_duration
start_time = time.time()
while not emergency_stop and (time.time() - start_time) < duration:
time_slice = min(remaining_duration, duration - (time.time() - start_time))
# Appel de la fonction manoeuvre avec ou sans vitesse selon le besoin
if speed is not None:
maneuver_function(time_slice, speed)
else:
maneuver_function(time_slice)
remaining_duration = duration - (time.time() - start_time)
# Fonction pour traiter les étapes sélectionnées
def process_selected_steps(filename):
global current_step_index, remaining_duration
with open(filename, 'r', encoding='utf-8') as f:
selected_steps = json.load(f)
while current_step_index < len(selected_steps):
if emergency_stop: # Si arrêt d'urgence, attendre que l'obstacle soit dégagé
time.sleep(0.1)
continue
step = selected_steps[current_step_index]
maneuver = step['maneuver']
distance_value = step['distance_value']
duration = calculate_duration(distance_value)
remaining_duration = duration # Initialiser la durée restante
# Appel de la fonction de manoeuvre avec une vitesse fixe de 20
if maneuver == "maneuver-unspecified":
execute_maneuver(Ab.maneuver_unspecified, duration)
elif maneuver == "turn-slight-left":
execute_maneuver(Ab.turn_slight_left, duration, base_speed)
elif maneuver == "turn-sharp-left":
execute_maneuver(Ab.turn_sharp_left, duration, base_speed)
elif maneuver == "u-turn-left":
execute_maneuver(Ab.u_turn_left, duration, base_speed)
elif maneuver == "turn-left":
execute_maneuver(Ab.left, duration, base_speed)
elif maneuver == "turn-slight-right":
execute_maneuver(Ab.turn_slight_right, duration, base_speed)
elif maneuver == "turn-sharp-right":
execute_maneuver(Ab.turn_sharp_right, duration, base_speed)
elif maneuver == "u-turn-right":
execute_maneuver(Ab.u_turn_right, duration, base_speed)
elif maneuver == "turn-right":
execute_maneuver(Ab.right, duration, base_speed)
elif maneuver == "straight":
execute_maneuver(Ab.forward, duration, base_speed)
elif maneuver == "ramp-left":
execute_maneuver(Ab.ramp_left, duration, base_speed)
elif maneuver == "ramp-right":
execute_maneuver(Ab.ramp_right, duration, base_speed)
elif maneuver == "merge":
execute_maneuver(Ab.merge, duration, base_speed)
elif maneuver == "fork-left":
execute_maneuver(Ab.fork_left, duration, base_speed)
elif maneuver == "fork-right":
execute_maneuver(Ab.fork_right, duration, base_speed)
elif maneuver == "ferry":
execute_maneuver(Ab.stop, duration)
elif maneuver == "ferry-train":
execute_maneuver(Ab.stop, duration)
elif maneuver == "roundabout-left":
execute_maneuver(Ab.roundabout_left, duration, base_speed)
elif maneuver == "roundabout-right":
execute_maneuver(Ab.roundabout_right, duration, base_speed)
else:
print(f"Manoeuvre inconnue : {maneuver}")
# Incrémenter l'index de l'étape seulement si l'arrêt d'urgence n'a pas été déclenché
if not emergency_stop:
current_step_index += 1
# Nom du fichier contenant les étapes sélectionnées
selected_steps_filename = '/home/christian/WebControl/logs/selected_steps_short.json'
# Démarrer la surveillance des obstacles dans un thread séparé
obstacle_thread = Thread(target=monitor_obstacles)
obstacle_thread.daemon = True
obstacle_thread.start()
# Attendre avant de démarrer
print("Le départ est prévu dans 10 secondes...")
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
print("5 secondes...")
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
print("Départ imminent !")
try:
# Appel de la fonction pour traiter les étapes sélectionnées
process_selected_steps(selected_steps_filename)
status = "scenario successful"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
# Arrêter les threads
Ab.stop_event_obstacle.set()
# Attendre que les threads se terminent
obstacle_thread.join()
print("Fin de la surveillance d'obstacle")
Ab.cleanup()
# Vérification finale et affichage du statut
if status in ["scenario successful"]:
print("Le scenario fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le scenario a rencontré un problème : {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -0,0 +1,174 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import json, time, sys
from threading import Thread
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
status = "initialization"
base_speed = 20 # Vitesse fixe de 20
current_step_index = 0
emergency_stop = False
remaining_duration = 0
adjusted_speed = Ab.vitesse_queue.get()
# Fonction pour calculer la durée en fonction de la distance
def calculate_duration(distance_value):
speed_factor = 0.001 # Exemple 0.01/100m:s | 0.001/1km/s
return distance_value * speed_factor
def execute_maneuver(maneuver_function, duration):
global remaining_duration
start_time = time.time()
while not emergency_stop and (time.time() - start_time) < duration:
time_slice = min(remaining_duration, duration - (time.time() - start_time))
# Lire la vitesse ajustée de la queue si disponible
if not Ab.vitesse_queue.empty():
adjusted_speed = Ab.vitesse_queue.get()
else:
adjusted_speed = base_speed # Utiliser la vitesse de base si la queue est vide
# Appel de la fonction manoeuvre avec la vitesse ajustée
maneuver_function(time_slice, adjusted_speed)
remaining_duration = duration - (time.time() - start_time)
# Fonction pour traiter les étapes sélectionnées
def process_selected_steps(filename):
global current_step_index, remaining_duration
with open(filename, 'r', encoding='utf-8') as f:
selected_steps = json.load(f)
while current_step_index < len(selected_steps):
if emergency_stop: # Si arrêt d'urgence, attendre que l'obstacle soit dégagé
time.sleep(0.1)
continue
step = selected_steps[current_step_index]
maneuver = step['maneuver']
distance_value = step['distance_value']
duration = calculate_duration(distance_value)
remaining_duration = duration # Initialiser la durée restante
# Appel de la fonction de manoeuvre avec une vitesse fixe de 20
if maneuver == "maneuver-unspecified":
execute_maneuver(Ab.maneuver_unspecified, adjusted_speed)
elif maneuver == "turn-slight-left":
execute_maneuver(Ab.turn_slight_left, duration, adjusted_speed)
elif maneuver == "turn-sharp-left":
execute_maneuver(Ab.turn_sharp_left, duration, adjusted_speed)
elif maneuver == "u-turn-left":
execute_maneuver(Ab.u_turn_left, duration, adjusted_speed)
elif maneuver == "turn-left":
execute_maneuver(Ab.left, duration, adjusted_speed)
elif maneuver == "turn-slight-right":
execute_maneuver(Ab.turn_slight_right, duration, adjusted_speed)
elif maneuver == "turn-sharp-right":
execute_maneuver(Ab.turn_sharp_right, duration, adjusted_speed)
elif maneuver == "u-turn-right":
execute_maneuver(Ab.u_turn_right, duration, adjusted_speed)
elif maneuver == "turn-right":
execute_maneuver(Ab.right, duration, adjusted_speed)
elif maneuver == "straight":
execute_maneuver(Ab.forward, duration, adjusted_speed)
elif maneuver == "ramp-left":
execute_maneuver(Ab.ramp_left, duration, adjusted_speed)
elif maneuver == "ramp-right":
execute_maneuver(Ab.ramp_right, duration, adjusted_speed)
elif maneuver == "merge":
execute_maneuver(Ab.merge, duration, adjusted_speed)
elif maneuver == "fork-left":
execute_maneuver(Ab.fork_left, duration, adjusted_speed)
elif maneuver == "fork-right":
execute_maneuver(Ab.fork_right, duration, adjusted_speed)
elif maneuver == "ferry":
execute_maneuver(Ab.stop, duration)
elif maneuver == "ferry-train":
execute_maneuver(Ab.stop, duration)
elif maneuver == "roundabout-left":
execute_maneuver(Ab.roundabout_left, duration, adjusted_speed)
elif maneuver == "roundabout-right":
execute_maneuver(Ab.roundabout_right, duration, adjusted_speed)
else:
print(f"Manoeuvre inconnue : {maneuver}")
# Incrémenter l'index de l'étape seulement si l'arrêt d'urgence n'a pas été déclenché
if not emergency_stop:
current_step_index += 1
# Nom du fichier contenant les étapes sélectionnées
selected_steps_filename = '/home/christian/WebControl/logs/selected_steps_short.json'
# Démarrer la surveillance des obstacle dans un thread séparé
vitesse_thread = Thread(target=Ab.monitor_vitesse)
vitesse_thread.daemon = True
vitesse_thread.start()
print("Surveillance de la vitesse en cours")
# Démarrer la surveillance des obstacle dans un thread séparé
obstacle_thread = Thread(target=Ab.monitor_obstacle)
obstacle_thread.daemon = True
obstacle_thread.start()
print("Surveillance d'obstacle en cours")
# Attendre avant de démarrer
print("Le départ est prévu dans 10 secondes...")
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
print("5 secondes...")
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
time.sleep(1)
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
time.sleep(1)
print("Départ imminent !")
try:
# Appel de la fonction pour traiter les étapes sélectionnées
# Appel de la fonction pour traiter les étapes sélectionnées
process_selected_steps(selected_steps_filename)
status = "scenario successful"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
# Arrêter les threads
Ab.stop_event_vitesse.set()
Ab.stop_event_obstacle.set()
# Attendre que les threads se terminent
vitesse_thread.join()
obstacle_thread.join()
print("Fin de surveillance de la vitesse")
print("Fin de la surveillance d'obstacle")
Ab.LIDAR_MODULE.close() # Fermeture propre du port série
Ab.cleanup()
# Vérification finale et affichage du statut
if status in ["scenario successful"]:
print("Le scenario fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le scenario a rencontré un problème : {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -0,0 +1,56 @@
import time
import sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
# Variable de statut pour indiquer le bon fonctionnement
status = "initialization"
# Durée limite d'exécution en secondes
time_limit = 10
start_time = time.time()
try:
# Envoi de la commande pour initialiser le capteur
while True:
# Vérification si le temps limite est dépassé
if time.time() - start_time > time_limit:
break
if Ab.LIDAR_MODULE.in_waiting >= 9:
if b'Y' == Ab.LIDAR_MODULE.read() and b'Y' == Ab.LIDAR_MODULE.read():
Dist_L = Ab.LIDAR_MODULE.read()
Dist_H = Ab.LIDAR_MODULE.read()
Dist_Total = (Dist_H[0] * 256) + Dist_L[0]
for i in range(0, 5):
Ab.LIDAR_MODULE.read() # Lecture et ignore des octets supplémentaires
print("Distance à l'avant du véhicule:", Dist_Total, "cm")
status = "measurement successful"
# Ajuster la vitesse en fonction de la distance LIDAR
vitesse_ajustee = Ab.ajuster_vitesse_selon_distance(Dist_Total)
if vitesse_ajustee > 0:
Ab.forward(0.1, vitesse_ajustee) # Avancer avec la vitesse ajustée
else:
Ab.emergencystop() # S'arrêter si trop proche d'un obstacle
Ab.LIDAR_MODULE.reset_input_buffer()
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
Ab.LIDAR_MODULE.close() # Fermeture propre du port série
Ab.cleanup()
# Vérification finale et affichage du statut
if status in ["measurement successful"]:
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import sys
sys.path.append('/home/christian/WebControl/modules/')
from SimpleMFRC522 import SimpleMFRC522
RFID_MODULE = SimpleMFRC522()
from AlphaBot import AlphaBot
Ab = AlphaBot()
try:
# Lecture initiale du tag RFID
print("### Lecture RFID ###")
print("Approchez le tag RFID du capteur:")
print("(ID, Contenu)", RFID_MODULE.read())
time.sleep(3)
# Écriture sur le tag RFID
data = "TEST RFID "
print("### Écriture RFID ###")
print("Valeur qui sera écrite:", data)
print("Approchez le tag RFID du capteur:")
RFID_MODULE.write(data)
print("Succès de l'écriture sur le tag RFID.")
time.sleep(3) # Attente courte avant de vérifier l'écriture
# Seconde lecture du tag RFID
print("### Lecture RFID ###")
print("Approchez le tag RFID du capteur:")
print("(ID, Contenu)", RFID_MODULE.read())
time.sleep(3)
except Exception as e:
print(f"Erreur lors de l'écriture RFID: {e}")

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess, time, sys
sys.path.append('/home/christian/WebControl/modules/')
from SimpleMFRC522 import SimpleMFRC522
RFID_MODULE = SimpleMFRC522()
from AlphaBot import AlphaBot
Ab = AlphaBot()
status = "initialization"
try:
while True:
time.sleep(3)
# Ab.set_angle(0)
print("La porte est actuellement fermée.\nVeuillez approcher votre badge RFID du capteur pour accéder au véhicule.")
id_rfid, text_rfid = RFID_MODULE.read()
rfid_content = RFID_MODULE.read()
if text_rfid == "TEST RFID ":
Ab.set_angle(90)
print(f"Bienvenue, {text_rfid.rstrip()} \nJe suis heureux de pouvoir partager un trajet avec vous !")
time.sleep(5)
print("Installez-vous confortablement !")
time.sleep(2)
print("Votre voiture autonome est prête à partir.")
try:
subprocess.run(['python3', 'apps/itineraire_create.py'], check=True)
try:
print("Nous préparons votre trajet en toute sécurité.")
Ab.set_angle(0)
# Changer si nécessaire 'apps/itineraire_suivre.py' en 'apps/itineraire_suivre_emergency.py'
subprocess.run(['python3', 'apps/itineraire_suivre_emergency.py'], check=True)
print("Merci d'avoir utilisé notre service !")
time.sleep(2)
Ab.set_angle(90)
print("Nous espérons que vous avez apprécié votre trajet.")
time.sleep(2)
print("À bientôt avec CARIA !")
status = "scenario successful"
except subprocess.CalledProcessError as e:
print(f"Erreur lors de l'exécution du script step2_suivre_itineraire: {e}")
status = "error"
except subprocess.CalledProcessError as e:
print(f"Erreur lors de l'exécution du script step1_prepare_itineraire: {e}")
status = "error"
elif text_rfid in ["CHRIS "]:
Ab.set_angle(90)
print(f"Bienvenue, {text_rfid.rstrip()}.\nLa porte du véhicule est maintenant ouverte!")
status = "scenario successful"
else:
Ab.set_angle(0)
print("Bonjour, vous n'êtes pas autorisé à entrer dans le véhicule.\nLa porte reste fermée.")
print(rfid_content)
time.sleep(2)
status = "interrupted"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
Ab.PWMSERVO.stop()
Ab.cleanup()
# Vérification finale et affichage du statut
if status == "movement successful":
print("Le scenario fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le scenario a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -17,7 +17,7 @@ input {
.counter {
position: relative;
bottom: 98px;
left: 0px;
left: 50px;
font-size: 48px;
text-align: center;
color: blue;
@@ -47,42 +47,6 @@ input {
transition: box-shadow 0.3s;
border-radius: 50px;
}
.button_fct {
margin: 10px 15px 10px 15px;
width: auto;
height: 50px;
transition: box-shadow 0.3s;
border-radius: 50px;
}
/* Button toogle */
.button-container {
display: flex;
flex-direction: column;
align-items: flex-start;
}
input[type="checkbox"] {
margin: 10px 15px 10px 15px;
width: 50px;
height: 30px;
-webkit-appearance: none;
appearance: none;
background-color: #ddd;
border-radius: 25px;
position: relative;
cursor: pointer;
}
input[type="checkbox"]:before {
content: '';
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: white;
top: 50%;
left: 3px;
transform: translateY(-50%);
transition: 0.2s;
}
input[type="checkbox"]:checked:before {
left: calc(100% - 33px);
.form-check-input {
transform: scale(1.5); /* Augmente la taille du bouton */
}

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Arrêter le processus motion
if ! sudo pkill -f motion; then
echo "Erreur: Impossible d'arrêter le processus motion."
exit 1
fi
# Attendre quelques secondes pour s'assurer que le processus est bien arrêté
sleep 5
# Démarrer le processus motion
if ! sudo /usr/bin/motion &; then
echo "Erreur: Impossible de démarrer le processus motion."
exit 1
fi
# Attendre quelques secondes pour s'assurer que le processus est bien démarré
sleep 5
echo "Le service motion a été redémarré avec succès. Vous pouvez maintenant vérifier le fonctionnement sur l'interface web."
# Ouvrir l'interface web dans le navigateur par défaut
echo "Pour tester la vidéo, ouvrez le lien suivant dans votre navigateur : http://192.168.253.194:8081/"

View File

@@ -0,0 +1,10 @@
#!/bin/bash
# Naviguer vers le répertoire du module MFRC522
cd modules/MFRC522-python
# Installer le module MFRC522
sudo python3 setup.py install
# Confirmation de l'installation
echo "Installation du module MFRC522 terminée."

View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Afficher un message de confirmation
echo "Le Raspberry Pi va redémarrer maintenant."
# Redémarrer le Raspberry Pi
sudo reboot

Binary file not shown.

View File

@@ -31,6 +31,7 @@ ExplorerHAT==0.4.2
Flask==1.1.2
Flask-SocketIO==5.3.6
fourletterphat==0.1.0
future==1.0.0
gpiozero==1.6.2
greenlet==3.0.3
guizero==1.1.1
@@ -40,6 +41,7 @@ idna==2.10
ipykernel==5.4.3
ipython==7.20.0
ipython_genutils==0.2.0
iso8601==2.1.0
isort==5.6.4
itsdangerous==1.1.0
jedi==0.18.0
@@ -96,7 +98,7 @@ pyOpenSSL==20.0.1
pyparsing==2.4.7
PyQt5==5.15.2
PyQt5-sip==12.8.1
pyserial==3.5b0
pyserial==3.5
pysmbc==1.0.23
python-apt==2.2.1
python-dateutil==2.8.1
@@ -122,6 +124,7 @@ semver==2.10.2
Send2Trash==1.6.0b1
sense-emu==1.2
sense-hat==2.6.0
serial==0.0.97
simple-websocket==1.0.0
simplejpeg==1.6.4
simplejson==3.17.2

7
WebControl/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,119 +1,26 @@
$(function(){
var isTouchDevice = "ontouchstart" in document.documentElement ? true : false;
var BUTTON_DOWN = isTouchDevice ? "touchstart" : "mousedown";
var BUTTON_UP = isTouchDevice ? "touchend" : "mouseup";
$("input[type='checkbox']").change(function() {
var id = this.id;
if (this.checked) {
$.post("/cmd", id, function(data, status){});
} else {
$.post("/cmd", "stop", function(data, status){});
}
});
$('input[type="range"]').change(function() {
var speed = this.value;
$.post('/cmd', {speed: speed});
});
});
// Test
$(function() {
$('#servo').change(function() {
var isChecked = $(this).is(':checked');
var action = isChecked ? 'start' : 'stop';
$.post('/servo_motor', { action: action });
});
});
$(function() {
$('#motor').change(function() {
var isChecked = $(this).is(':checked');
var action = isChecked ? 'start' : 'stop';
$.post('/motor_speed_move', { action: action });
});
});
$(function() {
$('#obstacle').change(function() {
var isChecked = $(this).is(':checked');
var action = isChecked ? 'start' : 'stop';
$.post('/infrared_obstacle_module', { action: action });
});
});
$(function () {
$("#lidar").change(function () {
var isChecked = $(this).is(":checked");
var action = isChecked ? "start" : "stop";
$.post("/lidar_module", { action: action });
});
});
$(function () {
$("#rfidrw").change(function () {
var isChecked = $(this).is(":checked");
var action = isChecked ? "start" : "stop";
$.post("/rfid_read_write_module", { action: action });
});
});
// Fonctionnalité
$(function () {
$("#ITO").change(function () {
var isChecked = $(this).is(":checked");
var action = isChecked ? "start" : "stop";
$.post("/infrared_tracking_objects", { action: action });
});
});
$(function () {
$("#IOA").change(function () {
var isChecked = $(this).is(":checked");
var action = isChecked ? "start" : "stop";
$.post("/infrared_obstacle_avoidance", {
action: action,
});
});
});
// Fonction pour mettre à jour l'angle de rotation de l'aiguille en fonction de la vitesse
function updateRotation(speed) {
const minSpeed = 0; // Vitesse minimale en km/h
const maxSpeed = 120; // Vitesse maximale en km/h
const maxAngle = 138; // Angle maximal de l'aiguille (correspondant à la vitesse maximale)
// Limiter la vitesse minimale
speed = Math.max(minSpeed, speed);
// Limiter la vitesse maximale
speed = Math.min(maxSpeed, speed);
// Calcul de l'angle en fonction de la vitesse
const angle = (speed / maxSpeed) * maxAngle;
// Mise à jour de l'aiguille avec le nouvel angle
updatePointerRotation(angle);
}
// Fonction pour mettre à jour l'aiguille avec un nouvel angle
function updatePointerRotation(angle) {
const minAngle = -130; // Angle minimal de l'aiguille
const maxAngle = 138; // Angle maximal de l'aiguille
// Limiter l'angle minimum
const maxAngle = 138; // Angle maximal de l'aiguille (correspondant à la vitesse maximale)
// Limiter la vitesse et angle minimale
speed = Math.max(minSpeed, speed);
// Limiter la vitesse et angle maximale
speed = Math.min(maxSpeed, speed);
// Calcul de l'angle en fonction de la vitesse
var angle = (speed / maxSpeed) * maxAngle;
angle = Math.max(minAngle, angle);
// Limiter l'angle maximum
angle = Math.min(maxAngle, angle);
// Mise à jour de l'aiguille avec le nouvel angle
// Calculer la rotation en fonction de l'angle et de la direction
let rotation = (angle + 112) * 1.923; // Convertir l'angle en rotation (360/242)
// Mise à jour de l'aiguille
const pointer = document.getElementById("pointer");
pointer.style.transform = `translateX(-50%) rotate(${rotation}deg)`;
}
// Fonction pour mettre à jour le compteur avec la nouvelle valeur de vitesse
function updateCounter(speed) {
const counter = document.getElementById("counter");
// Ajouter des zéros devant la vitesse si elle est inférieure à 100
const formattedSpeed = ("000" + speed).slice(-3);
counter.textContent = formattedSpeed;
}
$(function () {
var isTouchDevice = "ontouchstart" in document.documentElement ? true : false;
var BUTTON_DOWN = isTouchDevice ? "touchstart" : "mousedown";
@@ -131,12 +38,40 @@ $(function () {
$("input").change(function () {
var speed = this.value;
const counter = document.getElementById("counter");
$("#speed-display").text(speed); // Met à jour l'élément HTML avec l'id 'speed-display' avec la nouvelle valeur
updateRotation(speed); // Met à jour l'aiguille avec la nouvelle vitesse
updateCounter(speed); // Met à jour le compteur avec la nouvelle vitesse
$.post("/cmd", { speed: speed }); // Envoie la nouvelle valeur de vitesse au serveur
// Ajouter des zéros devant la vitesse si elle est inférieure à 100
const formattedSpeed = ("000" + speed).slice(-3);
counter.textContent = formattedSpeed; $.post("/cmd", { speed: speed }); // Envoie la nouvelle valeur de vitesse au serveur
});
// Positionner l'aiguille à la valeur 50 lors de l'initialisation
updateRotation(50);
updateRotation(30);
});
$(function () {
var isTouchDevice = "ontouchstart" in document.documentElement ? true : false;
var BUTTON_DOWN = isTouchDevice ? "touchstart" : "mousedown";
var BUTTON_UP = isTouchDevice ? "touchend" : "mouseup";
$("input[type='checkbox']").change(function () {
var id = this.id;
if (this.checked) {
$.post("/cmd", id, function (data, status) {});
} else {
$.post("/cmd", "stop", function (data, status) {});
}
});
$('input[type="range"]').change(function () {
var speed = this.value;
$.post("/cmd", { speed: speed });
});
});
function confirmReboot() {
if (confirm("Êtes-vous sûr de vouloir redémarrer le Raspberry Pi ?")) {
document.getElementById("rebootForm").submit();
}
}

View File

@@ -0,0 +1,21 @@
$(document).ready(function () {
function updateTestStatus() {
$.getJSON("/test_status", function (data) {
let tableBody = $("#testStatusTable");
tableBody.empty(); // Vider le tableau avant d'ajouter les nouvelles lignes
// Parcourir les résultats des tests et ajouter une ligne pour chaque test
$.each(data, function (test, result) {
let status = result ? "Réussi" : "Échoué";
let row = `<tr><td>${test}</td><td>${status}</td></tr>`;
tableBody.append(row);
});
});
}
// Mettre à jour l'état des tests toutes les 5 secondes
setInterval(updateTestStatus, 5000);
// Appel initial pour charger l'état des tests immédiatement
updateTestStatus();
});

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
[
{
"distance_value": 141,
"maneuver": "maneuver-unspecified"
},
{
"distance_value": 231,
"maneuver": "turn-sharp-left"
},
{
"distance_value": 397,
"maneuver": "maneuver-unspecified"
},
{
"distance_value": 70,
"maneuver": "maneuver-unspecified"
},
{
"distance_value": 160,
"maneuver": "turn-left"
},
{
"distance_value": 407,
"maneuver": "turn-right"
},
{
"distance_value": 424,
"maneuver": "turn-left"
},
{
"distance_value": 960,
"maneuver": "roundabout-right"
},
{
"distance_value": 2230,
"maneuver": "ramp-right"
},
{
"distance_value": 5935,
"maneuver": "fork-right"
},
{
"distance_value": 4403,
"maneuver": "fork-right"
},
{
"distance_value": 3099,
"maneuver": "ramp-left"
},
{
"distance_value": 391,
"maneuver": "keep-left"
},
{
"distance_value": 1674,
"maneuver": "merge"
},
{
"distance_value": 829,
"maneuver": "keep-left"
},
{
"distance_value": 413,
"maneuver": "keep-left"
},
{
"distance_value": 193,
"maneuver": "merge"
},
{
"distance_value": 476,
"maneuver": "turn-left"
},
{
"distance_value": 305,
"maneuver": "turn-right"
}
]

View File

@@ -0,0 +1,22 @@
[
{
"distance_value": 197,
"maneuver": "maneuver-unspecified"
},
{
"distance_value": 1313,
"maneuver": "turn-right"
},
{
"distance_value": 507,
"maneuver": "ramp-right"
},
{
"distance_value": 4465,
"maneuver": "merge"
},
{
"distance_value": 5935,
"maneuver": "fork-right"
}
]

455
WebControl/logs/steps.json Normal file
View File

@@ -0,0 +1,455 @@
[
{
"distance": {
"text": "0.1 km",
"value": 141
},
"duration": {
"text": "1 min",
"value": 37
},
"end_location": {
"lat": 48.82129579999999,
"lng": 2.2737025
},
"html_instructions": "Head <b>southwest</b> on <b>Rue de l'Abbé Grégoire</b> toward <b>Rue de la Glacière</b>",
"polyline": {
"points": "kq~hHsj{LdAxBDHP`@@@JTDHDHDFLXBFJPJP"
},
"start_location": {
"lat": 48.82214339999999,
"lng": 2.2751386
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.2 km",
"value": 231
},
"duration": {
"text": "1 min",
"value": 64
},
"end_location": {
"lat": 48.821996,
"lng": 2.276619
},
"html_instructions": "Sharp <b>left</b> onto <b>Rue d'Alembert</b>",
"maneuver": "turn-sharp-left",
"polyline": {
"points": "cl~hHsa{L@M@I?K?K?GAIAKAEAKAKIk@AEE_@AECSc@sDMs@GUEMCKCGKSY{@"
},
"start_location": {
"lat": 48.82129579999999,
"lng": 2.2737025
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.4 km",
"value": 397
},
"duration": {
"text": "1 min",
"value": 71
},
"end_location": {
"lat": 48.8230712,
"lng": 2.2815447
},
"html_instructions": "Continue onto <b>Rue de l'Abbé Derry</b>",
"polyline": {
"points": "op~hH{s{LKFIs@COAM?O@y@@a@?u@CeAAg@AUCq@CSAQCWEYG]ESMg@ACQu@EOWgAa@}BAKCMAECESk@Qa@"
},
"start_location": {
"lat": 48.821996,
"lng": 2.276619
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "70 m",
"value": 70
},
"duration": {
"text": "1 min",
"value": 21
},
"end_location": {
"lat": 48.8234637,
"lng": 2.2822848
},
"html_instructions": "Continue onto <b>Rue du Chevalier de la Barre</b>",
"polyline": {
"points": "ew~hHsr|LUm@M_@EKM_@CGCC?AAAAACAEE"
},
"start_location": {
"lat": 48.8230712,
"lng": 2.2815447
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.2 km",
"value": 160
},
"duration": {
"text": "1 min",
"value": 41
},
"end_location": {
"lat": 48.8248221,
"lng": 2.2819013
},
"html_instructions": "Turn <b>left</b> onto <b>Av. du Général de Gaulle</b>/<wbr/><b>D71</b>",
"maneuver": "turn-left",
"polyline": {
"points": "sy~hHgw|L_@Je@Ja@LQFG@_@HC@EB_@NC@WJIBA@A?A?A?A?A?AAA?AA?AAAACGK"
},
"start_location": {
"lat": 48.8234637,
"lng": 2.2822848
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.4 km",
"value": 407
},
"duration": {
"text": "1 min",
"value": 82
},
"end_location": {
"lat": 48.8219346,
"lng": 2.2853073
},
"html_instructions": "Turn <b>right</b> onto <b>Bd du Lycée</b>/<wbr/><b>D50</b>",
"maneuver": "turn-right",
"polyline": {
"points": "cb_iH{t|Lb@g@`DcEpFcHZ_@tAcBVU"
},
"start_location": {
"lat": 48.8248221,
"lng": 2.2819013
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.4 km",
"value": 424
},
"duration": {
"text": "1 min",
"value": 83
},
"end_location": {
"lat": 48.8204157,
"lng": 2.2905512
},
"html_instructions": "Turn <b>left</b> onto <b>Rue Antoine Fratacci</b>/<wbr/><b>D50</b>",
"maneuver": "turn-left",
"polyline": {
"points": "ap~hHej}L?EAG?E?A?C?I?G?ALuBD[BYDW@ADU?CVeAh@wBZsAZoAFSJc@Jm@@ELk@@EVgA`@_BFWFWFSJ]"
},
"start_location": {
"lat": 48.8219346,
"lng": 2.2853073
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "1.0 km",
"value": 960
},
"duration": {
"text": "3 mins",
"value": 203
},
"end_location": {
"lat": 48.8253839,
"lng": 2.3004907
},
"html_instructions": "At the roundabout, take the <b>4th</b> exit onto <b>Rue Jean Bleuzen</b>/<wbr/><b>D130</b>",
"maneuver": "roundabout-right",
"polyline": {
"points": "sf~hH}j~L@@@?@?@@@?@?@?@?@?@ABA@A@A@A@A@A@C?A@A?A@A?C?A@A?A?C?A?C?C?AAC?A?CAA?CAA?AACAAACAAA?AA?AA?A?AAC?A?A?A?A@O_@GOGSGOGQe@eAOQi@kAMYO[o@sAEIYk@Wk@Yk@MUEMo@qAO]_@u@Qc@GMM[Sg@EKGSQ_@_@eACGEKIQm@_B?AM[IQ?CGKOc@G[AKAGAEAG_AeCM_@]eA[w@CICIGQIQM_@Si@GSYy@KSKWEICGIMIIIIECEEIAG?"
},
"start_location": {
"lat": 48.8204157,
"lng": 2.2905512
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "2.2 km",
"value": 2230
},
"duration": {
"text": "4 mins",
"value": 219
},
"end_location": {
"lat": 48.8192297,
"lng": 2.3292151
},
"html_instructions": "Turn <b>right</b> to merge onto <b>Blvd Périphérique</b>",
"maneuver": "ramp-right",
"polyline": {
"points": "se_iHai`MU@VeB@A?A^mCJq@TiBD]Jw@Fs@RsB?ACa@J}@BUPqAJs@VoBFe@@C\\iCNaAJu@Fe@D[PmAHi@Da@DU@GVqBl@mEr@gF\\aCb@eD`@yCb@yCJ{@VgBRwAFe@F]N_ATiAJg@PcAD[Ly@VmBRwAZwBD]Hg@@MRuADUFi@NgANmA@ERuBH_A@MLgA@M@OLy@D_@Jq@Js@?CHo@F_@R{AHm@L}@Hm@Jw@PoAVgBFa@DYR}A?AVeB?CLgAVuBRuAJ{@"
},
"start_location": {
"lat": 48.8253839,
"lng": 2.3004907
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "5.9 km",
"value": 5935
},
"duration": {
"text": "5 mins",
"value": 287
},
"end_location": {
"lat": 48.7705456,
"lng": 2.3452899
},
"html_instructions": "Keep <b>right</b> at the fork to continue on <b>A6a</b>",
"maneuver": "fork-right",
"polyline": {
"points": "e_~hHs|eMLI@AFa@BGF]@IFa@DQHYJw@Fg@@GBK@M@IFg@LeABYFg@@IDY@M?CHi@BO@I@G@IBIBMDQDMBK@IDMBIBGBGFMDKBGBIDIHODIJQHOLQHOHOPWNWLSLSLSHOBALUDKDGFOFOBGBKJWBKBK@GBI@IFg@L}@H_A@CBY@C?GBIBK@G?A@C@A@C?A@A@A@A@ABCBABCDAJEFCFCDADAFAFAD?B?B?B?B?D?D@D?D@FBH@FBLDh@PVHRFn@TTHTFVHVFTFTFVBVDT@J@P@N?J?L?B?VAFAPAVCTCVGVEDCPETIRIVKRKBCTMVQHGJI@AJIFEDC?ADCHKFIBA@A?A@A@EdBwAnBaBJKNM?AHIHGrAkAJInBeBPOVUVSPQj@e@RQJKFGNMpAiAJIHIROFGROTQPMbAm@~@e@TKZM^O`@Mj@QTGTEVGVE`@G\\E\\ED?RANADAXAx@AxC?dA@l@?T?v@?l@?n@@r@?X?P?T?X?X@VAN?ZATATAPAH?LAPCLCNCTEB?NEr@QBARGRIRI\\MRKFEb@URMRKPMJILKJINKFGDCr@m@HGb@_@f@c@TQTQTQPMVOFELINIl@[TKVKRIXKBAf@Oh@OVE@A^G`@G\\Ep@G^Ah@AL?H?P?N?X@H?L@XBD?`@D`@Dj@JhDh@NBzATH@XDz@N\\Dt@Lf@Dl@DH?J?F@f@?L@^Cb@Ab@C`@EB?ZEh@I\\INCPEJCTG`@ONE~@]PITIlBu@NIz@[f@QlAe@bBo@p@WTIf@ONGf@O`@K`@K\\I@?BAh@KREFATE\\EZEh@If@GTC^CFAb@CLAb@AVCN?H?TAJ?fA?^?P?^@X@f@B^@N@v@Ff@B^B\\BrBL`@BN@n@DVB^BB?|@F|@FL?F@R@F@bAFZ@VBl@D`AFf@DF?d@DJ?x@Df@DF@H?dAFX@B@T@fNz@v@Fn@Df@BJ@N@P@D?RBfAHR@n@FF@z@L"
},
"start_location": {
"lat": 48.8192297,
"lng": 2.3292151
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "4.4 km",
"value": 4403
},
"duration": {
"text": "3 mins",
"value": 193
},
"end_location": {
"lat": 48.7348556,
"lng": 2.3655247
},
"html_instructions": "Keep <b>right</b> at the fork to continue on <b>A106</b>, follow signs for <b>Aéroport Orly</b>",
"maneuver": "fork-right",
"polyline": {
"points": "}nthHaaiMJX@?HBf@NTFp@X@?`@Pj@V`@Rf@XB@f@VVNXPDBTLTLPJRH\\LVHZH\\Hh@JNBF@P@j@Db@Bl@?@?d@Al@AX?z@AFAJ?d@CNBfEWLCf@GB?TEZGVCREj@Mp@Sn@QTI^Oh@SBAb@Q\\Q\\QVOVMv@e@LKl@c@NKZUf@c@VUPQb@a@DEj@k@hAgAzB{B`B_BjEgE\\]nGkGtAuAPQFGVUPSx@w@hAiAJI\\]JIJK@Ax@w@PSRSt@s@nDmD~B}BXYZYJM|@}@zAyABA^_@VYj@i@`@a@XY\\]ZW~F}FtAsAJKXYJKh@i@TSj@k@FIDCRSBCHITS`@c@FG|@{@v@w@TULKTUXYDCJKNOJKJIZYPONMPOROLKd@[^UDCFEFEBAPKLIZO`@STK\\M^On@Uj@STGbBi@JEPGRGFADCLEh@Q|@Yp@SXKVITGdA]^MXI~@Yz@YNG`@M`@M^Mv@Wl@QDA\\Mx@WVI`@MXKNERG|@YJE|Bu@PEHE@?DA|Bu@lBm@l@O"
},
"start_location": {
"lat": 48.7705456,
"lng": 2.3452899
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "3.1 km",
"value": 3099
},
"duration": {
"text": "5 mins",
"value": 271
},
"end_location": {
"lat": 48.7074919,
"lng": 2.3713861
},
"html_instructions": "Exit on the <b>left</b> onto <b>N7</b> toward <b>Évry</b>/<wbr/><b>Paray-Vieille-Poste</b>/<wbr/><b>Athis-Mons</b>",
"maneuver": "ramp-left",
"polyline": {
"points": "{omhHo_mMHU@ABCrAe@PIZKvAg@d@S@A`@]l@QbA]`@MXIpBo@\\MVIj@QdA]BAhA]vAe@XKf@OhBk@BAv@SnC{@fBk@RGzBq@vBs@n@Un@Un@Uh@O^MjC{@LEb@O\\INEXI^IHCJCJALCNCLCNAtAMD?FAfHOb@Ab@Ab@AjDIZAZ?vEKvCGbECF?hBGl@CPBRAd@AfAEj@CTAD?zAItCGn@A~@Ch@AD?TC^?~AEnCEfACb@A^?VAZAnAG\\CTARAx@?pAC|@CTAR?z@Cr@A~@Ax@A"
},
"start_location": {
"lat": 48.7348556,
"lng": 2.3655247
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.4 km",
"value": 391
},
"duration": {
"text": "1 min",
"value": 45
},
"end_location": {
"lat": 48.7039886,
"lng": 2.3716268
},
"html_instructions": "Keep <b>left</b>",
"maneuver": "keep-left",
"polyline": {
"points": "ydhhHednMJGTAbAAlAC~AEl@Al@CxBED?NAZAF?NAtAEd@CJ@"
},
"start_location": {
"lat": 48.7074919,
"lng": 2.3713861
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "1.7 km",
"value": 1674
},
"duration": {
"text": "4 mins",
"value": 258
},
"end_location": {
"lat": 48.6890215,
"lng": 2.3710222
},
"html_instructions": "Merge onto <b>Av. François Mitterrand</b>/<wbr/><b>N7</b><div style=\"font-size:0.9em\">Continue to follow N7</div>",
"maneuver": "merge",
"polyline": {
"points": "}nghHuenMh@Av@?TARAvBEjBEp@AzAEx@?VAb@AdAEv@AjACh@?^?p@?f@Ax@AbAAJ?RBTBn@J~C^lANz@FbAJr@H|ARp@HB@xBXjAN^D`@FH@`BPx@LxCZp@Db@@F?Z@R@zB@\\ATAx@Ij@K\\G\\GHAh@Kf@MXKVI"
},
"start_location": {
"lat": 48.7039886,
"lng": 2.3716268
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.8 km",
"value": 829
},
"duration": {
"text": "2 mins",
"value": 116
},
"end_location": {
"lat": 48.6828291,
"lng": 2.3771681
},
"html_instructions": "Keep <b>left</b> to continue on <b>Av. de la Cr de France</b>/<wbr/><b>N7</b><div style=\"font-size:0.9em\">Continue to follow N7</div>",
"maneuver": "keep-left",
"polyline": {
"points": "kqdhH{anMxAm@LG@?\\Sd@UzA{@VOf@c@fAeAjAmAf@g@PSNQp@y@Z_@\\_@`@c@TWj@u@^g@h@q@@?RWd@k@TWl@u@h@q@Za@jAyA`AiAp@y@LQ"
},
"start_location": {
"lat": 48.6890215,
"lng": 2.3710222
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.4 km",
"value": 413
},
"duration": {
"text": "1 min",
"value": 34
},
"end_location": {
"lat": 48.6799071,
"lng": 2.3806212
},
"html_instructions": "Keep <b>left</b>",
"maneuver": "keep-left",
"polyline": {
"points": "ujchHihoMLWn@y@FIHI\\c@Za@f@m@jAwAZa@Za@rAcBt@_ARUTYf@m@b@i@BELI"
},
"start_location": {
"lat": 48.6828291,
"lng": 2.3771681
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.2 km",
"value": 193
},
"duration": {
"text": "1 min",
"value": 34
},
"end_location": {
"lat": 48.6785366,
"lng": 2.3822313
},
"html_instructions": "Merge onto <b>Av. du Général de Gaulle</b>/<wbr/><b>N7</b>",
"maneuver": "merge",
"polyline": {
"points": "mxbhH{}oMzD{ELOfAuA"
},
"start_location": {
"lat": 48.6799071,
"lng": 2.3806212
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.5 km",
"value": 476
},
"duration": {
"text": "2 mins",
"value": 108
},
"end_location": {
"lat": 48.68178,
"lng": 2.385035
},
"html_instructions": "Turn <b>left</b> onto <b>Rue Carnot</b>",
"maneuver": "turn-left",
"polyline": {
"points": "{obhH}gpMKSQYS[IQCQ?SAOAu@?SAI?CAEEIIYACAACCA?A?A?A?C@EBIFIHURA@C?A?A?AACCQWQQY[IIGEMGGCSKuAi@[MgAc@m@U]KQCQCWCC?GAGAAAAAA??AAACMAE?C?C?E@G?K"
},
"start_location": {
"lat": 48.6785366,
"lng": 2.3822313
},
"travel_mode": "DRIVING"
},
{
"distance": {
"text": "0.3 km",
"value": 305
},
"duration": {
"text": "1 min",
"value": 30
},
"end_location": {
"lat": 48.67910939999999,
"lng": 2.3859466
},
"html_instructions": "Turn <b>right</b> onto <b>Quai de Châtillon</b>/<wbr/><b>D931</b><div style=\"font-size:0.9em\">Destination will be on the left</div>",
"maneuver": "turn-right",
"polyline": {
"points": "cdchHmypMXGr@IBAbBY~A[bAYNERGx@YrAe@HE"
},
"start_location": {
"lat": 48.68178,
"lng": 2.385035
},
"travel_mode": "DRIVING"
}
]

View File

@@ -1,155 +1,180 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
from bottle import get,post,run,route,request,template,static_file,TEMPLATE_PATH
from bottle import get,redirect,post,run,route,request,response,template,static_file,TEMPLATE_PATH
from joyit_mfrc522 import SimpleMFRC522
from modules.AlphaBot import AlphaBot
import threading, socket, os, sys, time, subprocess, ssl
import threading, socket, os, sys, time, subprocess, ssl, json,signal
TEMPLATE_PATH.append('/home/christian/WebControl/')
car = AlphaBot()
certfile = '/home/christian/WebControl/ssl/cert.pem'
keyfile = '/home/christian/WebControl/ssl/key.pem'
Ab = AlphaBot()
script_process = None
speed = 50 # Valeur de vitesse par défaut
duration = 1
speed = 30
# Stocke les dernières données reçues
validation_results = {"name": None, "confidence": None}
@get("/")
def index():
return template('templates/index')
# Chemin vers le fichier JSON
json_file_path = '/home/christian/WebControl/logs/resultats_tests.json'
# Lire le fichier JSON
with open(json_file_path, 'r') as f:
data = json.load(f)
last_15_results = data[-10:][::-1]
return template('templates/index', message="", results=last_15_results)
@get("/tests")
def tests():
return template("templates/tests")
# Test programmes
@post('/servo_motor')
def servo_motor():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'tests/servo_motor.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post('/motor_speed_move')
def motor_speed_move():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'tests/motor_speed_move.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post('/infrared_obstacle_module')
def infrared_obstacle_module():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'tests/infrared_obstacle_module.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post('/lidar_module')
def lidar_module():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['sudo', 'python3', 'tests/lidar_module.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post('/rfid_read_write_module')
def rfid_read_write_module():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'tests/rfid_read_write_module.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@get("/access")
def show_validation():
# Rendre le fichier HTML access.html avec les résultats actuels
return template("templates/access",name=validation_results["name"],confidence=validation_results["confidence"],status="Aucune validation reçue" if not validation_results["name"] else "Succès")
# Fonctionnalité programmes
@post('/infrared_tracking_objects')
def infrared_tracking_objects():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'apps/infrared_tracking_objects.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post('/infrared_obstacle_avoidance')
def infrared_obstacle_avoidance():
global script_process # Assurez-vous d'utiliser la variable globale script_process dans cette fonction
action = request.forms.get('action')
if action == 'start':
script_process = subprocess.Popen(['python3', 'apps/infrared_obstacle_avoidance.py'])
elif action == 'stop' and script_process is not None:
script_process.terminate() # Arrêter le script si script_process est défini
return 'OK'
@post("/access")
def access():
global validation_results
# Récupère les données de la requête
data = request.json
name = data.get('name')
confidence = data.get('confidence')
# Met à jour les résultats
validation_results["name"] = name
validation_results["confidence"] = confidence
# Affiche les résultats dans la console
print(f"Validation received: Name: {name}, Confidence: {confidence}")
# Répond avec un succès
response.status = 200
return {"status": "success"}
@post("/restartPi")
def restart_pi():
try:
# Commande pour redémarrer le Raspberry Pi
subprocess.run('sudo reboot', shell=True, check=True)
message = "Redémarrage en cours..."
except Exception as e:
# Gestion des erreurs, retour d'un message d'erreur si la commande échoue
message = f"Erreur lors du redémarrage: {str(e)}"
# Retourne un message au client
return template('<b>{{message}}</b><br><form action="/" method="post"><input type="submit" value="Retour"></form>', message=message)
@post("/restartMotion")
def restart_motion():
try:
# Arrêter Motion si en cours
subprocess.run('sudo pkill -f motion', shell=True, check=True)
# Redémarrer Motion
subprocess.run('sudo /usr/bin/motion', shell=True, check=True)
message = 'Motion redémarré'
except subprocess.CalledProcessError as e:
# Gestion des erreurs si les commandes échouent
message = f"Erreur lors du redémarrage de Motion: {str(e)}"
# Retourner un message au client
return template('<b>{{message}}</b><br><form action="/" method="post"><input type="submit" value="Retour"></form>', message=message)
@post("/cmd")
def cmd():
global speed # Déclarer speed comme variable globale pour pouvoir y accéder dans cette fonction
global speed, script_process
response.content_type = 'application/json'
# Lecture du code de commande depuis la requête
code = request.body.read().decode()
speed_str = request.POST.get('speed')
# Récupération de la vitesse si elle est présente
speed_str = request.forms.get('speed')
if speed_str is not None:
try:
speed = int(speed_str)
if 0 <= speed <= 100:
car.setPWMA(speed)
car.setPWMB(speed)
Ab.setPWMA(speed)
Ab.setPWMB(speed)
print("Vitesse définie à", speed)
else:
return json.dumps({"error": "La vitesse doit être comprise entre 0 et 100."})
except ValueError:
print("") # Invalid speed value
return json.dumps({"error": "La vitesse doit être un nombre entier."})
try:
if code == "stop":
Ab.stop(duration)
message = 'Voiture arrêtée'
elif code == "forward":
Ab.forward(duration, speed)
message = 'Voiture en avant'
elif code == "backward":
Ab.backward(duration, speed)
message = 'Voiture en arrière'
elif code == "turnleft":
Ab.left(duration, speed)
message = 'Voiture tourne à gauche'
elif code == "turnright":
Ab.right(duration, speed)
message = 'Voiture tourne à droite'
# TESTS
elif code == "testServo":
script_process = subprocess.Popen(['python3', 'tests/servo_motor.py'])
message = 'Servo moteur OK'
elif code == "appRFIDCarDoor":
script_process = subprocess.Popen(['python3', 'tests/rfid_open_door.py'])
message = 'Module RFID Door OK'
elif code == "testRotor":
script_process = subprocess.Popen(['python3', 'tests/motor_speed_move.py'])
message = 'Moteurs OK'
elif code == "testLidar":
script_process = subprocess.Popen(['sudo', 'python3', 'tests/lidar_module.py'])
message = 'Module Lidar OK'
elif code == "testObstacle":
script_process = subprocess.Popen(['python3', 'tests/infrared_obstacle_module.py'])
message = 'Module IR obstacle OK'
#APPS
elif code == "appRFID":
script_process = subprocess.Popen(['python3', 'apps/rfid_read_write_module.py'])
message = 'Lecture et écriture RFID OK'
elif code == "appLidarSpeed":
script_process = subprocess.Popen(['sudo', 'python3', 'apps/lidar_speed_move.py'])
message = 'Régulation de la vitesse par Lidar OK'
elif code == "appEmergencyStop":
script_process = subprocess.Popen(['python3', 'apps/infrared_obstacle_avoidance.py'])
message = 'Emergency STOP par IR OK'
else:
return json.dumps({"error": f"Commande inconnue ({code})"})
except Exception as e:
return json.dumps({"error": str(e)})
return json.dumps({"message": message})
if code == "stop":
car.stop()
elif code == "forward":
car.forward(speed)
elif code == "backward":
car.backward(speed)
elif code == "turnleft":
car.left(speed)
elif code == "turnright":
car.right(speed)
else:
print("") # Unknown command
return "OK"
@route('/<filename>')
@route('/<filename:path>')
def server_static(filename):
return static_file(filename, root='./')
@route('/templates/<filename>')
@route('/templates/<filename:path>')
def server_templates(filename):
return static_file(filename, root='./templates/')
@route('/images/<filename>')
@route('/images/<filename:path>')
def server_images(filename):
return static_file(filename, root='./images/')
@route('/fonts/<filename>')
@route('/fonts/<filename:path>')
def server_fonts(filename):
return static_file(filename, root='./fonts/')
@route('/js/<filename>')
@route('/js/<filename:path>')
def server_js(filename):
return static_file(filename, root='./js/')
@route('/css/<filename>')
@route('/css/<filename:path>')
def server_css(filename):
return static_file(filename, root='./css/')
@route('/modules/<filename>')
@route('/modules/<filename:path>')
def server_modules(filename):
return static_file(filename, root='./modules/')
@route('/apps/<filename>')
@route('/apps/<filename:path>')
def server_apps(filename):
return static_file(filename, root='./apps/')
@route('/tests/<filename>')
@route('/tests/<filename:path>')
def server_tests(filename):
return static_file(filename, root='./tests/')
# Chemins vers le certificat SSL et la clé privée
certfile = '/home/christian/WebControl/ssl/cert.pem'
keyfile = '/home/christian/WebControl/ssl/key.pem'
# Créez un contexte SSL
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile)
def wait_for_network():
while True:
try:
@@ -159,9 +184,14 @@ def wait_for_network():
s.close()
return localhost
except OSError:
print("Le réseau est inaccessible. Réessai dans 5 secondes...")
print("Le réseau est inaccessible. Réessayer dans 5 secondes...")
time.sleep(5)
localhost = wait_for_network()
run(host=localhost, port=8000, server='wsgiref', debug=True, ssl_context=ssl_context)
# Créez un contexte SSL
# ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile)
# run(host=localhost, port=8000, server='wsgiref', debug=True, ssl_context=ssl_context)
run(host=localhost, port=8000, server='wsgiref', debug=True)

View File

@@ -1,21 +1,30 @@
import time,json, os, serial, threading, queue
import RPi.GPIO as GPIO
import time
import os
from datetime import datetime
class AlphaBot(object):
def __init__(self, in1=12, in2=13, ena=6, in3=20, in4=21, enb=26):
self.IN1 = in1
self.IN2 = in2
self.IN3 = in3
self.IN4 = in4
self.ENA = ena
self.ENB = enb
# Définition des broches module d'évitement d'obstacles
DAOUT_PIN = 19
AOUT_PIN = 16
def __init__(self):
self.LIDAR_MODULE = serial.Serial('/dev/ttyAMA0', 115200, timeout=1) # SERIAL
self.LIDAR_MODULE.write(b'\x42\x57\x02\x00\x00\x00\x01\x06')
self.RED_LIGHT = 17
self.OBSTACLE_PIN = 16
self.SERVO_PIN = 27
self.IN1 = 12
self.IN2 = 13
self.ENA = 6
self.IN3 = 20
self.IN4 = 21
self.ENB = 26
speed = 30
self.stop_event_obstacle = threading.Event()
self.stop_event_vitesse = threading.Event()
self.vitesse_queue = queue.Queue()
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.OBSTACLE_PIN, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(self.SERVO_PIN, GPIO.OUT)
GPIO.setup(self.RED_LIGHT, GPIO.OUT)
GPIO.setup(self.IN1, GPIO.OUT)
GPIO.setup(self.IN2, GPIO.OUT)
GPIO.setup(self.IN3, GPIO.OUT)
@@ -24,52 +33,267 @@ class AlphaBot(object):
GPIO.setup(self.ENB, GPIO.OUT)
self.PWMA = GPIO.PWM(self.ENA, 500) # Utilisation d'une fréquence de 500 Hz pour le PWM
self.PWMB = GPIO.PWM(self.ENB, 500)
self.PWMSERVO = GPIO.PWM(self.SERVO_PIN, 50) # Utilisation d'une fréquence de 50 Hz pour le servo
self.PWMA.start(0) # Démarre avec un rapport cyclique de 0 (moteurs arrêtés)
self.PWMB.start(0)
self.PWMSERVO.start(0)
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
def stop(self):
def ajuster_vitesse_selon_distance(self, distance, vitesse_max=70, vitesse_min=20):
if distance < 20: # Distance critique, arrêt
vitesse = 0
elif distance < 50: # Très proche, ralentir
vitesse = vitesse_min
else: # Vitesse normale
vitesse = vitesse_max * (distance / 100)
vitesse = max(vitesse_min, min(vitesse, vitesse_max))
return vitesse
def set_angle(self, angle):
if 0 <= angle <= 180:
pulse_width_ms = (angle / 180) * (2 - 1) + 1
duty_cycle = (pulse_width_ms / 20) * 100
self.PWMSERVO.ChangeDutyCycle(duty_cycle)
# Calcul du temps nécessaire pour atteindre l'angle donné
movement_time = (angle / 60) * 0.15 # 0.12 sec pour 60 degrés
time.sleep(movement_time)
else:
print("Angle hors de portée. Le rapport cyclique doit être compris entre 2,5 et 12,5.")
def blink_led(self, blink_duration=0.2):
self.blinking = True
while self.blinking: # Continue tant que blinking est True
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
time.sleep(blink_duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
time.sleep(blink_duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
# Fonction pour les manœuvres non spécifiées
def maneuver_unspecified(self, duration):
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
print("Manoeuvre non spécifiée")
time.sleep(duration)
def stop(self, duration):
GPIO.output(self.RED_LIGHT, GPIO.HIGH)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(0)
self.PWMB.ChangeDutyCycle(0)
print("Le robot est arreté")
def forward(self, speed):
GPIO.output(self.IN1, GPIO.HIGH)
print(f"Arrêt durant {duration} secondes")
time.sleep(duration)
GPIO.output(self.RED_LIGHT, GPIO.LOW)
def emergencystop(self):
# Lancer le clignotement dans un thread séparé
blink_thread = threading.Thread(target=self.blink_led)
blink_thread.start()
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(0)
self.PWMB.ChangeDutyCycle(0)
print("Arrêt d'urgence !")
time.sleep(0.1)
# Stopper le clignotement de la LED
self.blinking = False
blink_thread.join() # Attendre que le thread de clignotement se termine
# FORWARD MOVE
def forward(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Avancer durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
print("Le robot avance avec une vitesse de", speed)
def ramp_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.5)
print(f"Traitement pour prendre la rampe de gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def fork_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.1)
print(f"Traitement pour prendre la fourche de gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def ramp_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 1.5)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour prendre la rampe de droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def backward(self, speed):
def fork_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1.1)
print(f"Traitement pour prendre la fourche de droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def merge(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.8)
self.PWMB.ChangeDutyCycle(speed * 0.8)
print(f"Traitement pour fusionner dans le trafic durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
# BACKWARD MOVE
def backward(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Reculer durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
# LEFT MOVE
def left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print("Le robot recul avec une vitesse de", speed)
def left(self, speed):
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
print("Le robot tourne à guauche avec une vitesse de", speed)
def right(self, speed):
print(f"Tourner à guauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_slight_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 0.1)
print(f"Traitement pour tourner légèrement à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_sharp_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1)
print(f"Traitement pour tourner brusquement à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def u_turn_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour faire demi-tour à gauche durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration * 2)
def roundabout_left(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.LOW)
GPIO.output(self.IN2, GPIO.HIGH)
GPIO.output(self.IN3, GPIO.LOW)
GPIO.output(self.IN4, GPIO.HIGH)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 0.5)
print(f"Traitement pour tourner à gauche au rond-point durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
# RIGHT MOVE
def right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print("Le robot tourne à droite avec une vitesse de", speed)
print(f"Tourner à droite durant {duration} secondes à une vitesse de", speed)
time.sleep(duration)
def turn_slight_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.1)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour tourner légèrement à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def turn_sharp_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed * 1)
print(f"Traitement pour tourner brusquement à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def u_turn_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour faire demi-tour à droite durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration * 2)
def roundabout_right(self, duration, speed):
GPIO.output(self.RED_LIGHT, GPIO.LOW)
GPIO.output(self.IN1, GPIO.HIGH)
GPIO.output(self.IN2, GPIO.LOW)
GPIO.output(self.IN3, GPIO.HIGH)
GPIO.output(self.IN4, GPIO.LOW)
self.PWMA.ChangeDutyCycle(speed * 0.5)
self.PWMB.ChangeDutyCycle(speed)
print(f"Traitement pour tourner à droite au rond-point durant {duration} secondes à une vitesse de", speed,"MPH")
time.sleep(duration)
def setPWMA(self, value):
"""
@@ -94,26 +318,75 @@ class AlphaBot(object):
self.PWMA.ChangeDutyCycle(left)
self.PWMB.ChangeDutyCycle(right)
def objetrack_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Tracking_Objects.py')
# Fonction pour surveiller les obstacle en arrière-plan
def monitor_obstacle(self):
global emergency_stop
while not self.stop_event_obstacle.is_set():
DR_status = GPIO.input(self.OBSTACLE_PIN)
if DR_status == 0: # Obstacle détecté
self.emergencystop()
emergency_stop = True
while GPIO.input(self.OBSTACLE_PIN) == 0: # Attendre que l'obstacle soit dégagé
time.sleep(0.1)
print("Obstacle dégagé. Attente de 5 secondes avant de reprendre.")
emergency_stop = False
time.sleep(0.05) # Pause légère pour éviter la surcharge du CPU
def linetrack_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Line_Tracking.py')
def monitor_vitesse(self):
try:
while not self.stop_event_vitesse.is_set():
if self.LIDAR_MODULE.in_waiting >= 9:
if b'Y' == self.LIDAR_MODULE.read() and b'Y' == self.LIDAR_MODULE.read():
Dist_L = self.LIDAR_MODULE.read()
Dist_H = self.LIDAR_MODULE.read()
Dist_Total = (Dist_H[0] * 256) + Dist_L[0]
for i in range(0, 5):
self.LIDAR_MODULE.read() # Lecture et ignore des octets supplémentaires
print("Distance à l'avant du véhicule:", Dist_Total, "cm")
# Définir les paramètres de vitesse
vitesse_max = 50 # Vitesse maximale en unités (à ajuster)
distance_min = 10 # Distance minimale pour une vitesse de 0 (en cm)
# Ajuster la vitesse en fonction de la distance mesurée
if Dist_Total <= distance_min:
vitesse_ajustee = 0 # Arrêter si trop proche
elif Dist_Total > 100: # Distance maximale où la vitesse est maximale
vitesse_ajustee = vitesse_max
else:
# Calculer la vitesse en fonction de la distance
vitesse_ajustee = int(vitesse_max * (Dist_Total - distance_min) / (100 - distance_min))
# Mettre la vitesse ajustée dans la queue
self.vitesse_queue.put(vitesse_ajustee)
except Exception as e:
print(f"Erreur lors de la mesure de la vitesse: {e}")
# En cas d'erreur, vous pouvez décider de placer une valeur par défaut dans la queue
self.vitesse_queue.put(None)
def objetavoid_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Obstacle_Avoidance.py')
def cleanup(self):
GPIO.cleanup()
print("Nettoyage des GPIO effectué.")
def obstacleavoid_ultrason(self):
os.system('sudo python3 ~/AppControl/Ultrasonic_Obstacle_Avoidance.py')
def move_ultrason(self):
os.system('sudo python3 ~/AppControl/Ultrasonic_Ranging.py')
def control_ir(self):
os.system('sudo python3 ~/AppControl/Infrared_Remote_Control.py')
def face_ia(self):
os.system('sudo python3 ~/AppControl/visage_camera_raspberry.py')
def line_ia(self):
os.system('sudo python3 ~/AppControl/visage_camera_v2_raspberry.py')
def enregistrer_resultats(self, nom_script, fonctionnement_ok, status):
# Préparer les données à enregistrer
nouveau_resultat = {
'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'nom': nom_script,
'fonctionnement_ok': fonctionnement_ok,
'status': status
}
# Chemin vers le fichier de logs
fichier_logs = './logs/resultats_tests.json'
# Charger les données existantes si le fichier existe
if os.path.exists(fichier_logs):
with open(fichier_logs, 'r') as f:
try:
resultats = json.load(f)
except json.JSONDecodeError:
resultats = []
else:
resultats = []
# Ajouter le nouveau résultat
resultats.append(nouveau_resultat)
# Enregistrer les résultats mis à jour dans le fichier JSON
with open(fichier_logs, 'w') as f:
json.dump(resultats, f, indent=4)
print("Résultats enregistrés avec succès.")

View File

@@ -0,0 +1,89 @@
# Code by Simon Monk https://github.com/simonmonk/
from joyit_mfrc522 import MFRC522
class SimpleMFRC522:
READER = None
KEY = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
BLOCK_ADDRS = [8, 9, 10]
def __init__(self):
self.READER = MFRC522()
def read(self):
id, text = self.read_no_block()
while not id:
id, text = self.read_no_block()
return id, text
def read_id(self):
id = self.read_id_no_block()
while not id:
id = self.read_id_no_block()
return id
def read_id_no_block(self):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None
return self.uid_to_num(uid)
def read_no_block(self):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None, None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None, None
id = self.uid_to_num(uid)
self.READER.MFRC522_SelectTag(uid)
status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
data = []
text_read = ''
if status == self.READER.MI_OK:
for block_num in self.BLOCK_ADDRS:
block = self.READER.MFRC522_Read(block_num)
if block:
data += block
if data:
text_read = ''.join(chr(i) for i in data)
self.READER.MFRC522_StopCrypto1()
return id, text_read
def write(self, text):
id, text_in = self.write_no_block(text)
while not id:
id, text_in = self.write_no_block(text)
return id, text_in
def write_no_block(self, text):
(status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
if status != self.READER.MI_OK:
return None, None
(status, uid) = self.READER.MFRC522_Anticoll()
if status != self.READER.MI_OK:
return None, None
id = self.uid_to_num(uid)
self.READER.MFRC522_SelectTag(uid)
status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
self.READER.MFRC522_Read(11)
if status == self.READER.MI_OK:
data = bytearray()
data.extend(bytearray(text.ljust(len(self.BLOCK_ADDRS) * 16).encode('ascii')))
i = 0
for block_num in self.BLOCK_ADDRS:
self.READER.MFRC522_Write(block_num, data[(i*16):(i+1)*16])
i += 1
self.READER.MFRC522_StopCrypto1()
return id, text[0:(len(self.BLOCK_ADDRS) * 16)]
def uid_to_num(self, uid):
n = 0
for i in range(0, 5):
n = n * 256 + uid[i]
return n

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,413 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
#
# Copyright 2014,2018 Mario Gomez <mario.gomez@teubi.co>
#
# This file is part of MFRC522-Python
# MFRC522-Python is a simple Python implementation for
# the MFRC522 NFC Card Reader for the Raspberry Pi.
#
# MFRC522-Python is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MFRC522-Python is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with MFRC522-Python. If not, see <http://www.gnu.org/licenses/>.
#
from gpiozero import DigitalOutputDevice
import spidev
import signal
import time
import logging
class MFRC522:
MAX_LEN = 16
PCD_IDLE = 0x00
PCD_AUTHENT = 0x0E
PCD_RECEIVE = 0x08
PCD_TRANSMIT = 0x04
PCD_TRANSCEIVE = 0x0C
PCD_RESETPHASE = 0x0F
PCD_CALCCRC = 0x03
PICC_REQIDL = 0x26
PICC_REQALL = 0x52
PICC_ANTICOLL = 0x93
PICC_SElECTTAG = 0x93
PICC_AUTHENT1A = 0x60
PICC_AUTHENT1B = 0x61
PICC_READ = 0x30
PICC_WRITE = 0xA0
PICC_DECREMENT = 0xC0
PICC_INCREMENT = 0xC1
PICC_RESTORE = 0xC2
PICC_TRANSFER = 0xB0
PICC_HALT = 0x50
MI_OK = 0
MI_NOTAGERR = 1
MI_ERR = 2
Reserved00 = 0x00
CommandReg = 0x01
CommIEnReg = 0x02
DivlEnReg = 0x03
CommIrqReg = 0x04
DivIrqReg = 0x05
ErrorReg = 0x06
Status1Reg = 0x07
Status2Reg = 0x08
FIFODataReg = 0x09
FIFOLevelReg = 0x0A
WaterLevelReg = 0x0B
ControlReg = 0x0C
BitFramingReg = 0x0D
CollReg = 0x0E
Reserved01 = 0x0F
Reserved10 = 0x10
ModeReg = 0x11
TxModeReg = 0x12
RxModeReg = 0x13
TxControlReg = 0x14
TxAutoReg = 0x15
TxSelReg = 0x16
RxSelReg = 0x17
RxThresholdReg = 0x18
DemodReg = 0x19
Reserved11 = 0x1A
Reserved12 = 0x1B
MifareReg = 0x1C
Reserved13 = 0x1D
Reserved14 = 0x1E
SerialSpeedReg = 0x1F
Reserved20 = 0x20
CRCResultRegM = 0x21
CRCResultRegL = 0x22
Reserved21 = 0x23
ModWidthReg = 0x24
Reserved22 = 0x25
RFCfgReg = 0x26
GsNReg = 0x27
CWGsPReg = 0x28
ModGsPReg = 0x29
TModeReg = 0x2A
TPrescalerReg = 0x2B
TReloadRegH = 0x2C
TReloadRegL = 0x2D
TCounterValueRegH = 0x2E
TCounterValueRegL = 0x2F
Reserved30 = 0x30
TestSel1Reg = 0x31
TestSel2Reg = 0x32
TestPinEnReg = 0x33
TestPinValueReg = 0x34
TestBusReg = 0x35
AutoTestReg = 0x36
VersionReg = 0x37
AnalogTestReg = 0x38
TestDAC1Reg = 0x39
TestDAC2Reg = 0x3A
TestADCReg = 0x3B
Reserved31 = 0x3C
Reserved32 = 0x3D
Reserved33 = 0x3E
Reserved34 = 0x3F
serNum = []
def __init__(self, bus=0, device=0, spd=1000000, pin_mode=10, pin_rst=-1, debugLevel='WARNING'):
self.spi = spidev.SpiDev()
self.spi.open(bus, device)
self.spi.max_speed_hz = spd
self.logger = logging.getLogger('mfrc522Logger')
self.logger.addHandler(logging.StreamHandler())
level = logging.getLevelName(debugLevel)
self.logger.setLevel(level)
if pin_rst == -1:
pin_rst = 15
self._RST = DigitalOutputDevice(pin_rst, initial_value=True)
self.MFRC522_Init()
def MFRC522_Reset(self):
self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
def Write_MFRC522(self, addr, val):
val = self.spi.xfer2([(addr << 1) & 0x7E, val])
def Read_MFRC522(self, addr):
val = self.spi.xfer2([((addr << 1) & 0x7E) | 0x80, 0])
return val[1]
def Close_MFRC522(self):
self.spi.close()
def SetBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp | mask)
def ClearBitMask(self, reg, mask):
tmp = self.Read_MFRC522(reg)
self.Write_MFRC522(reg, tmp & (~mask))
def AntennaOn(self):
temp = self.Read_MFRC522(self.TxControlReg)
if (~(temp & 0x03)):
self.SetBitMask(self.TxControlReg, 0x03)
def AntennaOff(self):
self.ClearBitMask(self.TxControlReg, 0x03)
def MFRC522_ToCard(self, command, sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
if command == self.PCD_AUTHENT:
irqEn = 0x12
waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
irqEn = 0x77
waitIRq = 0x30
self.Write_MFRC522(self.CommIEnReg, irqEn | 0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)
self.Write_MFRC522(self.CommandReg, self.PCD_IDLE)
for i in range(len(sendData)):
self.Write_MFRC522(self.FIFODataReg, sendData[i])
self.Write_MFRC522(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self.SetBitMask(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self.Read_MFRC522(self.CommIrqReg)
i -= 1
if ~((i != 0) and ~(n & 0x01) and ~(n & waitIRq)):
break
self.ClearBitMask(self.BitFramingReg, 0x80)
if i != 0:
if (self.Read_MFRC522(self.ErrorReg) & 0x1B) == 0x00:
status = self.MI_OK
if n & irqEn & 0x01:
status = self.MI_NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self.Read_MFRC522(self.FIFOLevelReg)
lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
if lastBits != 0:
backLen = (n - 1) * 8 + lastBits
else:
backLen = n * 8
if n == 0:
n = 1
if n > self.MAX_LEN:
n = self.MAX_LEN
for i in range(n):
backData.append(self.Read_MFRC522(self.FIFODataReg))
else:
status = self.MI_ERR
return (status, backData, backLen)
def MFRC522_Request(self, reqMode):
status = None
backBits = None
TagType = []
self.Write_MFRC522(self.BitFramingReg, 0x07)
TagType.append(reqMode)
(status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
if ((status != self.MI_OK) | (backBits != 0x10)):
status = self.MI_ERR
return (status, backBits)
def MFRC522_Anticoll(self):
backData = []
serNumCheck = 0
serNum = []
self.Write_MFRC522(self.BitFramingReg, 0x00)
serNum.append(self.PICC_ANTICOLL)
serNum.append(0x20)
(status, backData, backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, serNum)
if (status == self.MI_OK):
i = 0
if len(backData) == 5:
for i in range(4):
serNumCheck = serNumCheck ^ backData[i]
if serNumCheck != backData[4]:
status = self.MI_ERR
else:
status = self.MI_ERR
return (status, backData)
def CalulateCRC(self, pIndata):
self.ClearBitMask(self.DivIrqReg, 0x04)
self.SetBitMask(self.FIFOLevelReg, 0x80)
for i in range(len(pIndata)):
self.Write_MFRC522(self.FIFODataReg, pIndata[i])
self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
i = 0xFF
while True:
n = self.Read_MFRC522(self.DivIrqReg)
i -= 1
if not ((i != 0) and not (n & 0x04)):
break
pOutData = []
pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
return pOutData
def MFRC522_SelectTag(self, serNum):
backData = []
buf = []
buf.append(self.PICC_SElECTTAG)
buf.append(0x70)
for i in range(5):
buf.append(serNum[i])
pOut = self.CalulateCRC(buf)
buf.append(pOut[0])
buf.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
if (status == self.MI_OK) and (backLen == 0x18):
self.logger.debug("Size: " + str(backData[0]))
return backData[0]
else:
return 0
def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
buff = []
# First byte should be the authMode (A or B)
buff.append(authMode)
# Second byte is the trailerBlock (usually 7)
buff.append(BlockAddr)
# Now we need to append the authKey which usually is 6 bytes of 0xFF
for i in range(len(Sectorkey)):
buff.append(Sectorkey[i])
# Next we append the first 4 bytes of the UID
for i in range(4):
buff.append(serNum[i])
# Now we start the authentication itself
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT, buff)
# Check if an error occurred
if not (status == self.MI_OK):
self.logger.error("AUTH ERROR!!")
if not (self.Read_MFRC522(self.Status2Reg) & 0x08) != 0:
self.logger.error("AUTH ERROR(status2reg & 0x08) != 0")
# Return the status
return status
def MFRC522_StopCrypto1(self):
self.ClearBitMask(self.Status2Reg, 0x08)
def MFRC522_Read(self, blockAddr):
recvData = []
recvData.append(self.PICC_READ)
recvData.append(blockAddr)
pOut = self.CalulateCRC(recvData)
recvData.append(pOut[0])
recvData.append(pOut[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
if not (status == self.MI_OK):
self.logger.error("Error while reading!")
if len(backData) == 16:
self.logger.debug("Sector " + str(blockAddr) + " " + str(backData))
return backData
else:
return None
def MFRC522_Write(self, blockAddr, writeData):
buff = []
buff.append(self.PICC_WRITE)
buff.append(blockAddr)
crc = self.CalulateCRC(buff)
buff.append(crc[0])
buff.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
status = self.MI_ERR
self.logger.debug("%s backdata &0x0F == 0x0A %s" % (backLen, backData[0] & 0x0F))
if status == self.MI_OK:
buf = []
for i in range(16):
buf.append(writeData[i])
crc = self.CalulateCRC(buf)
buf.append(crc[0])
buf.append(crc[1])
(status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
if not (status == self.MI_OK) or not (backLen == 4) or not ((backData[0] & 0x0F) == 0x0A):
self.logger.error("Error while writing")
if status == self.MI_OK:
self.logger.debug("Data written")
def MFRC522_DumpClassic1K(self, key, uid):
for i in range(64):
status = self.MFRC522_Auth(self.PICC_AUTHENT1A, i, key, uid)
# Check if authenticated
if status == self.MI_OK:
self.MFRC522_Read(i)
else:
self.logger.error("Authentication error")
def MFRC522_Init(self):
self.MFRC522_Reset()
self.Write_MFRC522(self.TModeReg, 0x8D)
self.Write_MFRC522(self.TPrescalerReg, 0x3E)
self.Write_MFRC522(self.TReloadRegL, 30)
self.Write_MFRC522(self.TReloadRegH, 0)
self.Write_MFRC522(self.TxAutoReg, 0x40)
self.Write_MFRC522(self.ModeReg, 0x3D)
self.AntennaOn()

View File

@@ -0,0 +1,4 @@
from .MFRC522 import MFRC522
from .SimpleMFRC522 import SimpleMFRC522
name = "joyit_mfrc522"

View File

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Home CARIA1</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="fonts/SegmentLED.ttf">
<script src="js/jquery.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-sm">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="http://192.168.253.194:8000/">CARIA</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="http://192.168.253.194:8000/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/access">Accès</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="http://192.168.253.194:8081">Vidéo</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/tests">Test</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container text-center my-4">
<h1 class="mb-4">Interface d'accès</h1>
<div class="card mx-auto shadow-lg" style="max-width: 500px;">
<div class="card-body">
<h3 class="h5">Dernière validation reçue</h3>
<p class="mb-2"><strong>Nom:</strong> {{name}}</p>
<p class="mb-2"><strong>Confiance:</strong> {{confidence}}</p>
<p><strong>Status:</strong> {{status}}</p>
</div>
</div>
<div class="row">
<div class="col">
<hr><p class="footer fw-bold">CARIA Project | Cunat-Brulé © 2023-2024 Tous droits réservés
</div>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,90 +1,194 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>admin AUTO1</title>
<title>Home CARIA1</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="fonts/SegmentLED.ttf">
<script src="js/jquery.js"></script>
<script src="js/jquery.js"></script>
</head>
<body>
<div class="container" align="center">
<h1>Interface d'administration</h1>
<div class="card-group">
<div class="card text-bg-light mb-3" style="min-width: 350px; max-width: 25rem;">
<div class="card-header">Vitesse de déplacement</div>
<div class="card-body">
<div class="speedometer">
<div class="pointer" id="pointer">
<img src="images/pointer.png" alt="Needle">
</div>
</div>
<div class="counter led-counter" id="counter">050</div>
<input title="speed-level" type="range" min="20" max="100">
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-sm">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="http://192.168.253.194:8000/">CARIA</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="http://192.168.253.194:8000/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/access">Accès</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="http://192.168.253.194:8081">Vidéo</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/tests">Test</a>
</li>
</ul>
</div>
</div>
<div class="card text-bg-light mb-3" style="min-width: 380px; max-width: 25rem;">
<div class="card-header">Contrôle des déplacements</div>
<div class="card-body">
<div class="container text-center">
<div class="row">
<div class="col">
<button id="forward" class="button_cmd glyphicon glyphicon-arrow-up"> Avancer </button>
</nav>
<div class="container my-4">
<div class="row g-4 justify-content-center text-center">
<h1 class="mb-4">Interface d'administration</h1>
<div class="col-lg-4">
<div class="card text-bg-light mb-3">
<div class="card-header fw-bold">Vitesse de déplacement</div>
<div class="card-body align-self-center">
<div class="speedometer">
<div class="pointer" id="pointer">
<img src="images/pointer.png" alt="Needle">
</div>
</div>
<div class="counter led-counter" id="counter">030</div>
<input title="speed-level" value="30" type="range" min="25" max="50">
</div>
</div>
<div class="row">
<div class="col">
<button id='turnleft' class="button_cmd glyphicon glyphicon-arrow-left"> Gauche </button>
</div>
<div class="col-lg-4">
<div class="card text-bg-light shadow-sm">
<div class="card-header fw-bold">Contrôle des déplacements</div>
<div class="card-body">
<div class="row mb-3">
<div class="col">
<button id="forward" class="button_cmd glyphicon glyphicon-arrow-up fw-bold"> Avancer </button>
</div>
</div>
<div class="col">
<button id='stop' class="button_cmd"> STOP </button>
</div>
<div class="col">
<button id='turnright' class="button_cmd glyphicon glyphicon-arrow-right"> Droite </button>
</div>
</div>
<div class="row">
<div class="col">
<button id='backward' class="button_cmd glyphicon glyphicon-arrow-down"> Reculer </button>
<div class="col">
<button id='turnleft' class="button_cmd glyphicon glyphicon-arrow-left fw-bold"> Gauche </button>
</div>
<div class="col">
<button id='stop' class="button_cmd fw-bold"> STOP </button>
</div>
<div class="col">
<button id='turnright' class="button_cmd glyphicon glyphicon-arrow-right fw-bold"> Droite </button>
</div>
</div>
<div class="row">
<div class="col">
<button id='backward' class="button_cmd glyphicon glyphicon-arrow-down fw-bold"> Reculer </button>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card text-bg-light shadow-sm">
<div class="card-header fw-bold">Caméra</div>
<div class="card-body">
<img class="rounded mx-auto d-block" src="http://192.168.253.194:8081" alt="Camera" width="100%">
</div>
</div>
</div>
</div>
<div class="row g-4 justify-content-center">
<h1 class="my-4 text-center">Test de fonctionnement</h1>
<div class="col-lg-4">
<div class="card text-bg-light shadow-sm">
<div class="card-header text-center fw-bold">Composants</div>
<div class="card-body">
<div class="d-flex flex-column">
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="testServo">
<label class="form-check-label ps-4" for="testServo">Servo moteur</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="testRFIDCarDoor">
<label class="form-check-label ps-4" for="testRFIDCarDoor">Ouverture de porte par RFID</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="testRotor">
<label class="form-check-label ps-4" for="testRotor">Moteurs et vitesse Gauche|Droite</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="testLidar">
<label class="form-check-label ps-4" for="testLidar">Module lidar</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="testObstacle">
<label class="form-check-label ps-4" for="testObstacle">Module d'obstacles</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card text-bg-light mb-3" style="min-width: 350px; max-width: 25rem;">
<div class="card-header">Caméra</div>
<div class="card-body">
<img class="rounded mx-auto d-block" src="http://192.168.74.194:8081" width="100%"/>
<div class="col-lg-4">
<div class="card text-bg-light shadow-sm">
<div class="card-header text-center fw-bold">Fonctionnalités</div>
<div class="card-body">
<div class="d-flex flex-column">
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="appEmergencyStop">
<label class="form-check-label ps-4" for="appEmergencyStop">Arrêt d'urgence</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="appLidarSpeed">
<label class="form-check-label ps-4" for="appLidarSpeed">Module lidar</label>
</div>
<div class="form-check form-switch my-2 fw-bold">
<input class="form-check-input" type="checkbox" id="appRFID">
<label class="form-check-label ps-4" for="appRFID">Module RFID Lecture/Ecriture</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h1>Test de fonctionnement</h1>
<div class="row row-cols-1 row-cols-md-2 g-2">
<div class="card text-bg-light m-4" style="max-width: 30rem;">
<div class="card-header">Composants</div>
<div class="card-body">
<div class="button-container">
<label for='obstacle'><input type="checkbox" id='obstacle' class="button_fct btn btn-primary">Module d'obstacles</label>
<label for='motor'><input type="checkbox" id='motor' class="button_fct btn btn-primary">Moteurs et vitesse Guauche|Droite</label>
<label for='servo'><input type="checkbox" id='servo' class="button_fct btn btn-primary">Servo moteur</label>
<label for='lidar'><input type="checkbox" id='lidar' class="button_fct btn btn-primary">Module lidar</label>
<label for='rfidrw'><input type="checkbox" id='rfidrw' class="button_fct btn btn-primary">Module RFID Lecture/Ecriture</label>
<div class="col-lg-4 text-center">
<div class="card text-bg-light shadow-sm">
<div class="card-header fw-bold">Dépannage</div>
<div class="card-body">
<form id="rebootForm" action="/restartPi" method="post" class="mb-2">
<button type="button" id="restartPi" class="btn btn-danger w-100" onclick="confirmReboot()">Redémarrer le Raspberry Pi</button>
</form>
<form id="motionForm" action="/restartMotion" method="post">
<button type="submit" id="restartMotion" class="btn btn-warning w-100">Redémarrer Motion</button>
</form>
</div>
</div>
</div>
</div>
<div class="card text-bg-light m-4" style="max-width: 30rem;">
<div class="card-header">Fonctionnalités</div>
<div class="card-body">
<div class="button-container">
<label for='ITO'><input type="checkbox" id='ITO' class="button_fct btn btn-primary">Suivi d'objet</label>
<label for='IOA'><input type="checkbox" id='IOA' class="button_fct btn btn-primary">Evitement d'obstacle</label>
<div class="row text-center">
<h1 class="my-4">Historique des programmes</h1>
<!-- Tableau pour afficher les résultats des tests -->
<div class="col-lg-10 mx-auto">
<div class="table-responsive">
<table class="table table-bordered table-hover shadow-sm">
<thead class="table-light">
<tr>
<th>Date</th>
<th>Nom du Test</th>
<th>Fonctionnement OK</th>
<th>Status</th>
</tr>
</thead>
<tbody>
% for result in results:
<tr>
<td>{{ result['date'] }}</td>
<td>{{ result['nom'] }}</td>
<td>{{ 'Oui' if result['fonctionnement_ok'] else 'Non' }}</td>
<td>{{ result['status'] }}</td>
</tr>
% end
</tbody>
</table>
</div>
</div>
</div>
<div class="row text-center">
<div class="col">
<hr><p class="footer fw-bold">CARIA Project | Cunat-Brulé © 2023-2024 Tous droits réservés
</div>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,19 +1,48 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Test CARIA1</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CARIA</title>
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="fonts/SegmentLED.ttf">
<script src="js/jquery.js"></script>
</head>
<body>
<div id="container" class="container" align="center">
<hr><h1>Interface de tests</h1><hr>
</div>
<nav class="navbar navbar-expand-lg navbar-light bg-light shadow-sm">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="http://192.168.253.194:8000/">CARIA</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="http://192.168.253.194:8000/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/access">Accès</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="http://192.168.253.194:8081">Vidéo</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://192.168.253.194:8000/tests">Test</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container text-center my-4">
<h1>Interface de tests</h1>
<div class="row">
<div class="col">
<hr><p class="footer fw-bold">CARIA Project | Cunat-Brulé © 2023-2024 Tous droits réservés
</div>
</div>
</div>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,26 +1,43 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import time, sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
ObstaclePin = 16
status = "initialization"
DURATION_LIMIT = 5
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(ObstaclePin, GPIO.IN)
def loop():
while True:
if GPIO.input(ObstaclePin) == GPIO.LOW:
print("Obstacle détecté")
else:
print("Aucun obstacle détecté")
time.sleep(0.5) # Attendre un peu entre les lectures pour éviter les faux positifs
if __name__ == '__main__':
setup()
try:
start_time = time.time() # Enregistrer l'heure de début
try:
loop()
except KeyboardInterrupt:
GPIO.cleanup()
while time.time() - start_time < DURATION_LIMIT:
if GPIO.input(Ab.OBSTACLE_PIN) == GPIO.LOW:
print("Obstacle détecté")
GPIO.output(Ab.RED_LIGHT, GPIO.HIGH)
status = "obstacle detected"
else:
print("Aucun obstacle détecté")
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
status = "no obstacle detected"
time.sleep(0.5) # Attendre un peu entre les lectures pour éviter les faux positifs
except Exception as e:
print(f"Erreur pendant l'exécution: {e}")
status = "erreur"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
finally:
GPIO.output(Ab.RED_LIGHT, GPIO.LOW)
Ab.cleanup()
# Vérification finale et affichage du statut
if status in ["obstacle detected", "no obstacle detected"]:
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -1,23 +1,50 @@
import serial
import time
import sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
# Variable de statut pour indiquer le bon fonctionnement
status = "initialization"
# Durée limite d'exécution en secondes
time_limit = 7
start_time = time.time()
try:
ser = serial.Serial('/dev/ttyAMA0', 115200, timeout=1)
# Envoi de la commande pour initialiser le capteur
ser.write(b'\x42\x57\x02\x00\x00\x00\x01\x06')
while True:
if ser.in_waiting >= 9:
if b'Y' == ser.read() and b'Y' == ser.read():
Dist_L = ser.read()
Dist_H = ser.read()
# Vérification si le temps limite est dépassé
if time.time() - start_time > time_limit:
break
if Ab.LIDAR_MODULE.in_waiting >= 9:
if b'Y' == Ab.LIDAR_MODULE.read() and b'Y' == Ab.LIDAR_MODULE.read():
Dist_L = Ab.LIDAR_MODULE.read()
Dist_H = Ab.LIDAR_MODULE.read()
Dist_Total = (Dist_H[0] * 256) + Dist_L[0]
for i in range(0, 5):
ser.read() # Lecture et ignore des octets supplémentaires
print("Distance:", Dist_Total, "cm")
except serial.SerialException as e:
print("Erreur série:", e)
Ab.LIDAR_MODULE.read() # Lecture et ignore des octets supplémentaires
print("Distance à l'avant du véhicule:", Dist_Total, "cm")
status = "measurement successful"
time.sleep(1)
Ab.LIDAR_MODULE.reset_input_buffer()
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
if 'ser' in locals():
ser.close() # Fermeture propre du port série
Ab.LIDAR_MODULE.close() # Fermeture propre du port série
Ab.cleanup()
# Vérification finale et affichage du statut
if status in ["measurement successful"]:
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -1,45 +1,46 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
# Variable de statut pour indiquer le bon fonctionnement
status = "initialization"
# Test de la classe AlphaBot avec différentes vitesses pour les moteurs individuels
def test_alphabot_speed():
bot = AlphaBot()
try:
while True: # Boucle infinie
for speed in range(20, 101, 40):
print(f"Test de vitesse à {speed}%")
# Vérifier si speed est une chaîne non vide
if speed != '':
# Test des moteurs en avance
bot.forward(speed)
time.sleep(1)
bot.stop()
time.sleep(0.5)
# Test des moteurs en arrière
bot.backward(speed)
time.sleep(1)
bot.stop()
time.sleep(0.5)
# Test du moteur gauche en avant et moteur droit en arrière
bot.left(speed)
time.sleep(1)
bot.stop()
time.sleep(0.5)
# Test du moteur gauche en arrière et moteur droit en avant
bot.right(speed)
time.sleep(1)
bot.stop()
time.sleep(0.5)
except KeyboardInterrupt:
bot.cleanup()
if __name__ == "__main__":
test_alphabot_speed()
duration = 0.5
try:
for speed in range(20, 81, 30):
print(f"Test de vitesse à {speed}%")
# Test des moteurs en avance
Ab.forward(duration, speed)
Ab.stop(1)
# Test des moteurs en arrière
Ab.backward(duration, speed)
Ab.stop(1)
# Test du moteur gauche en avant et moteur droit en arrière
Ab.left(duration, speed)
Ab.stop(1)
# Test du moteur gauche en arrière et moteur droit en avant
Ab.right(duration, speed)
Ab.stop(1)
status = "move successful"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors du test: {e}")
status = "error"
finally:
Ab.cleanup()
# Vérification finale et affichage du statut
if status == "move successful":
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time, sys
sys.path.append('/home/christian/WebControl/modules/')
from SimpleMFRC522 import SimpleMFRC522
RFID_MODULE = SimpleMFRC522()
from AlphaBot import AlphaBot
Ab = AlphaBot()
status = "initialization"
fonctionnement_ok = False
# Lecture initiale du tag RFID
try:
print("La porte est actuellement fermée.\nVeuillez approcher votre badge RFID du capteur pour accéder au véhicule.")
id_rfid, text_rfid = RFID_MODULE.read()
if text_rfid in ["CHRIS "]:
Ab.set_angle(90)
print(f"Salut {text_rfid.rstrip()}, votre accès est validé avec succès.\nLa porte du véhicule est maintenant ouverte!")
status = "Access successful"
elif text_rfid == "TEST RFID ":
Ab.set_angle(90)
print(f"Bienvenue, {text_rfid.rstrip()}.\nLa porte du véhicule est maintenant ouverte!")
status = "Access successful"
else:
print("Bonjour, vous n'êtes pas autorisé à entrer dans le véhicule.\nLa porte reste fermée.")
status = "Access denied"
print(f"(ID, Text)",id_rfid, text_rfid)
time.sleep(2)
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
Ab.PWMSERVO.stop()
time.sleep(2)
# Vérification finale et affichage du statut
if status == "Access successful":
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env python
# Importation des bibliothèques
import time
from gpiozero import LED
from joyit_mfrc522 import SimpleMFRC522
# Initialisation de l'objet pour le module RFID
reader = SimpleMFRC522()
# Fonction pour la lecture du tag RFID
def read_rfid():
print("### Lecture RFID ###")
print("Approchez le tag RFID du capteur:")
id, text = reader.read()
print("ID:", id)
print("Contenu:", text)
time.sleep(5)
# Fonction pour l'écriture sur le tag RFID avec gestion des erreurs
def write_rfid(data, max_attempts=3):
print("### Écriture RFID ###")
print("Valeur qui sera écrite:", data)
print("Approchez le tag RFID du capteur:")
try:
reader.write(data)
print("Succès de l'écriture sur le tag RFID.")
time.sleep(3) # Attente courte avant de vérifier l'écriture
except Exception as e:
print(f"Erreur lors de l'écriture RFID: {e}")
time.sleep(3) # Attendre avant de réessayer
# Lecture initiale du tag RFID
read_rfid()
# Écriture sur le tag RFID
write_rfid("TEST RFID")
# Seconde lecture du tag RFID
read_rfid()

View File

@@ -1,31 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import time,sys
sys.path.append('/home/christian/WebControl/modules/')
from AlphaBot import AlphaBot
Ab = AlphaBot()
# Définir la broche GPIO pour le signal du servo-moteur
SERVO_PIN = 27
status = "initialization"
try:
Ab.set_angle(0)
print("Positionné à 0°")
time.sleep(2)
Ab.set_angle(90)
print("Positionné à 90°")
time.sleep(2)
Ab.set_angle(180)
print("Positionné à 180°")
time.sleep(2)
Ab.set_angle(0)
print("Positionné à 0°")
status = "movement successful"
except KeyboardInterrupt:
print("Interruption par l'utilisateur.")
status = "interrupted"
except Exception as e:
print(f"Erreur lors de l'exécution: {e}")
status = "error"
finally:
Ab.PWMSERVO.stop()
Ab.cleanup()
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(SERVO_PIN, GPIO.OUT)
# Vérification finale et affichage du statut
if status == "movement successful":
print("Le composant fonctionne correctement.")
fonctionnement_ok = True
else:
print(f"Le composant a rencontré un problème: {status}.")
fonctionnement_ok = False
def set_angle(angle):
pwm = GPIO.PWM(SERVO_PIN, 50) # Fréquence PWM de 50 Hz
pwm.start(2.5) # Position neutre (angle de 0 degrés)
duty_cycle = angle / 18.0 + 2.5 # Convertir l'angle en devoir (duty cycle)
pwm.ChangeDutyCycle(duty_cycle)
time.sleep(0.5) # Attendre que le servo atteigne la position désirée
pwm.stop()
if __name__ == '__main__':
try:
setup()
while True:
# Faire tourner le servo-moteur de 0 à 180 degrés avec un pas de 30 degrés
for angle in range(0, 181, 30):
print("Rotation du servo moteur à {} degrés".format(angle))
set_angle(angle)
time.sleep(1)
except KeyboardInterrupt:
GPIO.cleanup()
Ab.enregistrer_resultats(sys.argv[0], fonctionnement_ok, status)