Affichage des articles dont le libellé est robot. Afficher tous les articles
Affichage des articles dont le libellé est robot. Afficher tous les articles

13/08/2017

SmagYun, Comment accéder aux fonctionnalités Arduino depuis Javascript

Nous avons vu dans l'article précédent comment modifier la page d'accueil de la carte SmagYùn. 


Pour rappel, la carte SmagYùn est une préparation particulière de la carte Arduino Yùn, spécialement adaptée pour le développement d'applications multi-utilisateurs, comme pour un brainstorming, ou pour des jeux multi-utilisateurs, en réseau localisé (hotspot).

Quelque exemples d'applis pour la carte SmagYun

Pour commander une carte SmagYun déjà configurée, ou poser des questions : twitter @DFaveris ou  scenaristeur@gmail.com ou sms au 0671578914.




Nous allons voir aujourd'hui comment accéder aux fonctionnalités Arduino, afin de développer des applications / jeux qui peuvent agir dans le monde réel. On pourra accéder à la totalité des fonctionnalités Arduino (moteurs, leds, capteurs...) au moyen de la librairie https://github.com/ideino/ideino-linino-lib .


Dans l'article précédent, nous avions utilisé l'interface d'administration officielle "ArduinoOs" pour modifier la page d'accueil, tout en mentionnant qu'il était possible d'utiliser WinSCP et putty, et c'est ce que nous allons faire dans ce tutoriel.


Attention ! ! !
On considère ici que vous êtes connecté sur le Wifi "Arduino-Yun-XXX" et que votre carte SmagYun est accessible à l'adresse IP 192.168.240.1, comme expliqué dans l'article précédent :



Accéder au système de fichiers de la carte SmagYùn via Winscp.


Après avoir installé WinSCP, créez un nouveau site et paramétrez le comme suit : 
- Protocole de fichiers : SCP,
- Nom d'hôte : 192.168.240.1
- Numéro de port : 22
- Nom d'utilisateur : root

SmagYun Winscp Connexion parametres
SmagYun Winscp Connexion parametres

Cliquez ensuite sur "Connexion".
Saisissez le mot de passe d'administration de votre carte SmagYun, et validez par "OK"

SmagYun Winscp Connexion Login
SmagYun Winscp Connexion Login


Une fois connecté avec WinSCP, la partie gauche représente le disque de votre ordinateur, la partie droite, le système de fichier de la carte SmagYun. Vous pouvez vous y déplacer et parcourir le système de fichier et notamment retrouver le dossier /www dans lequel vous avez modifié la page d'accueil de la carte dans l'article précédent ;-). A vous de voir la manière la plus pratique pour modifier vos fichiers.


SmagYun WinSCP www
SmagYun WinSCP www

Afin de faciliter l'édition des fichiers à partir de WinSCP, il convient maintenant de modifier ses préférences, et de lui dire quel éditeur de texte utiliser. Nous avons choisi ici Notepad++, qui remplit grandement notre besoin pour cette tâche .
Dans WinSCP, sélectionnez dans le menu : Options / Préférences , cliquez sur "ajouter" et dans la section "Editeur externe" allez chercher votre éditeur favoris.

SmagYun WinSCP Preferences Editeur Notepadpp
SmagYun WinSCP Preferences Editeur Notepadpp


Maintenant que nous pouvons accéder aux fichiers de la carte SmagYun, on va entrer dans le vif du sujet.


Tester un premier script Javascript sur la carte SmagYun.

Avec la préparation SmagYun vous trouverez dans le répertoire /root/examples quelques exemples d'utilisation des fonctionnalités Arduino depuis javascript. Ce script sera lancé par nodejs, environnement déjà installé.
Naviguez maintenant jusqu'au répertoire /root/examples/

SmagYun WinSCP root examples
SmagYun WinSCP root examples

L'exemple qui nous intéresse dans un premier temps, est le fichier blink.js présent dans /root/examples/ .

Pour le lancer, on a encore une fois plusieurs options, on peut :
- comme dans l'article précédent passer par la page d'accueil / Admin / ArduinoOs / icone Arduino en haut à gauche / Utilities... mais cette fois, au lieu d'utiliser File Manager, choisissez "Terminal".
- utiliser putty


Utilisation de putty : 

Comme avec WinSCP, on va devoir configurer putty :
- Host Name  : 192.168.240.1
- Port : 22

SmagYun Putty Configuration
SmagYun Putty Configuration

Si putty vous demande d'ajouter / mettre à jour la clé ssh, validez.

SmagYun Putty SSHKey
SmagYun Putty SSHKey
Vous pouvez maintenant vous connecter au système Linux de la carte SmagYun, en saisissant le nom d'utilisateur et le mot de passe (rappel : "arduino" par défaut, à changer !!!).

SmagYun putty Connexion
SmagYun putty Connexion

Si tout se passe bien vous devriez maintenant voir l'invite de commande :

SmagYun putty Connecte
SmagYun putty Connecte


On continue, on approche, allons maintenant voir ce qui se trouve dans /root/examples avec les commandes cd et ls :

cd /root/examples
et
ls


SmagYun putty ls root examples
SmagYun putty ls root examples

Cool, on retrouve ici notre fichier "blink.js"... tout va bien...
pour le lancer c'est pas plus compliqué que de lancer la commande node blink.js


SmagYun Putty lancement blink.js
SmagYun Putty lancement blink.js

Patientez quelques secondes que le script s'initialise.
Si pas de message d'erreur vous devriez normalement voir la led rouge (branchée en parrallèle de la pin 13) clignoter .






Pour arrêter le script utilisez la combinaison de touches Ctrl+C.
Jetons maintenant un œil au code utilisé pour faire clignoter cette LED :
Pour ce faire, retournez dans WinSCP et double-cliquez sur le fichier "blink.js", si WinSCP est bien configuré (éditeur dans préférences), Notepad++ devrait s'ouvrir avec le code du script blink.js



