Johnny 3


robot Johnny 3

Description :

Le robot Johnny 3 est une petite plateforme robotique basée sur un Raspberry Pi, conçue pour tester des algorithmes de vision par ordinateur, tout en restant aussi abordable que possible.


Liste des composants :

- Raspberry Pi avec son boîtier
- carte SD d'au moins 8Go
- webcam usb
- Dongle Wifi
- Powerbank capable de fournir 2A
- carte driver moteurs
- 2 moteurs 3-6V avec réducteur
- câbles Dupont
- chassis imprimé en 3D
- 2 élastiques
- patin glisseur en feutre

Pour le Raspberry Pi, j'ai utilisé mon Raspberry Pi 2B, tournant sous Raspbian 32 bits. Un Raspberry Pi 3 peut également être utilisé. Pour la version 4, il faudra une batterie capable de fournir au moins 3A. Le dongle Wifi utilisé est un TP-Link-WN725N Nano, doté d'un débit de 150Mbps, choisi principalement pour son faible prix et son faible encombrement. L'installation des drivers sur Raspbian est assez complexe, mais possible en suivant ce tutoriel. A noter que les Raspberry PI 3B disposent d'une antenne wifi intégrée. La batterie utilisée est une Revolt PB-160 d'une capacité de 5000mAH et capable de délivrer 2,4A. Elle a aussi la particularité d'avoir des dimensions comparables à la carte du Raspberry PI. Le robot peut utiliser n'importe quelle webcam USB du commerce. Il est cependant conseillé d'utiliser un modèle avec un support plat. La carte driver moteurs est une carte comportant un L293D pour piloter 2 petits moteurs cc 3-6V avec réducteur. La carte doit être modifiée par une connexion reliant l'alimentation du composant avec l'alimentation des moteurs (sinon, relier le + du bornier avec le VCC du connecteur avec un câble).

Modification du driver
Il faut modifier le driver moteur en soudant ces deux pins ensembles.

Le chassis et les roues sont imprimées depuis les modèles suivants. Ces modèles peuvent être imprimés par des imprimantes avec un faible volume d'impression (10x10x10cm) et ne nécessitent pas de support. Un radeau est toutefois conseillé.
- Chassis : robot_base5.stl
- Roue : robot_wheel5.stl
- Support driver : driver_support.stl

Pièces à imprimer
Pièces du chassis.


Assemblage :

- On commence par intégrer les deux moteurs dans le chassis. Si les moteurs ne tiennent pas correctement, une ou plusieurs couches de ruban adhésifs peuvent être ajoutés pour augmenter légèrement l'épaisseur du moteur. Les câbles doivent sortir par l'ouverture à l'arrière.
- Empiler et attacher le boîtier du Raspberry Pi et la batterie à l'aide de ruban adhésif double-face. Les ports USB du Raspberry Pi et les ports de la batterie doivent être à l'arrière du robot. Le câble USB doit sortir de la batterie, puis longer le bord de la batterie jusqu'au port d'alimentation du Raspberry PI.
- Fixer le bloc Raspberry/batterie dans l'emplacement prévu du chassis à l'aide de ruban adhésif double-face. Le câble USB d'alimentation doit sortir par l'encoche à l'avant-gauche du chassis, et doit pouvoir se connecter sans difficulté dans le port d'alimentation du Raspberry. On connecte ensuite le dongle Wifi sur un des ports USB du Raspberry Pi.
- Insèrer la carte moteur dans son support. Les borniers doivent être alignés avec l'encoche. Le support est ensuite fixé par ruban adhésif double-face sur le boitier du Raspberry Pi, sans masquer l'ouverture du GPIO, et les deux tiges vers l'arrière, dépassant du boîtier.
- Connecter les câbles des moteurs sur la carte driver, et les huits cables reliant le Raspberry Pi et la carte driver (vois schéma ci-dessous).

connexions entre composants connexions entre le raspberry pi et la carte moteur connexion avec les moteurs
Câblage des composants. Les câbles reliés aux broches ENABLE doivent être reliées à des port PWM du Raspberry Pi. Si le driver n'a pas été modifié, on peut ajouter un câble entre le second connecteur 5V du Raspberry Pi et le Vin du driver moteur.
- fixer la webcam à l'avant du robot avec du ruban adhésif double-face. Enrouler le câble USB autours des deux tiges du support driver, puis brancher la prise sur un port USB du Raspberry PI.
- Ajoutez les roues sur les axes des moteurs, puis placez les élastiques, qui serviront de pneus. Enfin, ajoutez le patin glissant dans l'encoche à l'avant, sous le robot.
ajout de la caméra et du patin
On ajoute la caméra et le patin glissant.


Installation logicielle :

