« SE5 ECEAI/eceai 2023/2024/GodardDelcourt » : différence entre les versions

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche
Ligne 277 : Ligne 277 :




[[Fichier:EmulatorDelgod.png|vignette]]
[[Fichier:EmulatorDelgod.png|500px]]
 
 


===Résultat===
===Résultat===

Version du 22 janvier 2024 à 19:08

Introduction

Objectifs du projet

Le projet vise à distribuer le calcul à différents endroits du réseau pour optimiser les performances et la sobriété énergétique. Un réseau d'objets connectés, de passerelles, et d'un serveur sera mis en place pour collecter, traiter, et évaluer les données environnementales.

Mise en œuvre du réseau

Description générale

Configuration de la Machine Virtuelle

Nous allons devoir créer une machine virtuelle sur Chassiron avec un accès internet IPv6.
Cette machine virtuelle sera déployée grâce à Xen et sera nommée "delgodVM".
La commande lancée pour créer la machine est la suivante :

xen-create-image --hostname delgodVM --force --dist bookworm --size 10G --memory 10G --dir /usr/local/xen --password glopglop --dhcp --bridge bridgeStudents

Nous allons par la suite devoir configurer son réseau, sa résolution DNS, et ses sources de paquets Debian.
Pour configurer le réseau de notre serveur, nous allons devoir modifier le fichier /etc/network/interfaces qui est un fichier de configuration réseau dans lequel les paramètres de l'interface sont spécifiés.

auto enX0
iface enX0 inet6 auto

Pour configurer la résolution DNS de notre serveur, nous allons modifier le fichier /etc/resolv.conf. Ce fichier permet de spécifier la configuration des serveurs de nom (DNS) pour résoudre les noms de domaine en adresses IP. Nous allons donc réaliser la configuration DNS suivante fournie dans le sujet :

domain plil.info
search plil.info
nameserver 2a01:c916:2047:c800:216:3eff:fe82:8a5c

Pour modifier les sources des paquets Debian, nous allons modifier le fichier /etc/apt/sources.list en rajoutant les paquets suivants :

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

Et nous allons aussi supprimer le fichier /etc/apt/apt.conf.d/01proxy.

Raspberry Pi

Image de la Raspberry Pi pour connexion avec le serveur via WiFi.

Nous allons tout d'abord devoir connecter la Raspberry Pi au WiFi nommé WIFI_IE_1. Pour configurer la Raspberry Pi, nous allons tout d'abord devoir la connecter en série à un ordinateur. Pour savoir quels pins il est nécessaire de connecter, il faut se fier à l'image ci-dessous. La partie alimentation n'est pas à connecter car trop faible pour alimenter la Raspberry Pi, nous allons donc devoir brancher sur secteur la carte grâce à une alimentation USB.

IMAGE RASP

Après avoir connecté la Raspberry Pi sur l'ordinateur, nous pouvons vérifier sur quelle interface la carte est connectée avec la commande

 ls /dev

Par exemple, ici la carte était sur ttyUSB0. Nous pouvons ensuite lancer une liaison série avec minicom grâce à la commande

minicom -s

et les paramètres suivants ttyUSB0 et 115200 8N.

Puis, pouvons configurer le wifi, nous allons dans un terminal de la Raspberry Pi, taper les commandes suivantes afin d'accéder à la configuration du système :

raspi-config

Puis nous sommes allées dans ""System Options"" afin de pouvoir configurer les différentes informations qui vont nous permettre d'avoir le WiFi sur la carte.
Pour vérifier si nos modifications ont bien fonctionné, nous avons réalisé la commande ip a pour vérifier sir le wlan0 était bien Up, et nous avons aussi ping google.com pour vérifier si le WiFi fonctionnait. Tout cela était correct.

Informations concernant la Raspberry Pi :
Adresse ip : 172.26.145.129
User pour le SSH : pifou

Objets Connectés

Utilisation d'un STM32F401RE avec un capteur de distance (Nucleo-53L5A1).

Protocole de communication et acquisition des données.

Acquisition des données

Nous allons devoir développer un firmware embarqué afin collecter des données, nous allons pour cela utiliser un code STM32 Cube IDE qui va nous aider à collecter les données du capteur.

La première étape consiste alors a installer STM32 Cube IDE pour l'objet connecté (STM32F401RE) avec capteur de distance (Nucleo-53L5A1).

Cependant, nous avons eu de nombreux problème pour installer ce logiciel sur les zabeths de l'école. Nous avons donc du utiliser un ordinateur personnel sous windows afin d'installer STM32CubeIDE. Afin de téléverser le programme sur notre objet connecté muni du capteur, nous allons devoir connecter celui-ci en série avec notre ordinnateur. Le code sera par la suite placé sur l'objet grâce à l'application.