SmagYun Notepadpp edition Blinkjs
SmagYun Notepadpp edition Blinkjs


Quelques explications sur ce code javascript s'imposent pour la compréhension de la suite :

---

/***
 * file: blink.js
 * version: 3.0
 * author: https://github.com/quasto
 * license: mit
 * description: in this example the board led on digital pin 13 will 
 *      blink every 1 second .
 ***/
 
var linino = require('ideino-linino-lib'),
    board = new linino.Board();

var pin13 = board.pin.digital.D13,
    ctrl = true;
    
board.connect( function(){
    board.pinMode(pin13, board.MODES.OUTPUT);
    
    setInterval(function(){
        if(ctrl){
            board.digitalWrite(pin13, board.HIGH);
            ctrl = false;
        }
        else{
            board.digitalWrite(pin13, board.LOW);
            ctrl = true;
        }
    },1000);
});


---

var linino = require('ideino-linino-lib'),  : import de la librairie / node_module ideino-linino-lib
board = new linino.Board(); : création d'une nouvelle carte
var pin13 = board.pin.digital.D13,  : on déclare une variable pin13 correspondant à la broche digitale D13 de la carte
ctrl = true;  : et une variable ctrl pour savoir si la led est allumée ou éteinte
board.connect( function(){ ... }); : javascript étant un langage événementiel, on créé un evenement rattaché à l'objet "board" créé précédemment. Cet événement "connect" lancera la fonction incluse dans "function(){...}" dès que la carte sera connectée et opérationnelle.
board.pinMode(pin13, board.MODES.OUTPUT); : on assigne le mode OUTPUT à pin13 pour dire que les informations sur ce pin seront en sortie (envoyées par la carte) comme pour tous les moteurs où LED, contrairement aux capteurs (luminosité, température...) boutons que l'on configurera en INPUT.
setInterval(function(){... },1000); : ça c'est du javascript, et évalue son contenu toutes les 1000 milliseconds (1 seconde).
if(ctrl){...}else{...} : en fonction de la valeur de "ctrl" on exécute la première ou la seconde partie.
board.digitalWrite(pin13, board.HIGH); : utilise la fonction digitalWrite de la "board" pour écrire "board.HIGH" dans pin13.
board.HIGH a pour valeur 1 et correspond à la LED allumée, alors que board.LOW a pour valeur 0 et correspond à la LED éteinte.





Voilà donc le code pour faire clignoter la LED, "Easy" me direz-vous ...

Comme expliqué juste au dessus, la led rouge sur la carte Arduino est branchée en parallèle avec la pin 13.

N'oubliez pas d'arrêter le script lorsque vous branchez / débranchez des composants sur la carte.

Pour vérifier ces propos, branchez une LED sur la PIN13, avec une résistance de 220 ohms pour protéger la LED :




Relancez le script avec "node blink.js" dans putty, les deux LED devrait maintenant clignoter de concert...


Ctrl+C pour arrêter.

C'est bien beau, tout ça, mais on n'a pas encore touché au code.
Essayons par exemple de brancher une deuxième LED sur la pin12.

Dans WinSCP, cliquez droit sur "blink.js" , puis Dupliquer :

SmagYun WinSCP blink duplique
SmagYun WinSCP blink duplique

Nommez-le "blink_double.js" et modifiez le code comme suit (bon on ne vas pas se fouler, on va juste copier les lignes concernant la pin13, et modifier HIGH en LOW, et LOW en HIGH) :

---

/***
 * file: blink.js
 * version: 3.0
 * author: https://github.com/quasto
 * license: mit
 * description: in this example the board led on digital pin 13 will 
 *      blink every 1 second .
 ***/
 
var linino = require('ideino-linino-lib'),
    board = new linino.Board();

var pin13 = board.pin.digital.D13,
pin12 = board.pin.digital.D12,
    ctrl = true;
    
board.connect( function(){
    board.pinMode(pin13, board.MODES.OUTPUT);
board.pinMode(pin12, board.MODES.OUTPUT);
    
    setInterval(function(){
        if(ctrl){
            board.digitalWrite(pin13, board.HIGH);
   board.digitalWrite(pin12, board.LOW);
            ctrl = false;
        }
        else{
            board.digitalWrite(pin13, board.LOW);
   board.digitalWrite(pin12, board.HIGH);
            ctrl = true;
        }
    },1000);
});

---


Branchez une deuxième LED, comme la première, sur la pin12, lancez ce nouveau script avec "node blink_double.js"
C'est beau l'alternance !





Prochain tutoriel : utiliser nodejs, express et socket.io pour créer un serveur WEB et utiliser ideino-linino-lib depuis une page web.

Pour commander une carte SmagYun déjà configurée, ou poser des questions : twitter @DFaveris ou  scenaristeur@gmail.com ou sms au 0671578914.



Quelque exemples d'applis pour la carte SmagYun

Extrait de la page ideino-linino-lib avec les proprietes et fonctions fournies par cette librairie : 

Properties and Functions

The board object has these main properties :
  • HIGH: is the high signal level for digital pins.
  • LOW: is the low signal level for digital pins.
  • MODES: contains the operating mode of a pin
    • .OUTPUT is the output operating mode of a digital pin.
    • .INPUT is the input operating mode of a digital pin (analog are in input mode by default).
    • .PWM is the pwm operating mode of a digital pin.
    • .SERVO is the servo operating mode of a digital pin.
  • pin: contains all the available pins of the board, grouped by typology :
    • .digital
    • .analog
    • .pwm
    • .servo
  • logger: is the log object used by the library with infodebug and error level, console and file appender (see advanced configuration)
  • model: is the model name of the board