D'un point de vue logiciel, le Raspberry Pi 2 du robot tourne sous Raspbian 11 Bullseye en version 32bits, installé sur une carte SD. Une fois la carte SD insérée dans le Raspberry Pi, connectez un écran sur le port HDMI, une souris et un clavier, et connecter un câble Ethernet pour accéder au réseau. Pendant l'installation, utilisez de préférence le chargeur secteur du Raspberry (pour éviter de tomber en panne de batterie pendant une installation).

Une fois sur le bureau de Raspbian, on commence par installer le driver du dongle Wifi (seulement sur Rapberry Pi ne disposant pas de leur propre antenne) en suivant ce tutoriel. Débranchez ensuite le câble ethernet, puis connecter vous sur votre réseau Wifi. Ouvrez un terminal, puis entrez la commande ifconfig pour récupérer l'adresse IP du Raspberry Pi sur le réseau.

On installe ensuite les logiciels nécessaires. Il est conseillé d'installer les logiciels suivants :
- openssh-server : pour se connecter en ssh depuis un autre poste,
- xrdp : pour se connecter à distance sur une session graphique (e.g. Remmina),
- OpenJDK : pour utiliser le code fourni sur cette page. Le robot utilise la version 17,
- Python3 : pour programmer en Python,
- guvcview : pour tester la caméra.

On installe ensuite OpenCV en suivant ce tutoriel. Il faut toutefois s'assurer, après la commande CMake, que le compilateur a bien trouvé les exécutables ANT et JNI. Il faut également sauter la commande make clean pour ne pas supprimer le fichier .jar généré. Si tout s'est bien déroulé, après une longue compilation, le fichier .jar doit être présent dans le dossier /home/pi/opencv/build/bin, et les librairies .so dans le dossier /home/pi/opencv/build/lib.

Eteignez le Raspberry Pi, puis débranchez l'écran, la souris et le clavier. Redémarrez-le, puis attendez que le dongle se mette à clignoter. On peut dès lors se connecter au Raspberry Pi depuis un autre PC connecté au même réseau local, soit par SSH, soit par un logiciel de bureau à distance (comme Remmina). Pour une connexion en SSH, entrez la commande suivante, avec l'adresse IP du Raspbeery Pi (ici 192.168.1.10), puis entrez votre mot de passe (celui-ci ne s'affiche pas dans la console, c'est normal).

ssh -X pi@192.168.1.10

Ceci ouvre une session en ligne de commande sur le Raspberry Pi. Pour une session graphique, utilisez le logiciel Remmina sous Linux ou Bureau à distance sous Windows, puis entrer l'adress IP, l'identifiant et le mot de passe, pour ouvrir une session graphique distante depuis votre PC.

Utilisation du robot :

Nous pouvons désormais envoyer et exécuter des programmes Java et Python. Pour rester organisé, on peut créer deux dossiers 'Java' et 'Python' dans le dossier utilisateur, avec l'interface graphique ou en ligne de commande :

mkdir Java
mkdir Python

On peut ensuite envoyer des programmes .jar ou .py avec la commande SCP en ligne de commande. Pour celà, sur le PC, on ouvre une autre console dans le dossier où se trouve le programme, puis on entre la ligne de commande suivante :

scp mon_programme.jar pi@192.168.1.10:/Java
  ou
scp mon_programme.py pi@192.168.1.10:/Python

Le mot de passe du Raspberry Pi est demandé pour permettre le transfert. Il faut l'écrire dans la console (celui-ci ne s'affiche pas). Avec une interface graphique, il est également possible de transférer les programmes à l'aide d'une clé USB, en copiant les programmes sur la clé depuis le PC puis en les collant dans les dossiers sur le raspberry pi.

On exécute ensuite les programmes en ligne de commande. Sur une console en SSH depuis le PC, ou sur une console ouverte depuis le bureau à distance raspbian, on utilise :

cd ~/Java
sudo java -jar mon_programme.jar
  ou
cd ~/Python
sudo python3 mon_programme.py

La commande 'sudo' n'est nécessaire que dans le cas où le programme doit manipuler le port GPIO du Raspberry PI. Dans le cas où le programme utilise un déport d'affichage (X11 forwarding), l'erreur suivante peut apparaître :

X11 connection rejected

Le problème se résout facilement avec la commande suivante :

export XAUTHORITY=$HOME/.Xauthority

Pour eteindre le robot, on utilise la commande suivante, puis, lorsque les leds du Raspberry Pi cessent de clignoter, on débranche le câble USB d'alimentation.

sudo halt

Programmes de tests :

Les programmes suivants permettent de tester les moteurs et la caméra du robot. Le programme robot_motor_test affiche une fenêtre avec des boutons permettant de piloter les moteurs. Les boutons carrés permettent de faire avancer, reculer et tourner le robot, le boutons ronds permenttent de contrôler les moteurs indépendamment.