Pour récupérer les données, nous allons utiliser un programme d'exemple fourni par --. Ce code est disponible en annexes. Pour vérifier le fonctionnement de ce code, nous avons lancé une liaison série sur l'objet connecté (grâce à Putty par exemple) et nous avons bien pu récupérer des données.

Cependant, ce code ne nous convenait pas, nous avons donc du le modifier afin d'obtenir des données brutes séparées par une virgule (ce qui n'était pas le cas sur le programme originel).

//CODE

Protocole de communication

Raspberry Pi & capteur

Tout d'abord, nous allons devoir mettre en oeuvre un protocole de communication permettant l'envoi de données entre la carte (Raspberry Pi) et le capteur.

Nous avons alors décidé de créer un script en Python qui permet au capteur de communiquer ses données à la Raspberry Pi, grâce à la liaison série entre les deux appareils. Comme nous avons vu précédemment, le code installé sur le capteur permet l'envoi de données brutes sur la liaison série, de la forme suivante :

Données capteur csv.png

Le code Python que nous avons implémenté sur la Raspberry Pi va permettre de récupérer ces données. Le script se trouve à l'endroit suivant sur la carte ~/Documents/lecture/reader.py. Lors de son lancement, celui ci va obtenir les données envoyées par le capteur, puis il va ranger ces données dans un fichier nommé store_data.csv. Le script que nous avons écrit est le suivant :

import serial
ser = serial.Serial (
    # Port série pour lire les données
    port='/dev/ttyACM0',
    # Débit de la communication série
    baudrate=460800,
    # Check pour la parité, ici on ne le fait pas
    parity=serial.PARITY_NONE,
    # Nombre de commandes séries à accepter avant expiration du délai
    timeout=1
)

# Ouverture du fichier "store_data.csv"
file = open(r"store_data.csv","w")

# Mise en pause du programme pendant 1 seconde pour éviter de surcharger le port série
while 1:
    x=ser.readline()
    output=str(x, 'UTF-8')
    file.write(output)
    print (x)

file.close()

Raspberry Pi et serveur

Nous allons ensuite mettre en oeuvre un protocole de communication entre la Raspberry Pi et le serveur que nous avons créé. D'après les consignes du sujet, nous devons faire en sorte que ce protocole soit facilement étendu à un grand nombre de Raspberry Pi. C'est pourquoi après quelques recherches, nous avons décide de réaliser un protocole de communication HTTP initié avec un script Python.

Tout d'abord, un script Python sera réalisé sur notre serveur nommé delgodVM pour le spécialiser en un serveur web qui va nous permettre de gérer les requêtes HTTP. Ainsi, sur le serveur delgodVM, nous allons pouvoir lancer notre serveur Python HTTP avec le script créé et avoir le retour suivant :

Lancement serveur http.png

Le script est le suivant :

import socket
from http.server import HTTPServer, SimpleHTTPRequestHandler
import json

PORT = 8080
class MyHandler(SimpleHTTPRequestHandler):
  def do_GET(self):
	if self.path == '/ip':
  	self.send_response(200)
  	self.send_header('Content-type', 'text/html')
  	self.end_headers()
  	self.wfile.write(f'Your IP address is {self.client_address[0]}'.encode())
  	return
	else:
  	return SimpleHTTPRequestHandler.do_GET(self)
    

  def do_POST(self):
	if self.path== '/data':
  	content_length = int(self.headers['Content-Length'])
  	data = self.rfile.read(content_length).decode('utf-8')
  	data_dict = json.loads(data)

  	print("Donnees recues:", data_dict)

  	self.send_response(200)
  	#Ouverture du fichier pour stocker les donnees
  	file = open(r"store_data.csv","a")
 	 
  	#Donnes ecrites dans le fichier .csv
  	file.write(data_dict)
 	 
	else :
  	self.send_response(404)
  	self.end_headers()

class HTTPServerV6(HTTPServer):
    address_family = socket.AF_INET6

def main():
  #Ouverture du fichier pour stocker les donnees
  #file = open(r"store_data.csv","w")
  server = HTTPServerV6(('::',PORT),MyHandler)
  print("Serveur actif sur le port :", PORT)
  server.serve_forever()  
  #Fermeture du fichier
  file.close()

if __name__ == '__main__':
  main()

Pout vérifier (de plus) si notre serveur est bien lancé, nous allons essayer d'y accéder grâce à une page web sur une zabeth de l'école à l'adresse suivante : http://[2001:660:4401:6050:216:3eff:fe1a:f9c3]:8080

Accès serveur web.png

De la Raspberry Pi, on vérifie qu’on peut bien accéder au serveur Python HTTP :

Test accès serveur avec curl.png

