netscratch : passerelle Scratch/rObOscratch

Configuration de Scratch

Un fichier json est créé pour définir de nouveaux blocs :


{  "extensionName": "rObOtScratch",
   "extensionPort": 9010,
   "blockSpecs": [
      ["r", "Valeur du capteur %m.capteur", "capteur"],
      [" ", "Stop", "ST"],
      [" ", "Avant", "AV"],
      [" ", "Arrière", "AR"],
      [" ", "Droite", "DR"],
      [" ", "Gauche", "GA"],
      [" ", "Fixer la vitese à %n", "V", 50],
      [" ", "Mettre la vitesse du moteur %m.moteur à %n", 50],
      ["r", "Capteur droit", "CD"],
      ["r", "Capteur gauche", "CG"],
   ],
   "menus": {
      "capteur": ["droit", "gauche"],
      "moteur": ["droit", "gauche"],
    },
}

Lorsqu’on clique avec « shift » + « clic droit » sur le menu « fichier », un item « Importer l’extension expérimentale » apparaît.
On sélectionne alors le fichier json créé. À cet instant, un nouveau lot de blocs devient accessible dans le choix
de blocs « Ajouter blocs ».


Traitement des trames reçues de Scratch

Lorsque le programme scratch s’exécute, chaque instruction en relation avec le pilotage du robot génère une requête http vers l’adresse 127.0.0.1:9010. Puisqu’il y a des variables internes au robot, scratch interroge également en permanence ce serveur avec des requêtes /poll pour obtenir en retour l’état des variables.

Voici deux trames HTTP reçues de Scratch. Ce sont toutes les mêmes, à l’URL près.
En rouge: la partie qui nous intéresse vraiment.


GET /ST HTTP/1.1
Host: 127.0.0.1:9010
Accept-Encoding: deflate, gzip
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, text/css, image/png, image/jpeg, image/gif;q=0.8, application/x-shockwave-flash, video/mp4;q=0.9, flv-application/octet-stream;q=0.8, video/x-flv;q=0.7, audio/mp4, application/futuresplash, */*;q=0.5
User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR) AppleWebKit/531.9 (KHTML, like Gecko) AdobeAIR/2.6
x-flash-version: 10,2,159,1
Connection: Keep-Alive
Referer: app:/Scratch.swf


GET /poll HTTP/1.1
Host: 127.0.0.1:9010
Accept-Encoding: deflate, gzip
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, text/css, image/png, image/jpeg, image/gif;q=0.8, application/x-shockwave-flash, video/mp4;q=0.9, flv-application/octet-stream;q=0.8, video/x-flv;q=0.7, audio/mp4, application/futuresplash, */*;q=0.5
User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR) AppleWebKit/531.9 (KHTML, like Gecko) AdobeAIR/2.6
x-flash-version: 10,2,159,1
Connection: Keep-Alive
Referer: app:/Scratch.swf

....

Architecture logicielle de la passerelle netscratch

La classe ServeurM est la classe principale.
Au lancement, le serveur recherche l’adresse du robot. Le robot se comporte comme un hotspot wifi. L’ordinateur est connecté sur ce wifi.
Lorsque la passerelle connaît sa propre adresse IP externe, elle en déduit l’adresse du robot (même adresse, mais qui se termine par « .1 »)
Elle attend une connexion de scratch sur le port 9010. Dès qu’un client est connecté, il est pris en charge par une classe Lien.

La classe Lien analyse la requête http et selon le cas, envoie une commande au robot ou bien lui demande l’état des capteurs. Dans le cas des capteurs, une réponse est renvoyée à scratch.

La classe CommandeT sert à faire une requête http au robot.

La fonction java chargée de l’acquisition et du traitement des trames:

// Attente d'une trame HTTP, et traitement
// trame "poll" -> il faut renvoyer les variables à scratch
// trame "/AV", "/AR" ... -> on exécute la commande au niveau du robot
protected byte[] lireTrame(){
   byte[] b = null;
   do {
      try {
         try {Thread.sleep(30);} catch(Exception e){}
         int N = dis.available(); // nombre d'octets disponibles 
         if (N!=0) {
            b = new byte[N];
            dis.read(b);
            // transforme le tableau d'octets en chaîne java : 
            String str = new String(b); 
            System.out.println(str);
            String[] T = str.split("GET");
            if (T.length>1) {
               String[] T2 = T[1].split("HTTP");
               if (T2[0].indexOf("poll") >= 0) retourVariables();
               else  envoieCommande(T2[0]);
            }
         }
      } catch (Exception e){System.out.println("Erreur de reception");}
  } while (b==null);
  return b;
}

Lorsque le programme scratch qui s’exécute est :

L’affichage de la passerelle en correspondance est :

Archive netscratch