IoT et interface naturelle (2) : réalité augmentée

Dans mon précédent article, j'ai présenté un type d'interface naturelle basée sur l'assistant vocal de Google.

Cette fois, nous allons explorer les possibilités de la réalité augmentée! Avant de commencer, une petite démonstration :

Comme vous pouvez le constater, le but est de récupérer en temps réel les données émises par un objet connecté (la poubelle), pour les afficher en réalité augmentée lors de son survol, avec n'importe quel type de terminal (smartphone, tablette...).

AR.js

L'interface en réalité augmentée est réalisée à partir du framework AR.js. Son intérêt principal est de s'appuyer sur les technos web (HTML, Javascript) et donc d'être utilisable sur toutes les plateformes. Voici un exemple de page web utilisée dans la démonstration précédente :


&html*
 &head*
  &title*ARjs&/title*
  &script src="https://aframe.io/releases/0.8.0/aframe.min.js"*&/script*
  &script src="https://rawgit.com/donmccurdy/aframe-extras/master/dist/aframe-extras.loaders.min.js"*&/script*
  &script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js"*&/script*
  &script*
   /*AFRAME.registerComponent('cursor-listener', {
     init: function () {
    this.el.addEventListener('click', function (evt) {
      // alert('click');
    });
     }
   });
   // https://stackoverflow.com/questions/47032056/gltf-cursor-listener-click-event-in-a-frame
   AFRAME.registerComponent('raycaster-autorefresh', {
     init: function () {
    var el = this.el;
    this.el.addEventListener('model-loaded', function () {
      var cursorEl = el.querySelector('[raycaster]');
      cursorEl.components.raycaster.refreshObjects();
    });
     }
   });*/
  &/script*
 &/head*

 &body style='margin : 0px; overflow: hidden;'*
  &a-scene arjs="debugUIEnabled: false;"*
   &a-assets*
    &img id="full" src="img/full.png"/*
    &img id="empty" src="img/empty.png"/*
    &img id="medium" src="img/medium.png"/*
    &img id="low" src="img/low.png"/*
    &img id="recycle" src="img/recycle.png"/*
   &/a-assets*
   &!-- handle marker with hiro preset --*
   &!--&a-marker preset="hiro"*--*
   &a-marker-camera preset="custom" type='pattern' url='data/can-marker.patt'*
    &!--&a-image id="levelIndicator" src="#empty"  width="3" height="2" position="-2 2 0"*&/a-image*--*
    &a-text value="Fill level" position="0 2.6 0" width="10" anchor="left" color="#00BFFF"*&/a-text*
    &a-text test-counter font="exo2bold" id="fillLevel" value="0 %" position="0 2.1 0" width="15" anchor="left" color="#00BFFF"*&/a-text*
    &a-image src="#recycle"  width="1" height="1" position="-1.5 -2 0"*&/a-image*
    &a-text value="Next interv." position="-0.9 -1.6 0" width="10" anchor="left" color="#00BFFF"*&/a-text*
    &a-text id="date" font="exo2bold" value="01 Jan 2018" position="-0.9 -2.4 0" width="20" anchor="left" color="#00BFFF"*&/a-text*
    &a-entity position="-1.5 2 0"*
     &a-entity id="threeDcan" gltf-model="url(obj/trash.gltf);" position="0 0 0" cursor-listener*&/a-entity*
     &a-animation attribute="rotation"
        dur="4000"
        fill="forwards"
        to="0 360 0"
        repeat="indefinite"*&/a-animation*
     &a-animation begin="click" attribute="position" to="-1 2 0"
      easing="linear" dur="50" fill="backwards" repeat="10"*&/a-animation*
    &/a-entity*
   &/a-marker-camera*
   &!--&a-camera*
    &a-cursor*&/a-cursor*
   &/a-camera*--*
   &a-entity light="type: ambient; color: #FFF; intensity: 5;"*&/a-entity*
  &/a-scene*
  &script*
   ...
   document.querySelector('a-scene').querySelector('#date').setAttribute('value', getDate(daysCount));
   ...
  &/script*
 &/body*
&/html*

PS : pour des raisons de compatibilité, j'ai du remplacer dans cet extrait les '<' par '&' et '>' par '*'.

En détails

Quelques précisions sur le fonctionnement de cette démonstration :

  • Utilisation d'un tag personnalisé : le tag basique Hiro (utilisé par défaut par AR.js pour reconnaître la scène) a été remplacé par un tag personnalisé, via la balise : a-marker-camera preset="custom" type='pattern' url='data/can-marker.patt' et l'outil en ligne Marker Training
  • Intégration de modèle 3D animé : pour permettre l'intégration dans la scène d'un modèle 3D animé, il est nécessaire de se procurer un modèle (au format GLTF, via Sketchfab par ex) et d'intégrer le script aframe-extras.loaders.min.js
  • Gestion de l'éclairage : dès lors que vous ajoutez des modèles dans une scène, il faut commencer à jouer avec les lumières. Ici une lumière d'ambiance général a été mise en place : a-entity light="type: ambient; color: #FFF; intensity: 5;"
  • Manipulation du DOM : c'est ce qui constitue un des points fort du framework AR.js. Vous pouvez utiliser Javascript pour manipuler les éléments de la scène 3D de la même manière que le DOM 2D standard HTML!

Connectivité

Qui dit technos web, dit Javascript : il est donc possible d'utiliser n'importe quel code (par ex websockets) pour vous connecter à la source de données (la plateforme IoT) afin de récupérer toutes les données et créer des interactions avec la réalité augmentée!

Enjoy!


Fichier(s) joint(s) :