12/08/2017

SmagYun, une Arduino Yùn préparée pour les développeurs Web et développeurs de jeux multi-joueurs

Smagyun, qu'est-ce que c'est ?


SmagYun est une préparation particulière de la carte Arduino Yun officielle.

SmagYun Démos : node avec socket.io pour le temps réel, threejs, p5js, phazer, babylon,
SmagYun Démos : node avec socket.io pour le temps réel, threejs, p5js, phazer, babylon,


Pour commander une carte SmagYun déjà configurée, ou poser des questions : twitter @DFaveris ou  scenaristeur@gmail.com ou sms au 0671578914.


Vous pouvez vous balader avec et la brancher sur un chargeur de smartphone micro-usb, ou sur une batterie pour l'emmener ou vous voulez : dans le bus, au parc, en soirée...

ArduinoYun photo officielle
ArduinoYun photo officielle



SmagYun est "tunnée" pour faciliter le développements en proposant un environnement prêt à l'emploi pour le développement d'applications multi-utilisateurs ou de jeux multi-joueurs en réseau local, fourni par un hotspot localisé. Ainsi vous jouez avec les gens qui sont à côté de vous... Une mini-console multi-joueurs...

Comme une Nintendo Switch? Non, pas vraiment, puisque là, chacun possède déjà la manette dans sa poche (son smartphone), de plus, on peut customiser les applications pour agir dans le monde réel, ce que ne fait pas la Nintendo Switch ( Accès aux fonctionnalités Arduino : moteurs, capteurs...) et pour trois fois moins cher que la Switch).

Ces jeux peuvent en effet utiliser les fonctionnalités de la carte Arduino ainsi que les fonctionnalités des smartphones comme contrôleur : accéléromètre, GPS, appareil photo, micro...

SmagYun facilite également la découverte de la programmation avec des outils simples (P5JS...), et de la robotique, la découverte de l'écosystème Arduino et des objets connectés (iot)...

+ Une communauté d'utilisateurs / développeurs pour partager les jeux et applications.

Sur SmagYun, on peut héberger des projets : Javascript, P5js, Threejs, nodejs, babylonjs, phazer, unity, python... Le php est également possible, mysql...



Pour des informations sur la carte Arduino Yun officielle, reportez-vous aux nombreuses documentations proposées sur l'un des deux sites Arduino officiels ou ailleurs sur le net, ça ne manque pas, ici on va parler de SmagYun...


Pour commander une carte SmagYun déjà configurée, ou poser des questions : twitter @DFaveris ou  scenaristeur@gmail.com ou sms au 0671578914.


Par où commencer ?

L'Arduino Yun est un peu particulière de par sa configuration : une puce Arduino et une puce Linux.

ArduinoYun utilisée par SmagYun
ArduinoYun utilisée par SmagYun


La préparation SmagYun vous permet de vous affranchir de la programmation de la partie Arduino et vous donne accès aux fonctionnalités Arduino directement depuis une page Web programmée en JavaScript.

Cette préparation transforme les 8Mb de stockage et les bascule sur la carte sd (8Go par exemple), elle inclue également l'installation des outils nécessaires pour vous faciliter les développements, comme l'installation de Nodejs, ou de lininoio. Vous n'avez qu'à la brancher et vous occuper du développement des applications/jeux comme décrit ci-dessous...

La carte SmagYun (ArduinoYun préparée par Smag0) fournit par défaut un hotspot wifi "Arduino-Yun-XXXXXXXXXX" sur lequel on peut connecter un ordinateur ou un smartphone.

SmagYun HotSpot Wifi Connexion
SmagYun HotSpot Wifi Connexion


Une fois connecté à ce wifi, vous pouvez lancer votre navigateur à l'adresse http://192.168.240.1 pour voir la page d'accueil de la carte.

SmagYùn Accueil
SmagYùn Accueil


1ère étape : Comment modifier la page d'accueil de SmagYun ?

La page d’accueil précitée peut être modifiée, c'est le fichier "index.html" du répertoire /www dans le système Linux de la carte.

SmagYun Modification de la page d'accueil
SmagYun Modification de la page d'accueil

Pour y accéder plusieurs solutions s'offrent à vous :
- depuis la page d'accueil :
- rendez-vous dans la section Admin, et cliquez sur "ArduinoOs", saisissez le mot de passe de la carte (arduino par défaut, PENSEZ A LE CHANGER SI VOUS ETES ADMIN !!!!)

SmagYun Admin section
SmagYun Admin section


SmagYun ArduinoOs Login
SmagYun ArduinoOs Login



- une fois entré dans l'interface ArduinoOs, cliquez sur l'icone Arduino en haut à gauche, puis sur Utilities, et file Manager. Vous avez ici accès à l'ensemble des fichiers du système Linux.

SmagYun FileManager
SmagYun FileManager



- sélectionnez sur la gauche "Arduino storage", et naviguez jusqu'au dossier /www

SmagYun Arduino Storage



- double-cliquez sur index.html, et sélectionnez un éditeur de texte (code mirror ou textpad)

SmagYun Edition page d'accueil, sélection de l'éditeur
SmagYun Edition page d'accueil, sélection de l'éditeur


- faites les modifications souhaitées, et enregistrez votre fichier.

SmagYun Edition page d'accueil, Code-Mirror
SmagYun Edition page d'accueil, Code-Mirror


- retournez à l'adresse http://192.168.240.1, vous devriez voir vos modifications apparaître.
 Ce n'est pas plus compliqué que cela.
Vous pouvez de cette manière customiser votre page et l'adapter à vos besoins.


