CARIA.2.2
Update for the final presentation huge change with previous version
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
@@ -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.")
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
59
WebControl/apps/itineraire_create.py
Normal file
59
WebControl/apps/itineraire_create.py
Normal 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}")
|
||||
75
WebControl/apps/itineraire_suivre.py
Normal file
75
WebControl/apps/itineraire_suivre.py
Normal 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)
|
||||
170
WebControl/apps/itineraire_suivre_emergency.py
Normal file
170
WebControl/apps/itineraire_suivre_emergency.py
Normal 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)
|
||||
174
WebControl/apps/itineraire_suivre_emergency_speed.py
Normal file
174
WebControl/apps/itineraire_suivre_emergency_speed.py
Normal 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)
|
||||
56
WebControl/apps/lidar_speed_move.py
Normal file
56
WebControl/apps/lidar_speed_move.py
Normal 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)
|
||||
31
WebControl/apps/rfid_read_write_module.py
Normal file
31
WebControl/apps/rfid_read_write_module.py
Normal 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}")
|
||||
71
WebControl/apps/scenario_rfid.py
Normal file
71
WebControl/apps/scenario_rfid.py
Normal 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)
|
||||
@@ -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 */
|
||||
}
|
||||
18
WebControl/fixs/fix_motion.sh
Normal file
18
WebControl/fixs/fix_motion.sh
Normal 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/"
|
||||
10
WebControl/fixs/fix_rfid.sh
Normal file
10
WebControl/fixs/fix_rfid.sh
Normal 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."
|
||||
7
WebControl/fixs/reboot.sh
Normal file
7
WebControl/fixs/reboot.sh
Normal 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.
@@ -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
7
WebControl/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -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();
|
||||
}
|
||||
}
|
||||
21
WebControl/js/test_status.js
Normal file
21
WebControl/js/test_status.js
Normal 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
BIN
WebControl/logs/motionlogs.txt
Normal file
BIN
WebControl/logs/motionlogs.txt
Normal file
Binary file not shown.
1808
WebControl/logs/resultats_tests.json
Normal file
1808
WebControl/logs/resultats_tests.json
Normal file
File diff suppressed because it is too large
Load Diff
78
WebControl/logs/selected_steps.json
Normal file
78
WebControl/logs/selected_steps.json
Normal 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"
|
||||
}
|
||||
]
|
||||
22
WebControl/logs/selected_steps_short.json
Normal file
22
WebControl/logs/selected_steps_short.json
Normal 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
455
WebControl/logs/steps.json
Normal 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"
|
||||
}
|
||||
]
|
||||
@@ -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)
|
||||
|
||||
@@ -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.")
|
||||
Binary file not shown.
89
WebControl/modules/SimpleMFRC522.py
Normal file
89
WebControl/modules/SimpleMFRC522.py
Normal 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
|
||||
BIN
WebControl/modules/__pycache__/AlphaBot.cpython-39.pyc
Normal file
BIN
WebControl/modules/__pycache__/AlphaBot.cpython-39.pyc
Normal file
Binary file not shown.
BIN
WebControl/modules/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
WebControl/modules/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
413
WebControl/modules/joyit_mfrc522/MFRC522.py
Normal file
413
WebControl/modules/joyit_mfrc522/MFRC522.py
Normal 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()
|
||||
4
WebControl/modules/joyit_mfrc522/__init__.py
Normal file
4
WebControl/modules/joyit_mfrc522/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .MFRC522 import MFRC522
|
||||
from .SimpleMFRC522 import SimpleMFRC522
|
||||
|
||||
name = "joyit_mfrc522"
|
||||
57
WebControl/templates/access.html
Normal file
57
WebControl/templates/access.html
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
48
WebControl/tests/rfid_open_door.py
Normal file
48
WebControl/tests/rfid_open_door.py
Normal 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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user