Tuteur : Stéphane Bazeille
Groupe : Braun Florian, Eckler Louis, Hebinger Pierre, Tissot Hugo, Zaid El Khil Damien, Benjamin Zimmermann, Jérémy Binder
Sommaire
Cahier des charges
1. Présentation générale du problème
1.1. Projet
1.2. Contexte
1.3. Énoncé du besoin
1.4. Environnement du produit
2. Expression fonctionnelle du besoin
3. Cadre de réponse pour chaque fonction
Gestion et réalisation du projet
1. Tester et communiquer avec tous les capteurs
A) Caméra
a) Configuration
b) Branchement
c) Code
B) Centrale inertielle
a) Configuration
b) Branchement
c) Code
C) GPS
a) Configuration
b) Branchement
c) Code
2. Enregistrer les données et photos
A) Enregistrer les données textes
a) Installation nécessaires
b) Code
B) Enregistrer les photos
3) Envoyer les données et photos sur les serveurs
A) Envoi des données textes au serveur MQTT
B) Envoi de photos au serveur FTP
4) Réceptions des données et photos ( client à serveur)
A) Serveur FTP
B) Serveur Node.js / Mysql
a) Mise en place de l’infrastructure web
b) Installation des extension node.js
c) Code de réception node.js
5) Interface utilisateur
A) Interface utilisateur Raspberry PI
B) Interface utilisateur côté serveur
a) code
6) Finalisation du programme principale
7) Création du boîtier
Vidéo de présentation
Cahier des charges
1. Présentation générale du produit
1.1. Projet
Le projet Tracker GPS consiste à créer un dispositif portable, permettant d’enregistrer un parcours lors d’une randonnée. Les données sont, par la suite, retranscrites sur un carte gérée sur un site internet.
1.2. Contexte
Afin de porter à bien le projet, nous sommes constitués d’un groupe de 7 personnes.
Dans un premier temps il faudra étudier le fonctionnement de chaque module (GPS, IMU, Caméra), ainsi que celui de la Raspberry, cela est primordial pour la compréhension et la réalisation. Après avoir connecté puis communiqué avec les capteurs, il sera nécessaire de les programmer un à un pour au final créer un seul et unique programme. En parallèle, il faudra créer une interface (site internet), sur lequel on serait capable d’afficher le trajet, et une autre interface (écran du Raspberry), pour pouvoir lancer le programme et visualiser les différentes informations.
1.3. Enoncé du besoin
1.4 Environnement du produit
Le dispositif final doit être facilement transportable et doit répondre à un minimum de contraintes environnementales:
- résister à l’humidité
- s’adapter aux différentes météo
La liste de matériel nécessaire :
- Batterie
- Raspberry PI
- GPS, IMU (centrale inertielle)
- Caméra
- Écran d’interaction
- Boîtier
- Serveur MQTT
- Serveur FTP
- Site Internet
Pour tout ces composants, le coût à l’achat représente 202 €, un coût qui ne nous est pas soumis car tout le matériel a été fourni par l’IUT.
2. Expression fonctionnelle du besoin
Fonction | Désignation | Critères d’appréciations | Niveau | Flexibilité | Observations |
FP1 | Permettre à l’utilisateur de consulter les informations sur son parcours |
– visualiser sur un écran – carte avec un tracé visible du trajet |
/ | / | / |
FC1 | Récolter les données du Raspberry PI |
– envoyer les différentes coordonnées GPS – envoyer les images prises avec le Raspberry PI |
photos toutes les 30s / données toutes les 2 secondes |
±10 s pour les photos / ± 2 s pour les données |
quelques secondes de retard possibles pour l’envoi des données lors de l’envoi d’une photo |
FC2 | Transporter le tracker GPS |
– boîtier contenant le Raspberry pi – un boitier léger |
/ | poids agréable à transporter.
taille: peu encombrant |
capteur gps plus efficace quand à l’extérieur du boîtier |
FC3 | Communiquer avec le Raspberry PI | -communiquer à l’aide de serveur MQTT et FTP | sans fil | / | / |
FC4 | Être alimenté en énergie | -batterie | 1h | minimum 30 minutes | 2h |
FC5 | Être ergonomique |
-Forme : des poignées (pour faciliter le transport) -Couleur : transparent (pour avoir un regard sur les composants) |
une bonne prise en main | / | / |
FC6 | Environnement | – dispositif résistant à l’humidité et non influencé par la pression atmosphérique | résister à une météo pluvieuse | résister à une légère pluie | mettre le capteur GPS dans le boitier pour plus d’étanchéité, mais une perte d’efficacité du capteur |
FC7 | Coût | – coût final accessible | 250€ | + ou – 50€ | 202€ sans le support |
3. Cadre de réponse par fonction
FP1
Le tracker pourra afficher les données récoltées sur un écran Raspberry, puis il pourra également consulter son trajet tracé sur une carte sur un site internet.
FC1
Les données pourront être récoltés toutes les 2 secondes. Les photos seront quant à elle récoltées toutes les 10 secondes. Un retard de quelques secondes pourra se faire remarquer lors de l’envoi d’une photo.
FC2
Le tracker GPS sera transporté dans un boîtier contenant tous les composants. Le boîtier sera en plastique et donc léger. Cependant pour avoir une meilleure efficacité du GPS il est possible de fixer le module GPS à l’extérieur, si le besoin s’en fait ressentir.
FC3
Le raspberry Pi pourra envoyer les données récoltées grâce à un serveur MQTT (pour les données) et grâce à un serveur FTP (pour les photos).
FC4
Le tracker GPS sera alimenté grâce à une batterie externe, pour une autonomie de 2h de trajet avant rechargement.
FC5
Le tracker GPS sera ergonomique grâce au boîtier qui possédera des poignées. Il serait également possible de fixer une sangle sur le boitier pour pouvoir le porter autour du cou. Le boîtier sera transparent afin de pouvoir visualiser les composants.
FC6
Le dispositif sera protégé par le boîtier et sera donc résistant à l’humidité. Le tracker pourra résister à une légère pluie. Cependant l’écran étant positionné sur le dessus, il ne pourra pas résister à une forte pluie.
FC7 Le dispositif doit avoir un coût finale proche de 250€, en prenant en compte le Raspberry PI, le module GPS, la centrale inertielle, la caméra, l’écran tactile Raspberry PI, la batterie et le support du dispositif.
Gestion et réalisation du projet
1. Tester et communiquer avec tous les capteurs
A) Caméra
(Braun/Eckler)
a) Configuration
Avant de brancher la PiCamera sur votre Raspberry Pi, il faut autoriser la caméra à interagir avec la carte, pour cela il faut exécuter:
sudo raspi-config |
b) Branchement
Vous pouvez ensuite brancher la PiCamera à l’endroit indiqué:
c) Code
Le code ci-dessous permet de prendre une photo et de la sauvegarder dans un fichier sur la Raspberry Pi:
from picamera import PiCamera from time import sleep camera = PiCamera () titre = 4 // si on veut que la photo se nomme “image4”. Cette ligne sera par la suite remplacé pour pouvoir sauvegarder les photos à la suite avec un numéro différent def cameraInitialisation () : camera.rotation = 180 camera.hflip = True def cameraCapture (titre) : camera.start_preview () sleep (2) camera.capture (‘/home/pi/Desktop/Images/image%s.jpg’ % titre) // Mettre entre les parenthèses le fichier où vous voulez sauvegarder les photos camera.stop_preview () cameraInitialisation () cameraCapture (titre) |
documentation sur la PiCamera:
https://www.raspberrypi.org/documentation/hardware/camera/
B) Centrale inertielle
(Zaid El Khil / Tissot / Hebinger)
a) Configuration
Avant de commencer quelconque branchement, il faut configurer votre Raspberry PI pour pouvoir lire les données de la centrale inertielle.
Nous allons utiliser le support I2C de la Raspberry PI:
sudo apt-get install -y python-smbus sudo apt-get install -y i2c-tools sudo apt-get install i2c-tools libi2c-dev |
puis exécuter:
sudo raspi-config |
pour accéder au panneau de configuration et suivre les instructions suivantes:
- aller sur “Interfacing Option”
- ensuite I2C
- Activer
- puis reboot
- ensuite il faut commenter dans la “Blacklist de l’I2C”
sudo nano /etc/modprobe.d/raspi-blacklist.conf |
et placer un “ # ” devant blacklist i2c-bcm2708
- il faut éditer le module conf file
sudo nano /etc/modules |
et y ajouter deux lignes: i2c-dev
i2c-bcm2708
- puis reboot le système une nouvelle fois.
b) Branchement
Pour le branchement de la centrale inertielle, il faut donc relier l’IMU au Raspberry PI en réalisant le montage suivant:
ensuite la commande:
sudo i2cdetect -y 1 ou sudo i2cdetect -y 0 |
selon votre Raspberry PI
Un tableau comme ci-dessous devrait apparaître, si ces valeurs sont visibles, alors la configuration et le branchement ont été correctement effectué.
c) Code
Afin de pouvoir lire correctement les données du magnétomètre, de l’accéléromètre et du gyroscope disponible avec la centrale inertielle, le code ,disponible sur le lien ci-dessous, sera nécessaire.
https://drive.google.com/open?id=1-dwNxMipXEEbJau5epRVy8zdp7lH6LXU
Avec ce code nous allons commencer par initialiser et paramétrer les sorties pour ensuite les lire comme souhaité.
Les données affichées à l’écran correspondent aux valeurs des axes X, Y et Z du magnétomètre, de l’accéléromètre et du gyroscope.
Pour plus de détails sur les paramètres, les datasheets sont disponibles sur les liens ci-dessous.
datasheet de l’accéléromètre et du gyroscope https://www.pololu.com/file/0J1087/LSM6DS33.pdf
datasheet du magnétomètre https://www.pololu.com/file/0J1089/LIS3MDL.pdf
C) GPS
(Zimmermann/Binder)
a) Configuration
Pour configurer le module GPS nous avons dû désactiver l’interface série du raspberry en allant dans : Menu>Préférences>Raspberry Pi Configuration. Puis « Serial » sur « Disable ».
Nous avons ensuite modifié dans un terminal le “sudo nano /boot/cmdline.txt” en y retirant : console=ttyAMA0,115200.
b) Branchement
Pour brancher le module GPS sur le raspberry nous avons simplement utilisé un câble USB vers micro-USB ce qui nous a permis d’avoir un branchement plus propre et plus soigné plutôt que de brancher le module directement avec les broches.
c) Code
Pour pouvoir utiliser correctement le module GPS et récupérer les données qu’il nous fournit nous avions besoin tout d’abord d’installer le module :
sudo apt-get update sudo apt-get install gpsd gpsd-clients python-gps |
Grâce à ça nous pouvions par la suite récupérer les données du GPS grâce à la commande “gpsd”.
Ensuite, afin de récupérer les données qui nous intéressaient nous avons utilisé le code suivant qui nous a permis d’avoir la longitude, l’altitude, la vitesse de déplacement…
from gps import * import os def mon_cgps(): session = gps(mode=WATCH_ENABLE) try: while True: donnees = session.next() if donnees[‘class’] == « TPV »: os.system(‘clear’) print ‘ Information GPS’ print ‘—————————————-‘ print ‘latitude ‘ , session.fix.latitude print ‘longitude ‘ , session.fix.longitude print ‘temps utc ‘ , session.utc print ‘altitude (m) ‘ , session.fix.altitude print ‘vitesse (m/s) ‘ , session.fix.speed print ‘satellites ‘ , session.satellites except KeyError: pass except KeyboardInterrupt: print « Ferme par l’utilisateur » except StopIteration: print « GPSD s’est arrete » finally: session = None |
2. Enregistrer les données et photos
A) Enregistrer les données textes
(Hebinger)
Pour enregistrer les données des différents capteurs directement sur la RaspBerry nous avons choisi la sauvegarde sous forme de tableau.
a) Installation nécessaires
Avant de pouvoir utiliser le script de sauvegarde il faut tout d’abord installer les librairies d’écritures xL à l’aide de la commande suivante
sudo apt-get install python-xlwt |
Toute la documentation nécessaire à la compréhension de cette dernière est disponible ici : https://pypi.org/project/xlwt/
b) Code
Tout le script nécessaire se trouve en suivant ce lien : https://drive.google.com/open?id=1d6-4YDzDVPpVTdZg8sJKrt0wrI_OgpVD
Après initialisation du code à l’aide de la commande:
enregistrementExcelInitialiser(trajet_id) |
il suffit de faire appel à la commande suivante:
enregistrementExcelValeures(…) |
celle-ci ajoutera une ligne au tableau contenant toutes les valeurs spécifiées.
B) Enregistrer les photos
(Eckler/Hebinger)
Le code permettant de sauvegarder les photos est directement contenu dans le code permettant de la prendre, il suffit de changer ce dernier pour modifier l’emplacement de cette dernière:
camera.capture (‘/home/pi/Desktop/Images/image%s.jpg’ % titre) |
3) Envoyer les données et photos sur les serveurs
A) Envoi des données textes au serveur MQTT
(Eckler/Tissot/Hebinger)
Avant de pouvoir envoyer quelques chose il nous faut un serveur. Nous avons utilisé le serveur “broker.hivemq.com” ,qui est gratuit, sur le topic “iutmulhouse”, pour pouvoir envoyer nos données textes.
Avant de coder il faut paramétrer la Raspberry PI:
sudo pip install paho-mqtt |
Il faut ensuite écrire un script en python pour envoyer les données sur le serveur.
Le code est assez simpliste:
import paho.mqtt.publish as publish import time import random def envoiDonnee(n, host): print(« sending…. ») publish.single(« iutmulhouse », »%s » %n, hostname=host) »’ //exemple de données à envoyer while True: n = « ‘trajet-2′,0515,45458,677,456,78954,236,7891,1587,6814,-987,-785,1548998,5489,4899,0.5,0.748,8,’toto' » envoiDonnee(n, » ») time.sleep(3) »’ |
Les données que nous envoyons correspondent à:
- id du trajet
- temps
- les 3 valeurs indiquées par le magnétomètre
- les 3 valeurs indiquées par le accéléromètre
- les 3 valeurs indiquées par le gyroscope
- les 4 valeurs indiquées par le GPS
- les 3 valeurs indiquées par le magnétomètre en Gauss
- titre photo
Enfin, pour pouvoir vérifier et visualiser ces données sur le serveur nous avons utilisé l’application “MQTT Snooper”.
*Message Queuing Telemetry Transport
B) Envoi de photos au serveur FTP
(Tissot)
Pour l’envoi des photos nous avons choisi d’utiliser un serveur FTP. Pour se faire, nous avons tout d’abord crée un emplacement dédié au projet sur le serveur « /geotracker.cf/htdocs/trajets/ ».
Ensuite nous avons initialisé la Raspberry PI avec la commande suivante:
sudo apt-get install vsftpd |
Puis, nous avons écrit un script en python en 2 étapes:
- Créer un dossier avec l’id du trajet sur le serveur FTP (utiliser lors d’un nouveau trajet)
import ftplib import time def creerDossier(dossier): server = ‘185.27.134.11’ username = ‘b7_21363641’ password = ‘mdp’ ftp_connection = ftplib.FTP(server, username, password) remote_path = « /geotracker.cf/htdocs/trajets/ » ftp_connection.cwd(remote_path) ftp_connection.mkd(dossier) //”dossier” correspond à l’id du trajet |
- Envoyer la photo sur le serveur dans le dossier que nous venons de créer
def envoiPhoto(local, photo, dossier): server = ‘185.27.134.11’ username = ‘b7_21363641’ password = ‘mdp’ ftp_connection = ftplib.FTP(server, username, password) remote_path = « /geotracker.cf/htdocs/trajets/ » ftp_connection.cwd(remote_path + dossier) fichier = open(local + photo, ‘rb’) ftp_connection.storbinary(‘STOR ‘+photo, fichier) fichier.close() //”local” correspond à l’endroit ou la photo à été enregistré après avoir été prise //”photo” correspond au nom de la photo donné lors de son enregistrement |
Il ne reste plus qu’à aller voir sur le serveur si les commandes ont bien été effectué.
*File Transfer Protocol
4) Réceptions des données et photos ( client à serveur)
A) Serveur FTP
(Hebinger)
Pour serveur FTP nous avons utilisé celui fourni directement par notre hébergeur web que nous utiliserons plus tard pour le site ( cela permet aussi de faciliter l’accès à ces photos à partir du site ).
Ce serveur nous permet donc de stocker toutes les photos.
La seule chose qu’il faut faire pour préparer le serveur à recevoir les données est de créer un dossier “trajets” dans le dossier web du serveur, ici “htdocs”. Ce dossier permettra de contenir les photos des différents trajets.
exemple:
geotracker.cf/htdocs/trajets/trajet-1/image-0.jpg |
B) Serveur Node.js / Mysql
(Hebinger)
Les données texte sont sauvées à l’aide d’un serveur node.js et d’une base de données MySQL.
MySQL est un protocole permettant la sauvegarde de données sous forme de table tel un tableur excel. node.js est un protocole serveur permettant l’exécution indépendante de code javascript.
Le serveur node va pouvoir se connecter au serveur de communication MQTT afin de récupérer les infos envoyées par le Raspberry-Pi et va ensuite directement les inscrire dans la base de données MySQL.
a) Mise en place de l’infrastructure web
Pour notre infrastructure web nous avons fait le choix de nous servir uniquement de services gratuit afin de ne pas être limité par le temps.
Pour cela Heroku à été notre premier choix afin d’héberger le serveur node.js car fiable jusqu’ici : https://www.heroku.com/
Puis nous avons pris un hebergeur MySQL, pour cela nous nous sommes tournés vers db4free : https://www.db4free.net
Côté installation pour le MySQL c’est très simple il suffit de se connecter au serveur avec les informations fournies lors de l’inscription. Pour nous cela s’est fait à travers PhpMyAdmin.
Puis il faut créer une nouvelle table de données afin de stocker les informations.
Pour le serveur node.js, Heroku procure une installation à travers dropbox suite à l’inscription.
interface sur le site de Heroku suite à l’envoi des données
b) Installation des extension node.js
Pour le serveur node.js nous nous sommes servis de plusieurs “packages” permettants de faciliter la création d’applications et de supprimer les répétitions inutiles et sources d’erreurs.
- express
- mqtt
- mysql
- web-mqtt-client
cela peut se faire à travers la console node.js et des commandes suivantes :
npm install MySQL npm install mqtt |
c) Code de réception node.js
Le code de réception sous node.js permet de se connecter au serveur de communication MQTT, il va attendre un évènement “on message” afin de lire le message envoyé par la Raspberry-Pi et en envoyer les informations à la base MySQL à travers la commande “sendDataToMysql”
code complet commenté disponible ici : https://drive.google.com/open?id=1y4qjYR4vDO6iCB4ZVGP_rQUBJmR7wtqb
5) Interface utilisateur
A) Interface utilisateur Raspberry PI
(Zaid El Khil / Tissot)
Afin de pouvoir contrôler et lire directement le programme et d’assurer son bon fonctionnement, la création d’une interface utilisateur est nécessaire.
Pour cela, nous avons écrit un script en python en plusieurs étapes:
- Créer les dimensions de l’interface, mettre en place un bouton “Nouveau Trajet” et un bouton “Fin de trajet”, ainsi qu’une scrutation en continu de ces boutons lors du lancement du programme.
# -*- coding: utf-8 -*- from tkinter import * import time main = Tk() loop=False def scanning (): if loop: print (‘scanning…’) main.after(1000,scanning) main.geometry(« 1280×720 ») main.title(‘interface traquer’) app = Frame (main) Depart = Button(main,text= »Nouveau trajet »,command= NouveauDepart, bg=’#06D806′, width=15, height=2).place(x=’50’,y=’40’) Arrive = Button(main,text= »Fin », command= Fin, bg=’#E31E00′, width=15, height=2).place(x=250,y=40) main.after(1000,scanning) main.mainloop() |
- création d’une Scrollbar et d’une zone d’affichage de texte afin de visionner en temps réel les données récupérées et envoyées.
scrollbar = Scrollbar(main) scrollbar.pack(ipadx=50, side = RIGHT, fill= Y) mylist= Listbox(main, yscrollcommand= scrollbar.set ) def afficher(t): for line in range(1): mylist.insert(END,t) mylist.pack(pady=100, expand=50, side = LEFT ,fill = BOTH) scrollbar.config(command = mylist.yview) |
- Attribuer une fonction à chaque bouton.
def NouveauDepart(): global loop loop= True print (‘Nouveau départ’) t = « Nouveau départ » afficher(t) def Fin(): global loop loop=False print(« Fin de trajet ») t = « Fin de trajet » afficher(t) |
(La création d’un nouveau trajet et le lancement des prises de données lors de l’appui sur le bouton “Nouveau départ” sera défini sur le programme final, et de même pour l’arrêt de prise de données lors de l’appui sur le bouton “Fin de trajet”.)
← Visuel de l’interface
B) Interface utilisateur côté serveur
(Hebinger)
L’interface utilisateur serveur permet à l’utilisateur du traqueur GPS de consulter ses différents trajets sur une carte. Il pourra consulter les différentes photos prises et voir un tracé de son parcours, le tout sur une carte ou il pourra choisir entre une vue type “carte” et “satellite”.
Un menu déroulant permet de choisir le trajet voulu et un bouton permet d’actualiser le tracé en temps réel.
Les photos sont accessibles à travers un clic sur les pointeurs le long du trajet.
Le Site est accessible à cette adresse : http://geotracker.cf et est hébergé par https://byet.host/
Il a été créé à l’aide de différents langages de programmation tels que le javascript, le php, et le HTML/CSS.
L’accès au service de carte nécessite un code d’API google disponible gratuitement à travers leur plateforme : https://developers.google.com/maps/
a) code
L’interface se sert de HTML et de CSS pour le visuel. L’interactivité est gérée par du javascript et l’accès à la base de données se fait à travers du javascript et du php.
Le code complet, commenté, du site est disponible en suivant ce lien : https://drive.google.com/open?id=1ww60wHfPfqo16twtB_ymCQpQmDPzUTUy
6) Finalisation du programme principale
(Hebinger/Tissot)
Pour le programme final nous avons donc rassemblé les différents codes en utilisant la fonction “import”.
Le programme final peut se découper en plusieurs phases:
- L’initialisation du code pour l’interface Raspberry PI
- L’initialisation des différents capteurs en appelant les fonctions “central.initialise()” et
“camera.cameraInitialisation ()” - Attribuer aux boutons “nouveau départ” et “fin de trajet” leurs fonctions respectives
- La boucle principale qui envoie et enregistre les données toutes les 2 secondes et les photos toutes les 30 secondes
Pour plus de détails le programme est disponible sur le lien suivant:
https://drive.google.com/open?id=1ojvLKpooMv4-dqw6wrcToLJsb8RanAMJ
7) Création du boîtier
(Zaid El Khil / Braun /Eckler)
- Pour la création du boîtier nous avons opté pour un support cubique pouvant permettre le transport de tous les capteurs, batterie, écran et câble. Nous l’avons réalisé à l’aide d’une découpe laser.
- Nous lui avons ajouté des encoches suffisamment grandes pour pouvoir travailler un minimum sur les câbles en cas de petits problèmes (pour les plus gros problèmes qui nécessitent plus d’espace d’intervention nous avons permis l’ouverture du support au niveau de l’écran).
- De plus pour le bon fonctionnement des capteurs, la position dans le support est primordiale, leur position n’est donc pas mis au hasard, notamment pour la centrale inertielle et le capteur GPS qui selon leur orientation offriront des valeurs plus ou moins faussées. La caméra aura une encoche pour lui permettre de prendre des photos.
- Pour plus d’étanchéité nous avons collé les parties basses du boîtier avec une colle industrielle (bien que nous ne pouvons pas assurer une étanchéité maximum en vu des moyens que nous avons).
Vidéo de présentation