Pour modifier les fichiers de la carte SmagYun, vous pouvez également utiliser :
- Winscp et Putty depuis Windows.
- Scp et ssh depuis Linux.
plus d'infos sur l'utilisation de WinSCP et putty avec la carte SmagYun dans l'article suivant.


Configurer Winscp et Putty avec l'adresse 192.168.240.1, et SCP pour Winscp.


le repertoire /www est un serveur web. sa configuration peut s'effectuer dans le fichier /etc/config/uhttpd

La pluplart des fichiers de config se trouve dans /etc ou /etc/config.
La configuration est modifiable via les commandes UCI

L'interface Arduinoos permet la plupart des opérations de gestion de la carte.
L'interface Luci permet également d'effectuer des opérations de la carte (basée sur OpenWrt)


Pour commander une carte SmagYun déjà configurée, ou poser des questions : twitter @DFaveris ou  scenaristeur@gmail.com ou sms au 0671578914.



Bien maintenant que l'on sait comment accéder aux fichiers et les modifier, tentons d'utiliser les fonctionnalités Arduino depuis Javascript :

SmagYun, Comment accéder aux fonctionnalités Arduino depuis Javascript



+
!! A compléter au plus vite !! avec :

Comment développer des applications / jeux multijoueurs sur la carte SmagYun ?

Des applications multi-utilisateurs et des jeux multi-joueurs
-> Le répertoire Root et l'utilisation de socket.io avec NodeJs


SmagYun Démos : node avec socket.io, threejs, p5js, phazer, babylon
SmagYun Démos : node avec socket.io, threejs, p5js, phazer, babylon 






Utiliser les fonctionnalités Arduino depuis une page Web
-> exemple blink dans ide + node

Comment connecter SmagYun sur un réseau Existant Wifi, Ethernet

30/07/2016

03/04/2016

Convertir sqlite, xls ou ods en RDF

L'un des buts du graph http://rdf-smag0.rhcloud.com/smag.html est d'interconnecter les bases de données disparates.

Une amie m'indique qu'elle est en train de monter une base de données sur les robots... intéressant, c'est exactement ce qu'il me faut pour mon projet Smag0, et la gestion des ressources, des objets connectes...
Voyons comment l’intégrer au graph RDF :
1 : qui va mettre à jour cette base ? Cette amie ? les constructeurs ? les utilisateurs ???
-> intégrer les données au serveur Fuseki, ou un lien vers la source de données mise à jour ailleurs ?
2 : la source actuelle est un fichier robot.db
 --> comment la transformer au format RDF ? on a deux tables robots et devices
--> j'avais dejà fait des tests pour transformer XLS et ODS en RDF , donc la première idée est d'extraire les deux tables en csv, de les convertir en ods, puis d'adapter l'outil que j'avais déjà utiliser pour repasser au format rdf... --> pas simple
--> autre option a étudier : sql.js https://github.com/kripken/sql.js 


outil d'extraction ODS vers RDF basé sur Processing 2 ( pas testé avec 3) avec :
[Une librairie permettant de gérer les fichiers ODS : https://incubator.apache.org/odftoolkit/downloads.html]
La librairie Jena Apache

26/02/2016

Dreamcatcher V3 integration dans Meteor

in English, at the bottom of this post ;-)

La version hébergée sur Météor n'est plus, préférez la version "Autonome Collaboratif "







