Un NXT à commande vocale !

mardi 28 septembre 2010
par  Sylvain Cacheux
popularité : 3%

Le kit de base NXT comporte un microphone. On peut s’en servir comme télécommande. Voici comment.

La commande vocale s’insinue partout. Les derniers GPS, les téléphones portables incluent maintenant des processeurs suffisamment puissants, voire même des puces dédiées, leur permettant de proposer cette fonctionnalité.

Le NXT ne la propose pas de base, comblons donc cette lacune !

Ben oui mais comment qu’c’est-y don’ possible, cré fieux !??

Effectivement, les plus avertis d’entre vous auront vite remarqué que le NXT ne contient pas un Intel Quad Core ni 2 Gb de RAM et se demandent donc une architecture si modeste peut quand même faire reconnaitre la voix !

Forcément, y’a un truc.

Mon idée n’est pas de reconnaitre la voix en tant que telle, mais un ordre.

Whouah, quelle différence sibylline !

Ok, je développe.

Évidemment, le NXT n’est pas capable de reconnaitre des mots, et encore moins des phrases. En revanche, il sait capter du bruit via son micro.

Ce micro n’indique au NXT que l’intensité sonore qu’il détecte, avec un niveau variant de 0 (rien) à 100 (saturation du micro). Le NXT possède aussi des timers. Je commence à voir votre oeil qui s’illumine !

Voilà : il suffit de mesurer pendant combien de temps un niveau sonore est détecté !

On utilise un timer qu’on déclenche lorsque le niveau sonore détecté par le NXT dépasse un certain seuil (qu’on calibre auparavant sur le niveau sonore ambiant). C’est la détection de l’ordre (T0).

C’est bien, on a détecté un ordre. Mais lequel ?

En fait, le timer s’arrête lorsque le niveau sonore baisse, c’est à dire la fin de l’ordre (T1).

Du coup, il suffit de comparer T1-T0 (=ordre) à une table.

Exemple :
- Si 0 < ordre < 500 ms, alors effectuer telle action
- Si 500 ms < ordre < 1 s, alors effectuer telle autre action
- Si 1s < ordre < 1,5 s, alors effectuer encore telle autre action.
- etc.

Voici, ci-dessous, un programme en RobotC (à copier/coller directement dans RobotC, qui remettra en forme) qui met en pratique cette théorie. Dans ce programme, vous verrez qu’en fonction de la longueur de votre ordre, un numéro s’affiche sur l’écran.

A vous de modifier cela pour faire faire à votre NXT ce que vous voulez !

Un bémol cependant : il faut évidement garder le niveau sonore à un certain niveau pour que le NXT continue de mesurer la durée de l’ordre. C’est pour cela que j’ai ajouter une petite pause dans la boucle. Elle évite de couper la mesure entre 2 mots. C’est une petite bidouille qui peut être améliorée, je vous laisse tester !

A bientôt pour de nouvelles aventures !

#pragma config(Sensor, S1,     soundSensor,         sensorSoundDB)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

/*--------------------------------------------------------------------------------------------------------*\
|*                                                                                                        *|
|*                                        - commandes vocales -                                           *|
|*                                            ROBOTC on NXT                                               *|
|*                                                                                                        *|
|*  This program runs tasks depending on sound delay, which can be assimilated to vocal commands.         *|
|*                                                                                                        *|
|*                                        ROBOT CONFIGURATION                                             *|
|*    NOTES:                                                                                              *|
|*    1)  The 1 second delay is needed to avoid obtaining inaccurate initial readings.                    *|
|*                                                                                                        *|
|*    MOTORS & SENSORS:                                                                                   *|
|*    [I/O Port]              [Name]              [Type]              [Description]                       *|
|*    Port B                  motorB              NXT                 Right motor                         *|
|*    Port C                  motorC              NXT                 Left motor                          *|
|*    Port 1                  soundSensor         Sound Sensor        Sound Db Right                      *|
\*-------------------------------------------------------------------------------------------------------*/

int NiveauReference, DureeSon;


