Vibrato

De fablab
Aller à : navigation, rechercher

Informations générales

Cadre du projet :

  • Encadrant : Rémi Pincent
  • Nombre d'étudiants : 3 à 5
  • Lieu : le projet aura lieu dans les ateliers d'Amiqual4Home ainsi qu'au fabMSTIC


Contexte

Allez jeter un coup d’œil ici

Dans un premier temps vous pourrez réviser vos gammes en utilisant "mogees". Certains d'entre vous utiliseront "mogees" pour rendre interactifs des objets de votre quotidien soigneusement identifiés. Vous ne contrôlerez pas un synthétiseur avec les notes générées mais des éléments de votre habitat. Vous pourrez travailler dans l'appartement d'expérimentation afin de définir et tester des scénarios définissant les actions associées aux vibrations captées par "mogees".

Les autres étudiants se pencheront sur le fonctionnement de Mogees. Grâce à un ou plusieurs capteurs PVDF vous réaliserez un microphone de contact DIY. Associé au logiciel que vous allez développer, vous serez capable de remplacer (avantageusement?) "mogees" pour les scénarios identifiés précédemment.


Sujet

Dans le cadre ce projet, nous vous proposons de :

  • prendre en main et comprendre précisément le fonctionnement de "mogees"
  • découvrir les capteurs de vibrations et plus spécifiquement les PVDF
  • réaliser l'interfaçage entre capteurs PVDF et microcontrôleur
  • réaliser le logiciel se chargeant de la classification des différentes zones d'interaction pour un objet donné

Flyer111.png

Conception de l'objet

Pour détecter les vibrations de la table, nous utilisons la pièce piézoélectrique suivante : Piezo.png

Afin d'avoir un meilleur signal, le signal détecté par la pièce piézoélectrique est amplifié par le circuit amplificateur suivant :
Schemacircuit.png

Le montage correspondant donne alors :
20160407 154109.jpg

La comparaison des signaux nous donne :
Scope 0.png
En jaune : signal en sortie directe de la pièce piézoélectrique
En vert : signal amplifié (noter l'echelle)

L'amplification est assez satisfaisante pour que de faibles frappes sur la table soient bien détectées par le système.

On procède alors à la conception du PCB à l'aide de Kicad :
Pcb.jpg

L'arduino fait un premier traitement du signal reçu en le décomposant en série de Fourier (FFT). Il envoie ensuite les infos sur le port USB.
Le code de l'arduino est le suivant :


   /*
      2 fft_adc.pde
      3 guest openmusiclabs.com 8.18.12
      4 example sketch for testing the fft library.
      5 it takes in data on ADC0 (Analog0) and processes them
      6 with the fft. the data is sent out over the serial
      7 port at 115.2kb.  there is a pure data patch for
      8 visualizing the data.
      9 */
  
   #define LOG_OUT 1 // use the log output function
   #define FFT_N 256 // set to 256 point fft
   
   #include <FFT.h> // include the library
   
   void setup() {
     Serial.begin(230400); // use the serial port
     TIMSK0 = 0; // turn off timer0 for lower jitter - delay() and millis() killed
     ADCSRA = 0xe5; // set the adc to free running mode
     ADMUX = 0x40; // use adc0
     DIDR0 = 0x01; // turn off the digital input for adc0
   }
   
   void loop() {
     while (1) { // reduces jitter
       cli();  // UDRE interrupt slows this way down on arduino1.0
       for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
         while (!(ADCSRA & 0x10)); // wait for adc to be ready
         ADCSRA = 0xf5; // restart adc
         byte m = ADCL; // fetch adc data
         byte j = ADCH;
         int k = (j << 8) | m; // form into an int
         k -= 0x0200; // form into a signed int
         k <<= 6; // form into a 16b signed int
         fft_input[i] = k; // put real data into even bins
         fft_input[i + 1] = 0; // set odd bins to 0
       }
       // window data, then reorder, then run, then take output
       fft_window(); // window the data for better frequency response
       fft_reorder(); // reorder the data before doing the fft
       fft_run(); // process the data in the fft
       fft_mag_log(); // take the output of the fft
       
       sei(); // turn interrupts back on
       Serial.write(255); // send a start byte
       Serial.write(fft_log_out, 128); // send out the data
     }
   }


Il ne reste plus qu'à organiser le tout :
Boiteouverte.jpg



Boitepiezo.jpg



Boiteusb.jpg



Boitefermee.jpg


Étapes de réflexion pour le traitement des données

1. La première étape a été d'étudier les utilisations possibles du Mogees et ses limitations. Le principal problème qui est apparu était de ne pas pouvoir faire deux impulsions en même temps, ce qui devient très limitant d'un point de vue musical mais qui ne l'est pas pour l'utilisation (maison connnectée) que nous voulons apporter à notre objet. De plus, il est interessant de noter que l'application distingue les vibrations sous forme de disques qu'il localise dans un rectangle. Si alors deux disques se recoupent, c'est que les gestes enregistrés se ressemblent trop, il est alors déconseillé de garder les deux gestes.

