Difference between revisions of "Projets:Perso:2016:Lepton Websocket"

From Electrolab
Jump to: navigation, search
(Module camera FLIR Lepton)
(Remarques finales)
Line 71: Line 71:
 
== Remarques finales ==
 
== Remarques finales ==
  
TODO : fonctionnement du soft, navigateurs compatibles, rescaling, changement de port
+
=== Fonctionnement du software ===
 +
 
 +
Voici une petite description de la manière dont j'ai codé le software serveur.
 +
 
 +
Le software est composé de deux parties :
 +
* une clase ''lepton'' qui lit en permanence les images de la caméra
 +
* un serveur web qui fournit une interface et envoie les images au navigateur.
 +
 
 +
La classe ''lepton'' lit en permanence une nouvelle image à travers le port SPI, dans un thread séparé pour ne pas bloquer le reste du programme. L'image est encodée en niveaux de gris avec 2 octets par pixel. Deux buffers alloués au lancement du programme sont utilisés pour stocker l'image et sont pointés par deux pointeurs A et B. Chaque nouvelle image est lue dans A puis, lorsqu'elle est disponible, les pointeurs A et B sont intervertis et un compteur indiquant le numéro de l'image disponible est incrémenté, le tout atomiquement. B est maintenant disponible à la lecture tandis qu'une nouvelle image commence à être lue dans A. Ce système permet de ne jamais faire de copies mémoire ni d'allocations dynamiques, et maximise les performances. Enfin, une méthode ''grab_image'' permet à n'importe quel autre thread de lire la dernière image disponible. Cette méthode prend aussi en paramètre le numéro de la dernière image que ce thread a obtenue et dispose d'un système de ''condition_variable'' pour attendre que la prochaine image soit disponible et de ne pas lire plusieurs fois la même.
 +
 
 +
