« SE5 ECEAI/eceai 2023/2024/jcie » : différence entre les versions
Ligne 176 : | Ligne 176 : | ||
=== Implémentation de l'IA : === | === Implémentation de l'IA : === | ||
Maintenant qu'on a une communication pour envoyer un fichier à notre serveur depuis la raspberry grâce à notre API, nous la modifions pour que la Raspberry puisse lire la valeur du capteur à ultrason, l'envoyer à notre serveur et recevoir en réponse, la prédiction de l'IA. Nous créons donc une route '''''/predict''''' sur notre API qui récupère les valeurs du capteurs données en paramètre et renvoie la prédiction de l'IA : | |||
@app.route('/predict',methods=["GET","POST"]) | |||
== <div class="mcwiki-header" style="border-radius: 15px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #42acc9; vertical-align: top; width: 96%;"> Entrainement de l'IA </div> == | == <div class="mcwiki-header" style="border-radius: 15px; padding: 15px; font-weight: bold; color: #FFFFFF; text-align: center; font-size: 80%; background: #42acc9; vertical-align: top; width: 96%;"> Entrainement de l'IA </div> == |
Version du 18 janvier 2024 à 15:45
Introduction Projet IE Delannoy - Lemaire
L’objectif de ce projet est de distribuer le calcul à différents endroits du réseau afin d’être en mesure de proposer des pistes d’optimisation que ce soit en terme de performance ou en terme de sobriété énergétique. Pour cela, vous allez mettre en œuvre un réseau d’objets connectés à des passerelles et à un serveur. Les objets collecteront des données de l’environnement et suivant les scénarios traiteront les données ou les enverront de façon brute à la passerelle ou au serveur. Chaque scénario sera évalué en terme de performance de calcul et de sobriété énergétique. Les indicateurs de performances sont à définir (indicateur pour le calcul, pour l’énergie mais aussi un indicateur combiné).
Présentation du Projet
Le but de notre projet est de réaliser une application permettant de déterminer l'action faite par un joueur de Pierre-Feuille-Ciseau. Notre système devra donc reconnaitre les différents mouvements fait par le joueur.
Mise en oeuvre du réseau
Création VM XEN
Nous avons commencé par créer une machine virtuelle sur Chassiron avec la commande :
xen-create-image --hostname jcie --force --dist bookworm --size 10G --memory 1G --dir /usr/local/xen --password glopglop --dhcp --bridge bridgeStudents
Configuration de la VM
Configuration de l'interface enX0 en ipv6:
auto enX0 iface enX0 inet6 auto
Modification du fichier resolv.conf:
Ce fichier permet de stocker les adresses des serveurs DNS du système. Dans notre cas, nous allons interroger le serveur DNS de l'école: plil.info.
domain plil.info search plil.info nameserver 2a01:c916:2047:c800:216:3eff:fe82:8a5c
Modification du fichier sources.list:
Ce fichier se situe dans le répertoire "/etc/apt/". Il référence l'ensemble des sources utilisées par l'utilitaire APT pour télécharger les paquets.
Nous avons ajouté deux nouvelles sources :
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
Configuration de la borne WIFI Cisco
La connexion avec la borne Wifi CISCO se fait via minicom sur le port ttyS0 avec un baudrate de 9600.
Pour réaliser notre point d'accès, nous avons configurer l'interface dot11Radio1
Nous avons nommé notre point d'accès Wifi: WiFi_IE_1
Pour la connexion à celui-ci nous devons utiliser le mot de passe glopglop.
Pour l'attribution de l'adresse, on utilise le protocole DHCP. Dans la définition de notre protocole, on exclut les intervalles d'adresses suivantes : 172.26.145.1 - 172.26.145.100 et 172.26.145.139 - 172.26.145.254
Le point d'accès a été modifié par Monsieur Redon pour les projets PEIP. On a maintenant :
Dans le protocole DHCP:
- default-router 172.26.145.251 (changement car besoin pour les PEIP)
- dns-server: 193.48.57.33 (changement car problème avec le serveur DNS initial)
Configuration de la Raspberry
Dans le cadra du projet, nous avons à disposition une Raspberry PI 4 model B que nous allons configurer. Pour ce faire, nous utilisons le logiciel le "Raspberry PI Imager" pour choisir notre OS.
Maintenant que nous avons une carte SD prête pour la Raspberry, nous la configurons via sa liaison série en passant par minicom :
root@zabeth18: / $ minicom -D /dev/ttyACM0 -b 9600
De plus, nous modifions le fichier /etc/network/interfaces pour pouvoir connecter notre carte au réseau wifi créé plus haut :
Nous verifions ensuite que nous avons une adresse IP :
Capteur NUCLEO - 53L5A1
Pour ce projet, nous disposons d'une STM32 Nucléo F401RE muni d'un capteur à ultrason X-Nucleo-53L5A1.
Pour pouvoir entrainer notre IA, nous devons faire en sorte d'afficher et de ressortir sur la liaison série les données du capteur. Pour ce faire, nous utilisons le fichier example "53L5A1_ThresholdDetection". Nous modifions la fonction print_result pour afficher 16 valeurs à la suite :
Après avoir téléversé, nous pouvons vérifier le bon fonctionnement du programme en nous connectant à la carte via minicom :
root@raspberrypi:/dev$ minicom -D ttyACM0 -b 460800
Communication VM-Raspberry
Envoie de donnée :
Dans notre projet, nous avons besoin de remonter les données de notre capteur branché en liaison série à la Raspberry sur le port "ttyACM0". Nous allons donc passer par des requêtes API entre le serveur sur chassiron et notre Raspberry.
Programmation côté Raspberry :
Du côté Raspberry, nous programmons un script en python qui lit sur la liaison série les valeurs du capteurs et les envoie via une requête POST vers le serveur
#Import Librairies import requests import json import serial #Variable STM32_port = "/dev/ttyACM0" baudrate = 460800 Serial_link = serial.Serial(STM32_port,baudrate,timeout=1) print("Serial link done") liste_mesures=[] for i in range(101): print("Mesure",i) mesure = Serial_link.readline().decode('utf-8') liste_mesures.append(mesure) data_to_send = json.dumps(liste_mesures) url_request = "http://[2001:660:4401:6050:216:3eff:fe68:8176]:8080" headers = { 'Content-type':'application/json', 'Accept':'application/json' } r = requests.post( url_request, json=data_to_send, headers=headers ) print(f"Status code : {r.status_code}")
Programmation côté Serveur :
La communication entre notre VM et la Raspberry est possible. Nous arrivons à effectuer un ping de l'une sur l'autre en passant par l'addresse IPv6.
IPv6 VM : 2001:660:4401:6050:216:3eff:fe68:8176
IPv6 Raspberry : 2001:660:4401:6050:da3a:ddff:fe59:4cb5
Nous programmons ensuite une API sur notre VM en utilisant la libraire Flask.
#Import Librairies import json from flask import Flask from flask import request from waitress import serve from flask import Response from flask_cors import CORS from flask_cors import cross_origin app = Flask(__name__) cors = CORS(app, ressourceas={r"/api/*":{"origins":"*"}}) def compute_data(data): filename = input("Nom du fichier :") to_write = data.split("\"")[1:-1] with open(filename, "w") as f: i = 0 for elem in to_write: if i == 0: print("We skip") else: if (i%2) == 0: print("Data writed :",elem[:-4]) f.write(elem[:-4]) f.write("\n") i = i + 1 #Main @app.route('/',methods=["GET","POST"]) @cross_origin() def hello(): data = request.json compute_data(data) return data if __name__ == '__main__': print("Listening") serve(app,host="::",port="8080")
Implémentation de l'IA :
Maintenant qu'on a une communication pour envoyer un fichier à notre serveur depuis la raspberry grâce à notre API, nous la modifions pour que la Raspberry puisse lire la valeur du capteur à ultrason, l'envoyer à notre serveur et recevoir en réponse, la prédiction de l'IA. Nous créons donc une route /predict sur notre API qui récupère les valeurs du capteurs données en paramètre et renvoie la prédiction de l'IA :
@app.route('/predict',methods=["GET","POST"])
Entrainement de l'IA
Entrainement avec NanoEdge AI Studio :
Pour le projet, nous avons d'abord développé et entrainé notre IA sur la plateforme NanoEdge AI Studio. Pour ce faire, nous devons d'abord définir un projet de classification de n-class ("pierre","feuille","ciseau") en utilisant un capteur générique à 16 axes. Pour ce faire, nous modifions le code de la STM32 pour qu'elle renvoie une ligne contenant 16*16 mesure en continue. Une fois le projet créé, nous ajoutons 3 signaux correspondant à nos dataset de "Pierre", "Feuille" et "Ciseau". Pour rajouter des valeurs dans notre dataset, nous utilisons la liaison série pour lire les valeurs de notre capteur.
Entrainement avec Scikit :
Pour la suite de notre projet, nous avons developpé et entrainé une IA avec Scikit.
Pour commencer, nous avons du construire un fichier csv reprenant nos mesures sur un format de 16 valeurs. Pour chaque mesure, on ajoute en amont de la mesure la catégorie (feuille, ciseau ou pierre).
Pour construire ce fichier, nous avons assemblé trois fichiers csv de test que nous avons généré grâce à notre capteur : un fichier d'entrainement Pierre.csv, un fichier d'entrainement Ciseau.csv et un fichier d'entrainement Feuille.csv .
Pour faire cette concaténation nous avons développer un programme python prenant en entrée nos fichiers d'entrainement et fournissant en sortie le fichier csv chifoumIA.
line_feuille = [] line_pierre = [] line_ciseau = [] with open("Feuille.csv","r") as f: line_feuille = f.readlines() with open("Pierre.csv","r") as f: line_pierre = f.readlines() with open("Ciseau.csv","r") as f: line_ciseau = f.readlines() with open("chifoumIA.csv","w") as f: for elem in line_feuille: if(elem != ""): f.write("feuille,") f.write(elem) for elem in line_pierre: if(elem != ""): f.write("pierre,") f.write(elem) for elem in line_ciseau: if(elem != ""): f.write("ciseau,") f.write(elem)
ipv6 jcie : 2001:660:4401:6050:216:3eff:fe68:8176