Nous en sommes maintenant à la V3 de Dreamcatcher : les plus curieux peuvent déjà y jeter un oeil : http://smag0.meteor.com/

  1.  v1 : http://smag-smag0.rhcloud.com/DreamCatcher/
    1. explications : http://smag0.blogspot.fr/2015/08/dreamcatcher-lattrape-reves.html
    2. Fonctionnalités :
      1. test de la bibliothèque de la bibliothèque traer pour processingjs pour gérer un environnement physique de répulsion, attraction des noeuds, deplacement à la souris, zoom avec les flèches (voir notice/help)
      2. test de drag&drop
      3. test d'integration, export de fichier rdf , n3
      4. sauvegarde de graphe avec touche "s" chargement des données depuis un serveur Fuseki, un sparql endpoint, via une requete sparl ou un service web hebergé ailleurs avec Java/Jena
      5. Creation de sessions pour travailler à plusieurs sur un graphe
    3. utilisationhttp://smag-smag0.rhcloud.com/DreamCatcher/help.html
  2. v2 : http://smag-smag0.rhcloud.com/DreamCatcher1/
    1. explications : http://smag0.blogspot.fr/2015/12/dreamcatcher-ou-comment-partager-des.html
    2. Fonctionnalités : une evolution de la V1, avec prise en charge de la 3D, grâce à P5JS, test égalment avec three.js 
    3. utilisation
      1. cliquer sur "charger Demo" puis sur afficher texte
      2. les curseurs permettent de zoomer, déplacer la caméra
  3. v3 ; http://smag0.meteor.com/
    1. explications : http://smag0.blogspot.fr/2016/02/dreamcatcher-v3-integration-dans-meteor.html
    2. besoin; besoin d'une identification, authentification pour partager, donner des droits sur les graphes, les sessions
    3. dépôt github : https://github.com/scenaristeur/dreamcatcher-smag0
    4. utilisation
      1. en arrivant sur la page d'accueil, on peut s'authentifier, ou créer son compte, 
      2. ensuite on peut créer un post ou participer aux post existants
        1. creer un post : rien de plus simple (attention aux lien, s'il existe déjà, ça empeche de créer le post)
        2. ajouter un triplet ou statement à un post existant, en insérant un sujet, une propriete, et un objet, et en validant. ce triplet/statement devrait s'insérer dans le graphe en haut de page . si aucun graphe n'apparait : revenez sur la page d'accueil, puis actualisez, ( tous les fichiers ne semblent pas encore chargés si on atterit directement sur un post)



version anglaise : 

Dreamcatcher V3 integration in Meteor
We are now in V3 Dreamcatcher: the curious can already have a look: http://smag0.meteor.com/

 v1: http://smag-smag0.rhcloud.com/DreamCatcher/
explanations http://smag0.blogspot.fr/2015/08/dreamcatcher-lattrape-reves.html
features:
test library for the library traer processing.js to manage a physical environment repulsion, attraction knots, displacement mouse, zoom with the mouse (see manual / help)
drag & drop test
integration testing, rdf file export, n3
Backup graph with "s" key data loading from a Fuseki server, endpoint sparql, via a request sparl or a hosted web service elsewhere with Java / Jena
Creation of sessions to work together on a graph
Use: http://smag-smag0.rhcloud.com/DreamCatcher/help.html
v2: http://smag-smag0.rhcloud.com/DreamCatcher1/
explanations http://smag0.blogspot.fr/2015/12/dreamcatcher-ou-comment-partager-des.html
Features: an evolution of the V1, with support of 3D, thanks to P5JS, égalment test Three.js
use :
click "Load Demo" and then display text
sliders allow you to zoom, move the camera
v3; http://smag0.meteor.com/
explanations http://smag0.blogspot.fr/2016/02/dreamcatcher-v3-integration-dans-meteor.html
need; require identification, authentication to share, give rights on graphs, sessions
use :
arriving on the home page, you can authenticate or create an account,
then you can create a post or participate in existing post
create a post: nothing simpler (watch link, if it exists, it prevents creating the post)
add a triplet or statement to an existing post, inserting a subject, a property and an object, and validating. this triplet / statement should be part of the graph to the top. if no graph will appear: return to the home page and then refresh, (all files do not yet appear directly responsible if it lands on a post)

19/02/2016

La halle Girard un lieu pour la Lyon French






Bonjour à tous !

Vous le savez sans doute en ayant suivi les activités de notre collectif OpenARA, nous allons répondre à l’appel d’offre de la Halle Girard (http://www.marchesonline.com/appels-offres/avis/concession-de-service-relative-a-la-gestion-et-l-anima/ao-6844828-1)

Qu’est ce que c’est ?

Il s’agit de la concession de service relative à la gestion et l'animation du bâtiment Totem de la French Tech de Lyon.

Le progrès de Lyon résume ainsi : « Dès 2017, un petit bout du monde, très agité, des technologies nouvelles. Ici se réalisera en effet, « le futur lieu Totem de la French Tech » et « la véritable vitrine de la filière numérique lyonnaise ».

Le réseau OpenARA, c’est à dire nous tous (!), avons décidé de tenter notre chance en répondant à cet appel d’offre. Ce n’est pas tout OpenARA qui répond, conformément à nos principes depuis le début de cette aventure, c’est tout ceux qui le peuvent et le désirent. Nous respectons les engagements que nous avons pris en commun : toute la construction de ce dossier est ouverte et disponible, chacun d’entre vous est appelé à se manifester et à contribuer au dossier.

Cela peut paraitre un peu complexe de prime abord, mais ...

NOUS AVONS BESOIN DE LA CONTRIBUTION DE CHACUN AU DOSSIER POUR POUVOIR RÉPONDRE DANS LES DÉLAIS

soit ... le 4 mars !

Les liens utiles
- vers le Drive Totem:
https://drive.google.com/folderview?id=0B2mWkS5A4S81LXMyX2NUNFVtX1U&usp=sharing

- vers le Hackpad Totem pour le suivi de l’avancement :
https://hackpad.com/Btiment-Totem-qad0kuO3nTS

- Recrutement des membres du consortium avant le 20 Février, à chacun de nous d'indiquer dans ce tableur qui il va contacter (cette liste permet l'ajout d'autres "prospects", si vous en sentez l'opportunité)
https://docs.google.com/spreadsheets/d/1Pgm3jQ7wv63B_XLsJAkveKo6FVPp3XWRk31rXKirLaQ/edit?usp=sharing

Le forum slack d’OpenARA :
Pour mémoire, chacun est invité également à participer aux discussions sur
https://openara.slack.com
(ouvert à tous sur simple demande par mail à l’un des membres à moi par exemple)

Il s'agit d'une occasion rare de se réapproprier un système et d'en faire quelque chose de sympa et d’utile pour tous.

Merci de faire passer ces éléments à toutes les personnes et organisations capables de contribuer à une réponse collective rapide ! N’hésitez pas à contribuer vous-même.

Tous les membres du réseau peuvent répondre à vos questions ou pour tout point et coordination.

Quelques contacts :
Benjamin CHOW PETIT : benjaminchowpetit@gmail.com ou06.95.07.00.51
Pierre AUMONT : pierre.aumont@gmail.com ou 06 68 38 46 03
RIEUL TECHER : rieul.techer@gmail.com

A bientôt dans les documents !
Pierre, Benjamin, Connie, Rieul, Rémy, Kévin, Virgil, Emmanuel, Stéphane, Xavier, Adrien, Samuel, Nicolas etc ...


07/01/2016

un nouveau script pour installer le pcduinobot




Le pcduinobot est un rover wifi à base de pcduino, comme décrit à maintes reprises sur ce blog.







L'installation automatisée des fonctionnalités utiles est maintenant disponible via un script bash disponible ici : https://drive.google.com/file/d/0B0zEK4yLB5C6bGxWb0YxUnNtZFU/view?usp=sharing
EDIT : des pbs de droits que je n'ai pas encore résolu : lancez le script 2 fois : 1fois en utilisateur ubuntu et une fois en root... + pb pour récupérer la librairie pyduino, voir à passer tout le bouzin sous nodejs

que fait ce script ? il reprend la procédure d'installation décrite ici : http://smag0.blogspot.fr/2015/12/reinstallation-pcduino.html

11/11/2015

Sphero-Carto

Le but de cet article est de proposer une utilisation du robot Sphero d'Orbotix pour établir la cartographie d'un environnement.
le code est disponible là : https://drive.google.com/file/d/0B0zEK4yLB5C6TUhLc0FRbVVKMVU/view?usp=sharing

En effet dans le projet Smag0, et d'après les trucs que j'ai pu lire un peu partout (SMA Ferber...), un robot/agent autonome se doit d'avoir une représentation de son environnement. J'avais donc envisagé il y a longtemps, d'utiliser le robot Sphero afin d'établir une cartographie de l'environnement en le faisant se balader dans l'environnement, en récupérant ses coordonnées, et en notant les points de collision. Cela pourrait permettre, par exemple à déterminer si une pièce est rangée et s'il faut envoyer d'autres robots autonomes pour la ranger.

Exemple d'application au projet Smag0 : Sphero établit une cartographie un jour où la chambre est rangée et la stocke comme étant la cartographie de référence avec points de collision pour les pieds de meubles, et autres objets. Lorsque les jours suivants, Sphero repasse, on compare les deux cartographies, si les points de collision se sont déplacés : les objets ont bougé, et il faut envisager de les ranger, ou déterminer si leur nouvelle position est respectable.

Après cette brève introduction, passons au fourneau :


LA RECETTE DU SPHERO-CARTO.
Ingrédients :
- 1 script sphero.js permettant d'accéder au fonctionnalités du robot Sphéro : https://github.com/orbotix/sphero.js  (les fonctionnalités sont là : https://github.com/orbotix/sphero.js/blob/master/lib/devices/sphero.js )
- 1 serveur node.js
- quelques workers JS...


"C'est dans les vieux pots qu'on fait la meilleure soupe"
Pensons maintenant notre appli comme un système multi-agents, comme des programmes autonomes qui communiquent entre eux, nous aurons par exemple :
- un module (ou worker en javascript) qui s'occupera du serveur de fichier,
- un autre de la gestion des commandes du robot sphero,
- un autre de l'interface visuelle,
- un autre s'occupera de la conception de la carte,
- on pourra en trouver un qui se chargera du stockage de l'information,
- un déterminera l'algorithme à utiliser pour une meilleure exploration de l'environnement...
- ... (on pourra en ajouter d'autre selon le besoin et les fonctionnalités envisagées)


Le serveur de fichier : 
Commençons par installer nodejs si ce n'est pas encore fait, puis installez le module sphero : "$ npm install sphero" comme préconisé ici https://github.com/orbotix/sphero.js

le module socket.io et le module keypress "npm install socket.io",  `npm install keypress`

Ensuite, je me suis basé sur le tutoriel du nouveau site P5.js pour l'interaction entre le serveur node.js et le module d'affichage p5.js : http://p5js.org/tutorials/ ou https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io

Choix a faire : Socket ? worker ?

code  de base du serveur serveur.js , à lancer avec la commande : node serveur.js


// http://smag0.blogspot.fr/2015/11/sphero-carto.html
// HTTP Portion
var http = require('http');
// URL module
var url = require('url');
var path = require('path');
// Using the filesystem module
var fs = require('fs');
// make sure you install this first - `npm install keypress`
var keypress = require("keypress");
var server = http.createServer(handleRequest);
server.listen(8080);
console.log('Server started on port 8080');
//SPHERO
var sphero = require("sphero");
var orb = sphero("COM3");
var stop = orb.roll.bind(orb, 0, 0),
  roll = orb.roll.bind(orb, 150);
var detectionCollisionInterval; //interval pour la detection de collision
var collisionBool=0;
var xSphero,ySphero=0;
var direction=0;
function handleRequest(req, res) {
  // What did we request?
  var pathname = req.url;
  // If blank let's ask for index.html
  if (pathname == '/') {
    pathname = '/index.html';
  }
  // Ok what's our file extension
  var ext = path.extname(pathname);
  // Map extension to file type
  var typeExt = {
    '.html': 'text/html',
    '.js': 'text/javascript',
    '.css': 'text/css'
  };
  // What is it?  Default to plain text
  var contentType = typeExt[ext] || 'text/plain';
  // User file system module
  fs.readFile(__dirname + pathname,
    // Callback function for reading
    function(err, data) {
      // if there is an error
      if (err) {
        res.writeHead(500);
        return res.end('Error loading ' + pathname);
      }
      // Otherwise, send the data, the contents of the file
      res.writeHead(200, {
        'Content-Type': contentType
      });
      res.end(data);
    }
  );
}
// WebSocket Portion
// WebSockets work with the HTTP server
var io = require('socket.io').listen(server);
var socketA;
// Register a callback function to run when we have an individual connection
// This is run for each individual user that connects
io.sockets.on('connection',
  // We are given a websocket object in our function
  function(socket) {
    console.log("We have a new client: " + socket.id);
socketA=socket;
    // When this user emits, client side: socket.emit('otherevent',some data);
    socket.on('mouse',
      function(data) {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'mouse' " + data.x + " " + data.y);
        // Send it to all other clients
        socket.broadcast.emit('mouse', data);
        // This is a way to send to everyone including sender
        // io.sockets.emit('message', "this goes to everyone");
      }
    );
    socket.on('color',
      function(data) {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'color' " + data.r + " " + data.g + " " + data.b);
        orb.color({
          red: data.r,
          green: data.g,
          blue: data.b
        });
        // Send it to all other clients
        // socket.broadcast.emit('mouse', data);
        // This is a way to send to everyone including sender
        // io.sockets.emit('message', "this goes to everyone");
      }
    );
    socket.on('start',
      function() {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'start' ");
        start();
      }
    );
    socket.on('stop',
      function() {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'stop' ");
        clearInterval(detectionCollisionInterval);
        orb.roll(0, 0);
      }
    );
    socket.on('startCalib',
      function() {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'startCalib' ");
        console.log("::START CALIBRATION::");
        orb.startCalibration();
      }
    );
    socket.on('stopCalib',
      function() {
        // Data comes in as whatever was sent, including objects
        console.log("Received: 'stopCalib' ");
        initialiseLocator();
        console.log("::FINISH CALIBRATION::");
        orb.finishCalibration();
      }
    );
    socket.on('disconnect', function() {
      console.log("Client has disconnected");
    });
  }
);
////////////////////////////////
// SPHERO
////////////////////////////////
orb.connect(function() {
  listen();
  orb.color("green");
  //option configurelocator
  initialiseLocator();
  orb.getBluetoothInfo(function(err, data) {
    console.log("bluetooth info fetched");
    if (err) {
      console.error("err:", err);
    }
    console.log("data:", data);
  });
   orb.detectCollisions();
  // orb.streamVelocity();
  // orb.streamGyroscope();
  var opts = {
    n: 200,
    m: 1,
    mask1: 0x00000000,
    pcnt: 0,
    mask2: 0x0D800000
  };
  orb.setDataStreaming(opts);
  orb.on("velocity", function(data) {
    console.log("::STREAMING VELOCITY::");
    console.log("  data:", data);
  });
  orb.on("dataStreaming", function(data) {
    //console.log("streaming data packet recieved");
 //  console.log("  data:", data);
 xSphero=data.xOdometer.value;
 ySphero=data.yOdometer.value*-1;
 collisionBool=0;
    console.log(data.xOdometer.value+" "+data.yOdometer.value);
 var dataToSend = {
    x: xSphero,
    y: ySphero,
z: collisionBool // 0 car pas de collision
  };
 socketEmit("position", dataToSend);
  });
  orb.on("gyroscope", function(data) {
    console.log("::STREAMING GYROSCOPE::");
    console.log("  data:", data);
  });
  orb.on("collision", function(data) {
    console.log("collision detected");
   // console.log("  data:", data);
    orb.color("red");
    collisionBool=1;
 var dataToSend = {
    x: xSphero,
    y: ySphero,
z: collisionBool // 0 car pas de collision
  };
 socketEmit("position", dataToSend);
    setTimeout(function() {
      orb.color("green");
   collisionBool=0;
    }, 1000);
  });
});
function socketEmit(entete , data){
if(socketA!=null){
socketA.emit(entete, data);
}
};
function start() {/*
orb.roll(200, direction);
//Determinons les premieres limites
//limite haute
while(collisionBool==0){
setInterval(function() {
orb.roll(200, direction);
}, 2000);
}
direction=direction*-1; //demi-tour
//limite basse
while(collisionBool==0){
setInterval(function() {
orb.roll(200, direction);
}, 2000); 
}
*/
if(collisionBool==0){
detectionCollisionInterval =setInterval(function() {
   //direction = Math.floor(Math.random() * 360);
    orb.roll(150, direction);
  }, 2000);
}else{
console.log("collision ne peut avancer");
direction = Math.floor(Math.random() * 360);
}
  // roll orb in a random direction, changing direction every second
 /* detectionCollisionInterval = setInterval(function() {
    var direction = Math.floor(Math.random() * 360);
    orb.roll(100, direction);
    //  readLocator()
  }, 2000);*/
};
function initialiseLocator() {
  var opts = {
    flags: 0x01,
    x: 0x0000,
    y: 0x0000,
    yawTare: 0x0
  };
  orb.configureLocator(opts, function(err, data) {
    console.log(err || "CONFIGURE LOCATOR data: " + data);
  });
  orb.setHeading(0, function(err, data) {
      console.log(err || "Heading réglé sur 0: " + data);
    });
direction=0;
};
function readLocator() {
  orb.readLocator(function(err, data) {
    if (err) {
      console.log("error: ", err);
    } else {
      console.log("dataLocator:");
      console.log("  xpos:", data.xpos);
      console.log("  ypos:", data.ypos);
      console.log("  xvel:", data.xvel);
      console.log("  yvel:", data.yvel);
      console.log("  sog:", data.sog);
      console.log(data);
      console.log(data[0]);
      console.log("");
    }
  });
};
function handle(ch, key) {
  var stop = orb.roll.bind(orb, 0, 0),
    roll = orb.roll.bind(orb, 60);
  if (key.ctrl && key.name === "c") {
    process.stdin.pause();
    process.exit();
  }
  if (key.name === "e") {
    orb.startCalibration();
  }
  if (key.name === "q") {
    orb.finishCalibration();
  }
  if (key.name === "up") {
    roll(0);
  }
  if (key.name === "down") {
    roll(180);
  }
  if (key.name === "left") {
    roll(270);
  }
  if (key.name === "right") {
    roll(90);
  }
  if (key.name === "space") {
    stop();
    clearInterval(detectionCollisionInterval);
  }
}
function listen() {
  keypress(process.stdin);
  process.stdin.on("keypress", handle);
  console.log("starting to listen for arrow key presses");
  process.stdin.setRawMode(true);
  process.stdin.resume();
}


fichier sketch.js

//les exemples pour SPHERO : https://github.com/orbotix/sphero.js/blob/master/examples/
//https://github.com/orbotix/sphero.js

/*
 * @name Slider
 * @description You will need to include the 
 * <a href="http://p5js.org/reference/#/libraries/p5.dom">p5.dom library</a>
 * for this example to work in your own project.<br><br>
 * Move the sliders to control the R, G, B values of the background.
 */
var rSlider, gSlider, bSlider,speedSlider;
var myDiv0;
var rougeDiv;
var vertDiv;
var bleuDiv;
// Keep track of our socket connection
var socket;
var xSphero, ySphero;
var positionsSphero = [];
var positionSphero;

function setup() {
  // create canvas
  createCanvas(windowWidth, windowHeight);
  background(0);
  positionSphero = createVector(0, 0, 0);
  // Start a socket connection to the server
  // Some day we would run this server somewhere else
  socket = io.connect('http://localhost:8080');
  // We make a named event called 'mouse' and write an
  // anonymous callback function
  socket.on('mouse',
    // When we receive data
    function(data) {
      console.log("Got: " + data.x + " " + data.y);
      // Draw a blue circle
      fill(0, 0, 255);
      noStroke();
      ellipse(data.x, data.y, 80, 80);
    }
  );

  socket.on('position',
    // When we receive data
    function(data) {
      console.log("Position: " + data.x + " " + data.y + " " + data.z);
      // Draw a blue circle
      // fill(100, 100, 255);
      // noStroke();
      // ellipse(data.x, data.y, 10, 10);
      xSphero = data.x;
      ySphero = data.y;
      collision = data.z;
      positionSphero = createVector(xSphero, ySphero, collision);
      append(positionsSphero, positionSphero);
    }
  );

  textSize(15)
  noStroke();

  // create sliders
  rSlider = createSlider(0, 255, 255);
  rSlider.position(720, 20);
  gSlider = createSlider(0, 255, 230);
  gSlider.position(720, 50);
  bSlider = createSlider(0, 255, 107);
  bSlider.position(720, 80);
  speedSlider= createSlider(0, 255, 66);
  speedSlider.position(720, 110);

  //boutons
  button = createButton('start Calibration');
  button.position(20, 120);
  button.mousePressed(startCalib);
  button = createButton('stop Calibration');
  button.position(150, 120);
  button.mousePressed(stopCalib);
  button = createButton('start');
  button.position(20, 150);
  button.mousePressed(start);
  button = createButton('stop');
  button.position(100, 150);
  button.mousePressed(stop);
    button = createButton('clear');
  button.position(180, 150);
  button.mousePressed(clear);

  //affiche
  rougeDiv = document.getElementById("rouge");
  vertDiv = document.getElementById("vert");
  bleuDiv = document.getElementById("bleu");
  xDiv = document.getElementById("positionX");
  yDiv = document.getElementById("positionY");
}

function draw() {
  var r = rSlider.value();
  var g = gSlider.value();
  var b = bSlider.value();
  var speed=speedSlider.value();
  background(r, g, b);
  text("red", 800, 20);
  text("green", 800, 50);
  text("blue", 800, 80);
   text("speed", 800, 110);
   
  // console.log(r, g, b);
  if ((r != rougeDiv.innerHTML) || (g != vertDiv.innerHTML) || (b != bleuDiv.innerHTML)) {
    rougeDiv.innerHTML = r;
    vertDiv.innerHTML = g;
    bleuDiv.innerHTML = b;
    sendRGB(r, g, b);
  }
  xDiv.innerHTML = xSphero;
  yDiv.innerHTML = ySphero;
  translate(width / 2, height / 2);
  fill(0);
  ellipse(xSphero, ySphero, 10, 10);
  for (i in positionsSphero) {
    var position = positionsSphero[i];
    if (position.z == 0) {
      fill(0, 255, 0);
    } else {
      fill(255, 0, 0);
    }
    ellipse(position.x, position.y, 3, 3);
  }
}


function start() {
  console.log("start p5");
  socket.emit('start', null);
}

function stop() {
  console.log("stop p5");
  socket.emit('stop', null);
}

function clear() {
  console.log("clear");
  positionsSphero = [];
  positionSphero = createVector(0, 0, 0);
 // socket.emit('clear', null);
}

function startCalib() {
  console.log("start calib");
  socket.emit('startCalib', null);
}

function stopCalib() {
  console.log("stop calib");
  socket.emit('stopCalib', null);
}


/*
function mouseDragged() {
  // Draw some white circles
  fill(255);
  noStroke();
  ellipse(mouseX, mouseY, 80, 80);
  // Send the mouse coordinates
  sendmouse(mouseX, mouseY);
}*/
//ENVOI de la couleur
function sendRGB(r, g, b) {
  // Make a little object with rgb 
  var data = {
    r: r,
    g: g,
    b: b
  };
  // Send that object to the socket
  socket.emit('color', data);
}
// Function for sending to the socket
function sendmouse(xpos, ypos) {
  // We are sending!
  console.log("sendmouse: " + xpos + " " + ypos);

  // Make a little object with  and y
  var data = {
    x: xpos,
    y: ypos
  };

  // Send that object to the socket
  socket.emit('mouse', data);
}



fichier index.html

 <!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Sphero</title>
    <script src="libraries/p5.js" type="text/javascript"></script>

    <script src="libraries/p5.dom.js" type="text/javascript"></script>
    <script src="libraries/p5.sound.js" type="text/javascript"></script>

    <style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style>

   <!-- <script language="javascript" type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.9/p5.min.js"></script>-->
    <script language="javascript" type="text/javascript" src="sketch.js"></script>
    <script language="javascript" type="text/javascript" src="/socket.io/socket.io.js"></script>
  </head>
  <body>
  <!-- <div id="connected" style="width:100px;height:100px">not connected</div> -->
  <div id="rouge">r</div>
  <div id="vert">b</div>
  <div id="bleu">v</div>
  <div id="positionX">X</div>
   <div id="positionY">Y</div>
  </body>
</html>

le code est disponible là : https://drive.google.com/file/d/0B0zEK4yLB5C6TUhLc0FRbVVKMVU/view?usp=sharing


Pour la gestion des webworkers avec nodejs : npm install webworker