2. Nous avons premièrement voulu extraire des données MIDI du Mogees avec des logiciels existant comme RTP-MIDI. Nous avons été confrontés notamment a des problèmes réseaux, nous avons alors nous avons préféré rester sur de l'extraction de fréquences.

3. C'est pourquoi nous nous sommes premièrement lancés dans l'utilisation d'un code opensource SPEK, permettant d'afficher les différentes fréquences d'un enregistrement. Problème de ce code, il était difficile de l'adapter au fonctionnement en temps réel, ce dernier étant absolument nécessaire pour une application de domotique.

4. Nous avons alors trouvé un pseudo-code faisant une FFT sur le stream audio :

   #construct one hanning window Function
   Chunk = 2048;
   windowed = [Chunk];
   hanning = [Chunk];
   for i 1:Chunk:
       hanning[i] = ((1 - cos(i*2*pi/Chunk-1))/2)
   
   #start capture from Mic
   while true:
       #into values capture 2048 points from your mic
       values=dataFromMic(Chunk);
       #Apply Window hanning = multiply window function(hanning) over your 2048 points
       for i 1:Chunk:
           windowed[i] = values[i] * hanning[i]
       #Apply FFT
       fftData=fft(windowed);
       #Get Magnitude (linear scale) of first half values
       Mag=abs(fftData(1:Chunk/2))
       # update/show results
       send_to_openHAB(Mag)
   end

Ce pseudo-code nous a amener alors à faire le choix du langage Python, que nous ne connaissions pas mais qui, après quelques recherches, nous semblait être le plus adapté à notre projet. Il possède de nombreuses bibliothèques de Maths adaptées au traitement de données.

5. Python nous a amener alors à trouver du traitement fréquentiel en real time (voir lien dans les sources). Ce code nous a permis d'avoir un premier type de traitement fréquentiel, l'idée de ce dernier étant de pouvoir afficher les courbes fréquentielles. L'affichage ne nous important peu, nous nous sommes inspiré du code pour pouvoir détecter les impulsions à l'aide d'une fonction <<Peak_detection>>.

6. Il nous a fallut ensuite travailler sur openhab, API de domotique permettant de relier tout type d'objet de domotique sur un même interface.

7. Création d'une interface graphique facilitant l'utilisation et la mise en place de l'objet.


Nous nous sommes basés sur ce code pour produire : https://github.com/sophieortiz/fablab_python

Accueil des données par Machine Learning

1. Principe:

Pour chacun des deux types de données que notre programme peut recevoir (soit par l'entrée micro pour le mogees, soit par USB pour le montage que nous avons réalisé), nous pouvons le lancer en deux modes différents: le mode apprentissage de nouveaux mouvements et le mode détection. Lors du mode apprentissage, les données recueillies sont stockées dans un fichier .db, grâce à la biliothèque shelve qui permet de sauvegarder des objets python. Lors du mode détection, au lancement du programme les exemples sont extraits du fichier .db et sont appris à l'algorithme de machine learning. Ensuite les données recueillies lors des coups assénés sont passées à l'algorithme qui va prédire de quel coup il s'agit.


2. Choix de l'algorithme de Machine Learning:

Notre programme s'appuie sur la bibliothèque ScikitLearn, qui contient plusieurs algorithmes de machine Learning. Nous avons choisit d'utiliser un algorithme SVM (Support Vector Machine) car ceux-ci sont adaptés à la classification (l'usage que nous voulons en faire) et sont efficaces même si nous avons un nombre d'exemple inférieur à la taille de chaque exemple (ce qui est notre cas, cf point numéro 3). L'algorithme s'appelle SVC (Support Vector Classification). Nous devons spécifier à cette algorithme un fonction kernel, qui joue un rôle important dans la façon dont les données sont analysées, et parmis les différents kernel à notre disposition, nous avons choisit un kernel polynomial car il donnait de meilleurs résultats.


3. Choix des données utilisées par l'algorithme

Ce procédé est similaire que l'on soit en mode apprentissage ou détection et que l'entrée soit micro ou USB. A chaque nouvelle mesure, nous recevons un tableau de taille fixe (64 pour l'entrée USB et 204 pour l'entrée micro) correspondant à la transformée de fourier du signal. Si la moyenne de ce tableau est supérieure à un certain seuil, alors il y a eut un coup et nous pouvons commencer notre analyse. Nous avons choisit d'utiliser ces données avant qu'elles soient analysées par peak detect (qui sert du coup uniquement à la visualisation), qui détectait les maximas et minimas du signal, car il est obligatoire que tout les échantillons donnés à l'algorithme de machine learning fassent la même taille.

Nous donnons à l'algorithme les tableaux de 7 mesures consécutives à partir de la première ayant dépacé le seuil concaténés en un seul, et cela constitue notre exemple. Cela permet d'observer l'évolution temporelle des vibrations après le coup, car cette évolution varie plus en fonction du type de coup que l'allure de la première mesure. Le chois du nombre de mesures (7) a été ajusté en fonction des performances obtenues: s'il est trop court la différence entre deux coups n'est pas encore assès signifative, s'il est trop long elle est écrasée par la similarité d'un retour au calme après le coup. Pour cette raison, nous ne pouvons pas apprendre à l'algorithme de ML un mouvement ou nous ferions deux coups successifs. Cela n'empêche pas que l'on peut se servir de combinaisons de coup quand même: nous apprenons à l'algorithme des coups atomiques, et si il en reconnait deux (ou plus) dans un intervalle de temps rapproché, cela constitue une combinaison.


Implémentation réalisée dans: machineLearning.py

Sources: http://scikit-learn.org/stable/modules/svm.html

http://www.technologies-ebusiness.com/enjeux-et-tendances/le-deep-learning-pas-a-pas

Python & Openhab

<< OpenHAB is a mature, open source home automation platform that runs on a variety of hardware and is protocol agnostic, meaning it can connect to nearly any home automation hardware on the market today. If you’ve been frustrated with the number of manufacturer specific apps you need to run just to control your lights, then I’ve got great news for you: OpenHAB is the solution you’ve been looking for – it’s the most flexible smart home hub you’ll ever find.>>

Openhab1.png

Openhab2.png


La première étape est de construire l'environnement Openhab adapté. On fait cela en créant des items différents pour chaque élément connecté de la maison.

Un avantage avec Openhab est qu'il est contrôlable à distance. C'est-à-dire qu'à l'aide d'une connexion web et d'une "requête openhab" dans un shell, nous pouvons changer les comportements d'un objet connecté. On utilise pour cela des commandes du type : curl --header "Content-Type: text/plain" --request PUT --data "ON"

Ces requêtes sont, dans le cas de notre projet, intégrées dans le code Python, qui lancera alors telle ou telle commande selon les données qui lui sont envoyées par notre détecteur.

C'est également à l'aide de règles Openhab que nous pouvons différencier des actions si nous faisons 1 - 2 ou 3 impulsions.

Dernière étape, rajouter un nouveau mouvement : nous utilisons alors la commande "echo" permettant d'écrire dans le fichier "vibrato.item" et modifiant les fichiers Openhab directement. Exemple de commande : 'sudo echo "Switch Light_Gest \"Gesture Control Light\" (Gesture, Lights) " >> configurations/items/vibrato.items'

Interface utilisateur

L'interface graphique a été réalisée en Qt.

Elle permet à l'utilisateur d'ajouter, enlever, modifier les options de la maison. On peut ainsi décider d'ajouter un son qui permet d'allumer la lumière par exemple.

On peut aussi régler les paramètres de la capture de son.



Fenetre.png

sources


http://www.echelleinconnue.net/outils/mobio/composants/LM386.pdf
http://wiki.openmusiclabs.com/wiki/ArduinoFFT

Code squelette de notre projet :

http://www.swharden.com/blog/2010-03-05-realtime-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and-wckgraph/

Aide Utilisation d'openhab :

http://www.makeuseof.com/tag/getting-started-openhab-home-automation-raspberry-pi/

Pour le machine learning:
http://scikit-learn.org/stable/modules/svm.html
http://www.technologies-ebusiness.com/enjeux-et-tendances/le-deep-learning-pas-a-pas


Reprise du projet : Vibrato v2.0

Architecture proposée

En reprenant le projet précédent, beaucoup d'idée d'extensions nous sont venues en tête à commencer par un boitier sans fil.
L'architecture que nous proposons est la suivante :
ArchiVibrato.png
L'idée est alors un capteur qui communique en Bluetooth les coups reçus à un Raspberry Pi.
Le Raspberry Pi analyse alors le coup est vérifie si il est présent dans la base de données des coups. Si le coup est dans la base de données, il envoi l'information à OpenHab qui exécute alors l'action associée.
La tablette Android est équipée d'une application que nous implémenterons qui permet de configurer les coups et les instructions.

Travail Réalisé

Le dépôt git du nouveau projet : https://github.com/Erennor/vibrato

Réalisation du boitier

Voici comment a été conçu le boitier :
BoitierVibrato.jpg

1. Prise USB pour recharge
2. Batterie
3. Circuit amplificateur + RFduino
4. Support + capteur piézoélectrique

Le circuit amplificateur n'est finalement pas utilisé car l'amplification du signal le faisait saturer très rapidement ce que faisait perdre beaucoup d'information du coup donné et donc compliquait la reconnaissance des coups.
La coque du capteur a été faite à l'aide d'une imprimante 3D. Une fois monté, le capteur ressemble à ceci :
Igloo.jpg
Une LED est apparente et la couleur correspond aux état du capteur :
Rouge : état d'attente, le capteur attend de détecter un coup.
Vert : Coup détecté, le capteur envoi alors la FFT du coup enregistré par Bluetooth.
Bleu : Calibration, le capteur se calibre à sa surface de contact pour définir une valeur de référence.