Utiliser openrov-cockpit sur Raspberry Pi ?

OpenROV Cockpit Web Interface

Pour éviter de refaire un développement complet et pouvoir bénéficier des développements déjà effectués sur openrov-cockpit qui est en Open Source, j'ai décidé d'étudier la possibilité de réutiliser le logiciel openrov-cockpit sur la Raspberry Pi. Si cela s'avère possible et avec un développement de modules spécifiques pour les modifications d'architecture, cela permettrait de gagner énormément de temps et ainsi éviter de redévelopper une solution "from scratch"

Récupération et étude des sources de la solution logicielle openrov-cockpit

OpenROV est une solution complètement OpenSource (Open Software et Open Hardware). Il est donc très facile d'étudier, de récupérer et d'adapter les développements suivant les besoins.

J'ai donc décidé de récupérer une copie des sources d'openrov-cockpit et d'étudier la possibilité de faire les adaptations nécessaires pour rendre le logiciel compatible avec la solution que j'ai retenue. J'ai trouvé une autre personne qui semble avoir tenté de réaliser la même chose il y a un an et a été au bout de l'adaptation. Mais les conditions de tests étaient bien plus proche en terme de matériel (réutilisation de la carte avec l'Arduino) et les problèmes rencontrés semblaient plutôt matériels. Comme de toute façon l'architecture n'est pas la même dans mon cas, cela vaut le coup de tenter et de voir quelles sont les adaptations qui seraient nécessaires (même si les développements et adaptations seront plus nombreux, cela éviterait de vraiment tout redévelopper).

cd
git clone https://github.com/OpenROV/openrov-cockpit.git

openrov-cockpit contient des liens en dur dans le code (on dirait du code de mes étudiants ;) et s'attend donc à trouver openrov-cockpit et Node.js à partir du dossier /opt. Donc il nous faut créer les lien symboliques qui vont nous permettre de rendre le tout fonctionnel.

sudo mkdir -p /opt/openrov
sudo ln -s /home/pi/openrov-cockpit /opt/openrov/cockpit

L'étude des sources montre que l'architecture est 3 tiers: le premier tiers est côté navigateur (client), le deuxième tiers et le côté serveur tournant sur la plate-forme et le troisième tiers est pour la gestion du micro-contrôleur (Arduino pour la gestion des moteurs et capteurs). Si tout fonctionne bien comme prévu, nous pourrons nous passer du troisième tiers pour la gestion des capteurs et actionneurs (et donc de toute la partie logicielle qui va avec), mais nous pourrions réutiliser tout le système de visualisation et de communication entre le client et le serveur, toute la partie graphique et faire des adaptations pour la partie "protocol serializer" pour le contrôle des capteurs et actionneurs (moteurs). Et si jamais cela ne fonctionne pas correctement et que je suis obligé de passer à la même base que OpenROV, j'aurais au moins déjà étudié le code pour pouvoir y apporter les améliorations souhaitées.

Tout le développement est organisé avec un système de plugins avec de grandes possibilités d'activer, désactiver, remplacer, ajouter, enlever ou modifier les plugins existants. Donc cela vaut vraiment le coup de tenter de faire marcher au moins la partie client serveur pour la visualisation.

Cette partie de communication entre le client (un navigateur sur un terminal) et la partie serveur (sur la plate-forme embarquée dans le Rov) est basé sur Node.js et la partie transmission des information vidéos sur l'utilisation de mjpeg-streamer. Nous avons vu dans l'étude sur le vidéo-streaming sur Raspberry Pi que la solution basée sur ffmepg et crtmpserver était beaucoup plus performante. Donc la première étape est d'installer Node.js et de voir si la communication client-serveur fonctionne bien plus de réaliser les adaptations nécessaires pour passer de mjpeg-streamer à ffmpeg-crtmpserver.

Installation de Node.js sur Raspberry Pi

Un paquetage Node.js est disponible sur Raspibian, mais celui-ci est obsolète à l'heure où j'écris ces pages (03/01/2015, màj le 05/11/2015). Il est donc préférable d'installer la version qui vous convient.

Installation d'un paquetage Node.js depuis un site tiers

La deuxième solution est d'installer Node.js à partir d'un paquetage fourni par un tiers. Après la mise à jour de cette page, la version de Node.js à installer est 0.12.6 (les versions plus récentes posent soucis sur Raspbian Wheezy). Vous trouverez les distribution de Node.js à l'adresse suivante: https://github.com/nodesource/distributions. Il est aussi nécessaire de faire la mise à jour du compilateur par défaut pour que lors de l'importation de nouveaux paquetages avec du code natif vous n'ayez pas d'erreur (compilation qui s'interrompt avec un "Segmentation fault" de gcc).

curl -sL https://deb.nodesource.com/setup_0.12 | sudo -E bash -
sudo apt-get install -y nodejs
node -v
npm -v

Installer les modules Node.js pour openrov-cockpit

Avant de lancer le service principal qui lance node (le serveur Node.js sur la Raspberry Pi), il est nécessaire d'installer les modules Node.js nécessaire pour openrov-cockpit. Voici donc les instructions pour installer ceux-ci. Vous pouvez à nouveau aller prendre un café...

# Installation de l'exécutable phantomjs qui n'est pas disponible pour ARM dans l'installation automatique
cd
wget https://github.com/piksel/phantomjs-raspberrypi/blob/master/bin/phantomjs?raw=true
mv phantomjs\?raw\=true phantomjs
chmod 755 phantomjs
sudo mv phantomjs /usr/local/bin
# Installation des modules nécessaires à openrov-cockpit pour fonctionner.
#  Vous pouvez maintenant aller prendre un café, il y en a pour un petit moment
export PATH=$PATH:.
cd /opt/openrov/cockpit/src
npm install
cd /opt/openrov/cockpit/src/static
npm install
npm run bower

Configurations pour lancer openrov-cockpit

Le code d'openrov-cockpit n'est pas forcément un exemple de code très bien fait. Il y a non seulement des chemins en dur dans le code, mais il nécessaire aussi des accès à différents chemins et répertoires pour lesquels seulement root a normalement accès. Mais je ne souhaite pas faire tourner le serveur Node.js en tant que super utilisateur (la Raspberry Pi ne sera pas accessible du monde entier, mais ce n'est tout de même pas très joli de faire tourner un serveur en tant que root!).

Voici donc les commandes que j'ai appliqué pour modifier créer les fichiers nécessaires ou les changements de droits nécessaires pour pourvoir lancer openrov-cockpit:

sudo touch /var/log/openrov.log
sudo chown pi:pi /var/log/openrov.log
sudo mkdir /usr/share/cockpit
sudo chown pi:pi /usr/share/cockpit
sudo mkdir -p /var/www/openrov/photos
sudo chown -R www-data:www-data /var/www/openrov
sudo adduser pi tty ; # to access /dev/ttyAMA0
sudo adduser pi www-data ; # to access /var/www

openrov-cockpit utilise la commande cpufreq-set. Il faut donc installer le paquetage cpufrequtils ou commenter ces lignes dans le code. J'ai opté pour cette première solution, dans un premier temps, en installant le paquetage.

sudo apt-get install cpufrequtils

Premier test d'openrov-cockpit avant toute modification

Avant de lancer openrov-cockpit pour la première fois, il est nécessaire de modifier quelques lignes dans le code pour éviter 2 soucis: la recherche de la communication sur un fichier "série" qui n'existe pas sur la Raspberry Pi et supprimer quelques informations envoyées sur la console qui ne toute façon ne fonctionneront pas (communication avec la plate-forme Arduino).

J'ai ainsi appliqué les modifications suivantes au fichier de configuration d'openrov-cockpit (lib/config.js).

'serial': '/dev/ttyAMA0',

Pour éviter de trop nombreux messages dans la console, j'ai aussi désactivé plusieurs messages concernant la communication avec Arduino. Voici les lignes que j'ai commentées dans le fichier lib/OpenROVController.js:

//Every few seconds we check to see if capabilities or settings changes on the Arduino.
//This handles the cases where we have garbled communication or a firmware update of the arduino.
setInterval(function () {
if (controller.notSafeToControl() === false) return;
controller.updateSetting();
controller.requestSettings();
controller.requestCapabilities();
}, 1000);
...
//This feature added after the swap to ms on the Arduino
console.log('Waiting for the capability response from Arduino before sending command.');
console.log('Arduno Version: ' + this.ArduinoFirmwareVersion);
console.log('Capability bitmap: ' + this.Capabilities);

Dans mon cas particulier, j'ai du aussi désactiver les services suivants pour pouvoir lancer Node.js (services en conflit sur l'utilisation du port 8080):

sudo service crtmpserver stop
sudo service lighttpd stop
sudo service videostream stop

Il ne reste plus qu'à tenter de lancer le service pour voir si cela fonctionne. Deux méthodes sont disponibles: (1) démarrer Node.js en temps que service ou bien (2) en tant que programme.

cd /opt/openrov/cockpit/linux
./openrov.service start

Mais pour les premières utilisations, nous allons nous contenter de lancer le programme manuellement.

cd /opt/openrov/cockpit/src
node app.js

Évidemment, comme nous ne sommes pas dans la même configuration, de nombreux problèmes vont survenir. Pour consulter le fonctionnement de OpenROV ou les erreurs rencontrées, il faut consulter le fichier suivant:

less /var/log/openrov.log

Pour réaliser les tests, il suffit de se connecter avec un navigateur (dans mon cas Firefox) pour tester si tout cela fonctionne bien. Donc allons vite à l'adresse: http://rov.local:8080/.

Test d'openrov-cockpit avec la vidéo de mjpg-streamer

Avant de me lancer dans la modification du code d'openrov-cockpit, il serait tout de même bien de tenter de le faire fonctionner pour voir si nous avons une chance d'aller plus loin. Pour pouvoir le lancer sans modifications majeures, il faut installer mjpg-streamer qui est la fonctionnalité permettant de visualiser le flux vidéo provenant de la caméra. Il suffit de vous référer à la section précédente présentant l'étude comparative pour le vidéo-streaming. Une fois cette étape réalisée, il faut vérifier que le système à base de mjpg-streamer fonctionne sans openrov-cockpit.

Waouh! Ça démarre, même si la vidéo n'est pas retransmise, mais seule la première image est affichée. En tout cas c'est sympa avec si peu de modifications d'avoir déjà ce résultat là. C'est donc très encourageant pour la suite. Reste à voir pourquoi la vidéo n'est pas affichée en live? Pourtant l'accès au périphérique semble bon car une première image s'affiche bien.

En fait après quelques heures de recherche, il s'avère que l'utilisation de Firefox provoque le problème de non visualisation du flux vidéo. En utilisant Chrome, tout fonctionne à merveille. Et ce comportement est confirmé par un post sur le forum d'OpenROV. Rien de très grave où du au portage, mais un problème sur lequel on pourra se pencher plus tard.

Prochaines étapes d'adaptation d'openrov-cockpit

A partir de ce point, il reste à voir comment apporter des modifications au projet pour le rendre compatible avec le matériel utilisé. Voici une liste non exhaustive des prochains problèmes à résoudre pour faire de openrov-cockpit l'interface qui fonctionnera complètement sur Raspberry Pi.

  • Visualiser la vidéo à l'aide du serveur de streaming ffmpeg, crtmpserver et lighttpd
  • Accéder au contrôle des moteurs via la solution adoptée (donc sans la partie Arduino)
  • Accéder aux capteurs que l'on connectera sur le GPIO de la Raspberry (via GroovePi par exemple)

Cela fait une petite liste de points, mais pas mal de travail en perspective.