panel motor
Panneau de contrôle des moteurs.

Code source :
- fichier JAR : robot_motor_test.jar
- code Java : robot_motor_test.zip

Pour utiliser le fichier JAR, il faut dans un premier temps l'envoyer sur le robot. Sur le PC, on ouvre une console dans le dossier où il se trouve, puis on entre dans une nouvelle console la commande suivante (il faut utiliser l'adresse du Raspberry Pi) :

scp robot_motor_test.jar pi@192.168.1.10:/home/pi/Java

Puis, sur la console connectée en SSH, on lance le programme avec :

cd ~/Java
sudo java -jar robot_motor_test.jar

Pour utiliser le code Java, il est recommandé d'utiliser une IDE (Eclipse, IntelliJ...), puis de créer un nouveau projet. On importe ensuite les fichiers .java dans le projet. Ce programme nécessite d'associer la librairie pi4j (avec Eclipse : clic droit sur le projet->Build Path->Configure Build Path, puis dans l'onglet libraries, cliquer sur 'Add External Jars...').

librairies pour le projet robot_motor_test
Le programme détecte automatiquement si il s'exécute sur un Raspberry Pi. Si ce n'est pas le cas, le GPIO n'est pas utilisé, à la place, les commandes motrices sont affichées sur la console.

La classe MotorControl permet d'initialiser les ports du GPIO utilisés pour contrôler les moteurs, et offre une fonction de bas niveau pour contrôler la vitesse et la direction des deux moteurs : la fonction setMotor(int vg,int vd) permet de définir la vitesse et la direction avec deux valeurs entre -100 et +100. La fonction stop() arrête les deux moteurs.
La classe Robot offre des fonctions de plus haut niveau pour contrôler le robot, notamment move(int g, int d, int time) qui permet de déplacer le robot pendant une durée définie (en millisecondes).

Le programme peut ensuite être exporté au format JAR pour être téléversé sur le robot (avec Eclipse : clic droit sur le projet->Export...->Java->Runnable JAR File->Next, puis on sélectionne le bon fichier Main, l'emplacement de destination, et l'option 'package required libraries into generated JAR', avant de finaliser en cliquant sur 'Finish').


Le programme robot_camera_test ouvre une fenêtre affichant simplement l'image de la caméra du robot.

panel camera
Affichage de la caméra.

Code source :
- fichier JAR : robot_camera_test.jar
- code Java : robot_camera_test.zip

Pour utiliser le fichier JAR, on ouvre, sur le PC, une console dans le dossier où il se trouve, puis on entre dans une nouvelle console la commande suivante :

scp robot_camera_test.jar pi@192.168.1.10:/home/pi/Java

Puis, sur la console connectée en SSH, on lance le programme avec :

cd ~/Java
java -jar robot_camera_test.jar

Pour utiliser le code Java, il faut associer ce programme à la librairie OpenCV (il faut l'installer au préalable sur le PC), et indiquer l'emplacement des librairies natives (.so sous linux, .dll sous windows).

librairies pour le projet robot_motor_test

La classe Camera permet d'initialiser la caméra du robot et de charger les librairies OpenCV. La fonction read() permet de capturer une nouvelle image, et la fonction setBufferedImage convertie l'image au format Mat (OpenCV) en BufferenImage pour l'affichage.

Une interface Web :

Ce programme permet de piloter le robot depuis un navigateur web (Firefox, Chrome, Opera...) tout en recevant le flux vidéo de la caméra. Le programme contient un serveur web simple hébergeant une page Html, et communique avec le client à l'aide de websockets pour recevoir les commandes utilisateur, envoyer des informations à afficher, et envoyer le flux vidéo de la caméra.


L'interface web (à gauche) permet de piloter le robot à l'aide des quatres boutons. L'affichage montre le flux vidéo de la caméra (à noter, le nombre d'images par seconde est faible à cause de la faible luminosité, la caméra augmentant le temps de pose pour chaque image).

Code source :
- Page HTML : index.html (clic droit -> enregistrer la cible du lien)
- fichier JAR : robot_camera_server.jar
- code Java : robot_camera_server.zip

Comme le programme a besoin d'un document spécifique (la page HTML), il est conseillé de créer un sous-dossier spécifique pour ce projet. Sur la console SSH (ou directement sur un bureau à distance), on peut créer, par exemple, le dossier avec les commandes suivantes :

cd ~/Java
mkdir robot_camera_server
cd robot_camera_server

Puis, depuis le PC, on ouvre une nouvelle console dans le dossier où se trouvent les fichiers JAR et HTML, et on entre les commandes SCP suivantes, avec l'adresse IP et le mot de passe du Raspberry Pi :

scp robot_camera_server.jar pi@192.168.1.10:/home/pi/Java/robot_camera_server
scp index.html pi@192.168.1.10:/home/pi/Java/robot_camera_server

Depuis la console SSH (ou depuis une console sur un bureau à distance), on lance le programme avec la commande suivante :

sudo java -jar robot_camera_server.jar

Le serveur web démarre, puis affiche son adresse dans la console SSH. À partir de n'importe quel PC, tablette ou smartphone connecté au même réseau, on peut ouvrir un navigateur web et entrer cette adresse dans la barre d'adresse, pour afficher la page d'interface. On peut alors piloter le robot à l'aide des touches directionnelles. On arrête le programme en cliquant sur le bouton 'stop system' (ou, depuis la console SSH, en faisant Ctrl+C).

address of the server
En démarrant, l'adresse du serveur affiche l'adresse pour se connecter à l'interface Web.

Pour utiliser le code Java, il faut associer ce programme aux librairies OpenCV (et indiquer l'emplacement des librairies natives) pour la caméra, pi4j pour l'accès au port GPIO, Java-Websocket, slf4j-api et slf4j-simple pour le serveur. Il faut également importer la page 'index.html'.

librairies pour le projet robot_camera_server

Le code source est divisé en trois packages :

classes du projet robot_camera_server

- Le package main:

Ce package contient les classes Main et Camera :
 - La classe Main initialise les différents modules du programme et organise son déroulement. Au démarrage, la fonction main détecte automatiquement si le programme s'exécute sur le Raspberry Pi ou un PC, afin d'activer ou non les fonctionnalités liées au port GPIO. elle contient également une fonction pour traiter les commandes utilisateur issues de l'interface Web, clientCommand(String command), et pour envoyer des messages vers l'interface Web, broadcast(String msg).
 - La classe Camera initialise les paramètres de la webcam et charge les librairies OpenCV. Sur un Raspberry Pi, les librairies seront chargées depuis le chemin indiqué par la variable 'path' dans la classe Main. Sur un PC, les librairies seront chargées depuis le chemin par défaut défini pendant l'installation d'OpenCV. La fonction read() permet de récupérer une nouvelle image de la webcam, et la fonction Mat2bufferedImage() convertit l'image au format Mat d'OpenCV en format BufferedImage.

- Le package robot:

Ce package contient les classes dédiées au contrôle des moteurs via le port GPIO : Robot et MotorControl. Ces classes sont similaires à celles du programme robot_motor_test.
 - La classe Robot contient des fonctions permettant de piloter le robot : setMotors(int l, int r) permet de définir la vitesse et la direction de chaque moteur (l=left, r=right) avec une vitesse entre -100 et +100. La fonction stop() arrête les deux moteurs. La fonction move(int l, int r, int time) contrôle le robot pendant une durée définie en millisecondes.
 - La classe MotorControl initialise et gère le port GPIO. À l'initialisation, les pins connectés à la carte moteur sont définis comme des sorties, et les signaux utlisés pour les commandes PWM sont définis. La fonction setMotor(int vg, int vd) permet de piloter les deux moteurs (valeur entre -100 et +100) et la fonction stop() arrète les deux moteurs.

- Le package servers:

Ce package gère le serveur Web hébergeant la page HTML et gère la communication avec le client. Il contient les classes suivantes :
 - La classe Serveur gère le serveur Web lui-même. À l'initialisation, elle détecte l'adresse IP du système (qui s'affiche sur la console) et initialise les websockets pour communiquer avec le client. Une classe interne, ServerHandler, gère la réception des requêtes client et envoie la page 'index.html'. La fonction stop() permet d'arrêter proprement le serveur et ses différents modules. La fonction broadcast(String msg) permet d'envoyer des messages et commandes à l'interface Web.
 - La classe DataWebSocket définit et gère un websocket pour communiquer avec l'interface Web. La fonction onMessage(WebSocket conn, String message) reçoit les commandes issues de l'interface Web et les transmet à la classe Main pour y être traitées.
 - La classe VideoSocket définit un socket pour envoyer un flux vidéo. La fonction pushImage(BufferedImage img) permet d'envoyer une image au format BufferedImage à l'interface Web. Cette classe exécute un thread à part qui exécute cette fonction toute les 50 millisecondes, permettant d'envoyer un flux vidéo constant.


Page HTML :

La page 'index.html' décrit la page Web telle qu'elle doit s'afficher dans le navigateur. La partie haute affiche le framerate. La partie centrale est une image qui prend pour source le socket vidéo du programme Java, permettant d'afficher en continue le flux vidéo de la caméra. La partie basse comporte un ensemble de boutons permettant de piloter le robot et de stopper le programme à distance. Dans l'en-tête, un bloc de code CSS permet la mise en page.
La page comporte également une section en javascript. Ce code permet à l'ouverture de la page de récupérer l'adresse IP du serveur pour se connecter au flux vidéo. Une fonction permet de recevoir et traîter des commandes issues du serveur, ainsi que des fonctions associées aux boutons de la page. Le protocole de communication définit les commandes suivantes :

- commandes du serveur :
framerate 20 : permet d'afficher le nombre d'images par secondes (ici, 20fps) du programme en haut de la page.

- commandes du client au serveur :
robot forward : commande pour faire avancer le robot
robot backward : commande pour faire reculer le robot
robot turnleft : faire pivoter le robot à gauche
robot turnright : faire pivoter le robot à droite
robot stop : commande pour stopper le robot
system stop : commande pour arrêter le programme à distance

Suivi d'un objet coloré :

Ce programme reprend le projet précedent, mais y ajoute un algorithme simple de détection de couleur primaire permettant au robot de s'orienter vers un objet coloré.

color detection interface
Détection du champignon rouge. La ligne rouge indique la colonne où le plus de rouge a été détecté.



Mode automatique : le robot s'oriente vers un objet coloré (ici, rouge).


Code source :
- Page HTML : index.html (clic droit -> enregistrer la cible du lien)
- fichier JAR : robot_camera_color.jar
- code Java : robot_camera_color.zip

Comme précédemment, il est conseillé de créer un sous-dossier spécifique pour ce projet. Sur la console SSH (ou directement sur un bureau à distance), on peut créer, par exemple, le dossier avec les commandes suivantes :

cd ~/Java
mkdir robot_camera_color
cd robot_camera_color

Puis, depuis le PC, on ouvre une nouvelle console dans le dossier où se trouvent les fichiers JAR et HTML, puis on entre les commandes SCP suivantes, avec l'adresse IP et le mot de passe du Raspberry Pi :

scp robot_camera_color.jar pi@192.168.1.10:/home/pi/Java/robot_camera_color
scp index.html pi@192.168.1.10:/home/pi/Java/robot_camera_color

Depuis la console SSH (ou depuis une console sur un bureau à distance), on lance le programme avec la commande suivante :

sudo java -jar robot_camera_color.jar

Le serveur web démarre, puis affiche son adresse dans la console SSH, que l'on peut entrer dans la barre d'adresse d'un navigateur Web. On peut alors piloter le robot à l'aide des touches directionnelles. Le flux vidéo montre la détection de couleur. Il est possible de sélectionner la couleur à rechercher (rouge, vert ou bleu) avec les trois boutons sous le flux vidéo. Le bouton 'change mode' permet de passer du mode manuel au mode automatique et inversement (l'affichage en haut indique le mode et la couleur actuelle). En mode automatique, le robot se tourne vers l'objet coloré la plus important dans son champ de vision. On arrête le programme en cliquant sur le bouton 'stop system' (ou, depuis la console SSH, en faisant Ctrl+C).

Pour utiliser le code Java, il faut associer ce programme aux mêmes librairies que pour le projet robot_camera_server : OpenCV, pi4j, Java-Websocket, slf4j-api et slf4j-simple. Ne pas oublier la page 'index.html'.

Le code source est divisé en quatre packages :

classes du projet robot_camera_color

- Le package main:

Ce package contient les classes Main et Camera :
 - La classe Main : par rapport au projet robot_camera_server, cette classe ajoute le sous-module de détection de couleur, et définit le mode de fonctionnement du robot (manuel ou automatique). L'image envoyée au socket vidéo est ici l'image générée par le module de détection de la couleur. La fonction clientCommand(String command) définit un ensemble de nouvelles commandes pour changer le mode de fonctionnement et la couleur à détecter.
 - La classe Camera : pas de différence avec le projet robot_camera_server.

- Le package robot:

Ce package contient les classes Robot et MotorControl :
 - La classe Robot ajoute une fonction action(int px) permettant de contrôler le robot de façon autonome en fonction de la position d'un objet sur l'image (px).
 - La classe MotorControl : pas de différence avec robot_camera_server.

- Le package servers:

Ce package contient les classes Serveur, DataWebSocket et VideoSocket, toutes trois identiques au projet robot_camera_server.

- Le package color:

Ce package contient la classe Detector, qui détecte les pixels d'une certaine couleur primaire dans l'image. La fonction detect(Mat img) détecte la position d'un objet coloré sur l'image, et la fonction Matrix2bufferedImage() génère l'image au format BufferedImage qui sera envoyée à l'interface Web.
La détection de la couleur se fait en comparant les valeurs des trois canaux de couleur d'un pixel. Par exemple, pour détecter la couleur rouge, la valeur du pixel sera : val=max(0,rouge - vert - bleu). Ainsi, seuls les pixels avec une forte dominance rouge seront détectés.
Pour détecter la position horizontale d'un objet coloré, on accumule les valeurs des pixels d'une même colonne, la colonne px avec la plus grande valeur donne l'orientation de l'objet.


Page HTML :

La page 'index.html' de ce projet ajoute dans la partie haute l'affichage du mode de fonctionnement du robot (manuel ou automatique) et la couleur recherchée (rouge, vert ou bleu). L'image reçue est celle générée par le module de détection de couleur. Sous l'image, trois boutons permettent de sélectionner la couleur primaire à rechercher. La partie basse ajoute un bouton pour changer le mode de fonctionnement du robot.
La section javascript ajoute des fonctions pour les boutons additionnels et permet la réception de deux nouvelles commandes. Le protocole de communication définit les commandes suivantes :

- commandes du serveur :
framerate 20 : permet d'afficher le nombre d'images par secondes (ici, 20fps) du programme en haut de la page.
mode automatic : permet d'afficher le mode de fonctionnement ('automatic' ou 'manual') en haut de la page.
color red : permet d'afficher la couleur recherchée ('red', 'green' ou 'blue') en haut de la page.

- commandes du client au serveur :
robot forward : commande pour faire avancer le robot
robot backward : commande pour faire reculer le robot
robot turnleft : faire pivoter le robot à gauche
robot turnright : faire pivoter le robot à droite
robot stop : commande pour stopper le robot
changemode : changer le mode de fonctionnement du robot
system red : change la couleur recherchée ('red', 'green' ou 'blue')
system stop : commande pour arrêter le programme à distance

Suivi d'un code-barre vertical :

Ce programme reprend le projet robot_camera_server, mais y ajoute un algorithme pour détecter des codes-barres verticaux. En connaissant la taille du code-barre, il est possible d'en définir la distance, et donc la position par rapport au robot.

barcode detection interface
Détection de codes-barres.


Code source :
- Page HTML : index.html (clic droit -> enregistrer la cible du lien)
- template code-barre : barcode.svg (clic droit -> enregistrer la cible du lien)
- fichier JAR : robot_camera_barcode.jar
- code Java : robot_camera_barcode.zip

Comme précédemment, il est conseillé de créer un sous-dossier spécifique pour ce projet. Sur la console SSH (ou directement sur un bureau à distance), on peut créer, par exemple, le dossier avec les commandes suivantes :

cd ~/Java
mkdir robot_camera_barcode
cd robot_camera_barcode

Puis, depuis le PC, on ouvre une nouvelle console dans le dossier où se trouvent les fichiers JAR et HTML, puis on entre les commandes SCP suivantes, avec l'adresse IP et le mot de passe du Raspberry Pi :

scp robot_camera_barcode.jar pi@192.168.1.10:/home/pi/Java/robot_camera_barcode
scp index.html pi@192.168.1.10:/home/pi/Java/robot_camera_barcode

Depuis la console SSH, on lance le programme avec la commande suivante :

sudo java -jar robot_camera_barcode.jar

Par défaut, en mode automatique, le robot suit le premier code-barre détecté dans l'image. Pour spécifier un code-barre particulier, il faut indiquer son code en paramètre (nombre entre 0 et 15) :

sudo java -jar robot_camera_barcode.jar 9

Le serveur web démarre, puis affiche son adresse dans la console SSH, que l'on peut entrer dans la barre d'adresse d'un navigateur Web. On peut alors piloter le robot à l'aide des touches directionnelles. Le flux vidéo montre la détection du ou des codes-barres. Le bouton 'change mode' permet de passer du mode manuel au mode automatique et inversement (l'affichage en haut indique le mode). En mode automatique, le robot s'oriente et se dirige vers le code spécifié (ou, par défaut, le premier code-barre détecté). On arrête le programme en cliquant sur le bouton 'stop system' (ou, depuis la console SSH, en faisant Ctrl+C).

Pour utiliser le code Java, il faut associer ce programme aux mêmes librairies que pour le projet robot_camera_server : OpenCV, pi4j, Java-Websocket, slf4j-api et slf4j-simple. Ne pas oublier la page 'index.html'.

Le code source est divisé en quatre packages :

classes du projet robot_camera_barcode

- Le package main:

Ce package contient les classes Main et Camera :
 - La classe Main : par rapport au projet robot_camera_server, cette classe ajoute le sous-module de détection de code-barre, et définit le mode de fonctionnement du robot (manuel ou automatique). L'image envoyée au socket vidéo est ici l'image générée par le module de détection de code-barre. La fonction clientCommand(String command) définit un ensemble de nouvelles commandes pour changer le mode de fonctionnement du robot.
 - La classe Camera : pas de différence avec le projet robot_camera_server.

- Le package robot:

Ce package contient les classes Robot et MotorControl :
 - La classe Robot ajoute une fonction action(int px, int height) permettant de contrôler le robot de façon autonome en fonction de la position et de la taille apparente d'un code-barre sur l'image.
 - La classe MotorControl : pas de différence avec robot_camera_server.

- Le package servers:

Ce package contient les classes Serveur, DataWebSocket et VideoSocket, toutes trois identiques au projet robot_camera_server.

- Le package barcode:

Ce package contient les classes Detector et Code, qui permettent la détection de code-barres. La classe Detector contient l'algorithme de détection. Il scanne l'image colonne par colonne et détecte les marqueurs du code-barre. Lorsqu'un code barre est détecté, il est enregistré à l'aide d'une instance d'objet code contenant ses propriétés de taille et position. Les instances avec un même code d'identification sont détectées, elles sont fusionnées. L'instance permet ainsi de définir le centre du code-barre, sa hauteur apparente et sa position. La classe Code contient des fonctions pour lire le code-barre, notamment son code d'identification bianaire et son orientation. La fonction Matrix2bufferedImage() génère l'image au format BufferedImage qui sera envoyée à l'interface Web.


Page HTML :

La page 'index.html' de ce projet ajoute dans la partie haute l'affichage du mode de fonctionnement du robot (manuel ou automatique). L'image reçue est celle générée par le module de détection de code-barres. La partie basse ajoute un bouton pour changer le mode de fonctionnement du robot.
La section javascript ajoute des fonctions pour les boutons additionnels et permet la réception d'une nouvelle commande. Le protocole de communication définit les commandes suivantes :

- commandes du serveur :
framerate 20 : permet d'afficher le nombre d'images par secondes (ici, 20fps) du programme en haut de la page.
mode automatic : permet d'afficher le mode de fonctionnement ('automatic' ou 'manual') en haut de la page.

- commandes du client au serveur :
robot forward : commande pour faire avancer le robot
robot backward : commande pour faire reculer le robot
robot turnleft : faire pivoter le robot à gauche
robot turnright : faire pivoter le robot à droite
robot stop : commande pour stopper le robot
changemode : changer le mode de fonctionnement du robot
system stop : commande pour arrêter le programme à distance

Suivi d'ARTags :

Ce programme reprend le projet robot_camera_server, mais y ajoute un algorithme pour détecter et suivre des marqueurs ARTags. Le robot peut alors suivre une séquence de marqueurs prédéfinie pour suivre un chemin.


Le robot suit une séquence de deux ARTags de code 404 et 33. Il se dirige vers un ARTag jusqu'à ce que sa talle apparente dépasse 110 pixels, puis passe à l'ARTag suivant. Une fois la séquence terminée, le robot suit le premier ARTag distant qu'il détecte. Le détecteur d'ARTags binarise l'image avec un seuil qui varie aléatoirement jusqu'à ce qu'il détecte le marqueur qu'il recherche.

Code source :
- Page HTML : index.html (clic droit -> enregistrer la cible du lien)
- template marqueur : ARTag.svg (clic droit -> enregistrer la cible du lien)
- fichier JAR : robot_camera_ARTag.jar
- code Java : robot_camera_ARTag.zip

À noter : le marqueur ARTag doit avoir un nombre pair de carrés noirs : le détecteur utilise le principe de bit de parité pour éliminer certains faux positifs.

Comme précédemment, il est conseillé de créer un sous-dossier spécifique pour ce projet. Sur la console SSH (ou directement sur un bureau à distance), on peut créer, par exemple, le dossier avec les commandes suivantes :

cd ~/Java
mkdir robot_camera_ARTag
cd robot_camera_ARTag

Puis, depuis le PC, on ouvre une nouvelle console dans le dossier où se trouvent les fichiers JAR et HTML, puis on entre les commandes SCP suivantes, avec l'adresse IP et le mot de passe du Raspberry Pi :

scp robot_camera_ARTag.jar pi@192.168.1.10:/home/pi/Java/robot_camera_ARTag
scp index.html pi@192.168.1.10:/home/pi/Java/robot_camera_ARTag

Depuis la console SSH, on lance le programme avec la commande suivante :

sudo java -jar robot_camera_ARTag.jar

Par défaut, en mode automatique, le robot suit le premier marqueur 'distant' (plus petit que 110 pixels de heuteur) qu'il détecte l'image. Pour spécifier une séquence de marqueurs à suivre, il faut les indiquer en paramètre :

sudo java -jar robot_camera_ARTag.jar 404 33

Le serveur web démarre, puis affiche son adresse dans la console SSH, que l'on peut entrer dans la barre d'adresse d'un navigateur Web. On peut alors piloter le robot à l'aide des touches directionnelles. Le flux vidéo montre la détection du ou des marqueurs ARTags, avec leur code et hauteur apparente. Le bouton 'change mode' permet de passer du mode manuel au mode automatique et inversement. En mode automatique, le robot pivote sur lui-même jusqu'à trouver le prochain marqueur ARTag de la séquence, puis se dirige vers lui. quand le marqueur est assez proche, il recherche le marquer suivant, et ainsi de suite. Quand la séquence est terminée (ou lorsque aucune séquence n'est définie); le robot se dirige vers le premier marqueur qu'il détecte. On peut redémarrer la séquence en cliquant sur le bouton 'initialize', et arrêter le programme en cliquant sur le bouton 'stop system'.

Pour utiliser le code Java, il faut associer ce programme aux mêmes librairies que pour le projet robot_camera_server : OpenCV, pi4j, Java-Websocket, slf4j-api et slf4j-simple. Ne pas oublier la page 'index.html'.

Le code source est divisé en quatre packages :

classes du projet robot_camera_ARTag

- Le package main:

Ce package contient les classes Main et Camera :
 - La classe Main : par rapport au projet robot_camera_server, cette classe ajoute le sous-module de détection de marqueurs ARTags, et définit le mode de fonctionnement du robot (manuel ou automatique). L'image envoyée au socket vidéo est ici l'image générée par le module de détection d'ARTags. La fonction clientCommand(String command) définit un ensemble de nouvelles commandes pour changer le mode de fonctionnement du robot.
 - La classe Camera : pas de différence avec le projet robot_camera_server.

- Le package robot:

Ce package contient les classes Robot et MotorControl :
 - La classe Robot ajoute une fonction action(int px, int pz, boolean search) permettant de contrôler le robot de façon autonome en fonction de la position et de la taille apparente d'un marqueur sur l'image, et si le robot est en recherche d'un marqueur ou non.
 - La classe MotorControl : pas de différence avec robot_camera_server.

- Le package servers:

Ce package contient les classes Serveur, DataWebSocket et VideoSocket, toutes trois identiques au projet robot_camera_server.

- Le package ARTag:

Ce package contient les classes Detector et Edges, qui permettent la détection de marqueurs ARTags.
 - La classe Detector contient un algorithme de détection de contours et une fonction Matrix2bufferedImage() qui génère l'image au format BufferedImage qui sera envoyée à l'interface Web.
. L'algoritme procède aux étapes suivantes :
   - Binarisation de l'image
   - Détection des points de contours
   - Détection de contours
Le détecteur filtre les contours trops petits pour être exploitables, les contours restants sont enregistrés comme des instances de Edge.
 - La classe Edge permet de détecter si un contours est bien un marqueur ARTag, et, le cas échéant, décode sont identifiant binaire. L'algoritme procède aux étapes suivantes :
   - Détections des coins (Algorithme FAST)
   - Elimination des contours qui n'ont pas 4 coins
   - Elimination des quadrilatères qui ne sont pas des carrés/losanges
   - Rectification de l'image du marqueur
   - Lecture de la couleur des 9 carrés internes
   - Elimination des marqueurs avec un nombre impair de carrés noirs
   - Décodage du code binaire du marqueur


Page HTML :

La page 'index.html' de ce projet ajoute dans la partie haute l'affichage du mode de fonctionnement du robot (manuel ou automatique) et le code du marqueur actuellement suivi (-1 si aucun). L'image reçue est celle générée par le module de détection d'ARTags. La partie basse ajoute un bouton pour changer le mode de fonctionnement du robot, ainsi qu'un bouton pour réinitialiser la séquence de marqueurs ARTags.
La section javascript ajoute des fonctions pour les boutons additionnels et permet la réception de deux nouvelles commandes. Le protocole de communication définit les commandes suivantes :

- commandes du serveur :
framerate 20 : permet d'afficher le nombre d'images par secondes (ici, 20fps) du programme en haut de la page.
mode automatic : permet d'afficher le mode de fonctionnement ('automatic' ou 'manual') en haut de la page.
target 33 : permet d'afficher le code du marqueur actuel (ici, le marqueur 33) en haut de la page.

- commandes du client au serveur :
robot forward : commande pour faire avancer le robot
robot backward : commande pour faire reculer le robot
robot turnleft : faire pivoter le robot à gauche
robot turnright : faire pivoter le robot à droite
robot stop : commande pour stopper le robot
changemode : changer le mode de fonctionnement du robot
system initialize : réinitialiser la séquence de marqueurs ARTags
system stop : commande pour arrêter le programme à distance