task main()
{
 NiveauReference = 0;
 DureeSon = 0;

 wait1Msec(1000);       // A one-second wait is required to cleanly initialize the Sound Sensor.
 eraseDisplay();

 //initializing ambiant sound level
 NiveauReference = SensorValue[soundSensor];
 nxtDisplayTextLine(0, "niveau actuel :");
 nxtDisplayTextLine(1, "%2i", NiveauReference);
 wait1Msec(3000);
 eraseDisplay();

 while(true)            // Infinite loop
 {
           ClearTimer(T1); // reseting timer and showing the current sound level
           nxtDisplayTextLine(0, "niveau son :");
           nxtDisplayTextLine(1, "%2i", SensorValue[soundSensor]);

           // checking if the sound level detects words
           while (SensorValue[soundSensor] > (NiveauReference + 10))
           {
              DureeSon = time1[T1]; // incrementing the variable according to timer to have the sound delay eared by the NXT
              nxtDisplayTextLine(2, "Ecoute depuis"); // indicating from how long the NXT "ears" words (orders)
              nxtDisplayTextLine(3, "   %2i ms", DureeSon);
              wait1Msec(250); // pause to avoid breaking measure word after word, can be adjusted.
              /* this pause is a kind of pb as if you are between 2 words at the end of pause, the loop ends...
                 another way of programing could be the following :
                 loop:
                 {
                 check sound level,
                 if sound level > reference + 10 then initiate timer
                 wait 500 ms (or a little less, for next measuring processing time)
                 measure timer :
                   if the sound level is under reference +10, then order 1 and end loop
                   else
                     wait another 500 ms (so we have a 1 second delay/order)
                     if the sound level is under reference +10, then order 2 and end loop
                     else
                              wait 1000 ms (so we have a 2 seconds delay/order)
                              if the sound level is under reference +10, then order 3 and end loop
                              else
                                      wait another 1000 ms (so we have a 3 seconds delay/order)
                                      if the sound level is under reference +10, then order 4 and end loop
                                      else
                                              wait another 1000 ms (so we have a 4 seconds delay/order)
                                              if the sound level is under reference +10, then order 5 and end loop
                                              else
                                                      wait another ? ms (so we have a more than 4 seconds delay/order)
                                                      if the sound level is under reference +10, then order 6 and end loop
                 }
              */
           }

           // checking if an "order" have been "eared"
           if (DureeSon > 0)
           {
             // defining orders depending on the order's delay
             if ((DureeSon >    0) & (DureeSon <  500)) DureeSon = 1;
      if ((DureeSon >  500) & (DureeSon < 1000)) DureeSon = 2;
             if ((DureeSon > 1000) & (DureeSon < 2000)) DureeSon = 3;
             if ((DureeSon > 2000) & (DureeSon < 3000)) DureeSon = 4;
             if ((DureeSon > 3000) & (DureeSon < 4000)) DureeSon = 5;
             if  (DureeSon > 4000)                      DureeSon = 6;

      switch (DureeSon)
      {
        case 1:
          nxtDisplayTextLine(3, "Ordre 1");
          wait1Msec(2000);
          break;
        case 2:
          nxtDisplayTextLine(3, "Ordre 2");
          wait1Msec(2000);
          break;
        case 3:
          nxtDisplayTextLine(3, "Ordre 3");
          wait1Msec(2000);
          break;
        case 4:
          nxtDisplayTextLine(3, "Ordre 4");
          wait1Msec(2000);
          break;
        case 5:
          nxtDisplayTextLine(3, "Ordre 5");
          wait1Msec(2000);
          break;
        case 6:
          nxtDisplayTextLine(3, "Ordre 6");
          wait1Msec(2000);
          break;
        case 0:
          nxtDisplayTextLine(3, "Ratage...");
          wait1Msec(2000);
          break;
        default:
      }
      // reinitializing the "order"
      DureeSon = 0;
      eraseDisplay();
    }
 }
}

Documents joints

C source - 5.9 ko
C source - 5.9 ko

Commentaires  (fermé)

Logo de Xavier D
vendredi 12 octobre 2012 à 15h08 - par  Xavier D

En regardant sur le site de Daniele Benedettelli, j’ai trouve une appli android pour faire parler son NXT et aussi pouvoir lui parler.

C’est la :
http://robotics.benedettelli.com/So...

J’ai testé, ca marche bien, la voix en TTS est bien, mais par contre dans l’autre sens ,quand on parle au robot, il faut des phrases en anglais, et reconnu par Google Voice.

Logo de Dagobot
mercredi 29 septembre 2010 à 21h20 - par  Dagobot

Merci pour cet article, c’est astucieux.
Je vais sûrement l’adapter pour que ça puisse être compatible Linux :)

Brèves

29 juillet 2011 - Mise à jour des pièces LDraw 2011-01

La première mise à jour des pièces LDraw pour 2011 est désormais disponible ! Au sommaire, 486 (...)

28 mars 2011 - Reportage sur la chaine de fabrication LEGO

Un reportage de National Geographic sur la compagnie LEGO, et plus particulièrement sur la (...)

23 février 2011 - Pierre Normandin présente le nouveau train LEGO Maersk 10219 en vidéo

Notre ami Pierre Normandin, designer LEGO CITY, présente dans cette vidéo le nouveau train LEGO (...)

31 décembre 2010 - Mise à jour des pièces LDraw 2010-03

Une nouvelle mise à jour des pièces officielles LDraw est disponible ! Au sommaire, 456 nouveaux (...)

21 juillet 2010 - Nouveau magazine LEGO dans les kiosques

Nouveauté dans les kiosques, le magazine LEGO n°01 vient de sortir. Au sommaire, pas grand (...)