Le serveur web écoute par défaut sur le port 80 du raspberry et fournit une interface HTTP qui affiche une page web contenue dans le fichier ''resp.html''. Cette page est écrite en HTML5/javascript et s'affiche dans le navigateur du client. Le code javascript de la page demande alors au navigateur de se connecter au serveur du raspberry pi à travers le protocole ''websocket'' et garde la connexion ouverte, la rouvrant si elle se perd. Le serveur détecte cette demande, ouvre une connexion upgradée ''websocket'' et attend de recevoir un paquet. Le client javascript envoie alors le numéro de la dernière image qu'il a reçue (0 si c'est la première). Le serveur reçoit ce numéro et appelle ''lepton.grab_image'' qui attend qu'une image différente soit disponible et la renvoie en données binaires brutes avec son numéro. Le client javascript reçoit l'image, détecte l'intensité maximale et minimale des pixels, ramène cette échelle de 0 à 255 pour former une image en niveaux de gris qu'elle agrandit et affiche sur un contexte de dessin ''canvas'' dans le navigateur. Ensuite, le client javascript renvoie le numéro de l'image obtenue pour demander l'image suivante, et la procédure recommence. Cette procédure réduit un peu le débit d'images mais permet au serveur de ne maintenir aucune information d'état sur le client (on parle de service web RESTful), ce qui simplifie la mise en ouevre et augmente les performances du raspberry. L'affichage est d'environ 10 images par seconde en bonnes conditions de connexion. Pour minimiser la latence, je désactive le buffering du serveur websocket avec ''WebSocket.setNoDelay(true)''.
 +
 
 +
Le serveur est codé en C++11, et utilise la librairie ''poco C++'' pour gérer les connexions HTTP/Websocket. Enfin, comme la page HTML5 utilise des technologies web récentes, un navigateur à jour est nécessaire pour la visualiser (évitez Internet Explorer).
 +
 
 +
=== Fonctionnement du software ===
 +
 
 +
TODO : rescaling, changement de port
  
 
TODO : mesure temperature
 
TODO : mesure temperature

Revision as of 12:31, 12 March 2016

Lepton Websocket
Auteur Damip
Tags du projet html5, javascript, websocket, flir, lepton, thermique, web, stream, raspberry
Utilisateur final Les gens hot
Type de projet

Projet personnel de Damip

Projet Lepton Websocket

Serveur web pour Raspberry Pi qui affiche en direct l'image provenant d'un module camera thermique FLIR Lepton.




Streaming web pour caméra thermique FLIR Lepton sur Raspberry Pi

Les caméras thermiques FLIR Lepton sont relativement peu chères (150€) et se branchent directement sur Raspberry Pi. Je présente ici un serveur que j'ai codé, qui tourne sur Raspberry, et qui permet de visualiser l'image thermique en direct depuis le réseau, et ce en n'utilisant qu'un simple navigateur web.

Module camera FLIR Lepton

TODO principe : corps noir, temperature / emissivite, microbolometres, shutter , angle de vue

Leptonmodule.jpg

Branchement au Raspberry Pi

Attention : le module Lepton est sensible aux décharges électrostatiques. Manipulez-le avec précaution.

Le module comporte 10 pins : CS, MOSI, MISO, CLK, GND, VIN, SDA, SCL. Les pins CS, MOSI, MISO et CLK correspondent à une interface SPI à travers laquelle sont transmises les images. VIN est l'alimentation du module. À connecter à 3.3V. GND est la masse. SDA et SCL sont correspondent à une interface I2C qui permet de lire des propriétés du module, et d'en contrôler certaines fonctions. L'interface I2C est optionnelle car la camera envoie déjà par défaut les images avec des paramètres préconfigurés sur le port SPI.

Pour raccorder le module au Raspberry Pi, suivez ce schéma :Leptonpipinout.png

Une fois branché ça ressemble à ça :

Leptonetpi.jpg


Configuration du Raspberry Pi

Il faut à présent activer le port SPI, et optionnellement le port I2C sur le raspberry que je suppose tourner sous Raspbian. Sur le raspberry, exécutez la commande suivante :

sudo raspi-config
  • allez dans Advanced Options puis SPI
  • suivez les instructions et activez le chargement du module SPI au démarrage
  • si vous avez branché l'I2C, il faut aussi activer son module de la même manière
  • quittez ensuite raspi-config en cliquant sur <Finish>. Acceptez le redémarrage.

Installation du software

TODO requirements : gcc avec C++11, libpoco new version, pthread


TODO uploader code

Visualisation

Pour regarder la caméra en stream temps réel, il vous suffit alors d'aller sur http://[ip du raspberry] avec votre navigateur depuis n'importe quel ordi pouvant se connecter à votre raspberry.

Le résultat ressemble à ceci, mais en live avec une fréquence de rafraichissement d'environ 10Hz :

Imgirlepton.png

Remarques finales

Fonctionnement du software

Voici une petite description de la manière dont j'ai codé le software serveur.

Le software est composé de deux parties :

  • une clase lepton qui lit en permanence les images de la caméra
  • un serveur web qui fournit une interface et envoie les images au navigateur.

La classe lepton lit en permanence une nouvelle image à travers le port SPI, dans un thread séparé pour ne pas bloquer le reste du programme. L'image est encodée en niveaux de gris avec 2 octets par pixel. Deux buffers alloués au lancement du programme sont utilisés pour stocker l'image et sont pointés par deux pointeurs A et B. Chaque nouvelle image est lue dans A puis, lorsqu'elle est disponible, les pointeurs A et B sont intervertis et un compteur indiquant le numéro de l'image disponible est incrémenté, le tout atomiquement. B est maintenant disponible à la lecture tandis qu'une nouvelle image commence à être lue dans A. Ce système permet de ne jamais faire de copies mémoire ni d'allocations dynamiques, et maximise les performances. Enfin, une méthode grab_image permet à n'importe quel autre thread de lire la dernière image disponible. Cette méthode prend aussi en paramètre le numéro de la dernière image que ce thread a obtenue et dispose d'un système de condition_variable pour attendre que la prochaine image soit disponible et de ne pas lire plusieurs fois la même.

Le serveur web écoute par défaut sur le port 80 du raspberry et fournit une interface HTTP qui affiche une page web contenue dans le fichier resp.html. Cette page est écrite en HTML5/javascript et s'affiche dans le navigateur du client. Le code javascript de la page demande alors au navigateur de se connecter au serveur du raspberry pi à travers le protocole websocket et garde la connexion ouverte, la rouvrant si elle se perd. Le serveur détecte cette demande, ouvre une connexion upgradée websocket et attend de recevoir un paquet. Le client javascript envoie alors le numéro de la dernière image qu'il a reçue (0 si c'est la première). Le serveur reçoit ce numéro et appelle lepton.grab_image qui attend qu'une image différente soit disponible et la renvoie en données binaires brutes avec son numéro. Le client javascript reçoit l'image, détecte l'intensité maximale et minimale des pixels, ramène cette échelle de 0 à 255 pour former une image en niveaux de gris qu'elle agrandit et affiche sur un contexte de dessin canvas dans le navigateur. Ensuite, le client javascript renvoie le numéro de l'image obtenue pour demander l'image suivante, et la procédure recommence. Cette procédure réduit un peu le débit d'images mais permet au serveur de ne maintenir aucune information d'état sur le client (on parle de service web RESTful), ce qui simplifie la mise en ouevre et augmente les performances du raspberry. L'affichage est d'environ 10 images par seconde en bonnes conditions de connexion. Pour minimiser la latence, je désactive le buffering du serveur websocket avec WebSocket.setNoDelay(true).

Le serveur est codé en C++11, et utilise la librairie poco C++ pour gérer les connexions HTTP/Websocket. Enfin, comme la page HTML5 utilise des technologies web récentes, un navigateur à jour est nécessaire pour la visualiser (évitez Internet Explorer).

Fonctionnement du software

TODO : rescaling, changement de port

TODO : mesure temperature