IMA4 2018/2019 P9 : Différence entre versions
(→Feuille d'heures) |
|||
(68 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | <include nopre noesc src="/home/pedago/pimasc/include/video-SpiderAndI-iframe.html" /> | ||
__TOC__ | __TOC__ | ||
<br style="clear: both;"/> | <br style="clear: both;"/> | ||
Ligne 169 : | Ligne 170 : | ||
==Liste des tâches à effectuer== | ==Liste des tâches à effectuer== | ||
− | + | '''Prélude : (Septembre-Décembre)''' | |
*Prise en main du sujet | *Prise en main du sujet | ||
*Lister le matériel nécessaire | *Lister le matériel nécessaire | ||
Ligne 175 : | Ligne 176 : | ||
− | + | '''Janvier''' | |
*Apprendre le langage Java à travers différentes mises en application notamment en Tp du langage orienté objets. | *Apprendre le langage Java à travers différentes mises en application notamment en Tp du langage orienté objets. | ||
*Alimenter notre Wiki | *Alimenter notre Wiki | ||
Ligne 181 : | Ligne 182 : | ||
− | + | ||
+ | '''Février''' | ||
*Apprendre à utiliser et à maîtriser l'environnement d'Android Studio. Pour cela, regarder des cours vidéos et textuels sur internet. | *Apprendre à utiliser et à maîtriser l'environnement d'Android Studio. Pour cela, regarder des cours vidéos et textuels sur internet. | ||
*Réaliser une première version d'une application avec des fonctionnalités basiques sur Android Studio. L'application permettra de passer d'une activité à l'autre (d'une page à l'autre) et ne fera rien d'extraordinaire pour le moment. | *Réaliser une première version d'une application avec des fonctionnalités basiques sur Android Studio. L'application permettra de passer d'une activité à l'autre (d'une page à l'autre) et ne fera rien d'extraordinaire pour le moment. | ||
*Alimenter notre Wiki | *Alimenter notre Wiki | ||
− | + | ||
+ | |||
+ | '''Mars''' | ||
*Utiliser notre première version de l'application pour pouvoir l'adapter à notre sujet c'est-à-dire essayer d'y inclure la réception des données du bracelet en arrière plan par exemple. | *Utiliser notre première version de l'application pour pouvoir l'adapter à notre sujet c'est-à-dire essayer d'y inclure la réception des données du bracelet en arrière plan par exemple. | ||
*Gérer la réception et l'envoi des données. Pour cela nous nous inspirons de l'exemple fourni par Monsieur Zocco qui vient du Git de Empatica et qui donne un exemple d'affichage temps réel des données collectées par le bracelet. | *Gérer la réception et l'envoi des données. Pour cela nous nous inspirons de l'exemple fourni par Monsieur Zocco qui vient du Git de Empatica et qui donne un exemple d'affichage temps réel des données collectées par le bracelet. | ||
Ligne 193 : | Ligne 197 : | ||
*Alimenter notre Wiki | *Alimenter notre Wiki | ||
− | + | ||
+ | |||
+ | '''Avril''' | ||
*Suite du codage notre Application. Ajouter la fonctionnalité d'envoi des données stockées dans un fichier par requête HTTP. | *Suite du codage notre Application. Ajouter la fonctionnalité d'envoi des données stockées dans un fichier par requête HTTP. | ||
*Faire en sorte que l'application s'utilise sans problèmes en tâche de fond (consommation énergétique faible). | *Faire en sorte que l'application s'utilise sans problèmes en tâche de fond (consommation énergétique faible). | ||
Ligne 200 : | Ligne 206 : | ||
*Alimenter notre Wiki | *Alimenter notre Wiki | ||
− | + | ||
+ | |||
+ | '''Mai''' | ||
*Alimenter notre Wiki | *Alimenter notre Wiki | ||
*Soutenance le 6 | *Soutenance le 6 | ||
Ligne 208 : | Ligne 216 : | ||
{| class="wikitable" | {| class="wikitable" | ||
− | !Tâche !! Prélude !! Heures S1 !! Heures S2 !! Heures S3 !! Heures S4 !! Heures S5 !! Heures S6 !! Heures S7 !! Heures S8 !! Heures S9 !! Heures S10 !! Total | + | !Tâche !! Prélude !! Heures S1 !! Heures S2 !! Heures S3 !! Heures S4 !! Heures S5 !! Heures S6 !! Heures S7 !! Heures S8 !! Heures S9 !! Heures S10 !! Heures S11 !! Heures S12 !! Heures S13 !! Total |
|- | |- | ||
| Analyse du projet | | Analyse du projet | ||
− | | 3 | + | |style="text-align:center;" bgcolor="#B0F2B6" |3 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
+ | | | ||
+ | | | ||
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
| | | | ||
− | |||
| | | | ||
| | | | ||
Ligne 223 : | Ligne 233 : | ||
| | | | ||
| | | | ||
+ | |style="text-align:center;" |4 | ||
|- | |- | ||
| Design de l'Application | | Design de l'Application | ||
| | | | ||
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 3 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 3 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
| | | | ||
| | | | ||
Ligne 234 : | Ligne 245 : | ||
| | | | ||
| | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
| | | | ||
| | | | ||
| | | | ||
+ | | | ||
+ | |style="text-align:center;" |8 | ||
|- | |- | ||
| Maîtrise d'Android Studio | | Maîtrise d'Android Studio | ||
Ligne 242 : | Ligne 256 : | ||
| | | | ||
| | | | ||
− | | 3 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 3 |
− | | 5 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 5 |
− | | 4 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 4 |
| | | | ||
| | | | ||
Ligne 251 : | Ligne 265 : | ||
| | | | ||
| | | | ||
+ | | | ||
+ | | | ||
+ | |style="text-align:center;" |12 | ||
|- | |- | ||
− | | Implémentation de l' | + | | Implémentation de l'application |
| | | | ||
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
| | | | ||
| | | | ||
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
| | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" |2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" |3 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
| | | | ||
| | | | ||
− | | | + | |style="text-align:center;" |14 |
− | | | ||
|- | |- | ||
| Gestion et récupération des données | | Gestion et récupération des données | ||
Ligne 273 : | Ligne 293 : | ||
| | | | ||
| | | | ||
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
| | | | ||
+ | |style="text-align:center;" |6 | ||
|- | |- | ||
| Ecriture dans un fichier | | Ecriture dans un fichier | ||
Ligne 287 : | Ligne 310 : | ||
| | | | ||
| | | | ||
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
+ | | | ||
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
+ | |style="text-align:center;" |3 | ||
|- | |- | ||
| Envoi des données vers un serveur | | Envoi des données vers un serveur | ||
Ligne 301 : | Ligne 327 : | ||
| | | | ||
| | | | ||
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 3 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 3 |
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
+ | | | ||
+ | |style="text-align:center;" |6 | ||
+ | |- | ||
+ | | Test de l'application en utilisation réelle | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 3 | ||
+ | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" |8 | ||
|- | |- | ||
| Rencontre avec M. Zocco | | Rencontre avec M. Zocco | ||
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
| | | | ||
| | | | ||
| | | | ||
| | | | ||
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
| | | | ||
| | | | ||
| | | | ||
| | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
| | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
| | | | ||
+ | |style="text-align:center;" |6 | ||
|- | |- | ||
− | | Remplissage du | + | | Remplissage du wiki |
− | | 2 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 1 |
− | | 1 | + | |style="text-align:center;" bgcolor="#B0F2B6" | 2 |
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 1 | ||
+ | |style="text-align:center;" |16 | ||
+ | |- | ||
+ | | Rédaction du rapport | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
| | | | ||
| | | | ||
| | | | ||
+ | | | ||
+ | | | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 2 | ||
+ | |style="text-align:center;" bgcolor="#B0F2B6" | 6 | ||
+ | |style="text-align:center;" |10 | ||
|- | |- | ||
− | !Total ! | + | !scope=col style="text-align:center;" | Total |
+ | !scope=col style="text-align:center;" | 6 | ||
+ | !scope=col style="text-align:center;" | 5 | ||
+ | !scope=col style="text-align:center;" | 4 | ||
+ | !scope=col style="text-align:center;" | 5 | ||
+ | !scope=col style="text-align:center;" | 8 | ||
+ | !scope=col style="text-align:center;" | 9 | ||
+ | !scope=col style="text-align:center;" | 6 | ||
+ | !scope=col style="text-align:center;" | 6 | ||
+ | !scope=col style="text-align:center;" | 10 | ||
+ | !scope=col style="text-align:center;" | 8 | ||
+ | !scope=col style="text-align:center;" | 7 | ||
+ | !scope=col style="text-align:center;" | 7 | ||
+ | !scope=col style="text-align:center;" | 4 | ||
+ | !scope=col style="text-align:center;" | 8 | ||
+ | |style="text-align:center;" bgcolor="#A1D4E5" | 93 | ||
|} | |} | ||
Ligne 344 : | Ligne 428 : | ||
==Semaine 1== | ==Semaine 1== | ||
− | + | ''Mercredi 16 janvier 2019 :''<br> | |
Nous entamons la première séance dédiée au Projet du Semestre 8. Nous commençons par réfléchir à notre cahier des charges et à l'organisation de notre travail. L'objectif majeur du projet est de réussir à réaliser une application Android qui répond à tous nos besoins et qui met en lien les données relevées par le bracelet avec un serveur Web. Les araignées n'auront plus ensuite qu'à aller lire sur le serveur les données disponibles. Avant de commencer à coder, il est important que nous fassions sur papier un premier modèle, un prototype de notre application. | Nous entamons la première séance dédiée au Projet du Semestre 8. Nous commençons par réfléchir à notre cahier des charges et à l'organisation de notre travail. L'objectif majeur du projet est de réussir à réaliser une application Android qui répond à tous nos besoins et qui met en lien les données relevées par le bracelet avec un serveur Web. Les araignées n'auront plus ensuite qu'à aller lire sur le serveur les données disponibles. Avant de commencer à coder, il est important que nous fassions sur papier un premier modèle, un prototype de notre application. | ||
− | |||
+ | '''Réflexion sur un premier prototype d'application''' | ||
Voici comment nous visualisons l'application que nous allons développer. | Voici comment nous visualisons l'application que nous allons développer. | ||
− | + | [[Fichier:SI_app_ouverture.jpg| 300px|left|thumb|Image: Ouverture de l'application]] | |
− | [[Fichier:SI_app_ouverture.jpg| 300px|left|thumb]] | ||
Ligne 379 : | Ligne 462 : | ||
− | + | [[Fichier:SI_app_page1.jpg| 300px|left|thumb|Image: 1ère page]] | |
− | [[Fichier:SI_app_page1.jpg| 300px|left|thumb]] | ||
Ligne 400 : | Ligne 482 : | ||
Pour pouvoir commencer notre projet, Mr Redon nous a donné de quoi simuler un périphérique Bluetooth. Il nous a donné : | Pour pouvoir commencer notre projet, Mr Redon nous a donné de quoi simuler un périphérique Bluetooth. Il nous a donné : | ||
− | + | *Module Bluetooth (802.15.1) | |
− | + | *Téléphone Android | |
− | + | *Arduino Uno. | |
− | |||
− | + | Cela nous permettra de remplacer le bracelet temporairement.<br> | |
+ | Nous avons commencé par étudier la documentation du module Bluetooth. <br> | ||
− | + | D'autre part, nous avons modélisé notre l'application pensée la semaine dernière sur le site: appinventor.mit.edu | |
− | + | Cela nous a permis de nous introduire au langage orienté objet : JAVA. Ce logiciel permet de coder en bloc. | |
− | |||
− | Cela nous a permis de nous introduire au | ||
Voici le rendu : | Voici le rendu : | ||
Ligne 464 : | Ligne 544 : | ||
Séance de projet (Mercredi 13 février) | Séance de projet (Mercredi 13 février) | ||
− | Lors de cette séance nous avons continué le visionnage du cours concernant Android Studio. Nous nous sommes intéressés à deux chapitres qui seront très utiles dans le cadre de notre projet | + | Lors de cette séance nous avons continué le visionnage du cours concernant Android Studio. Nous nous sommes intéressés à deux chapitres qui seront très utiles dans le cadre de notre projet : |
− | + | *Working with Bluetooth | |
− | + | *Submitting your App to Google Play | |
Dans le premier cours, nous utiliserons deux bibliothèques: | Dans le premier cours, nous utiliserons deux bibliothèques: | ||
Ligne 501 : | Ligne 581 : | ||
− | + | *Nous devons nous concentrer sur l'énergie consommée par l'application. Par des tests, il faudra assurer que l'application fonctionne '''une journée entière''' ! | |
− | + | *En nous aidant du Git Empatica en exemple, nous devons reproduire la réception des données mais la rendre invisible (enlever la partie affichage) pour consommer le moins d'énergie possible. | |
− | + | *Une fois les données récupérées, il faudra les écrire dans un fichier '''.JSON''', '''.XML''' ou '''.TXT''' et les envoyer via une requête HTTP sur le serveur cible (FTP) fourni par M. Zocco (sous forme de quatre balises). Nous commencerons par essayer d'envoyer un fichier avec simplement écrit Hello World pour vérifier le fonctionnement. | |
Pour s'intéresser à la partie énergétique de l'application, il va falloir trouver un équilibre entre le taux d'échantillonnage des données (envoyées sur le serveur et reçues par la montre) et l'interface de l'application. | Pour s'intéresser à la partie énergétique de l'application, il va falloir trouver un équilibre entre le taux d'échantillonnage des données (envoyées sur le serveur et reçues par la montre) et l'interface de l'application. | ||
− | + | *Une éventuelle perte de connexion sera gérée par le programme des araignées directement. | |
+ | |||
M. Fabien Zocco et M. Laurent Sparrow, nous ont prêté un bracelet Empatica afin de pourvoir commencer un travail plus concret. Ce bracelet est normalement utilisé pour des recherches dans le domaine de la santé (par exemple : prédire l'arrivée d'une crise d'épilepsie). | M. Fabien Zocco et M. Laurent Sparrow, nous ont prêté un bracelet Empatica afin de pourvoir commencer un travail plus concret. Ce bracelet est normalement utilisé pour des recherches dans le domaine de la santé (par exemple : prédire l'arrivée d'une crise d'épilepsie). | ||
Ligne 529 : | Ligne 610 : | ||
Pour les fichiers texte, on peut alors stocker chaque ligne dans un tableau et écrire toutes les lignes en une seule commande. | Pour les fichiers texte, on peut alors stocker chaque ligne dans un tableau et écrire toutes les lignes en une seule commande. | ||
− | List<String> lignes = Arrays.asList( | + | List<String> lignes = Arrays.asList(ACCx,-11/-2,ACCy,57/63,ACCz,-11/-5); |
Path fichier = Paths.get(mon-fichier.txt); | Path fichier = Paths.get(mon-fichier.txt); | ||
Ligne 602 : | Ligne 683 : | ||
Cependant, cette affichage temps-réel doit être gourmand en énergie. | Cependant, cette affichage temps-réel doit être gourmand en énergie. | ||
− | Pendant la réunion, nous avons décidé de minimiser les coûts énergétiques et donc de ne pas mettre d'affichage des valeurs relevées. Nous cherchons alors à avoir l'application la plus pure possible. Pour faire un exemple et vérifier que nous arrivons bien à récupérer les données nous décidons d'afficher seulement la batterie de la | + | Pendant la réunion, nous avons décidé de minimiser les coûts énergétiques et donc de ne pas mettre d'affichage des valeurs relevées. Nous cherchons alors à avoir l'application la plus pure possible. Pour faire un exemple et vérifier que nous arrivons bien à récupérer les données nous décidons d'afficher seulement la batterie de la montrer en temps-réel. Le reste s'actualise en arrière-plan. (voir Photo 2) |
Pour cela, il a fallu étudier le code du git de près pour le comprendre et pouvoir l'intégrer dans l'application. Cette étape a occupé une grande partie de la séance. Une fois le code assimilé et intégré, nous avons essayé de l'adapter pour n'afficher que la batterie. Le problème du code de l'exemple est qu'il intègre des bibliothèques empatica que nous ne connaissons pas et le bracelet donne l'impression qu'il contient déjà un programme ainsi que certains processus qui s’exécutent automatiquement. Ces derniers n’apparaissent pas dans le code donc il est difficile d'en modifier leur comportement. Par exemple, dans le code n'apparaît pas la boucle qui vérifie si les capteurs ont changé de valeur. Pourtant cette boucle existe forcément. | Pour cela, il a fallu étudier le code du git de près pour le comprendre et pouvoir l'intégrer dans l'application. Cette étape a occupé une grande partie de la séance. Une fois le code assimilé et intégré, nous avons essayé de l'adapter pour n'afficher que la batterie. Le problème du code de l'exemple est qu'il intègre des bibliothèques empatica que nous ne connaissons pas et le bracelet donne l'impression qu'il contient déjà un programme ainsi que certains processus qui s’exécutent automatiquement. Ces derniers n’apparaissent pas dans le code donc il est difficile d'en modifier leur comportement. Par exemple, dans le code n'apparaît pas la boucle qui vérifie si les capteurs ont changé de valeur. Pourtant cette boucle existe forcément. | ||
Ligne 665 : | Ligne 746 : | ||
==Semaine 8== | ==Semaine 8== | ||
− | L'objectif cette semaine est de réussir à mettre en lien les deux fonctionnalités travaillées la semaine passée. Pour l'instant, une seule | + | L'objectif cette semaine est de réussir à mettre en lien les deux fonctionnalités travaillées la semaine passée : '''la réception des données en arrière plan''' et '''l'écriture dans un fichier'''. Pour l'instant, une seule des deux est fonctionnelle : l'écriture dans un fichier. Il faut régler le problème d'enregistrement dans des variables. Nous avons constaté la semaine dernière que pour certains capteurs on reçoit plusieurs valeurs d'un seul coup, il faut donc mettre en place un système de traitement efficace. |
De plus, entre temps nous avons remarqué que certains capteurs ont des fréquences d'écoute plus élevées que les autres c'est-à-dire qu'ils envoient plus de valeurs (ou plus vite) que d'autres capteurs. On aura donc plus de valeurs mesurées pour les capteurs concernés. | De plus, entre temps nous avons remarqué que certains capteurs ont des fréquences d'écoute plus élevées que les autres c'est-à-dire qu'ils envoient plus de valeurs (ou plus vite) que d'autres capteurs. On aura donc plus de valeurs mesurées pour les capteurs concernés. | ||
Ligne 673 : | Ligne 754 : | ||
*il est primordial d'avoir les deux valeurs relevées par le capteur IBI pour rendre cette information exploitable. Jusqu'ici nous n'avions qu'une seule valeur. | *il est primordial d'avoir les deux valeurs relevées par le capteur IBI pour rendre cette information exploitable. Jusqu'ici nous n'avions qu'une seule valeur. | ||
*nous séparerons les valeurs par des '''/''', ce sera notre séparateur ainsi que le caractère '''\n''' de retour à la ligne entre chaque capteur différent. | *nous séparerons les valeurs par des '''/''', ce sera notre séparateur ainsi que le caractère '''\n''' de retour à la ligne entre chaque capteur différent. | ||
− | *le fichier comportera 30 valeurs par | + | *le fichier comportera 30 valeurs par capteur, cela correspond environ à une valeur par seconde. Le fichier sera alors le résultat de 30 secondes de mesure. |
+ | |||
+ | Pour l'Inter Beat Intervalle (IBI), Laurent Sparrow nous a expliqué que ce capteur mesure le temps séparant 2 battements cardiaques, il n’y a pas de fréquence d’échantillonnage pour cet indicateur. Normalement, on doit avoir 2 colonnes : 1 pour le timestamp, et l’autre pour la valeur (en seconde) de l’IBI (temps séparant 2 battements). Pour l’interpréter, on compte le nombre d’intervalles supérieures à 50 ms par exemple. Une autre analyse consiste à analyser les bandes de fréquence concernant ces valeurs (est-ce que les variations d’IBI sont de basse, moyenne et haute fréquence), sans chercher une valeur supérieure à 50 ms pour suivre l’exemple précédant. | ||
+ | |||
+ | L'ensemble des relevés des deux données vont ensuite permettre de catégoriser l’état psychologique de Fabien Zocco, son activation etc. Ceci permettra de piloter le robot. | ||
+ | |||
+ | |||
+ | '''Le blocage de la batterie en semaine 7''' n'était pas réel, c'était '''un bug''' de la montre qui n'envoyait pas la valeur de la batterie donc forcément rien n'était affiché. | ||
+ | Pour pouvoir écrire dans un fichier par la suite l'ensemble des valeurs d'un coup et pouvoir organiser le fichier comme souhaité, nous avons tout intérêt à stocker les valeurs reçues. Pour cela nous les stockeront dans un tableau. Chaque capteur aura son tableau de valeurs à remplir lui-même quand il en reçoit de nouvelles. Nous choisissons des tableaux statiques pour contrôler et limiter la mémoire utilisée. Par exemple : | ||
+ | private String [] temperatureLabel = new String[MAXVAL]; '''//Ce tableau contiendra les valeurs relevées de la température''' | ||
+ | Pour l'instant nous fixons '''MAXVAL''' à 10 pour effectuer quelques tests. Nous essayons donc de relever les 10 premières valeurs des capteurs de Température, d'IBI, d'EDA et d'accéléromètre. Une fois les valeurs stockées dans les tableaux respectifs et quand tout le monde a ses valeurs, nous écrivons dans un fichier les valeurs. Voici un premier essai avec seulement la température, l'ibi et l'eda : (voir Photo 1) | ||
+ | {|align=right | ||
+ | |[[Fichier:fichierResultat1.png|thumb|Photo 1<br />Fichier résultant|250px]] | ||
+ | |[[Fichier:fichierResultat2.png|thumb|Photo 2<br />Fichier affichant toutes les valeurs attendues dans le bon ordre|220px]] | ||
+ | |} | ||
+ | Le résultat est bon et proche de celui que l'on souhaite. Cependant, on remarque que les premières valeurs de la température sont erronées (très négatives) ! Nous rajoutons alors un petit bout de code pour pallier ce problème et ne pas prendre en compte les valeurs négatives. Ce n'est pas visible ici car le problème avait déjà été traité mais la première d'EDA est aussi erronée (égale à 0). Nous ajoutons aussi un autre test pour vérifier que la valeur nouvelle n'est pas identique à la précédente, de même on ne la prend pas en compte si c'est le cas. Ce dernier test est seulement pour la température et l'EDA qui envoient beaucoup plus de données que les autres capteurs. Voici à quoi ressemble le code de ces fonctions : | ||
+ | public void didReceiveTemperature(float temp, double timestamp) { | ||
+ | if(tempCpt < MAXVAL && !fileReady && temp>0) { | ||
+ | if(tempCpt == 0){ | ||
+ | temperatureLabel[tempCpt] = String.valueOf(temp); tempCpt++; | ||
+ | } | ||
+ | else{ | ||
+ | if(temperatureLabel[tempCpt-1].compareTo(String.valueOf(temp))!=0) | ||
+ | { | ||
+ | temperatureLabel[tempCpt]=String.valueOf(temp); | ||
+ | tempCpt++; | ||
+ | } | ||
+ | } | ||
+ | Log.i("DEBUG", "TEMP : " + String.valueOf(temp)); | ||
+ | } | ||
+ | if(tempCpt==MAXVAL) | ||
+ | tempCpt=0; | ||
+ | } | ||
+ | Pour le moment, le code n'est pas optimal, on s'arrête quand on a reçu 10 valeurs d'IBI (capteur le plus long à réagir). Remarque : tant qu'on n'a pas les valeurs d'IBI, la température continue de remplir son tableau et le remet à jour, on aura donc à la fin les 10 dernières valeurs de la température. L'avantage indéniable de procéder ainsi est qu'on est sûr d'avoir bien 10 valeurs pour chaque capteur à la fin tandis que si on relève les valeurs des capteurs pendant 30 secondes, peut-être qu'on aura moins de 30 valeurs pour l'IBI et plus de 30 pour la température (et l'EDA). Nous ferons en sorte par la suite de mettre en place un timer qui écrit les valeurs qu'il a reçu pendant une période précise (30 secondes ou plus) et puis nous nous mettrons d'accord avec Fabien Zocco pour qu'à l'arrivée, les araignées n'interprètent que les valeurs pertinentes. | ||
+ | |||
+ | Une fois les tests effectués et vérifiés, nous ajoutons les valeurs d'accéléromètre et voici l'état du fichier : (Voir photo 2) | ||
+ | |||
+ | Nous sommes assez satisfaits de ce résultat et allons maintenant nous pencher sur l'envoi du fichier vers le serveur FTP. | ||
+ | |||
+ | |||
+ | '''Envoi des fichiers sur le serveur''' | ||
+ | |||
+ | En partant, du code que nous avons rédigé en Java en semaine 7, nous essayons de l'intégrer et de l'adapter. Nous avons été confrontés à plusieurs problèmes. | ||
+ | |||
+ | Dans un premier temps, afin qu’Android Studio reconnaisse les méthodes et les fonctions de la Classe FTP, il faut télécharger la librairie: commons-net-3.6-src.zip disponible ici : [https://commons.apache.org/proper/commons-net/download_net.cgi]. | ||
+ | Par la suite, il faut la dézipper et placer le .jar dans le dossier de notre projet : app.libs. Pour qu'Android studio prenne en compte cette nouvelle bibliothèque, il faut d'abord lui indiquer le chemin dans le fichier build.graddle:app grâce à ce code. | ||
+ | |||
+ | dependencies { | ||
+ | implementation 'com.android.support:support-v4:18.0.0' | ||
+ | '''implementation files('libs/commons-net-3.3.jar')''' | ||
+ | } | ||
+ | repositories { | ||
+ | flatDir { | ||
+ | '''dirs 'app.libs'''' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Puis dans un second temps, il faut inclure la bibliothèque dans les classes (essentiellement le '''MainActivity.class''') qui l'utilise avec la ligne suivante: | ||
+ | import org.apache.commons.net.ftp.*; | ||
+ | |||
+ | |||
+ | En plus des permissions déjà mentionnées plus haut (Semaine 7), nous devons ajouter la permission suivante: | ||
+ | '''<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />''' | ||
+ | Elle permet d'avoir des informations sur l'état du réseau, contrairement à '''<uses-permission android:name="android.permission.INTERNET" />''' qui permet de se connecter à internet. | ||
+ | |||
+ | À présent, nous avons tout ce qu'il nous faut pour envoyer notre fichier sur le serveur. Nous nous sommes ensuite basés sur notre cours de '''PSR''' pour réaliser la suite. En effet, pour envoyer un fichier sur un serveur, il faut utiliser la '''programmation multi threadée'''. Voici la fonction pour se '''connecter au serveur.''' | ||
+ | |||
+ | private void connectFTP() { | ||
+ | final String serveur ="ftp.myftpserver.com"; | ||
+ | final String login = "mylogin"; | ||
+ | final String mdp = "mypassword"; | ||
+ | new Thread(new Runnable() { | ||
+ | public void run() { | ||
+ | boolean status = ftpclient.ftpConnect(serveur, login, mdp, 21); | ||
+ | if (status) { | ||
+ | Log.d(TAG, "Connection Réussie"); | ||
+ | } else { | ||
+ | Log.d(TAG, "Connection Ratée"); | ||
+ | } | ||
+ | } | ||
+ | }).start(); | ||
+ | } | ||
+ | |||
+ | Les threads sont un peu différents en JAVA qu'en C comme le montre le code ci-dessus, cependant l'utilisation est semblable. Pour comprendre le fonctionnement des Threads en Java, nous avons visité ce site : [http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html]. | ||
+ | |||
+ | Enfin la fonction pour '''envoyer le fichier''' : | ||
+ | |||
+ | public boolean ftpUpload(String chemin, String NomFichier, String NomDossier, Context context) { | ||
+ | boolean status = false; | ||
+ | try { | ||
+ | FileInputStream fileStream = new FileInputStream(chemin); | ||
+ | status = mFTPClient.storeFile(NomFichier, fileStream); | ||
+ | fileStream.close(); | ||
+ | return status; | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | Log.d(TAG, "upload failed: " + e); | ||
+ | } | ||
+ | return status; | ||
+ | } | ||
==Semaine 9== | ==Semaine 9== | ||
+ | |||
+ | Nous avons profité de la séance du lundi, pour mettre en commun nos deux parties. | ||
+ | Nous pouvons à présent visualiser le fichier envoyé sur le serveur à cette adresse : [ fichier_info.txt [http://www.fabienzocco.net/fichier_info.txt]]. | ||
+ | Si l'application est en route et que la montre est connectée, si nous actualisons la page après quelques temps, nous remarquons bien que les données affichées changent. Le fichier envoyé est bien modifié. | ||
+ | |||
+ | Comme dit en semaine 8, notre système d'enregistrement du fichier est encore un peu "précaire" et ne reflète pas la réalité des faits. Le fait d'attendre de recevoir un nombre de valeurs du capteur d''''IBI''' rend l'envoi du fichier irrégulier et complètement aléatoire car ce capteur n'est pas fiable. Nous décidons alors de mettre en place un système de '''timer''' pour envoyer les valeurs reçues toutes les 30 secondes. Pour cela deux possibilités en java : | ||
+ | * les Handlers | ||
+ | * les CountDownTimer | ||
+ | Les handlers permettent d'effectuer une action toutes les secondes par exemple en utilisant des threads. Voici un exemple : | ||
+ | Handler handler = new Handler(); | ||
+ | Runnable run = new Runnable() { | ||
+ | @Override | ||
+ | public void run() { | ||
+ | Log.i("DEBUG", "A second must have passed"); '''// Cet exemple envoie un message dans les logs toutes les secondes''' | ||
+ | handler.postDelayed(this, 1000); | ||
+ | } | ||
+ | }; | ||
+ | handler.post(run);*/ | ||
+ | |||
+ | |||
+ | Les CountDownTimer ont un fonctionnement différent. Comme leur nom l'indique, c'est un décompte. Par exemple : | ||
+ | new CountDownTimer(10000, 1000){ '''//On donne en paramètres le temps total et le coup d'horloge souhaité en milisecondes | ||
+ | @Override | ||
+ | public void onTick(long millisUntilFinished) { '''//onTick() est executé à chaque coup d'horloge (ici, chaque seconde) | ||
+ | Log.i("Second left", String.valueOf(millisUntilFinished/1000)); | ||
+ | } | ||
+ | @Override | ||
+ | public void onFinish() { '''//onFinish() est executé à la fin du timer (ici; au bout de 10 secondes) | ||
+ | Log.i("Finish", "It is done !"); | ||
+ | } | ||
+ | }.start(); | ||
+ | |||
+ | Après analyse de nos deux possibilités, nous optons pour l'utilisation d'un Handler, car nous souhaitons que l'action de comptage ne s'arrête pas. Il nous suffira alors d'incrémenter un compteur à chaque seconde et de le réinitialiser quand il arrive à 30 si on veut envoyer toutes les 30 secondes. | ||
+ | |||
+ | Nous implémentons cette solution et testons avec le site internet. En actualisant toutes les 30 secondes, nous observons bien que les valeurs se mettent à jour. Cette fois-ci, le fichier n'est pas forcément plein puisqu'il n'a pas forcément reçu 30 valeurs pour chaque capteur. C'est ce que nous attendions et ceci reflète bien la réalité de ce que nous recevons. | ||
+ | |||
+ | |||
+ | Nous avons donc réussi à mettre au point une première application fonctionnelle. Nous entrons alors dans la partie la plus importante de notre projet, le point sensible : '''l'ergonomie'''. En effet, plusieurs '''questions difficiles''' portaient sur la gestion de l'autonomie du téléphone ainsi que de la montre. | ||
+ | Nous pouvons désormais répondre à l'une d'entre elles, la fréquence d'envoi de la montre. En analysant de près le code et le comportement de la montre nous pouvons affirmer que le modèle E4 d'empatica envoie en continu des données. Nous pouvons seulement jouer sur la fréquence d'envoi du fichier de données mais la fréquence d'envoi de la montre reste un paramètre fixe. Il y a une sorte de boucle cachée dans le programme interne de la montre et qui fait qu'elle envoie des données dès qu'elle les relève avec ses capteurs. En réponse à '''la question sur l'autonomie de la montre''', nous ne pourrons donc pas beaucoup jouer dessus avec notre application. | ||
+ | |||
+ | Pour ce qui est de '''celle du téléphone''' nous allons effectuer plusieurs journées de test en faisant varier les paramètres que nous pouvons modifier comme la fréquence d'envoi etc. | ||
+ | |||
+ | |||
+ | === Mardi 19 mars : 1ère journée de test === | ||
+ | |||
+ | |||
+ | |||
+ | Nous commençons la journée avec 65 % pour le téléphone et 90 % de batterie pour la montre. | ||
+ | Nous envoyons un fichier toutes les 30 secondes. Nous avons ajouté un compteur à la fin de notre fichier. Ce compteur s'incrémente que lorsque le fichier s'est envoyé. De cette façon, nous pourrons savoir le nombre exact d'envoi en fonction du niveau de batterie perdu. Il nous permet aussi de vérifier de manière rapide et efficace si l'application continue de fonctionner correctement. | ||
+ | |||
+ | |||
+ | Nous avons laissé tourner le programme pendant presque 6 heures 30 sans arrêt. Nous avons envoyé 778 fois notre fichier, mis à jour à chaque fois avec de nouvelles valeurs. Pour cette première journée, nous n'avons pas utilisé le téléphone, l'application tournait en tâche de fond. En faisant une moyenne de nos valeurs, on constate que le téléphone perd environ 5 % de batterie par heure d'utilisation. La montre quant à elle, plus énergivore, en perd 10 % par heure. Avec de telles valeurs, nous pensons pouvoir faire fonctionner le programme pendant environ 9 heures. C'est un très bon résultat pour un premier essai. Cependant, on rappelle que nous n'avons pas utilisé le téléphone donc c'est sûr qu'en utilisation normale, le résultat serait bien moins bon. | ||
+ | |||
+ | |||
+ | Au moment d’arrêter l'application, nous avons fait une simulation du cas où la connexion serait subitement perdue, l'application s'est tout de suite arrêtée. Nous allons donc modifier le code pour la prochaine journée de test. Nous pensons que c'est parce que le téléphone a essayé d'envoyer le fichier sans vérifier avant qu'il était bien connecté à internet. | ||
+ | |||
+ | |||
+ | Nous refaisons alors le même test, cette fois-ci le téléphone est branché au PC pour observer les logs et comprendre l'erreur. Ce que nous pensions s'est bien avéré être la vérité. Le téléphone essayait (à la fin des 30 secondes) d'envoyer le fichier sans vérifier sa connexion à internet au préalable. Cette action provoquait alors une '''Exception''' et l'application était automatiquement arrêtée puis fermée. Nous avons corrigé ce problème en ajoutant des tests de connexion avant d'envoyer le fichier, ainsi si le téléphone perd la connexion au réseau subitement, il ne pourra pas envoyer le fichier. Il ressayera de le faire chaque seconde jusqu'à ce qu'il retrouve le réseau. Il reprendra alors le cours normal de son activité. | ||
+ | |||
+ | Nous avons choisi de noter les valeurs du niveau des batteries et de la fréquence d'envoi dans un fichier Excel afin de mieux voir l'évolution en fonction des jours (voir Graphique ci dessous). <br> | ||
+ | |||
+ | |||
+ | === Mercredi20 mars : 2ème journée de test === | ||
+ | |||
+ | Nous avons laissé tourner le programme pendant 6 heures. Cette fois-ci, nous avons modifié la fréquence d'envoi. Nous envoyons le fichier toutes les minutes. La fréquence d'envoi est donc multipliée par deux. L'objectif est de voir si la batterie du téléphone consomme moins. | ||
+ | |||
+ | Après test, nous avons remarqué que pour une fréquence d'envoi d'une minute, la batterie du téléphone diminue moins (1%/heure de moins que pour une fréquence d'envoi égale à 30s). La montre ne subit pas de modification, puisqu'elle envoi le même nombre de données. | ||
+ | |||
+ | [[Fichier: SpipderandIvalues.png|700px|center]] | ||
+ | |||
+ | === Séance projet === | ||
+ | |||
+ | Pour l'instant, nous avons une application Android fonctionnelle sans design. C'est une application basique avec un fond noir et un bouton. Nous avons profité de cette séance pour faire une deuxième version de l'application. Nous n'allons pas l'encombrer, parce qu'il ne faudrait pas que ça augmente la consommation de la batterie du téléphone. Nous choisissons un design simple qui reprend notre logo de départ. | ||
+ | |||
+ | Nous avons eu la possibilité de discuter avec nos professeurs Xavier Redon et Thomas Vantroys, qui nous ont indiqué que les mesures que nous faisions ne sont pas précises. Elles manquent de professionnalisme. Nous devons mesurer ce paramètre avec plus de précisions. Ils nous ont conseillé d'utiliser un logiciel "Energy Profiler" qui permet de bien identifier les variations. Peut-être même, de voir quelles sont les fonctions de notre application qui consomment le plus et ainsi de pouvoir changer, améliorer, optimiser les parties du code qui consomment le plus de batterie pour l'application. Nous ne trouvons pas encore l'outil adéquat pour mesurer la batterie pour le moment. | ||
==Semaine 10== | ==Semaine 10== | ||
+ | |||
+ | Lors de la séance, nous nous sommes renseignés sur un energy profiler. En effet, ce sera plus professionnel de passer par une application qui s'occupera d'étudier la consommation énergétique de notre application. Nous n'en avons trouvé qu'un seul que propose Android Studio. Son nom : Profiler. Il faut avoir une version assez récente du système d'exploitation d'Android pour utiliser cet outil, il faut avoir un niveau d'API de 21 au minimum, ce qui est le cas pour nous. | ||
+ | |||
+ | Cependant, pour avoir des informations sur la section batterie, il faut avoir la version 28 (nous avons la 21). Le téléphone fourni pour ce projet est bloqué à la version 21. Nous ne pouvons donc pas vraiment étudier la consommation de la batterie autrement qu'avant. | ||
+ | |||
+ | Nous avons mis en place un nouveau visuel, simplifié et qui affiche l'état de connexion avec internet et le bracelet. Nous avons rencontré des problèmes liés à la programmation multi-threadée. En effet, nous essayions de mettre à jour ces "Widgets" de texte au moment ou l'état de connexion du bracelet ou du réseau changeait. Nous utilisions alors simplement la méthode '''setText("Le texte que nous voulions")''', disponible pour les "Widgets" de type texte. Cette utilisation nous créait des soucis. | ||
+ | |||
+ | [[Fichier:threadErrors.png|800px|right]] | ||
+ | |||
+ | |||
+ | Pour régler ce soucis il fallait s'assurer que l'execution de cette méthode s'effectuait bien dans le thread principal, celui qui a crée l'application et pour cela il fallait ajouter le bout de code suivant que nous avons ajouté dans une nouvelle méthode pour simplifier son appel : | ||
+ | private void updateLabel(final TextView label, final String text) { | ||
+ | runOnUiThread(new Runnable() { | ||
+ | @Override | ||
+ | public void run() { | ||
+ | label.setText(text); | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | [[Fichier:SANDI_Envoi.png|200px|left]] | ||
+ | |||
+ | En fin de séance, nous avons rencontré Mr Zocco. Pour le moment, il est satisfait du rendu de l'application et de son ergonomie. Il nous a proposé de mettre en place une liste chaînée pour le capteur IBI. Cela permettrait de récupérer toutes les valeurs. En effet, pour cette variable il est important d'avoir toutes les valeurs qui sont envoyées de façon asynchrone par la montre. C'est essentiel pour l'analyse des données. Ainsi, une utilisation d'une liste chaînée permet d'avoir un stockage dynamique et donc de taille variable contrairement au tableau initial. | ||
+ | |||
+ | Nous avons aussi modifié le symbole utilisé pour désigner une case "vide" qui correspondait à '-' '''(char)''' dans nos tableaux. Nous l'avons remplacé par "999" '''(int)''', parce que ça sera plus simple pour Mr Zocco de lire le fichier et de récupérer si toutes les valeurs sont des entiers et non pas un mélange d'entiers et de string. | ||
+ | |||
+ | Voici à quoi peut ressembler le fichier de données que nous envoyons : | ||
+ | [[Fichier:SANDI_FE.png|1100px|center]] | ||
+ | |||
+ | |||
+ | Lors de la prochaine séance, nous allons essayer notre application avec une connexion '''3G/4G'''. Nous devons également chercher des cas critiques qui pourraient arrêter notre application. | ||
+ | |||
+ | ==Semaine 11== | ||
+ | |||
+ | Nous consacrons cette séance essentiellement aux tests sur différents appareils en 3G puis en 4G pour faire tourner l'application dans des conditions différentes de connexion internet. | ||
+ | |||
+ | Cependant, pour effectuer ces tests nous avons besoin d’emprunter le téléphone d'un de nos camarades, ne possédant pas nous même de téléphone sous Android. On aurait pu simplement insérer notre carte SIM dans le téléphone prêté pour le projet mais essayer sur un autre téléphone nous permettait de vérifier que l'application fonctionnait bien sur différents appareils du notre. | ||
+ | |||
+ | De plus, souvenez-vous en Semaine 10, nous ne pouvions tester le '''Profiler''' d'Android Studio à cause d'une version trop ancienne de l'OS installé sur le smartphone. Nous profitons alors de l'occasion des tests 3G/4G pour emprunter un téléphone dernier cri parmi ceux de nos camarades et de faire à la fois le test fonctionnel et énergétique. | ||
+ | |||
+ | Nous installons notre application sur deux smartphones empruntés et faisons les tests fonctionnels en 3G/4G. Petit problème rencontré : notre application n'a pas demandé l'autorisation d'écriture dans les données du téléphone ce qui provoque l'arrêt de l'application au moment de l'envoi, puisque l'application essaye d'envoyer un fichier qui n'existe pas. C'est étonnant puisque nous avions déjà ajouté une autorisation de l'application pour l'écriture dans les fichiers de l'appareil. En fouillant dans les paramètres du téléphone, nous trouvons comment activer cette option. Une fois activée, tout semble fonctionner comme en wi-fi. Les envois se font sans rencontrer de difficultés et l'application fonctionne normalement. | ||
+ | |||
+ | Maintenant que l'application fonctionne comme elle devrait, nous lançons le '''Profiler''' qui va nous donner des informations sur la consommation énergétique de l'application en temps réel. Voir Photo | ||
+ | |||
+ | [[Fichier:energyProf.png | 1000 px | center]] | ||
+ | |||
+ | |||
+ | Nous sommes déçus du résultat. Le logiciel nous donne une information très peu fiable puisque les pics énergétiques sont qualifiés de Faible, Moyen ou Élevé. C'est pas très précis mais on voit quand même que tous les pics sont bien bas dans le niveau '''Faible''' donc à priori, notre application ne consomme pas beaucoup. Mais par rapport à quoi ? C'est le problème de cet indicateur pas très intéressant ici. On remarque aussi les pics très marqués dans la partie '''Network''' correspondant aux envois de fichier. Le léger mouvement avant le pic d'envoi est dû à la tentative de connexion au serveur avant l'envoi. On a bien un pic d'envoi vers le serveur en jaune et de réception du serveur en bleu. De même au niveau du '''CPU''', le téléphone est loin d'être en surcharge et c'est normal. | ||
+ | |||
+ | Pour la fin de la séance, nous décidons d'optimiser au maximum notre fichier d'envoi. Lorsqu'il est bien rempli, il pèse environ '''1 Ko''' ce qui n'est pas beaucoup. Cependant, en tant qu'ingénieur, nous devons rendre le code le plus optimisé possible pour un fonctionnement optimal de l'application (et minimal dans sa consommation énergétique). Il est évident que plus le fichier est gros, plus le téléphone consomme de l'énergie à l'envoyer sur le serveur. Comme cet envoi a lieu plusieurs fois par minute et que nous voulons un fonctionnement sur toute une journée, il est important d'optimiser le contenu du fichier. Nous supprimons les espaces et les sauts de ligne inutiles. | ||
+ | Après ces modifications nous arrivons à une taille moyenne d'environ '''500 octets'''. | ||
+ | |||
+ | ==Suite et fin== | ||
+ | |||
+ | Pendant les vacances, nous avons eu une nouvelle réunion de projet, cette fois-ci via Skype avec Fabien Zocco et Laurent Sparrow. Nous faisons un point tous ensemble sur l'avancée du projet et voyons les points à améliorer. Quelques modifications supplémentaires du fichier nous sont demandées. Souvenez-vous, jusqu'à présent, comme expliqué en '''semaine 7''', nous gardions seulement les 15 dernières valeurs relevées mise à part pour l''''IBI''' que nous avons transformé en liste chaînée en '''semaine 10'''. | ||
+ | |||
+ | Pour permettre l'analyse exacte des données par Laurent, il nous a demandé d'envoyer toutes les valeurs d''''EDA''' aussi, donc de faire comme pour l'IBI en liste chaînée. Aussi, les valeurs d'accéléromètre peuvent être utiles dans l'analyse des mouvements de Fabien et donc il est préférable de moyenner les valeurs plutôt que de relever seulement les 15 dernières valeurs (1 valeur par seconde). En regardant la documentation [https://support.empatica.com/hc/en-us/articles/201608896-Data-export-and-formatting-from-E4-connect- Empatica], nous apprenons que le capteur relevant les valeurs d'accéléromètre travaille à 32 Hertz donc il relève 32 valeurs par seconde pour chaque coordonnée (X, Y et Z). Nous faisons en sorte donc que dans le code, le programme moyenne 32 valeurs par seconde pour utiliser toutes les valeurs relevées. | ||
+ | |||
+ | |||
+ | |||
+ | '''Partie exploitation des données :''' | ||
+ | Nous n’avons pas pu obtenir d’araignées-robots pour vérifier que notre partie fonctionne bien. Nous avons alors créé un programme sur Processing. Notre programme récupère les données sur le site http://www.fabienzocco.net/fichier_info.txt. | ||
+ | |||
+ | |||
+ | La fonction ls permet de récupérer les données du site à l’aide de la fonction loadString(<lien>). Cette opération est réalisée toutes les 15 secondes. Parce qu’il faut que la fréquence d’envoi sur le serveur soit la même que la fréquence de récupération. On utilise alors un compteur pour gérer le temps. A chaque appel de cette fonction nous remplissons un tableau de toutes les valeurs. Les données qui nous intéressent en l'occurrence les valeurs de l'accéléromètre (variable x seulement) se trouvent à la ligne 7. Avec la commande split, on sépare les données en précisant le séparateur utilisé sur le site: “/”, et on range ces valeurs dans un tableau. | ||
+ | La fonction draw permet de dessiner le cercle. Nous avons alors choisi de remplacer l'araignée par un cercle bleu. Ce dernier va se déplacer dans la fenêtre en suivant les valeurs récupérés par l’accéléromètre de la montre. Pour ce faire, nous avons modifié les coordonnées du centre du cercle. | ||
+ | |||
+ | |||
+ | Ci-dessous un exemple: | ||
+ | Lorsque qu’une personne qui porte le bracelet fait un mouvement de droite à gauche, on peut voir un déplacement du cercle de droite à gauche. | ||
+ | |||
+ | [[Fichier:SAI_testprog.gif|SAI_testprog.gif]] | ||
+ | |||
+ | |||
+ | Pour conclure sur ce projet, nous avons travaillé '''en équipe''' dans ce projet et le travail a été équitablement réparti. Nous avons pris soin à ce que la communication soit bonne et que le partage du travail soit équitable entre nous. | ||
+ | De plus, nous étions en '''réelle situation d’ingénieur''' avec un client et un projet à réaliser en un temps délimité. Ce côté était d’autant plus marqué parce que le demandeur et encadrant Monsieur Zocco était extérieur à l’école. Nous nous sommes positionnés en tant qu’ingénieurs, avons organisé des réunions projets pour obtenir des informations et des réponses à nos interrogations. Nous avons tenu au courant Monsieur Zocco tout au long du projet de nos avancées en lui faisant des retours réguliers. | ||
+ | Ce projet était '''prenant et enrichissant'''. Il nous a permis de développer les compétences que nous souhaitions et de découvrir la programmation pour applications mobiles. | ||
+ | |||
+ | L'application est fonctionnelle et nous sommes satisfaits du résultat obtenu. Elle sera utilisable pour la suite du projet par Fabien Zocco et Laurent Sparrow. | ||
+ | |||
+ | =Bibliographie= | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ | ||
+ | |- | ||
+ | | | ||
+ | ! scope="col" | Lien | ||
+ | |- | ||
+ | | Documentation Empatica sur les capteurs du bracelet E4 | ||
+ | | https://support.empatica.com/hc/en-us/articles/202581999-E4-wristband-technical-specifications | ||
+ | |- | ||
+ | | Dépot Git Empatica avec l’exemple | ||
+ | | https://github.com/empatica/empalink-sample-project-android/ | ||
+ | |- | ||
+ | | Informations sur le marché mobile de nos jours | ||
+ | | https://www.servicesmobiles.fr/20-chiffres-sur-le-marche-mobile-a-connaitre-en-2018-38749/ | ||
+ | |- | ||
+ | | Le lien vers le cours que nous avons utilisé: | ||
+ | | https://www.udemy.com/complete-android-n-developer-course/learn/v4/overview | ||
+ | |- | ||
+ | | Explication du Energy profiler d’Android Studio | ||
+ | | https://developer.android.com/studio/profile/android-profiler | ||
+ | |- | ||
+ | | Git d’une alternative Energy profiler pour une application .apk | ||
+ | | https://github.com/google/battery-historian | ||
+ | |- | ||
+ | | Site de Fabien Zocco, où on l’on trouve notre fichier de données | ||
+ | | http://www.fabienzocco.net/fichier_info.txt | ||
+ | |- | ||
+ | | Conseil pour la rédaction d’un rapport de projet | ||
+ | | https://www.irit.fr/~Armelle.Bonenfant/Enseignement/JavaSTRI/conseilsRapport.pdf | ||
+ | |} | ||
+ | |||
+ | Sans compter la multitude de pages Wikipédia et publications sur Stack Overflow qui nous ont aidé à nous sortir de différents problèmes même mineurs. | ||
+ | |||
=Documents Rendus= | =Documents Rendus= | ||
+ | |||
+ | Code source de l'application (Android Studio) : [[Média:SpiderAndI.zip]] | ||
+ | |||
+ | Rapport du projet : [[Média:RapportP9.pdf]] |
Version actuelle datée du 17 juin 2019 à 19:42
Sommaire
- 1 Présentation générale : Spider and i
- 2 Analyse du projet
- 2.1 Positionnement par rapport à l'existant
- 2.2 Scénario d'usage du produit ou du concept envisagé
- 2.3 Questions difficiles
- 2.4 Réponse à la question difficile
- 2.4.1 Comment gérer l’autonomie du téléphone ? Et celle du bracelet ?
- 2.4.2 Quelle est la fréquence d’envoi des messages de notre application ? Du bracelet ?
- 2.4.3 Comment fonctionne le capteur de sudation ?
- 2.4.4 Trouver, envisager une solution de secours au cas où les parties qui ne nous concernent pas n'aboutissent pas
- 3 Préparation du projet
- 4 Réalisation du Projet
- 5 Bibliographie
- 6 Documents Rendus
Présentation générale : Spider and i
Encadrants : Fabien Zocco / Thomas Vantroys
Eleves : Lina Mejbar / Nestor Martinez
Description
Deux hexapodes (robot à 6 pattes pouvant évoquer une grosse araignée mécanique, dimensions : 36,83 cm (L) x 43,18 cm (l) x jusqu'à 13,34 cm (h)) se font face sur un socle. Leurs interactions semblent alterner des phases de calme et de complicité, ou à l’inverse présentent des attitudes de défiance croissante voir d’agressivité manifeste. Ce jeu relationnel entre les deux robots instaure une sorte d’étrange chorégraphie artificielle, rythmée par les multiples variations de vitesses et les micro-mouvements esquissés par les hexapodes. Ces alternances et variations sont directement indexées sur le rythme cardiaque de l’artiste. Celui-ci sera, au cours des périodes d’exposition de l’oeuvre, en permanence équipé d’un bracelet connecté relevant ses données biométriques qui seront relayées via le réseau vers les deux robots.
Précisions supplémentaires concernant le sujet : Les hexapodes existent déjà. L'artiste porte (en permanence) à son poignet un bracelet connecté qui relève son rythme cardiaque ainsi que son niveau de sueur (capteur de sudation). Les données relevées à son poignet sont envoyés par bluetooth au téléphone de l'artiste. Par l'intermédiaire d'une application android, ces données sont envoyées sur un serveur web pour être récupérées par les robots équipés d'un dispositif le permettant (Raspberry).
Les araignées sont programmées pour réagir, bouger par rapport aux données qu'elles reçoivent. En fonction de si l'artiste est stressé, énervé, excité, les araignées agiront en conséquence de manière à imiter l'artiste.
Tout le travail d'analyse des données pour déterminer l'état de l'artiste est confié au laboratoire SCAlab.
La partie programmation des mouvements des araignées est effectuée par l'artiste lui-même. On pourra l'assister.
Notre travail à nous consiste à faire le lien entre le bracelet connecté et le téléphone en créant l'application nécessaire et rediriger par la suite les données sur un serveur.
Objectifs
- Etudier le langage Java pour apprendre à coder une application Android
- Apprendre à utiliser une API Bluetooth pour communiquer avec celle du bracelet
- Récupérer les données relevées par le bracelet
- Envoyer les données à un serveur web
Analyse du projet
Positionnement par rapport à l'existant
On assiste de nos jours à de nombreuses améliorations des nouvelles technologies. Donc de nombreux artistes développent ce nouveau secteur et se tournent vers de nouveaux horizons. De plus en plus d’étudiants suivent des cours de programmations dans les écoles d’arts. C’est ainsi que les artistes développent une certaine attirance pour ce domaine.
Quelques exemples :
- Adelin Schweitzer détourne des méthodes de surveillance militaire en utilisant des robots, ou des drones, contrôlés à distance proposant ainsi une nouvelle manière de découvrir des espaces urbains ou ruraux
- Dorothée Smith étude pour spectres, composé d’une caméra thermique, d’une puce électronique sous-cutanée qui implique au final un transfert de données cellulaires. Elle imagine ici une expérience limite où le moi, confronté à la menace de sa disparition, trouve dans la biotechnologie le moyen de sa résistance.
Le projet Spider&I se rapprochera du projet de Dorothée Smith mais la finalité sera différente. Notre projet à pour but final de contrôler des araignées après une récupération des données et son transfert vers une application Android.
Nous ne considérons pas vraiment de concurrence entre les artistes. Chaque artiste a sa propre vision de son projet. Il est vrai que ces artistes utilisent les mêmes outils : Capteurs, Arduino, Raspberry pi etc.
Cependant , ils trouvent une façon originale d'aboutir à un projet unique.
Scénario d'usage du produit ou du concept envisagé
Deux scénarios différents :
Scénario 1 :
---Mercredi 18 juillet 2018 de 18:30 à 22:00---
L'artiste : Fabien Zocco organise un vernissage d'exposition dans un lieu incontournable : la guinguette EP7, café/restaurant culturel. Très stressé par l'événement et par le fait de présenter son travail, son rythme cardiaque passe par des phases d'accélération et de décélération. Les données relevées par son bracelet connecté son envoyées en temps réel à notre application que nous avons conçue pour fonctionner avec deux araignées. Elles bougent sur le socle pendant tout le vernissage. Ainsi, les visiteurs peuvent visualiser à travers le comportement des araignées l'état émotionnel/psychologique de l'artiste.
Scénario 2 :
---Samedi 8 septembre 2018 de 18:30 à 22:00---
Fabien Zocco n'est pas sur les lieux de son exposition mais l'exposition a quand même lieu à EP7 dans le 13ème arrondissement de Paris, il y a probablement du public qui regarde attentivement le mouvement des araignées. Cette fois-ci les données sont envoyées avec un léger temps de latence. L'artiste passe par des périodes ou le réseau est très bon et par des périodes ou le réseau est difficile (métro). En cas de réseau difficile, les araignées liront les données d'un fichier "journée type" pour qu'elles continuent à divertir et évoluer à l'exposition.
Questions difficiles
- Comment gérer l’autonomie du téléphone ? Et celle du bracelet ?
- Quelle est la fréquence d’envoi des messages de notre application ? Du bracelet ?
- Comment fonctionne le capteur de sudation ?
- Trouver, envisager une solution de secours au cas où les parties qui ne nous concernent pas n'aboutissent pas.
Réponse à la question difficile
Comment gérer l’autonomie du téléphone ? Et celle du bracelet ?
Certaines applications sont vraiment gourmandes au niveau énergétique. Etant donné que nous souhaitons recevoir très souvent des informations du bracelet (porté par l'artiste), cela fera que notre application risque d'être énergivore. Afin d'éviter d'avoir une application trop coûteuse en énergie, nous allons permettre l'utilisation de l'application en tâche de fond. Cela nous permettra de réduire un peu la consommation énergétique de ce dernier. Nous pouvons également faire varier la fréquence de réception de données. Par exemple, on pourrait instaurer un mode "Economie d'énergie" qui permettrait d'envoyer moins de données mais sans impacter le projet. Concernant le bracelet, voici les informations concernant son autonomie en fonction de son mode d'utilisation.
- Mode partage en temps réel : 24h
- Mode d'enregistrement des données: 48h
- Temps de recharge: < 2 h
En accord avec Monsieur Zocco, nous n'avons donc pas besoin de gérer le problème d'autonomie pour la montre puisqu'il considère que son autonomie est largement suffisante.
Quelle est la fréquence d’envoi des messages de notre application ? Du bracelet ?
Nous souhaitons récupérer les données de la montre toutes les 3 à 4 minutes. Dans le cas expliqué plus haut, si le téléphone n'a plus de batterie il sera alors en mode "Economie d’énergie" et dans ce cas là les données seront reçues toutes les 30 minutes. Le bracelet est capable de faire du streaming, c'est-a-dire de l'envoi temps réel de ses données via Bluetooth ou de simplement stocker les données sur sa mémoire interne. Techniquement, il est équipé du Bluetooth Smart, le Bluetooth à basse consommation d'énergie, qui permet d'envoyer jusqu'à un Mégabit de données par secondes.
Comment fonctionne le capteur de sudation ?
Un capteur de sudation intégré dans une montre permet de suivre en temps réel, la micro transpiration des mains. En pratique c'est un patch qui est monté coté peau et qui relève le niveau de sodium et de chlorure présent dans la sueur. Ainsi, en fonction de la densité de sodium et de chlorure présents dans la sueur il est possible de déterminer avec plus ou moins de précisions, un niveau de stress. Cette information, ajoutée au rythme cardiaque, permettra de connaître l'humeur de l'artiste.
Trouver, envisager une solution de secours au cas où les parties qui ne nous concernent pas n'aboutissent pas
Pour ce qui est de la solution de secours nous dépendons de deux appareils sur ce projet : le bracelet et l'araignée.En effet, ces deux phases peuvent nous poser problème si l'artiste ne nous fournit pas le bracelet où si il y a un problème dans l’interprétation des données ou dans la programmation des données (ou si l'araignée ne nous ai pas fournie encore une fois).
Pour remplacer le bracelet, nous avons trouvé un capteur de sudation compatible arduino. Nous le connecterons à un arduino et nous ajouterons le bluetooth sur ce dernier.
Pour remplacer l'araignée, nous pourrons réutiliser des robots déjà existants à Polytech et faire en sorte que grâce à une Raspberry ils aillent lire nos données et que leurs mouvements changent en fonction.
Préparation du projet
Cahier des charges
L'artiste porte (en permanence) à son poignet un bracelet connecté qui relève son rythme cardiaque ainsi que son niveau de sueur (capteur de sudation). Les données relevées à son poignet sont envoyés par bluetooth au téléphone de l'artiste. Par l'intermédiaire d'une application android, ces données sont envoyées sur un serveur web pour être récupérées par les robots équipés d'un dispositif le permettant (Raspberry). Les araignées sont programmées pour réagir, bouger par rapport aux données qu'elles reçoivent. En fonction de si l'artiste est stressé, énervé, excité, les araignées agiront en conséquence de manière à imiter l'artiste.
Choix techniques : matériel et logiciel
Fournisseur | Quantité | Prix à l'unité (€) | Prix total (€) | URL | |
---|---|---|---|---|---|
Modules Bluetooth (802.15.1) | Mouser | 1 | 0€ | 0€ | https://www.mouser.fr/ProductDetail/Seeed-Studio/317030027?qs=wU1J8Md1npz%2f8UksA%252bh%252byw== |
Capteur de conductivité des doigts | GoTronic | 1 | 10€40 | 10€40 | https://www.gotronic.fr/art-module-de-conductivite-de-la-peau-gsr-grove-101020052-21341.htm |
Capteur de pouls | GoTronic | 1 | 22€60 | 22€60 | https://www.gotronic.fr/art-capteur-de-pouls-grove-103020024-23848.htm |
Téléphone Android | Polytech | 1 | 0€ | 0€ | |
Arduino Uno | Polytech | 1 | 0€ | 0€ | |
Total | 33€00 |
en vert : déjà donné
en gris : pas nécessaire
Liste des tâches à effectuer
Prélude : (Septembre-Décembre)
- Prise en main du sujet
- Lister le matériel nécessaire
- Discussion concernant les attentes de l'artiste
Janvier
- Apprendre le langage Java à travers différentes mises en application notamment en Tp du langage orienté objets.
- Alimenter notre Wiki
- Réfléchir à la récupération des données (API, Bluetooth ...)
Février
- Apprendre à utiliser et à maîtriser l'environnement d'Android Studio. Pour cela, regarder des cours vidéos et textuels sur internet.
- Réaliser une première version d'une application avec des fonctionnalités basiques sur Android Studio. L'application permettra de passer d'une activité à l'autre (d'une page à l'autre) et ne fera rien d'extraordinaire pour le moment.
- Alimenter notre Wiki
Mars
- Utiliser notre première version de l'application pour pouvoir l'adapter à notre sujet c'est-à-dire essayer d'y inclure la réception des données du bracelet en arrière plan par exemple.
- Gérer la réception et l'envoi des données. Pour cela nous nous inspirons de l'exemple fourni par Monsieur Zocco qui vient du Git de Empatica et qui donne un exemple d'affichage temps réel des données collectées par le bracelet.
- Apprendre à écrire des données dans un fichier en Java pour pouvoir par la suite l'envoyer.
- Assister Monsieur Zocco pour coder les mouvements des araignées (BONUS)
- Alimenter notre Wiki
Avril
- Suite du codage notre Application. Ajouter la fonctionnalité d'envoi des données stockées dans un fichier par requête HTTP.
- Faire en sorte que l'application s'utilise sans problèmes en tâche de fond (consommation énergétique faible).
- Diminuer le plus possible la consommation énergétique de l'application de manière à pouvoir l'utiliser toute la journée.
- Test des mouvements des araignées
- Alimenter notre Wiki
Mai
- Alimenter notre Wiki
- Soutenance le 6
Réalisation du Projet
Feuille d'heures
Tâche | Prélude | Heures S1 | Heures S2 | Heures S3 | Heures S4 | Heures S5 | Heures S6 | Heures S7 | Heures S8 | Heures S9 | Heures S10 | Heures S11 | Heures S12 | Heures S13 | Total |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Analyse du projet | 3 | 1 | 4 | ||||||||||||
Design de l'Application | 2 | 3 | 1 | 2 | 8 | ||||||||||
Maîtrise d'Android Studio | 3 | 5 | 4 | 12 | |||||||||||
Implémentation de l'application | 1 | 2 | 2 | 1 | 2 | 3 | 2 | 1 | 14 | ||||||
Gestion et récupération des données | 2 | 2 | 2 | 6 | |||||||||||
Ecriture dans un fichier | 1 | 1 | 1 | 3 | |||||||||||
Envoi des données vers un serveur | 1 | 2 | 3 | 6 | |||||||||||
Test de l'application en utilisation réelle | 2 | 2 | 3 | 1 | 8 | ||||||||||
Rencontre avec M. Zocco | 1 | 2 | 2 | 1 | 6 | ||||||||||
Remplissage du wiki | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 1 | 1 | 1 | 1 | 1 | 16 |
Rédaction du rapport | 2 | 2 | 6 | 10 | |||||||||||
Total | 6 | 5 | 4 | 5 | 8 | 9 | 6 | 6 | 10 | 8 | 7 | 7 | 4 | 8 | 93 |
Prologue
Semaine 1
Mercredi 16 janvier 2019 :
Nous entamons la première séance dédiée au Projet du Semestre 8. Nous commençons par réfléchir à notre cahier des charges et à l'organisation de notre travail. L'objectif majeur du projet est de réussir à réaliser une application Android qui répond à tous nos besoins et qui met en lien les données relevées par le bracelet avec un serveur Web. Les araignées n'auront plus ensuite qu'à aller lire sur le serveur les données disponibles. Avant de commencer à coder, il est important que nous fassions sur papier un premier modèle, un prototype de notre application.
Réflexion sur un premier prototype d'application
Voici comment nous visualisons l'application que nous allons développer.
- Lors de l'ouverture de l'application nous pourrons visualiser le nom de notre Projet : Spider&I, suivi d'un logo que nous allons créer. Ce dernier est composé d'une araignée encerclée par un bracelet connecté, ce qui permet de représenter le contrôle qu'a le bracelet sur le mouvement des araignées.
- Le logo SOS permettra en cas de besoin pour orienter notre utilisateur, d'expliquer le fonctionnement de l'application, les différents modes d'utilisation et comment se connecter correctement au bracelet E4 Empatica.
- Le logo en bas à droite, permettra d'avoir des informations sur l'état de connexion. Il sera présent et plus utile par la suite.
- Enfin le bouton le plus important sera l'onglet Connexion qui permettra de passer à la page suivante et de se relier au bracelet E4 Empatica par liaison Bluetooth.
- Le bouton Sos sera toujours présent pour diriger l'utilisateur en cas de doute.
- le rouage en haut à gauche représente (comme souvent) le bouton de réglage et permettra à l'utilisateur de jouer sur la vitesse de transmission des données. Il pourra donc ajuster selon ses besoins/envies les paramètres des différents modes.
- L'utilisateur aura le choix entre deux modes : Temps réel qui envoie des données à une fréquence élevée permettant de faire changer le comportement des araignées en fonction de l'état actuel psychologique de l'artiste et le mode économie d'énergie qui lui envoie les données à une fréquence moins importante pour minimiser les dépenses énergétiques de l'application.
- Logo/GIF en bas au centre qui changera en temps réel en fonction de l'état de la connexion. On a imaginé un logo qui représente l'utilisateur au milieu des ses deux appareils : le bracelet et l'araignée. Quand un mode est sélectionné et que l'envoi des données s'effectue, on pourra voir un flux se déplacer entre le bracelet et l'utilisateur puis entre l'utilisateur et l'araignée. On peut imaginer que selon le mode choisi, ce flux sera plus ou moins rapide.
- Logo POWER qui permettra d'arrêter la connexion avec le bracelet si aucun mode n'est sélectionné ou bien d'arrêter l'envoi des données dans le mode sélectionné pour permettre de modifier le mode ou juste d'arrêter le transfert de données.
- On retrouve le même logo en bas à droite qui schématisera l'état de connexion du bracelet avec le téléphone, ainsi si la connexion se dégrade, il se mettra à clignoter ou changer de couleur.
Semaine 2
Pour pouvoir commencer notre projet, Mr Redon nous a donné de quoi simuler un périphérique Bluetooth. Il nous a donné :
- Module Bluetooth (802.15.1)
- Téléphone Android
- Arduino Uno.
Cela nous permettra de remplacer le bracelet temporairement.
Nous avons commencé par étudier la documentation du module Bluetooth.
D'autre part, nous avons modélisé notre l'application pensée la semaine dernière sur le site: appinventor.mit.edu
Cela nous a permis de nous introduire au langage orienté objet : JAVA. Ce logiciel permet de coder en bloc. Voici le rendu :
Semaine 3
Cette semaine, nous décidons de nous attaquer à la connexion Bluetooth au périphérique.
Pour cela nous devons :
- Afficher la liste des différents périphériques détectés à proximité.
- Donner la possibilité de cliquer et ainsi sélectionné le périphérique sur lequel on veut se connecter.
- Après sélection d'un périphérique bluetooth à portée, l'application essayera de se connecter avec le périphérique.
L'idée étant qu'une fois connecté, on puisse récupérer des données sur le périphérique.
Nous utilisons MIT Inventor 2 pour coder l'application pour le moment donc nous devons par blocks les fonctionnalités comme suit.
Semaine 4
M. Zocco nous a transmis le dépôt Git pour la manipulation du bracelet. Nous constatons que les fonctions, les classes et le code à utiliser pour gérer le bracelet est codé grâce à Android Studio.
Les fichiers sont directement accessibles sur le dépôt du Bracelet : Dépôt Git Empatica 4
Nous abandonnons alors le MIT inventor pour apprendre à utiliser Android Studio. En effet, MIT inventor ne nous permettra pas de configurer et récupérer le bracelet comme nous le souhaitons.
Nous avons passé la séance à se familiariser avec l'environnement d'Android Studio. Nous avons regardé des tutoriels sur OpenClassrooms et Youtube. L'environnement d'Android Studio est difficile à prendre en main parce qu'elle contient énormément de fonctionnalités, de méthodes qu'il faut connaître pour pouvoir les utiliser. Pourtant, tout est là mais il faut apprendre les méthodes existantes à appeler pour faire telle ou telle action.
De plus Android Studio mêle des fichiers .java et des fichiers .xml. Les fichiers xml servent principalement à l'affichage graphique et à la déclaration des variables (graphiques) tandis que les fichiers java contiennent le code exécuté par l'application elle même.
Par la suite, pour gagner du temps nous avons acheté un cours vidéo complet sur la plateforme Udemy, connue pour son contenu très riche et ses offres de cours dans tous les domaines.
Nous avons passé en temps cumulé de visionnage près de 6 heures et demi à suivre différents tutoriels de prise en main d'Android Studio et nous commençons à être à l'aise. Bien sûr le temps de visionnage n'est pas équivalent au temps passé puisqu'il est intéressant de faire en même temps ce que montre le professeur et donc de faire des pauses régulières dans les vidéos.
Voici le cours dont nous nous sommes servi ainsi que le lien : Complete Android N Developer Course
Semaine 5
Séance de projet (Mercredi 13 février)
Lors de cette séance nous avons continué le visionnage du cours concernant Android Studio. Nous nous sommes intéressés à deux chapitres qui seront très utiles dans le cadre de notre projet :
- Working with Bluetooth
- Submitting your App to Google Play
Dans le premier cours, nous utiliserons deux bibliothèques:
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice;
Voici plusieurs méthodes qui vont nous être utiles:
BA.isEnabled() vérifie que le Bluetooth de notre périphérique est bien activé grâce à la méthode BA.disable() permet de désactiver le Bluetooth Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) nous permettra d'afficher les périphériques détectés
Afin d'afficher les périphériques connectés :
Set<BluetoothDevice> pairedDevices = BA.getBondedDevices(); ListView pairedDevicesListView = (ListView) findViewById(R.id.pairedDevicesListView); ArrayList pairedDevicesArrayList = new ArrayList(); for (BluetoothDevice bluetoothDevice : pairedDevices) { pairedDevicesArrayList.add(bluetoothDevice.getName()); }
Il faut créer une liste de pairedDevices, en utilisant la méthode getBondedDevices() qui permet de les sélectionner. Nous créons ensuite une ListView qui nous permettra de gérer l'affichage de nos informations. Nous parcourons les pairedDevices, et nous les ajoutons à la liste que nous souhaitons afficher. Par cette méthode nous pouvons utiliser la fonctionnalité bluetooth du téléphone et afficher les appareils à portée.
Pour la deuxième vidéo, elle montre étape par étape comment mettre une application créée avec Android Studio sur le Google Play Store. Nous suivons les étapes et y arrivons aussi. Cependant nous nous rendons compte que cette étape ne sera pas forcément indispensable pour nous puisque nous pourrons mettre l'application sur le téléphone directement par USB vu que le téléphone est en mode Développeur. Nous mettons de côté cette manœuvre.
Jeudi 14 février : Rendez-vous de prévu avec M. Fabien Zocco et M. Laurent Sparrow, chercheur chez SCAlab, jeudi 14 février de 10h à 12h.
Résumé des informations importantes à retenir :
- Nous devons nous concentrer sur l'énergie consommée par l'application. Par des tests, il faudra assurer que l'application fonctionne une journée entière !
- En nous aidant du Git Empatica en exemple, nous devons reproduire la réception des données mais la rendre invisible (enlever la partie affichage) pour consommer le moins d'énergie possible.
- Une fois les données récupérées, il faudra les écrire dans un fichier .JSON, .XML ou .TXT et les envoyer via une requête HTTP sur le serveur cible (FTP) fourni par M. Zocco (sous forme de quatre balises). Nous commencerons par essayer d'envoyer un fichier avec simplement écrit Hello World pour vérifier le fonctionnement.
Pour s'intéresser à la partie énergétique de l'application, il va falloir trouver un équilibre entre le taux d'échantillonnage des données (envoyées sur le serveur et reçues par la montre) et l'interface de l'application.
- Une éventuelle perte de connexion sera gérée par le programme des araignées directement.
M. Fabien Zocco et M. Laurent Sparrow, nous ont prêté un bracelet Empatica afin de pourvoir commencer un travail plus concret. Ce bracelet est normalement utilisé pour des recherches dans le domaine de la santé (par exemple : prédire l'arrivée d'une crise d'épilepsie).
Empatica propose une application sur ordinateur pour gérer le bracelet, mais pour des raisons de portabilité, nous allons créer notre application qui récupérera les données en utilisant la bibliothèque de la société.
Semaine 6
Le premier objectif lors de cette séance est d'apprendre à éditer un fichier .txt dans un programme JAVA. Une 1ère possibilité est d'utiliser la classe PrintWriter()
PrintWriter writer = new PrintWriter(mon-fichier.txt, UTF-8); writer.println(La première ligne); writer.println(La deuxième ligne); writer.close();
Une 2nde est d'utiliser la classe Files. Pour les fichiers texte, on peut alors stocker chaque ligne dans un tableau et écrire toutes les lignes en une seule commande.
List<String> lignes = Arrays.asList(ACCx,-11/-2,ACCy,57/63,ACCz,-11/-5); Path fichier = Paths.get(mon-fichier.txt);
//La commande suivante écrit les lignes en écrasant le texte déjà présent dans le fichier Files.write(fichier, lignes, Charset.forName(UTF-8));
//Pour écrire à la suite du fichier, il faut utiliser la commande suivante Files.write(fichier, ligne, Charset.forName(UTF-8), StandardOpenOption.APPEND);
Nous avons réussi à faire tourner un petit programme de création de fichier sur ordinateur mais avons rencontré des problèmes pour le faire sur l'application téléphone directement. L'application crash et s'éteint au moment de l’enregistrement du fichier. Nous pensons que c'est parce que nous avons mal géré (pour le moment) l'emplacement d'enregistrement du fichier ainsi que les droits nécessaires pour pouvoir le faire. C'est une question de temps avant que notre application puisse enregistrer son propre fichier.
Le 2ème objectif lors de cette séance est d'apprendre à utiliser Filezilla afin de pouvoir gérer l'envoi de notre fichier sur le serveur.
Nous avons trouvé un site qui nous va bien nous aider: dfarnier.fr/filezilla-manipuler-les-fichiers
M. Zocco nous a envoyé les informations nécessaires (hôte, login et mot de passe) afin d'essayer d'envoyer un fichier test helloword.txt sur son serveur. Nous allons suivre le mode d'emploi sur le site que nous avons trouvé.
C'est sur cette interface que l'on peut modifier des fichiers et les renvoyer sur le site de M. Zocco. Voici son site: http://www.fabienzocco.net/
Nous avons réussi à modifier le code du fichier test.txt qui est sur le serveur de M.Zocco. Nous allons maintenant apprendre à le faire en Java. Pour ce faire nous allons utiliser FTPClient Class de la librairie Apache Commons Net.
FTPClient client = new FTPClient(); FileInputStream fis = null; try { client.connect("ftp.domain.com"); client.login("admin", "secret"); Ici il faut renseigner les informations de M. Zocco
String filename = "Touch.dat"; fis = new FileInputStream(filename); Permet de créer un flux d'entrée
// Store file to server client.storeFile(filename, fis); Permet d'envoyer le fichier sur le serveur client.logout(); } catch (IOException e) { Vérifier qu'il n'y a pas d'erreur d'input/output e.printStackTrace(); } finally { try { if (fis != null) { fis.close();} client.disconnect(); } catch (IOException e) {e.printStackTrace();} }
Semaine 7
Cette semaine, nous travaillons séparément pour être plus efficace. Deux parties à gérer :
- La réception des données en arrière-plan. (Nestor)
- l'écriture dans un fichier pour l'envoi vers un serveur. (Lina)
1. Partie réception des données
L'objectif pour cette partie est donc de réussir à récupérer les données envoyées par le bracelet pour pouvoir les écrire dans un fichier par la suite. Nous devons donc nous inspirer de l'exemple disponible sur le git. Pour le faire fonctionner, nous suivons les instructions sur le git et nous rentrons notre API Key fournie par M. Sparrow lors de la réunion. Nous générons le fichier apk (fichier permettant l'installation de l'application) et nous l'installons sur le smartphone. Voici à quoi cela ressemble (voir Photo 1) :
On voit que toutes les informations relevées par le bracelet apparaissent à l'écran. On peut y voir la température, les coordonnées du bracelet dans l'espace grâce à l'accéléromètre etc. Cependant, cette affichage temps-réel doit être gourmand en énergie.
Pendant la réunion, nous avons décidé de minimiser les coûts énergétiques et donc de ne pas mettre d'affichage des valeurs relevées. Nous cherchons alors à avoir l'application la plus pure possible. Pour faire un exemple et vérifier que nous arrivons bien à récupérer les données nous décidons d'afficher seulement la batterie de la montrer en temps-réel. Le reste s'actualise en arrière-plan. (voir Photo 2)
Pour cela, il a fallu étudier le code du git de près pour le comprendre et pouvoir l'intégrer dans l'application. Cette étape a occupé une grande partie de la séance. Une fois le code assimilé et intégré, nous avons essayé de l'adapter pour n'afficher que la batterie. Le problème du code de l'exemple est qu'il intègre des bibliothèques empatica que nous ne connaissons pas et le bracelet donne l'impression qu'il contient déjà un programme ainsi que certains processus qui s’exécutent automatiquement. Ces derniers n’apparaissent pas dans le code donc il est difficile d'en modifier leur comportement. Par exemple, dans le code n'apparaît pas la boucle qui vérifie si les capteurs ont changé de valeur. Pourtant cette boucle existe forcément.
J'explique tout cela parce qu’en voulant sauvegarder les données dans des variables plutôt que dans de l'affichage pour pouvoir les écrire dans un fichier, la batterie ne s'affiche plus. Alors pour comprendre ce qu'il se passe, j'ai affiché dans les messages logs (invisibles pour l'utilisateur), les changements de la variable EDA qui correspond à l'activité électrodermale. Cela veut dire qu'à chaque fois qu'il change la valeur d'EDA il va afficher la nouvelle valeur dans les messages logs et voici ce que j'observe :
Je remarque qu'environ toutes les 1,5 secondes, il y a du nouveau dans les logs mais ce qui est étrange c'est que au même instant cette fonction envoie 6 variables parfois différentes en même temps. Je rappelle qu'à ce moment là je lui demande juste d'afficher dans les logs les changements sur le capteur d'EDA de la méthode didReceiveGSR. C'est comme si, la montre stockait les valeurs du capteur et les envoyait toutes d'un coup à intervalle régulier de 1,5 seconde. On dirait que la sauvegarde des valeurs dans des variables bloque l'affichage et la mise à jour de la batterie. C'est très étonnant. Pour l'instant je n'arrive pas à comprendre pourquoi ce processus est bloquant.
2. Partie écriture et envoi des données
L'objectif pour cette partie est de réussir à adapter le code que nous avons écrit la semaine passée en JAVA et de le rendre fonctionnel pour une application Android. Ce n'est pas forcément évident et c'est pas parce qu'un code fonctionne en JAVA qu'il sera utilisable et/ou adaptable pour une application mobile dans l'environnement Android Studio.
Problèmes rencontrés
En effet, le code JAVA était fonctionnel la semaine dernière, nous avons réussi à envoyer le fichier "essai.txt" sur le serveur. Notre code commence d'abord par le créer, l'ouvre, écrit "Je crée le fichier essai.txt" et fini par l'envoi sur le serveur en FTP.
Jusqu'à présent nous utilisions un émulateur Android pour essayer les applications qu'on codait. Mais étant donné que nous voulons accéder à la mémoire du téléphone, il faut générer le fichier .apk et l'installer sur ce dernier.
Lors de la séance, nous avons eu du mal générer le .apk depuis Android Studio sur Mac. Malgré le fait que la tablette soit en mode développeur, Android Studio ne reconnaissait pas l'appareil. Nous avons alors perdu beaucoup de temps puisque pour tester l'application, nous devions à chaque fois copier le fichier .apk sur une carte SD puis l'installer sur la tablette. L'inconvénient de cette méthode est que nous ne pouvons pas avoir plus d'informations sur les erreurs. (notamment l'affichage des logs, un outil indispensable qui permet de déboguer).
Code pour créer un fichier sous Android
Nous avons alors codé à l'aveugle, lorsque notre code ne fonctionnait pas, nous ne savions pas d'où venait le problème.
Le problème majeur que nous rencontrions était que notre application ne créait pas le fichier test que nous souhaitions, mais sans les logs c'était compliqué de savoir d'où venait le problème. Nous avons alors cherché sur internet. Nous avons alors vu que notre problème était récurent et pour le résoudre, il fallait rajouter la ligne ci-dessous dans le code d'un fichier du projet : Manifest.xml :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />.
Cette ligne de code donne la permission à notre application de pouvoir écrire et créer un fichier sur l'appareil.
Voici la partie la plus importante du code qui permet de créer un fichier "fichier_info.txt" (ou de l'écraser et d'en créer un nouveau s'il existe déjà).
File textFile = new File(Environment.getExternalStorageDirectory(), "fichier_info.txt"); //création du fichier try { String text2="\n Salut "; FileOutputStream fos = new FileOutputStream(textFile); fos.write(text.getText().toString().getBytes()); // Récupérer caractères rentrés par l'utilisateur et les écrire fos.write(text2.getBytes()); // Écrire des caractères (Type String) fos.close(); Toast.makeText(this, "File Saved.", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); }
La photo 4 montre l'application que nous avons créé pour tester l'écriture de fichier. On écrit ce qu'on veut dans la boîte de dialogue et en cliquant sur le bouton SAVE FILE, le texte tapé est directement enregistré dans le fichier fichier_info.txt. La photo 5 l'illustre.
Semaine 8
L'objectif cette semaine est de réussir à mettre en lien les deux fonctionnalités travaillées la semaine passée : la réception des données en arrière plan et l'écriture dans un fichier. Pour l'instant, une seule des deux est fonctionnelle : l'écriture dans un fichier. Il faut régler le problème d'enregistrement dans des variables. Nous avons constaté la semaine dernière que pour certains capteurs on reçoit plusieurs valeurs d'un seul coup, il faut donc mettre en place un système de traitement efficace.
De plus, entre temps nous avons remarqué que certains capteurs ont des fréquences d'écoute plus élevées que les autres c'est-à-dire qu'ils envoient plus de valeurs (ou plus vite) que d'autres capteurs. On aura donc plus de valeurs mesurées pour les capteurs concernés.
Nous avons donc contacté notre tuteur Monsieur Zocco ainsi que Monsieur Sparrow pour se mettre d'accord sur l'organisation du fichier final. Voilà ce qui ressort de cet échange :
- le fichier final devra présenter dans l'ordre les valeurs de Température, EDA, Accéléromètre et IBI.
- il est primordial d'avoir les deux valeurs relevées par le capteur IBI pour rendre cette information exploitable. Jusqu'ici nous n'avions qu'une seule valeur.
- nous séparerons les valeurs par des /, ce sera notre séparateur ainsi que le caractère \n de retour à la ligne entre chaque capteur différent.
- le fichier comportera 30 valeurs par capteur, cela correspond environ à une valeur par seconde. Le fichier sera alors le résultat de 30 secondes de mesure.
Pour l'Inter Beat Intervalle (IBI), Laurent Sparrow nous a expliqué que ce capteur mesure le temps séparant 2 battements cardiaques, il n’y a pas de fréquence d’échantillonnage pour cet indicateur. Normalement, on doit avoir 2 colonnes : 1 pour le timestamp, et l’autre pour la valeur (en seconde) de l’IBI (temps séparant 2 battements). Pour l’interpréter, on compte le nombre d’intervalles supérieures à 50 ms par exemple. Une autre analyse consiste à analyser les bandes de fréquence concernant ces valeurs (est-ce que les variations d’IBI sont de basse, moyenne et haute fréquence), sans chercher une valeur supérieure à 50 ms pour suivre l’exemple précédant.
L'ensemble des relevés des deux données vont ensuite permettre de catégoriser l’état psychologique de Fabien Zocco, son activation etc. Ceci permettra de piloter le robot.
Le blocage de la batterie en semaine 7 n'était pas réel, c'était un bug de la montre qui n'envoyait pas la valeur de la batterie donc forcément rien n'était affiché.
Pour pouvoir écrire dans un fichier par la suite l'ensemble des valeurs d'un coup et pouvoir organiser le fichier comme souhaité, nous avons tout intérêt à stocker les valeurs reçues. Pour cela nous les stockeront dans un tableau. Chaque capteur aura son tableau de valeurs à remplir lui-même quand il en reçoit de nouvelles. Nous choisissons des tableaux statiques pour contrôler et limiter la mémoire utilisée. Par exemple :
private String [] temperatureLabel = new String[MAXVAL]; //Ce tableau contiendra les valeurs relevées de la température
Pour l'instant nous fixons MAXVAL à 10 pour effectuer quelques tests. Nous essayons donc de relever les 10 premières valeurs des capteurs de Température, d'IBI, d'EDA et d'accéléromètre. Une fois les valeurs stockées dans les tableaux respectifs et quand tout le monde a ses valeurs, nous écrivons dans un fichier les valeurs. Voici un premier essai avec seulement la température, l'ibi et l'eda : (voir Photo 1)
Le résultat est bon et proche de celui que l'on souhaite. Cependant, on remarque que les premières valeurs de la température sont erronées (très négatives) ! Nous rajoutons alors un petit bout de code pour pallier ce problème et ne pas prendre en compte les valeurs négatives. Ce n'est pas visible ici car le problème avait déjà été traité mais la première d'EDA est aussi erronée (égale à 0). Nous ajoutons aussi un autre test pour vérifier que la valeur nouvelle n'est pas identique à la précédente, de même on ne la prend pas en compte si c'est le cas. Ce dernier test est seulement pour la température et l'EDA qui envoient beaucoup plus de données que les autres capteurs. Voici à quoi ressemble le code de ces fonctions :
public void didReceiveTemperature(float temp, double timestamp) { if(tempCpt < MAXVAL && !fileReady && temp>0) { if(tempCpt == 0){ temperatureLabel[tempCpt] = String.valueOf(temp); tempCpt++; } else{ if(temperatureLabel[tempCpt-1].compareTo(String.valueOf(temp))!=0) { temperatureLabel[tempCpt]=String.valueOf(temp); tempCpt++; } } Log.i("DEBUG", "TEMP : " + String.valueOf(temp)); } if(tempCpt==MAXVAL) tempCpt=0; }
Pour le moment, le code n'est pas optimal, on s'arrête quand on a reçu 10 valeurs d'IBI (capteur le plus long à réagir). Remarque : tant qu'on n'a pas les valeurs d'IBI, la température continue de remplir son tableau et le remet à jour, on aura donc à la fin les 10 dernières valeurs de la température. L'avantage indéniable de procéder ainsi est qu'on est sûr d'avoir bien 10 valeurs pour chaque capteur à la fin tandis que si on relève les valeurs des capteurs pendant 30 secondes, peut-être qu'on aura moins de 30 valeurs pour l'IBI et plus de 30 pour la température (et l'EDA). Nous ferons en sorte par la suite de mettre en place un timer qui écrit les valeurs qu'il a reçu pendant une période précise (30 secondes ou plus) et puis nous nous mettrons d'accord avec Fabien Zocco pour qu'à l'arrivée, les araignées n'interprètent que les valeurs pertinentes.
Une fois les tests effectués et vérifiés, nous ajoutons les valeurs d'accéléromètre et voici l'état du fichier : (Voir photo 2)
Nous sommes assez satisfaits de ce résultat et allons maintenant nous pencher sur l'envoi du fichier vers le serveur FTP.
Envoi des fichiers sur le serveur
En partant, du code que nous avons rédigé en Java en semaine 7, nous essayons de l'intégrer et de l'adapter. Nous avons été confrontés à plusieurs problèmes.
Dans un premier temps, afin qu’Android Studio reconnaisse les méthodes et les fonctions de la Classe FTP, il faut télécharger la librairie: commons-net-3.6-src.zip disponible ici : [1]. Par la suite, il faut la dézipper et placer le .jar dans le dossier de notre projet : app.libs. Pour qu'Android studio prenne en compte cette nouvelle bibliothèque, il faut d'abord lui indiquer le chemin dans le fichier build.graddle:app grâce à ce code.
dependencies { implementation 'com.android.support:support-v4:18.0.0' implementation files('libs/commons-net-3.3.jar') } repositories { flatDir { dirs 'app.libs' } }
Puis dans un second temps, il faut inclure la bibliothèque dans les classes (essentiellement le MainActivity.class) qui l'utilise avec la ligne suivante:
import org.apache.commons.net.ftp.*;
En plus des permissions déjà mentionnées plus haut (Semaine 7), nous devons ajouter la permission suivante:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Elle permet d'avoir des informations sur l'état du réseau, contrairement à <uses-permission android:name="android.permission.INTERNET" /> qui permet de se connecter à internet.
À présent, nous avons tout ce qu'il nous faut pour envoyer notre fichier sur le serveur. Nous nous sommes ensuite basés sur notre cours de PSR pour réaliser la suite. En effet, pour envoyer un fichier sur un serveur, il faut utiliser la programmation multi threadée. Voici la fonction pour se connecter au serveur.
private void connectFTP() { final String serveur ="ftp.myftpserver.com"; final String login = "mylogin"; final String mdp = "mypassword"; new Thread(new Runnable() { public void run() { boolean status = ftpclient.ftpConnect(serveur, login, mdp, 21); if (status) { Log.d(TAG, "Connection Réussie"); } else { Log.d(TAG, "Connection Ratée"); } } }).start(); }
Les threads sont un peu différents en JAVA qu'en C comme le montre le code ci-dessus, cependant l'utilisation est semblable. Pour comprendre le fonctionnement des Threads en Java, nous avons visité ce site : [2].
Enfin la fonction pour envoyer le fichier :
public boolean ftpUpload(String chemin, String NomFichier, String NomDossier, Context context) { boolean status = false; try { FileInputStream fileStream = new FileInputStream(chemin); status = mFTPClient.storeFile(NomFichier, fileStream); fileStream.close(); return status; } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "upload failed: " + e); } return status; }
Semaine 9
Nous avons profité de la séance du lundi, pour mettre en commun nos deux parties. Nous pouvons à présent visualiser le fichier envoyé sur le serveur à cette adresse : [ fichier_info.txt [3]]. Si l'application est en route et que la montre est connectée, si nous actualisons la page après quelques temps, nous remarquons bien que les données affichées changent. Le fichier envoyé est bien modifié.
Comme dit en semaine 8, notre système d'enregistrement du fichier est encore un peu "précaire" et ne reflète pas la réalité des faits. Le fait d'attendre de recevoir un nombre de valeurs du capteur d'IBI rend l'envoi du fichier irrégulier et complètement aléatoire car ce capteur n'est pas fiable. Nous décidons alors de mettre en place un système de timer pour envoyer les valeurs reçues toutes les 30 secondes. Pour cela deux possibilités en java :
- les Handlers
- les CountDownTimer
Les handlers permettent d'effectuer une action toutes les secondes par exemple en utilisant des threads. Voici un exemple :
Handler handler = new Handler(); Runnable run = new Runnable() { @Override public void run() { Log.i("DEBUG", "A second must have passed"); // Cet exemple envoie un message dans les logs toutes les secondes handler.postDelayed(this, 1000); } }; handler.post(run);*/
Les CountDownTimer ont un fonctionnement différent. Comme leur nom l'indique, c'est un décompte. Par exemple :
new CountDownTimer(10000, 1000){ //On donne en paramètres le temps total et le coup d'horloge souhaité en milisecondes @Override public void onTick(long millisUntilFinished) { //onTick() est executé à chaque coup d'horloge (ici, chaque seconde) Log.i("Second left", String.valueOf(millisUntilFinished/1000)); } @Override public void onFinish() { //onFinish() est executé à la fin du timer (ici; au bout de 10 secondes) Log.i("Finish", "It is done !"); } }.start();
Après analyse de nos deux possibilités, nous optons pour l'utilisation d'un Handler, car nous souhaitons que l'action de comptage ne s'arrête pas. Il nous suffira alors d'incrémenter un compteur à chaque seconde et de le réinitialiser quand il arrive à 30 si on veut envoyer toutes les 30 secondes.
Nous implémentons cette solution et testons avec le site internet. En actualisant toutes les 30 secondes, nous observons bien que les valeurs se mettent à jour. Cette fois-ci, le fichier n'est pas forcément plein puisqu'il n'a pas forcément reçu 30 valeurs pour chaque capteur. C'est ce que nous attendions et ceci reflète bien la réalité de ce que nous recevons.
Nous avons donc réussi à mettre au point une première application fonctionnelle. Nous entrons alors dans la partie la plus importante de notre projet, le point sensible : l'ergonomie. En effet, plusieurs questions difficiles portaient sur la gestion de l'autonomie du téléphone ainsi que de la montre.
Nous pouvons désormais répondre à l'une d'entre elles, la fréquence d'envoi de la montre. En analysant de près le code et le comportement de la montre nous pouvons affirmer que le modèle E4 d'empatica envoie en continu des données. Nous pouvons seulement jouer sur la fréquence d'envoi du fichier de données mais la fréquence d'envoi de la montre reste un paramètre fixe. Il y a une sorte de boucle cachée dans le programme interne de la montre et qui fait qu'elle envoie des données dès qu'elle les relève avec ses capteurs. En réponse à la question sur l'autonomie de la montre, nous ne pourrons donc pas beaucoup jouer dessus avec notre application.
Pour ce qui est de celle du téléphone nous allons effectuer plusieurs journées de test en faisant varier les paramètres que nous pouvons modifier comme la fréquence d'envoi etc.
Mardi 19 mars : 1ère journée de test
Nous commençons la journée avec 65 % pour le téléphone et 90 % de batterie pour la montre. Nous envoyons un fichier toutes les 30 secondes. Nous avons ajouté un compteur à la fin de notre fichier. Ce compteur s'incrémente que lorsque le fichier s'est envoyé. De cette façon, nous pourrons savoir le nombre exact d'envoi en fonction du niveau de batterie perdu. Il nous permet aussi de vérifier de manière rapide et efficace si l'application continue de fonctionner correctement.
Nous avons laissé tourner le programme pendant presque 6 heures 30 sans arrêt. Nous avons envoyé 778 fois notre fichier, mis à jour à chaque fois avec de nouvelles valeurs. Pour cette première journée, nous n'avons pas utilisé le téléphone, l'application tournait en tâche de fond. En faisant une moyenne de nos valeurs, on constate que le téléphone perd environ 5 % de batterie par heure d'utilisation. La montre quant à elle, plus énergivore, en perd 10 % par heure. Avec de telles valeurs, nous pensons pouvoir faire fonctionner le programme pendant environ 9 heures. C'est un très bon résultat pour un premier essai. Cependant, on rappelle que nous n'avons pas utilisé le téléphone donc c'est sûr qu'en utilisation normale, le résultat serait bien moins bon.
Au moment d’arrêter l'application, nous avons fait une simulation du cas où la connexion serait subitement perdue, l'application s'est tout de suite arrêtée. Nous allons donc modifier le code pour la prochaine journée de test. Nous pensons que c'est parce que le téléphone a essayé d'envoyer le fichier sans vérifier avant qu'il était bien connecté à internet.
Nous refaisons alors le même test, cette fois-ci le téléphone est branché au PC pour observer les logs et comprendre l'erreur. Ce que nous pensions s'est bien avéré être la vérité. Le téléphone essayait (à la fin des 30 secondes) d'envoyer le fichier sans vérifier sa connexion à internet au préalable. Cette action provoquait alors une Exception et l'application était automatiquement arrêtée puis fermée. Nous avons corrigé ce problème en ajoutant des tests de connexion avant d'envoyer le fichier, ainsi si le téléphone perd la connexion au réseau subitement, il ne pourra pas envoyer le fichier. Il ressayera de le faire chaque seconde jusqu'à ce qu'il retrouve le réseau. Il reprendra alors le cours normal de son activité.
Nous avons choisi de noter les valeurs du niveau des batteries et de la fréquence d'envoi dans un fichier Excel afin de mieux voir l'évolution en fonction des jours (voir Graphique ci dessous).
Mercredi20 mars : 2ème journée de test
Nous avons laissé tourner le programme pendant 6 heures. Cette fois-ci, nous avons modifié la fréquence d'envoi. Nous envoyons le fichier toutes les minutes. La fréquence d'envoi est donc multipliée par deux. L'objectif est de voir si la batterie du téléphone consomme moins.
Après test, nous avons remarqué que pour une fréquence d'envoi d'une minute, la batterie du téléphone diminue moins (1%/heure de moins que pour une fréquence d'envoi égale à 30s). La montre ne subit pas de modification, puisqu'elle envoi le même nombre de données.
Séance projet
Pour l'instant, nous avons une application Android fonctionnelle sans design. C'est une application basique avec un fond noir et un bouton. Nous avons profité de cette séance pour faire une deuxième version de l'application. Nous n'allons pas l'encombrer, parce qu'il ne faudrait pas que ça augmente la consommation de la batterie du téléphone. Nous choisissons un design simple qui reprend notre logo de départ.
Nous avons eu la possibilité de discuter avec nos professeurs Xavier Redon et Thomas Vantroys, qui nous ont indiqué que les mesures que nous faisions ne sont pas précises. Elles manquent de professionnalisme. Nous devons mesurer ce paramètre avec plus de précisions. Ils nous ont conseillé d'utiliser un logiciel "Energy Profiler" qui permet de bien identifier les variations. Peut-être même, de voir quelles sont les fonctions de notre application qui consomment le plus et ainsi de pouvoir changer, améliorer, optimiser les parties du code qui consomment le plus de batterie pour l'application. Nous ne trouvons pas encore l'outil adéquat pour mesurer la batterie pour le moment.
Semaine 10
Lors de la séance, nous nous sommes renseignés sur un energy profiler. En effet, ce sera plus professionnel de passer par une application qui s'occupera d'étudier la consommation énergétique de notre application. Nous n'en avons trouvé qu'un seul que propose Android Studio. Son nom : Profiler. Il faut avoir une version assez récente du système d'exploitation d'Android pour utiliser cet outil, il faut avoir un niveau d'API de 21 au minimum, ce qui est le cas pour nous.
Cependant, pour avoir des informations sur la section batterie, il faut avoir la version 28 (nous avons la 21). Le téléphone fourni pour ce projet est bloqué à la version 21. Nous ne pouvons donc pas vraiment étudier la consommation de la batterie autrement qu'avant.
Nous avons mis en place un nouveau visuel, simplifié et qui affiche l'état de connexion avec internet et le bracelet. Nous avons rencontré des problèmes liés à la programmation multi-threadée. En effet, nous essayions de mettre à jour ces "Widgets" de texte au moment ou l'état de connexion du bracelet ou du réseau changeait. Nous utilisions alors simplement la méthode setText("Le texte que nous voulions"), disponible pour les "Widgets" de type texte. Cette utilisation nous créait des soucis.
Pour régler ce soucis il fallait s'assurer que l'execution de cette méthode s'effectuait bien dans le thread principal, celui qui a crée l'application et pour cela il fallait ajouter le bout de code suivant que nous avons ajouté dans une nouvelle méthode pour simplifier son appel :
private void updateLabel(final TextView label, final String text) { runOnUiThread(new Runnable() { @Override public void run() { label.setText(text); } }); }
En fin de séance, nous avons rencontré Mr Zocco. Pour le moment, il est satisfait du rendu de l'application et de son ergonomie. Il nous a proposé de mettre en place une liste chaînée pour le capteur IBI. Cela permettrait de récupérer toutes les valeurs. En effet, pour cette variable il est important d'avoir toutes les valeurs qui sont envoyées de façon asynchrone par la montre. C'est essentiel pour l'analyse des données. Ainsi, une utilisation d'une liste chaînée permet d'avoir un stockage dynamique et donc de taille variable contrairement au tableau initial.
Nous avons aussi modifié le symbole utilisé pour désigner une case "vide" qui correspondait à '-' (char) dans nos tableaux. Nous l'avons remplacé par "999" (int), parce que ça sera plus simple pour Mr Zocco de lire le fichier et de récupérer si toutes les valeurs sont des entiers et non pas un mélange d'entiers et de string.
Voici à quoi peut ressembler le fichier de données que nous envoyons :
Lors de la prochaine séance, nous allons essayer notre application avec une connexion 3G/4G. Nous devons également chercher des cas critiques qui pourraient arrêter notre application.
Semaine 11
Nous consacrons cette séance essentiellement aux tests sur différents appareils en 3G puis en 4G pour faire tourner l'application dans des conditions différentes de connexion internet.
Cependant, pour effectuer ces tests nous avons besoin d’emprunter le téléphone d'un de nos camarades, ne possédant pas nous même de téléphone sous Android. On aurait pu simplement insérer notre carte SIM dans le téléphone prêté pour le projet mais essayer sur un autre téléphone nous permettait de vérifier que l'application fonctionnait bien sur différents appareils du notre.
De plus, souvenez-vous en Semaine 10, nous ne pouvions tester le Profiler d'Android Studio à cause d'une version trop ancienne de l'OS installé sur le smartphone. Nous profitons alors de l'occasion des tests 3G/4G pour emprunter un téléphone dernier cri parmi ceux de nos camarades et de faire à la fois le test fonctionnel et énergétique.
Nous installons notre application sur deux smartphones empruntés et faisons les tests fonctionnels en 3G/4G. Petit problème rencontré : notre application n'a pas demandé l'autorisation d'écriture dans les données du téléphone ce qui provoque l'arrêt de l'application au moment de l'envoi, puisque l'application essaye d'envoyer un fichier qui n'existe pas. C'est étonnant puisque nous avions déjà ajouté une autorisation de l'application pour l'écriture dans les fichiers de l'appareil. En fouillant dans les paramètres du téléphone, nous trouvons comment activer cette option. Une fois activée, tout semble fonctionner comme en wi-fi. Les envois se font sans rencontrer de difficultés et l'application fonctionne normalement.
Maintenant que l'application fonctionne comme elle devrait, nous lançons le Profiler qui va nous donner des informations sur la consommation énergétique de l'application en temps réel. Voir Photo
Nous sommes déçus du résultat. Le logiciel nous donne une information très peu fiable puisque les pics énergétiques sont qualifiés de Faible, Moyen ou Élevé. C'est pas très précis mais on voit quand même que tous les pics sont bien bas dans le niveau Faible donc à priori, notre application ne consomme pas beaucoup. Mais par rapport à quoi ? C'est le problème de cet indicateur pas très intéressant ici. On remarque aussi les pics très marqués dans la partie Network correspondant aux envois de fichier. Le léger mouvement avant le pic d'envoi est dû à la tentative de connexion au serveur avant l'envoi. On a bien un pic d'envoi vers le serveur en jaune et de réception du serveur en bleu. De même au niveau du CPU, le téléphone est loin d'être en surcharge et c'est normal.
Pour la fin de la séance, nous décidons d'optimiser au maximum notre fichier d'envoi. Lorsqu'il est bien rempli, il pèse environ 1 Ko ce qui n'est pas beaucoup. Cependant, en tant qu'ingénieur, nous devons rendre le code le plus optimisé possible pour un fonctionnement optimal de l'application (et minimal dans sa consommation énergétique). Il est évident que plus le fichier est gros, plus le téléphone consomme de l'énergie à l'envoyer sur le serveur. Comme cet envoi a lieu plusieurs fois par minute et que nous voulons un fonctionnement sur toute une journée, il est important d'optimiser le contenu du fichier. Nous supprimons les espaces et les sauts de ligne inutiles. Après ces modifications nous arrivons à une taille moyenne d'environ 500 octets.
Suite et fin
Pendant les vacances, nous avons eu une nouvelle réunion de projet, cette fois-ci via Skype avec Fabien Zocco et Laurent Sparrow. Nous faisons un point tous ensemble sur l'avancée du projet et voyons les points à améliorer. Quelques modifications supplémentaires du fichier nous sont demandées. Souvenez-vous, jusqu'à présent, comme expliqué en semaine 7, nous gardions seulement les 15 dernières valeurs relevées mise à part pour l'IBI que nous avons transformé en liste chaînée en semaine 10.
Pour permettre l'analyse exacte des données par Laurent, il nous a demandé d'envoyer toutes les valeurs d'EDA aussi, donc de faire comme pour l'IBI en liste chaînée. Aussi, les valeurs d'accéléromètre peuvent être utiles dans l'analyse des mouvements de Fabien et donc il est préférable de moyenner les valeurs plutôt que de relever seulement les 15 dernières valeurs (1 valeur par seconde). En regardant la documentation Empatica, nous apprenons que le capteur relevant les valeurs d'accéléromètre travaille à 32 Hertz donc il relève 32 valeurs par seconde pour chaque coordonnée (X, Y et Z). Nous faisons en sorte donc que dans le code, le programme moyenne 32 valeurs par seconde pour utiliser toutes les valeurs relevées.
Partie exploitation des données : Nous n’avons pas pu obtenir d’araignées-robots pour vérifier que notre partie fonctionne bien. Nous avons alors créé un programme sur Processing. Notre programme récupère les données sur le site http://www.fabienzocco.net/fichier_info.txt.
La fonction ls permet de récupérer les données du site à l’aide de la fonction loadString(<lien>). Cette opération est réalisée toutes les 15 secondes. Parce qu’il faut que la fréquence d’envoi sur le serveur soit la même que la fréquence de récupération. On utilise alors un compteur pour gérer le temps. A chaque appel de cette fonction nous remplissons un tableau de toutes les valeurs. Les données qui nous intéressent en l'occurrence les valeurs de l'accéléromètre (variable x seulement) se trouvent à la ligne 7. Avec la commande split, on sépare les données en précisant le séparateur utilisé sur le site: “/”, et on range ces valeurs dans un tableau.
La fonction draw permet de dessiner le cercle. Nous avons alors choisi de remplacer l'araignée par un cercle bleu. Ce dernier va se déplacer dans la fenêtre en suivant les valeurs récupérés par l’accéléromètre de la montre. Pour ce faire, nous avons modifié les coordonnées du centre du cercle.
Ci-dessous un exemple:
Lorsque qu’une personne qui porte le bracelet fait un mouvement de droite à gauche, on peut voir un déplacement du cercle de droite à gauche.
Pour conclure sur ce projet, nous avons travaillé en équipe dans ce projet et le travail a été équitablement réparti. Nous avons pris soin à ce que la communication soit bonne et que le partage du travail soit équitable entre nous.
De plus, nous étions en réelle situation d’ingénieur avec un client et un projet à réaliser en un temps délimité. Ce côté était d’autant plus marqué parce que le demandeur et encadrant Monsieur Zocco était extérieur à l’école. Nous nous sommes positionnés en tant qu’ingénieurs, avons organisé des réunions projets pour obtenir des informations et des réponses à nos interrogations. Nous avons tenu au courant Monsieur Zocco tout au long du projet de nos avancées en lui faisant des retours réguliers.
Ce projet était prenant et enrichissant. Il nous a permis de développer les compétences que nous souhaitions et de découvrir la programmation pour applications mobiles.
L'application est fonctionnelle et nous sommes satisfaits du résultat obtenu. Elle sera utilisable pour la suite du projet par Fabien Zocco et Laurent Sparrow.
Bibliographie
Lien | |
---|---|
Documentation Empatica sur les capteurs du bracelet E4 | https://support.empatica.com/hc/en-us/articles/202581999-E4-wristband-technical-specifications |
Dépot Git Empatica avec l’exemple | https://github.com/empatica/empalink-sample-project-android/ |
Informations sur le marché mobile de nos jours | https://www.servicesmobiles.fr/20-chiffres-sur-le-marche-mobile-a-connaitre-en-2018-38749/ |
Le lien vers le cours que nous avons utilisé: | https://www.udemy.com/complete-android-n-developer-course/learn/v4/overview |
Explication du Energy profiler d’Android Studio | https://developer.android.com/studio/profile/android-profiler |
Git d’une alternative Energy profiler pour une application .apk | https://github.com/google/battery-historian |
Site de Fabien Zocco, où on l’on trouve notre fichier de données | http://www.fabienzocco.net/fichier_info.txt |
Conseil pour la rédaction d’un rapport de projet | https://www.irit.fr/~Armelle.Bonenfant/Enseignement/JavaSTRI/conseilsRapport.pdf |
Sans compter la multitude de pages Wikipédia et publications sur Stack Overflow qui nous ont aidé à nous sortir de différents problèmes même mineurs.
Documents Rendus
Code source de l'application (Android Studio) : Média:SpiderAndI.zip
Rapport du projet : Média:RapportP9.pdf