Pour envoyer des données de la Raspberry PI au serveur HTTP, nous avons créé un script Python qui va permettre d'envoyer ces données par des requêtes HTTP. Ce script sera bien évidemment lancé de la Raspberry PI. Pour que l'envoi de données fonctionne, nous devons alors lancer le script permettant le fonctionnement du serveur web sur le serveur delgodVM (commande python3 ./server.py). Et nous devons lancer simultanément le script reader.py sur la Raspberry PI. Le script est le suivant :

import serial
import requests

ser = serial.Serial (
    # Port série pour lire les data
    port='/dev/ttyACM0',
    # Débit de la communication série
    baudrate=460800,
    # Check ds parités, ici on ne le fait pas
    parity=serial.PARITY_NONE,
    # Number of serial commands to accept before timing out
    timeout=1
)

# Open function to open the file "store_data.csv"
#file = open(r"store_data.csv","w")

url = "http://[2001:660:4401:6050:216:3eff:fe1a:f9c3]:8080/data"

while 1:
    url = "http://[2001:660:4401:6050:216:3eff:fe1a:f9c3]:8080/data"
    x=ser.readline()
    output=str(x, 'UTF-8')
#   file.write(output)
    data = output
    response = requests.post(url,json=data)
    print (x)
    if reponse.status_code == 200:
      print("Donnees envoyees avec succes")
    else:
      print(f"Échec de l'envoi. Code de statut : {response.status_code}")
      print(response.text)

#file.close()

Au final ,nous arrivons bien à recevoir les données sur le serveur Xen, par un paquet unique.

Reception des données.png

Le fichier reader2.py permet d’envoyer les paquets de données au serveur, qui les reçoit.

Stockage des Données

Notre serveur Xen reçoit maintenant les données de la carte grâce aux requêtes HTTP. Nous avons alors décidé de code un script python recevant les données et qui les stockes dans un fichier .csv sur le serveur afin de pouvoir par la suite utiliser les données du capteur.

Entraînement du modèle d’apprentissage

Entraînement sur NanoEdge AI Studio

Description

Pour commencer la partie Entraînement, nous avons décidé de commencer par NanoEdge AI Studio. Ce logiciel développé par STMicroelectronics

permet de "créer" une Intelligence Artificielle (IA), de manière simple et guidée.

Pour créer cette IA, nous avons tout d'abord dû connecter la carte STMicroelectronics au PC et lancer NanoEdge AI Studio.

"Signals"

Après avoir créé un projet "n-Class", nous avons dû rentrer les signaux que nous voulions faire apprendre. Dans notre cas, ce sont les lettres de A à J qui vont être apprises.

SignauxNEAIS.png

Après avoir fait tous les signaux que nous avons besoins, nous devons lancer le Benchmark.

Benchmark

Le Benchmark est une sorte d'étalon, c'est dans cette partie que l'IA cherche la meilleure librairie possible d'après les signaux envoyés dans la partie précédente.

Benchmark Delgod.png

Validation

Une fois que cette partie est terminée, nous pouvons passer à la partie Validation où nous pouvons importer un signal différent de ceux d'avant afin de choisir la meilleure librairie parmi celles trouvées dans la partie Benchmark.


Validation.png

Emulator

Enfin, nous pouvons tester en temps réel dans la partie Emulator si notre librairie a bien appris les signaux envoyés en entraînement.


EmulatorDelgod.png

Résultat

Nous avons filmé deux cas où l'IA reconnait les symboles C et I de la Langue des Signes Française (LSF) :

Entraînement avec un script Python

Mise en place du modèle embarqué et des modèles hybrides

Séance du 04/12/2023

AU cours de cette première séance, nous avons pu prendre en main les outils nécessaires à la réalisation de notre projet. L’objectif était de construire un serveur Xen et de configurer la RaspberryPi.

  • Machine virtuelle sur Chassiron avec un accès internet IPv6.
  • Image de la Raspberry Pi pour connexion avec le serveur via WiFi : nous avons installé une image ** sur la rapsberry pi

Séance du 18/12/2023

Au cours de cette séance, nous allons tout d'abord

  • Développer un firmware embarqué pour collecter les données, avec STM32 Cube IDE et donc un programme permettant d'acquérir les données du capteur.
  • Mettre en œuvre un protocole de communication entre les quatre objets et la Raspberry Pi en garantissant que toutes les données sont bien reçues. Utilisation de la liaison série entre la carte et le capteur. Sur le port ttyACM0, avec un script python lancé de la rapsberry. Les données du capteur sont ensuite stockées dans un fichier .csv.

Séance du 19/12/2023

  • Mise en place d'un serveur web http sur le serveur delgodVM pour permettre la communication grâce à des requêtes http entre la raspberry pi et le serveur. Tout ceci est réalisé grâce des scripts python.

Séance du 20/12/2023

  • Transmission des datas récupérées par le capteur de la raspberry pi vers le serveur http.
  • Vérfication de la réception de ces données brutes
  • Début de l'apprentissage de notre AI, reconnaissance de la langue des signes