IMA3/IMA4 2021/2023 P9 : Différence entre versions
(s) |
|||
Ligne 991 : | Ligne 991 : | ||
=<div class="mcwiki-header" style="border-radius: 15px; padding: 15px; font-weight: bold; color: #0000000; text-align: center; font-size: 80%; background: #d4d0d0; vertical-align: top; width: 98%;"> Présentation des résultats </div>= | =<div class="mcwiki-header" style="border-radius: 15px; padding: 15px; font-weight: bold; color: #0000000; text-align: center; font-size: 80%; background: #d4d0d0; vertical-align: top; width: 98%;"> Présentation des résultats </div>= | ||
+ | |||
+ | [[Fichier:Vidéo_présentation_résultats.mp4]] |
Version du 20 mai 2023 à 15:50
Sommaire
- 1 Sommaire
- 2 SEMESTRE 7
- 3 Objectifs du semestre 7
- 4 NIRYO NED 1 AVEC PYNIRYO 1
- 5 Traitement d'image et Aphelion
- 6 Aphelion, un logiciel pour le traitement d’image
- 7 Le traitement d’image, qu’est ce que c’est?
- 8 Prétraitement : amélioration de la qualité de l’image (Amélioration et Restauration d’images)
- 9 Restauration de l’image:
- 10 Analyse : extraction de l'information essentielle dans l’image (Segmentation)
- 11 Etat d'avancement du SEMESTRE 7
- 12 Perspectives
- 13 SEMESTRE 8
- 14 Contexte et objectifs du semestre 8
- 15 Notes opérationnelles
- 16 Etat des lieux
- 17 Rapport d'avancement
- 18 Présentation des résultats
Sommaire
1 - Semestre 7 :
I- Objectifs du semestre 7
II- Robot Nyrio NED1
III- Traitement d'image et Aphelion
IV- Etat d'avancement
V- Perspectives pour le Semestre 8
2 - Semestre 8 :
I- Contexte et objectifs du semestre 8
II- Notes opérationnelles
III- Etat des lieux
IV- Rapport d'avancement
V- Présentation des résultats (vidéo)
SEMESTRE 7
Objectifs du semestre 7
Se familiariser avec le Robot NED 1 et sa bibliothèque PyNiryo en testant plusieurs applications.
Utilisation de la caméra et l'obtention de plusieurs images qui vont nous servir pour le traitement d'image.
Expérimenter le traitement d’image avec le logiciel Aphelion.
Tenter de contrôler le robot à travers le logiciel Aphelion.
NIRYO NED 1 AVEC PYNIRYO 1
Le Robot
Ned est un bras robot collaboratif 6 axes conçu pour l’éducation et la recherche. Ned est conçu pour reproduire tous les mouvements requis dans les utilisations les plus avancées de l’industrie 4.0, avec une précision et une répétabilité de 0.5mm. La structure en aluminium de Ned lui confère une robustesse exemplaire, lui permettant d’accomplir avec fluidité les mouvements nécessaires à vos projets de robotique. Ce robot tire pleinement profit des capacités de la Raspberry Pi 4, avec un processeur 64-bit ARM V8 haute performance, 2Go de RAM, et une connectivité améliorée. Ned est un robot basé sur Ubuntu 18.04 et ROS (Robot Operating System) Melodic, une solution open-source complète conçue pour la robotique. Avec ROS, Ned dispose d’un ensemble de librairies permettant de concevoir des programmes les plus simples aux plus complexes pour répondre à vos besoins de manière flexible.
Les spécifications techniques des outils de Ned
Avec le système Easy Connect, changer d’outil n’a jamais été aussi simple. Il vous suffit de brancher votre outil, de connecter son câble et il est prêt à être utilisé. Ned est fourni avec un Gripper Custom. Ses mors standards peuvent manipuler de petits objets, et si vous possédez une imprimante 3D, vous pouvez créer vos propres mors.
Ned peut également être utilisé avec :
- Le Gripper Large qui a la capacité de saisir des objets plus gros tout en gardant la possibilité de se fermer entièrement.
- Le Gripper Adaptatif qui permet au robot de saisir des objets non standards avec des formes complexes (ex. un œuf).
- La Pompe à vide pour saisir des objets avec des surfaces planes et non poreuses. L’Électroaimant utile pour manipuler de un à plusieurs objets métalliques (ex. vis, boulons…).
- L’écosystème de Ned est conçu pour vous permettre de reproduire des cas d’utilisation avancés de l’industrie 4.0
- 2.7 si vous utilisez Python 2
- 3.6 si vous utilisez Python 3
Les spécifications techniques du Gripper Custom
Spécifications techniques de Ned
Interface mécanique
Ned est un bras robot 6 axes collaboratif. Il se compose de six articulations robotisées en aluminium recouvertes de plastique. Ned comprend 7 parties :
Espace de travail - Ned
Logiciel
Ned est un robot basé sur Raspberry, Arduino & ROS. Il utilise ROS afin de créer une interface entre le matériel et les liaisons de haut niveau. Voici sur le schéma suivant un aperçu global du logiciel de Ned afin de comprendre où sont placées chaque partie du logiciel.
PyNiryo est une API TCP créée avec Python, qui permet aux développeurs de créer des programmes robotiques et de contrôler les robots en communiquant à distance par le biais de leurs ordinateurs. Contrairement au Wrapper ROS Python, l’utilisateur ne nécessitera pas d’être connecté au robot par le biais d’un terminal.
Avant de programmer avec la bibliothèque PyNiryo 1, il faut avoir installé le langage de programmation Python sur son ordinateur. La version doit être égale ou supérieure:
Après, on vous montre quelque exemple du code avec PyNiryo 1:
Premier code pour tester le fonction de base
from pyniryo import* #l'adresse 'robot_ip_address' depend de son connection #avec le robot #si Connexion ethernet directe: 169.254.200.200 #si Mode Hotspot: 10.10.10.10 #si Simulation ou directement sur le robot: 127.0.0.1 #si l'Ordinateur et robot sont connectés au même routeur: il faut trouver #l'addresse IP du robot dans le VLAN robot_ip_address = "10.10.10.10" #connecter avec le robot et calibrer le robot = NiryoRobot(robot_ip_address) robot.calibrate_auto() #bouger les axes robot.move_joints(0.2, -0.3, 0.1, 0.0, 0.5, -0.8) #allumer le mode learning robot.arm.set_learning_mode(True) #arrêter le connection TCP robot.close_connection()
- Dans la ligne 1 on importe toutes les fonctions de la bibliothèque ‘pyniryo’.
- Dans la ligne 12 on définit l’adresse du robot, qui dépend de notre connexion avec Ned.
- Dans la ligne 15 on crée une instance de la classe NiryoRobot avec l’adresse IP correspondante pour avoir l’accès à toutes les fonctions du robot.
- Dans la ligne 16 on démarre une calibration automatique des moteurs si les moteurs n’ont pas encore été calibrés.
- Dans la ligne 19 on bouge les 6 axes du robot en donnant la position des 6 axes en radians (6 floats)
Il a y aussi le possibilité de bouger les robots avec:
'NiryoRobot.move_pose(x, y, z, roulis, tangage, lacet)’
x,y,z (floats) sont exprimés en mètres et roulis, tangage, lacet (floats) sont exprimés en radians
- Dans la ligne 22 on allume ‘learning mode’, qui nous permet de bouger Niryo au main et récupère la position
- Dans la ligne 25 on arrête la connexion avec Niryo
Code pour utiliser le gripper
from pyniryo import* robot_ip_address = "x.x.x.x" # Robot address # The pick pose pick_pose = PoseObject( x=0.25, y=0., z=0.15, roll=-0.0, pitch=1.57, yaw=0.0) # The Place pose place_pose = PoseObject( x=0.0, y=-0.25, z=0.1, roll=0.0, pitch=1.57, yaw=-1.57) def pick_n_place_version_2(robot): height_offset = 0.05 # Offset according to Z-Axis to go over pick & place poses gripper_speed = 400 pick_pose_high = pick_pose.copy_with_offsets(z_offset=height_offset) place_pose_high = place_pose.copy_with_offsets(z_offset=height_offset) # Going Over Object robot.move_pose(pick_pose_high) # Opening Gripper robot.open_gripper(gripper_speed) # Going to picking place robot.move_pose(pick_pose) # Closing gripper robot.close_gripper(gripper_speed) # Raising robot.move_pose(pick_pose_high) # Going Over Place pose robot.move_pose(place_pose_high) # Going to Place pose robot.move_pose(place_pose) # Opening Gripper robot.open_gripper(gripper_speed) # Raising robot.move_pose(place_pose_high) if __name__ == '__main__': # Connect to robot client = NiryoRobot(robot_ip_address) # Calibrate robot if robot needs calibration client.calibrate_auto() # Changing tool client.update_tool() # Commence du fonction pick_n_place pick_n_place_version_2(client) # Releasing connection client.close_connection()
- Dans les lignes 5-12 on définit les positions de saisir et déposer
- Dans ligne 17 il faut définir la vitesse du mouvement du gripper
- Dans les lignes 19-20 on définit les positions un peu dessus des positions de saisir et déposer
- Dans les lignes 22-35 on fait le process de se rendre jusqu'à la position de prélèvement avec move_pose, d’avant saisir un objet avec close_gripper, on ouvre le gripper avec open_gripper. Après on se rend à la position de placement et on y place l’objet.
- Dans ligne 47 update_tool() est pour équiper un nouvel outil. Cette fonction scannera les connexions au moteur et ajoutera le nouvel outil
- Dans ligne 51 on déconnecte alors le robot.
Code pour utiliser l’autre outil
from pyniryo import* robot = NiryoRobot("10.10.10.10") robot.calibrate_auto() robot.update_tool() # Pour relâcher un objet avec n’importe quel outil, vous pouvez utiliser la fonction robot.release_with_tool() robot.move_pose(0.2, -0.1, 0.25, 0.0, 1.57, 0.0) # Afin d’attraper des objets avec n’importe quel outil, vous pouvez utiliser la fonction robot.grasp_with_tool() robot.move_pose(0.2, 0.1, 0.25, 0.0, 1.57, 0.0) robot.release_with_tool() robot.close_connection()
Dans ligne 9 pour relâcher un objet avec n’importe quel outil, on peut utiliser la fonction release_with_tool()
- Open gripper pour les grippers
- Push Air pour la Pompe à Vide
- Deactivate pour l’Électroaimant
Dans ligne 13 Afin d’attraper des objets avec n’importe quel outil, on peut utiliser la fonction grasp_with_tool()
- Close gripper pour les grippers
- Pull Air pour la Pompe à vide
- Activate pour l’Électroaimant
Code pour utiliser le gripper
from pyniryo import* from PIL import Image # PIL = Pillow Library #source website https://note.nkmk.me/en/python-numpy-image-processing/ #another source https://www.pluralsight.com/guides/importing-image-data into-numpy-arrays robot = NiryoRobot("10.10.10.10") #hotspot mode robot.calibrate_auto() robot.update_tool() #getting image img_compressed = robot.get_img_compressed() img_array = uncompress_image(img_compressed) #displaying show_img_and_wait_close("img_stream", img_array) #transfers image_array into image file and saves it in the designated path im_jpg = Image.fromarray(img_array) img_array.save('~/Desktop/image_niryo.jpg') # ~ = user’s home directory
- Dans la ligne 2 on utilise la bibliothèque PIL sauvegarder l’image sur son ordinateur
- Dans la ligne 9 on met à jour les outils connectés au robot pour pouvoir utiliser le camera.
- Dans la ligne 12 on obtient l’image du flux vidéo dans un format compressé pour éviter de saturer le réseau.
- Dans la ligne 13 on décompresse l’image compressé.
- Après on affiche l’image et la sauvegarde sur l’ordinateur.
Traitement d'image et Aphelion
Aphelion, un logiciel pour le traitement d’image
Depuis plus de 25 ans, ADCIS fournit des produits logiciels de traitement et d’analyse d’images qui sont reconnus et appréciés. Aphelion Dev est le logiciel de choix pour les personnes qui développent des applications avancées en imagerie. Il bénéficie de l’expertise de l’équipe de développement d’ADCIS et des partenariats stratégiques avec des laboratoires de recherche internationaux. De plus, l’équipe d’ADCIS est reconnue pour l’efficacité et le professionnalisme du support technique fourni à ses clients.
L’interface utilisateur d’Aphelion Dev exploite les plus récents outils de Windows®, tels les composants .Net® et les outils de développement associés. Cette interface guide le nouvel utilisateur depuis l’acquisition d’images, en passant par l’analyse et le traitement, jusqu’à la génération d’un rapport d’analyse prêt à l’emploi. Dev fournit aux utilisateurs les plus expérimentés des outils pour développer des traitements avancés et automatisés qui deviennent rapidement des applications prêtes à être déployées. Plusieurs langages de macro-commandes sont disponibles afin d’automatiser une application d’imagerie.
Le traitement d’image, qu’est ce que c’est?
Trois grandes étapes résumées:
- Acquisition : de la scène physique à une forme numérique (capteur + système de numérisation)
- Pré-traitement : amélioration de la qualité de l’image (Restauration d’images, compression d’images, amélioration d’images)
- Analyse : extraction de l'information essentielle dans l’image (Segmentation, Représentation et Description structurelle, Reconnaissance des formes)
- Interprétation : description sémantique de l’image
(Passage à la description sémantique en regard à certains objectifs, Mesure de paramètres sur des formes, Description du contenu de la scène en termes de concepts non mathématiques, Modèles de connaissance pour estimer et prendre des décisions, Gestion de la base de connaissances, Système d’interrogation, Evaluation de la pertinence des réponses, Prise de décision)
Deux niveaux de traitement des images : Haut Niveau et Bas Niveau
Notre démarche s’inscrit dans le traitement d’image de bas niveau où les différentes étapes sont:
- Acquisition, numérisation
- Transmission, compression
- Rehaussement, restauration, amélioration, filtrage (prétraitements)
- Segmentation (contours, régions, texture)
- Reconnaissance des formes
- Compréhension de l’image
- Aide au diagnostic
- Commande d’automatismes
Le Haut Niveau de traitement d’image n’est pas nécessaire dans notre cas de figure, il est surtout utile pour des tâches plus complexes et sert à réaliser une interprétation d'images utilisant des connaissances expertes.
Domaines d’application du traitement d’images
-Imagerie aérienne et spatiale (Ressources naturelles et humaines, surveillance, météorologie,..)
-Industrie (Contrôle, Inspection et mesures automatiques, Vision robotique)
-Médecine (Cytologie, Tomographie, Echographie)
-Sciences (Interventions en milieu confiné, Astronomie, Robotique mobile,
-Biologie, Microscopie électronique)
-Art et communication (Télévision et vidéo, Transport information visuelle, Photographie, Edition, Archivage)
-Domaine militaire (Surveillance, Guidage automatique et poursuite d'engins, Topographie)
Dans notre cas de figure, il est question d’application dans l’industrie, ou on retrouve des projets qui s’apparentent au nôtre.
Prétraitement : amélioration de la qualité de l’image (Amélioration et Restauration d’images)
Amélioration de l’image:
Nous allons d’abord nous pencher sur l’amélioration d’image avant de passer à la restauration. Les techniques de prétraitement visant à l’amélioration de la qualité visuelle de l’image sont :
- Modification de l’histogramme
- Recadrage de la dynamique (Linéarisation)
- Egalisation
Modification d’histogramme par recadrage de la dynamique (Linéarisation)
L'intérêt des histogrammes réside dans l’évaluation de la qualité de la numérisation (amélioration) et l’adaptation de la dynamique des densités à la dynamique des niveaux de quantification Le redressement permet d'aligner horizontalement une image numérisée pour compenser l'inclinaison. Cette option permet de régler le contraste et la luminosité des images en couleur ou en niveaux de gris. Convertit les images en couleur en images à niveaux de gris.
Modification par égalisation
En traitement d'images, l'égalisation d'histogramme est une méthode d'ajustement du contraste d'une image numérique qui utilise l'histogramme. Elle consiste à appliquer une transformation sur chaque pixel de l'image, et donc d'obtenir une nouvelle image à partir d'une opération indépendante sur chacun des pixels.
Restauration de l’image:
A présent nous allons nous concentrer sur la restauration de l’image. L’objectif de la restauration est d’éliminer au maximum les distorsions du système d’acquisition afin d’obtenir une image la plus proche possible de l’image idéale. Ces distorsions peuvent êtres d’origines différentes. En effet, le “bruit” peut être lié au contexte de l’acquisition (mouvement, modification ponctuelle des conditions d’éclairage le rendant impossible à corriger sans l’opérateur humain), au capteur (distorsion des niveaux de gris ou à une mauvaise mise au point), à l’échantillonnage (effet « poivre et sel » au niveau de la discrétisation spatiale, mais peut être également lié à la nature de la scène Les techniques de prétraitement visant à la restauration de l’image après dégradations se décomposent en deux partie qui sont le lissage linéaire et le lissage non linéaire.
L’hypothèse fondamentale derrière le filtrage linéaire est que la moyenne de plusieurs échantillons devrait réduire le bruit (i.e. l’écart-type du signal résultat du moyennage de N échantillons devrait être plus faible que celui de la distribution de laquelle proviennent ceux-ci. Il se caractérise par une invariance à la position (le résultat du filtrage ne dépend que du voisinage d’un pixel et non de la position absolue du pixel dans l’image, et respecte les principes de mise à l’échelle et de superposition Le filtrage non linéaire quant à lui permet de réduire le bruit impulsionnel (multiplicatif), ce que le filtre moyenneur (ou même gaussien) n’arrive pas à faire, préserve mieux les discontinuités (sans les adoucir), est généralement plus coûteux en temps de calcul que le filtre linéaire moyenneur, et ne respecte pas les propriétés de commutativité et d’associativité du filtre linéaire
Analyse : extraction de l'information essentielle dans l’image (Segmentation)
On appelle segmentation d'une image l'opération consistant à identifier les structures d'intérêt dans cette image. On distingue deux types d'approches pour la segmentation : contour ou région. Dans l'approche contour, on cherche à isoler le ou les contours des objets d'intérêt. Le résultat se présente en général sous la forme d'un ensemble de chaînes de pixels, et des traitements additionnels sont souvent nécessaires pour associer les contours aux objets d'intérêt. L'autre approche cherche à identifier des régions de pixels homogènes au sein de l'image. Le critère d'homogénéité peut être l'intensité, la couleur, ou même la texture locale. Le résultat se présente soit sous la forme d'une image binaire, soit d'une image étiquetée, chaque étiquette ou label correspondant à une région.
Seuillage:
Il existe plusieurs méthodes pour détecter de manière automatique la valeur du seuil à appliquer. L'une des plus répandues est la méthode d'Otsu. Elle consiste à faire l'hypothèse que l'image contient deux classes, décrites chacune par une partie de l'histogramme de l'image. La qualité du seuillage est quantifiée en mesurant la variance des niveaux de gris de chaque classe. On cherche ensuite la valeur de seuil qui minimise les variances des deux classes, et on utilise cette valeur pour binariser l'image
Le but est d’affecter chaque pixel d’une image en niveaux de gris à une classe. Les classes correspondent aux intervalles de niveaux de gris. Le principe consiste à extraire des seuils à partir de l’histogramme (image/région), avant de passer à la classification d’un pixel p par comparaison de I(p) aux seuils
Etat d'avancement du SEMESTRE 7
Séance du 10.10.2022
Ayant débuté notre projet au semestre 7 et non au semestre 6, nous avons fait les premières recherches sur notre sujet. Pour préciser on fait des recherches sur le robot Bra Niryo Ned 1. L'objectif du projet sera de réaliser le traitement d’image avec un capteur de vision (caméra), cela signifie prendre l’image avec la caméra et la transmettre à un logiciel de traitement d’image (Aphelion) pour enfin envoyer l’image traitée à un robot bras et exécuter l’instruction.
Date: 21.10.2022
Aujourd’hui on a essayé de mettre en place une communication avec le robot bras Niryo Ned 1. On a essayé d’abord de se connecter avec le raspberry Pi, qui est le système d’exploitation du Niryo. On a essayé de mettre en place une communication visuelle avec VNC Viewer, mais on a rencontré plusieurs problèmes avec cette méthode. Par exemple, il n’était pas possible de mettre à jour notre programme en vue de corriger les erreurs. Mais on a réussi à se connecter avec le robot via le programme Niryo Studio, mais également à réaliser la communication avec le robot directement via remote sur notre computer, à savoir avec Pyniryo, qui est un TCP API fait avec python. Aussi, on s’est familiarisé avec le code fourni dans la documentation PyNiryo, bien que nous ayons eu des difficultés à coder le contrôle des pinces du robot.
Date: 28.10.2022
Aujourd’hui, on a essayé de fixer le problème de la pince, mais on n’a pas réussi. Puis, on a avancé sur la communication d'une caméra avec le robot bras. L’image prise par le robot est de meilleure qualité si on connecte la caméra au USB Port 3.0 que 2.0.
Date: 18.11.2022
Aujourd’hui, on a consulté différentes sources sur internet afin d’essayer de fixer le problème de la pince. On a également échangé avec l’autre groupe qui travaille sur le Niryo Ned 1. Malheureusement, pas de succès. On a décidé d'abandonner le problème de pince compte-tenu du fait que la priorité est le traitement d’image.
Date: 21.11.2022
Aujourd’hui, on a mis en place la communication avec la pince via une bibliothèque différente, à savoir la bibliothèque Python Ros Wrapper mais il était plus compliqué de commander le Niryo. Nous avons également contacté le bureau d’Aphelion afin d’obtenir la clé d’activation en vue d’obtenir la licence pour une période d’essai d’un mois.
Date: 25.11.2022
Aujourd’hui, on a écrit le code pour obtenir l’image d’une caméra et on a commencé à se familiariser avec le logiciel Aphelion. On a relevé la nécessité d’une documentation plus approfondie pour mieux comprendre le logiciel. On a demandé au professeur quelques documents/ TP concernant Aphelion.
Date: 28.11.2022
Aujourd’hui on a travaillé avec le logiciel aphelion pour le comprendre mieux. On a appris ce que la signification de l’histogramme. L’abscisse donne l’information concernant la couleur, du gris et ses différentes nuances au RGB (rouge, bleu et vert). On a cherché à comprendre le fonctionnement du traitement d' image, à savoir la convolution de chaque pixel de l’image par une matrice symétrique. En fonction de la valeur de la matrice on peut obtenir différents résultats via le traitement d'image. Après plusieurs tentatives pour contrôler le robot à travers Aphelion qui se sont soldées par des échecs. Finalement, la seule solution pour atteindre cet objectif aurait été d’ajouter la bibliothèque PyNyrio au logiciel Aphelion, ce qui n’est pas possible comme ce dernier n’est pas OPENSOURCE.
Date: 08.12.2022
On a échangé avec Matéo Pourrier, futur membre de notre groupe de projet, qui nous rejoindra au prochain semestre. On a pris le temps de parler de l’état d’avancement du projet, de ce qui a été réalisé jusqu’à maintenant (code de contrôle du robot Niryo, traitement d’image via Aphelion), mais également des perspectives futures que nous prévoyons par la suite. Cet échange nous a permis de faire le point sur la soutenance du 06/01.
Date: 15.12.2022
Aujourd’hui, on a fait le bilan avec M.Lakhal pour faire le point sur l’avancement de notre projet, sur la soutenance et sur les perspectives futures que nous avons pour le prochain semestre.
Perspectives
Création d’une interface Format : Page web
Fonctionnalités : Capturer des images à distance
Effectuer le traitement de l’image
Transmettre les données obtenues au robot et le Commander
Planning du S8
SEMESTRE 8
Contexte et objectifs du semestre 8
Introduction
Le Projet s’inscrivant dans le cadre des études en Systèmes Embarqués (Semestres 7 & 8) consiste en la réalisation d’une interface liant le contrôle du bras robotique et le traitement d’image. Si pendant le Semestre 7, nous nous sommes plus concentrés sur le contrôle du robot Niryo, nous avons consacré le semestre 8 à la mise en place de ces interfaces répondant à nos besoins.
Cahier des charges
Présentation du contexte général: Le projet décrit se déroule dans le cadre des Travaux Pratiques (TP) du cours SE5 (Systèmes Embarqués) et vise à lier le traitement d'image avec le contrôle d'un bras robotique Niryo.
Présentation contexte S7 : L'équipe de projet a d'abord travaillé sur le logiciel Aphelion pour le traitement d'image, tandis que le contrôle du robot était réalisé à l'aide du compilateur PyCharm. Cependant, l'équipe a rencontré des difficultés pour réaliser des interactions entre le traitement d'image et le contrôle du robot. Pour le semestre 8 (S8), l'équipe a dû réfléchir à une solution pratique pour répondre à leur besoin de lier ces deux aspects du projet.
Définition des objectifs S8: Les objectifs du projet sont les suivants :
Réaliser une interface d'accueil : Une interface d'accueil conviviale sera développée pour permettre à l'utilisateur de choisir entre les différentes fonctionnalités du projet, en l'occurrence le traitement d'image et le contrôle du robot, ainsi que faciliter la navigation entre les différentes interfaces.
Réaliser une interface de contrôle du robot avec un flux en direct de la caméra : L'équipe du projet développera une interface permettant de contrôler le bras robotique PyNiryo. Cette interface sera également connectée à une caméra en direct, ce qui permettra de visualiser en temps réel les mouvements du robot à l'aide de la caméra.
Réaliser une interface de traitement d'image : L'étudiant pourra choisir une image à traiter et écrire le code Python correspondant pour effectuer le traitement d'image souhaité. Une fois le code exécuté, l'image traitée sera affichée dans l'interface.
• En résumé, les objectifs du projet consistent à développer trois interfaces en Python : une pour le traitement d'image, une pour le contrôle du robot avec un flux en direct de la caméra, et une interface d'accueil pour faciliter l'utilisation globale du projet
Diagramme de Gantt
Cahier de spécifications
Description du Bras robotique Niryo:
• Bras de robot à 6 axes NED par Niryo
• Comprend un robot collaboratif à 6 axes open-source
• Conçu pour l'éducation, la formation professionnelle et la recherche
• Équipé du système EasyConnect
• Dispose d'une structure en aluminium pour donner robustesse et fluidité
• Basé sur Ubuntu 18.04 et ROS Melodic
• Reproduit tous les mouvements requis dans les processus industriels
Le bras de robot à 6 axes NED-Niryo est un robot à 6 axes basé sur des technologies open source conçues pour l'éducation, la formation professionnelle et les laboratoires de recherche. Développé par Niryo et fabriqué en France, Ned est le partenaire idéal pour l'enseignement et la recherche. En effet, ce robot offre la possibilité d'apprendre et de tester de nouveaux usages de la robotique orientés vers l'Industrie 4.0.
Le langage de programmation python :
Python est un langage de programmation interprété, multi paradigme et multiplateformes. Il favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl.
Tkinter:
Tkinter (de l'anglais Tool kit interface) est la bibliothèque graphique libre d'origine pour le langage Python, permettant la création d'interfaces graphiques. Elle vient d'une adaptation de la bibliothèque graphique Tk écrite pour Tcl.
Pycharm :
PyCharm est un IDE spécialisé pour les langages de programmation Python et Django. Il offre de riches et nombreuses fonctionnalités en matière d'édition, de débogage, de développement et de tests.
La caméra :
La caméra est branché au robot eti permet de capturer l’image concernée par le traitement d’image.
• En ce qui concerne les ressources, l’école Polytech nous a fourni un bras robotique Niryo ainsi qu’une caméra. Nous avons uniquement eu besoin de nos ordinateurs respectifs pour travailler sur ce projet.
Notes opérationnelles
a) Démarches et moyens
1- Définition des conteneurs
Ce bout de code va nous permettre de définir l’interface d'accueil ,après cette étape là ,on a passé à définir les boutons pour accéder à chaque interface de travail. Pour chaque interface on a défini une fonction qui va permettre de créer et de détailler le fonctionnement de chaque interface.
On prend comme exemple l’interface de traitement d’image
Ce bout de code représente juste une partie de la définition de la fonction de cette interface.Après la définition de l’interface et de ses caractéristiques qui diffèrent pour chaque interface, on passe à l’étape de déclaration des Composants.
2- Déclaration des composants
Après avoir créé nos fenêtres et déclaré leur géométrie et caractéristiques nous avons dû ajouter à notre interface des composants tels que des boutons, des labels servant à accueillir du texte, ou encore des canvas, composants servant à accueillir des images ou des flux vidéos.
Exemple de déclaration d’un bouton :
Déclaration d’un label :
Ces lignes de codes permettent d’instancier un composant, c'est-à-dire de créer en mémoire un objet qui garde en mémoire les informations et caractéristiques du composant.
3- Le placement des composants
Pour que les différents composants dont nous avions besoin pour accomplir nos objectifs apparaissent dans les interfaces que nous avons programmé, il faut désormais les placer dans la géométrie des différentes fenêtres.
On utilise pour cela des outils appelés gestionnaires de placements, ou Layout Managers en anglais. Tkinter l’outil de programmation d’interface que nous utilisons permet l’utilisation de différentes méthodes de gestion de placement des composants.
Dans notre projet nous avons utilisé les méthodes .place(), .pack() et .grid()
La stratégie de positionnement pack :
Elle divise le conteneur (dans notre projet les conteneurs sont les fenêtres créées pour les différentes interfaces) en cinq parties, le centre et les quatre côtés. Elle permet de disposer les composants de différentes manières autour de cette division du conteneur via ces différentes options.
Le placement des composants de l’interface d'accueil ont été réalisés à l’aide de cette stratégie de positionnement :
La stratégie de positionnement place :
Cette stratégie est celle à utiliser lorsque l’on souhaite placer les composants de manière précise dans un conteneur. En effet, elle effectue le placement d’un composant aux coordonnées (x,y) passées en paramètre.
Le placement des composants de l’interface de traitement d’image ont été réalisés à l’aide de la stratégie de positionnement place :
La stratégie de positionnement grid :
Cette dernière stratégie de positionnement permet de découper le conteneur en une grille contenant plusieurs cellules, chaque cellule étant désignée par sa ligne et sa colonne dans la grille. On place alors les composants dans la ou les cellules qui nous intéressent. Les options de la méthode rowspan et columnspan permettent d’assigner à un composant plusieurs cellules en largeur ou en hauteur.
Le placement des composants de l’interface de contrôle du robot ont été réalisés à l’aide de la stratégie de positionnement grid (exemple sur les boutons attraper et relâcher) :
Finalement, les trois membres du groupe ayant participé activement au code du projet et ayant des sensibilités différentes au niveau du placement des composants, nous nous sommes retrouvés à utiliser les trois stratégies de placement proposées par tkinter et nous avons ainsi pu comprendre certains des avantages et inconvénients de chacune de ces méthodes.
4- Les fonctions de commande
Maintenant que nous avions réussi à construire nos fenêtres (conteneurs) et les différents boutons et label dont nous avions besoin pour atteindre nos objectifs et garder une esthétique cohérente, il fallait désormais s'intéresser au code fonctionnel, aux fonctions que nous allions associer aux boutons en tant que “command”.
Exemple pour le bouton Homepose :
On définit tout d’abord la fonction de commande. On intègre ensuite à la fonction de commande l’entièreté du code que l’on souhaite exécuter lorsque l’utilisateur appuie sur le bouton.
Ici pour le bouton Homepose on se sert simplement d’une fonction venant de la librairie PyNiryo qui permet de remettre les axes du robot en position initiale : .move_to_home_pose()
Enfin lors de la déclaration du bouton, on le lie à sa fonction de commande via l’option de déclaration “command=home_pose”.
Ces deux étapes, construction de la fonction de commande, et liaison avec le composant qui doit la déclencher, suffisent à obtenir un composant au comportement fonctionnel. Nous avons par la suite répété l’opération en créant une fonction de commande pour chacune des actions proposées par nos interfaces, toujours en nous basant sur la librairie de commande du robot PyNiryo et sur les possibilités qu’elle nous offrait.
5- La phase de test
Après avoir réalisé une partie fonctionnelle du code que nous trouvions satisfaisante, nous sommes passés à la phase de tests. A l’aide du robot Niryo Ned 1 de polytech nous avons testé toutes les fonctionnalités de notre interface. Nous nous sommes ainsi rendu compte de nombreuses erreurs dans le code que nous avons pu corriger. Nous avons également pu nous assurer que toutes les possibilités offertes par l’interface étaient fonctionnelles. Toutefois, certains paramètres non contrôlables par l’interface elle-même (tel que la connexion wifi de la machine exécutant l’interface avec le robot utilisé) impliquent que certains cas d’erreurs subsistent. La prochaine étape de notre projet a été de trouver une parade à ces cas d’erreur.
6- La gestion des cas d’erreurs : Les exceptions
Dans un souci de simplicité pour l’utilisateur nous avons cherché à minimiser au maximum les cas d’utilisation de l’interface menant à des erreurs. Heureusement les langages orientés objets permettent pour cela de s’appuyer sur un élément très intéressant : les exceptions.
En langage objet une exception est un objet qui représente une erreur, décuplant les possibilités de gérer cette erreur. Une fonction attrapant une exception pourra ainsi ignorer l’erreur ou la transmettre à la fin de son exécution. Une des erreurs les plus fréquentes de notre interface est une erreur de connexion lors de la connexion au robot, ou lors de la création d’une instance ROS servant à accéder à la caméra du robot. En effet si on essaye d’effectuer une de ses actions sans être connecté au wifi du robot, on obtiendra forcément une erreur et on arrêtera le fonctionnement de cette partie de l’interface, ce qui n’est pas acceptable.
L’intégration de blocs try catch servant à intercepter l’exception causée par cette erreur nous permet d’isoler cette erreur de l'exécution du reste du code, et ainsi de ne pas causer d’erreur au niveau du fonctionnement de l’interface, tout en renvoyant un message d’erreur pour avertir l’utilisateur du problème.
Exemple du cas d’erreur explicité précédemment :
Dans la fonction de commande associée à “Connexion” on a placé un bloc try catch, ainsi qu’un appel à la messagebox de tkinter pour renvoyer un message informatif en cas d’erreur comme ceci :
Ainsi si on est pas connecté au wifi d’un robot et que l’on essaye d’appuyer sur connection on obtient ce message d’erreur :
Nous avons appliqué ce principe de gestion des erreurs pour certains cas identifiés comme entravant le fonctionnement de l’interface et ainsi limiter les problèmes lors de l’utilisation de celle-ci.
7- La recherche d’ergonomie
Finalement, nous avons consacré nos derniers efforts à la recherche d’ergonomie. En effet, pour améliorer notre travail et faciliter l’utilisation de l’interface, nous avons mis en place plusieurs démarches :
Le visuel de l’interface :
Pour simplifier l’expérience utilisateur nous avons choisi de garder l’interface sobre et la plus compréhensible possible. Au niveau de l’interface de traitement d’image, nous avons choisi d’expliciter les actions en proposant des boutons dont le design est basé sur des images représentant leur fonctionnalité. Pour le panneau de contrôle nous avons organisé cela de manière logique en proposant des groupes de composants qui ont des points communs au niveau de leur fonctionnalité.
L’information transmise à l’utilisateur :
Lors du développement de ces interfaces il nous a plusieurs fois semblé nécessaire pour la bonne utilisation de celles-ci de transmettre des informations supplémentaires sur son fonctionnement à l’utilisateur.
Dans cet objectif nous avons décidé d’utiliser une technique assez répandue dans le développement logiciel et d’interface utilisateur, les info-bulles (tooltips en anglais). Les info-bulles ou bulles d’aide sont des messages qui apparaissent lorsque l’utilisateur passe sa souris au-dessus d’un composant de l’interface. Elles permettent donc de transmettre de manière ergonomique et efficace de l’information à l’utilisateur sur la fonction logique associée au composant survolé.
Pour cela nous avons utilisé la librairie PMW (PythonMegaWidgets) qui contient de nouvelles classes de composants pour le développement d’interface via tkinter. Cette librairie nous permet d’utiliser une classe construite spécifiquement pour réaliser des info-bulles, la classe Baloon. De cette manière nous avons pu équiper nos composants d’informations supplémentaires et en simplifier l’utilisation :
Exemple de résultat obtenu pour les info-bulles :
b) Résultats commentés et justifiés
Interface d'accueil
Interface simple qui permet de donner le choix à l’étudiant de choisir l’interface qu’il souhaite utiliser, avec la possibilité de revenir vers le menu d’accueil et ainsi de passer de l’une à l’autre avec facilité.
Interface de traitement d'image
L’objectif de cette interface c’est d'offrir à l’étudiant une interface de traitement d’image en se basant sur l’image capturée par le robot.
Cette interface comporte plusieurs zones propres aux différentes fonctionnalités qu’on a voulu incorporer:
• Une zone de texte où l’étudiant va écrire son code de traitement d’image avec le langage de programmation python.
• Une zone d’affichage des erreurs de syntaxe qui permet d’indiquer à l’étudiant les erreurs.
• Une zone pour afficher l’image avant traitement.
• Une zone pour afficher l’image après traitement.
De plus, nous avons implémenté une zone où on peut apercevoir différents boutons avec différentes fonctionnalités:
• Un bouton pour sélectionner le code python dans le cas où l’étudiant possède déjà le code dans son système de fichiers
• Un bouton pour sauvegarder le code dans l’emplacement où l’étudiant veut enregistrer son code
• Un bouton pour exécuter le programme à condition que le programme soit sauvegardé dans le système de fichiers
• Un bouton pour sélectionner l’image qu’on veut traiter et afficher dans la zone dédiée à l’image avant traitement
• Un bouton pour sauvegarder l’image après traitement
• Un bouton de capture d’image. Ce bouton est connecté au robot Niryo et permet de récupérer l’image capturée par la caméra connectée au robot
Interface de contrôle du robot
L’objectif de cette interface est de permettre à l’utilisateur de contrôler simplement les mouvements des axes du robot et les actions permises par ses outils.
Pour atteindre les objectifs au niveau du panneau de contrôle du robot nous avons choisi de diviser l’interface en différentes sections, chacune se chargeant d’un type d’action nécessaire à l’utilisation du robot :
La section “Connection et calibrage”: Cette section permet à l'utilisateur d’établir une connexion avec un robot au wifi duquel la machine exécutant l’interface doit être connectée.
• Le bouton Homepose permet quant à lui de déplacer les axes du robot à leur position initiale
• Le bouton Learning mode permet quant à lui de passer le robot en mode apprentissage, ce qui arrête sa commande actuelle
• Enfin le bouton Déconnexion permet de fermer la connection au robot lorsque l’on a fini d’utiliser l’interface
La section “Contrôle du bras”: Cette section permet d’envoyer une commande pour déplacer l’un ou plusieurs des axes du robot, au niveau du bras ou de l’outil.
• Elle comporte 6 entrées correspondant à chaque axe déplaçable du robot. Chacune de ses entrées accepte une valeur décimale comprise dans une plage de valeurs.
• Le bouton Envoi commande permet ainsi de transmettre la commande choisie par l’utilisateur au robot. Ce bouton contient des blocs de gestion des exceptions (erreurs de code) potentielles et génère un message d’erreur pour l’utilisateur s'il ne respecte pas la plage de valeur, envoie une commande incomplète ou n’est pas connecté à un robot. Cette gestion des exceptions fait de cette section, la plus importante de l’interface, une section efficace et qui ne risque en aucun cas de compromettre le bon fonctionnement de l’interface.
La section “Utilisation d’outils”: Cette section permet de gérer simplement l’utilisation de l’outil connecté au robot.
• Le bouton détection d’outils permet au robot d’actualiser son référencement de l’outil qui y est connecté, et donc notamment de détecter un changement d’outil si il y en a un, ou encore de détecter un outil si celui-ci n’était pas déjà connecté au démarrage du robot.
• Ainsi un clic sur ce bouton permet d’être à jour au niveau de la détection de l’outil en donc le fonctionnement des boutons Attraper et Relâcher, qui permettent de commander les actions de fermeture et d’ouverture de l’outil en cours d’utilisation.
La section “Caméra”: Cette section sert à visualiser les informations données par la caméra connectée au robot. Elle permet d’avoir un rendu visuel de ce que le robot voit à mesure que l’on modifie sa position, mais également d’enregistrer une image du stream pour la garder en mémoire ou pour appliquer ensuite du traitement d’image sur celle-ci.
• Le bouton Ouvrir stream caméra gère l’ouverture d’une instance ROS à l’aide de la librairie PyNiryo. L’instance ROS était l’unique solution que nous avons pu trouver qui nous permettait de transmettre un flux vidéo et de l’afficher dans l’interface. En effet, cette instance ROS permet d'accéder aux fonctions de Vision de la librairie PyNiryo étant donnée que celles-ci sont basées sur ROS.
Nous avons donc créé un composant tkinter personnalisé via la classe Video_canvas dont le comportement est codé dans “video_canvas.py” pour pouvoir afficher les images en direct.
Nous avons ensuite codé une récupération d’image à la caméra via les fonctions de la librairie, puis enfin traité cette image.
On la décompresse, on inverse les couleurs car les fonctions d’affichage utilisent le format d’image RGB tandis que les fonctions de la librairie récupèrent l’image de la caméra sous la forme d’un tableau au format BGR. Par la suite via des outils comme PIL.Image une librairie de traitement d’image python on transforme l’image en un format ImageTk.PhotoImage que tkinter sait afficher dans un widget.
• Ainsi on obtient un stream vidéo fonctionnel que l’on peut arrêter au besoin via le bouton Quitter le stream.
Etat des lieux
Comparaison entre Aphelion et l’interface
Il y a plusieurs raisons pour lesquelles il a été plus concluant de créer sa propre interface pour le contrôle d'un bras robotique et le traitement d'image plutôt que d'utiliser une solution existante telle que Aphelion
Flexibilité : Nous avons pu personnaliser l'expérience en fonction de nos besoins spécifiques. Nous avons conçu une interface qui est plus facile à utiliser et qui répond mieux à nos exigences en matière de contrôle ou de traitement d'image.
Intégration : Nous avons pu l'intégrer facilement à notre environnement de travail et aux outils que nous utilisions déjà pour le projet (Linux, bibliothèques PyNiryo pour le bras robotique, PyCharm,...etc)
Coût : En utilisant une solution existante telle que Aphelion, nous devons payer pour des fonctionnalités que nous n’utilisons pas ou qui ne sont pas nécessaires pour notre projet. En créant notre propre interface, nous avons pu économiser de l'argent en utilisant uniquement les fonctionnalités dont nous avions besoin.
Apprentissage : Notre équipe a pu apprendre de nouvelles compétences en programmation et en développement de logiciels, ce qui nous sera bénéfique dans nos futurs projets.
• En résumé, créer sa propre interface pour le contrôle d'un bras robotique et le traitement d'image a pu nous offrir plus de flexibilité, une meilleure intégration, une réduction des coûts et une opportunité d'apprentissage pour notre équipe.
Limites sur le travail réalisé
L'interface pour le bras robotique Niryo offre une gamme complète de fonctionnalités pour la perception visuelle, mais il y a certaines limites et contraintes à prendre en compte lors de son utilisation.
Tout d'abord, l'une des principales limites de l'interface Python est la contrainte concernant la nomination des images que nous voulons "traiter". Notre code contraint en effet l’utilisateur à nommer “after.png” l’image dont il souhaite faire le traitement.
En outre, l’absence du plateau jouant le rôle de référentiel du set vision nous a limités dans notre progression pour faire attraper des objets au robot via traitement d’image. Toutefois, cette application nous paraît être un axe de développement potentiel simple et intéressant de l’interface.
De même, étant donné que nous n'avions pas la camera du set vision, nous avons eu des difficultés pour trouver la camera. Nous avons néanmoins trouver une solution transitoire pour pouvoir traiter le convoyeur par la suite, rendant la camera immobile au-dessus d'un point donné.
Travail restant et Voie envisagée pour la suite du projet
Convoyeur: Le module de vision Niryo Vision est conçu pour être utilisé avec un système de convoyeur pour les tâches de tri et de conditionnement. Le convoyeur est utilisé pour transporter les objets de manière fluide et régulière devant le module de vision, où ils sont analysés par le module de vision. Le bras robotique Niryo One peut alors être programmé pour saisir les objets détectés et les déplacer vers un emplacement prédéfini.
La bibliothèque PyNiryo Vision offre une fonctionnalité de suivi de convoyeur pour faciliter cette tâche. Cette fonctionnalité permet de suivre le mouvement du convoyeur en temps réel, en utilisant la caméra du module de vision. Le module de vision peut détecter la position et l'orientation des objets sur le convoyeur, et envoyer des instructions au bras robotique pour qu'il saisisse les objets lorsqu'ils atteignent un emplacement prédéfini.
Le suivi de convoyeur peut être réalisé en utilisant des algorithmes de vision avancés, tels que la segmentation d'image et la reconnaissance de formes, pour détecter les objets sur le convoyeur et estimer leur position et leur orientation. Le module de vision peut également utiliser des marqueurs spéciaux sur le convoyeur pour aider à suivre le mouvement et la position des objets.
En résumé, la bibliothèque PyNiryo Vision offre une fonctionnalité de suivi de convoyeur pour faciliter la tâche de tri et de conditionnement. Cette fonctionnalité permet au module de vision de suivre le mouvement du convoyeur en temps réel et de détecter la position et l'orientation des objets sur le convoyeur. Le bras robotique Niryo One peut alors être programmé pour saisir les objets détectés et les déplacer vers un emplacement prédéfini.
Traitement d’image:
La bibliothèque PyNiryo Vision est une extension logicielle open source de la bibliothèque PyNiryo développée par la société française Niryo. Cette bibliothèque est conçue pour être utilisée avec le bras robotique industriel Niryo One et le module de vision Niryo Vision.
PyNiryo Vision permet aux développeurs de créer des applications de robotique avancées en utilisant Python, en fournissant une interface simplifiée pour interagir avec le module de vision de Niryo. La bibliothèque permet de récupérer des images de la caméra du module de vision et de les traiter en temps réel à l'aide d'algorithmes de traitement d'image avancés tels que la reconnaissance d'objets, la segmentation d'image, la détection de mouvement, etc.
En utilisant PyNiryo Vision avec le bras robotique Niryo One, il est possible de réaliser des tâches de manipulation d'objets complexes en utilisant la perception visuelle. Par exemple, le robot peut être programmé pour détecter des objets spécifiques, les saisir et les déplacer vers un emplacement prédéfini. Cette fonctionnalité est très utile pour les tâches de pick-and-place, d'assemblage, de tri, de conditionnement, etc.
En résumé, PyNiryo Vision est une bibliothèque logicielle qui permet aux développeurs de créer des applications de robotique avancées en utilisant Python avec le bras robotique industriel Niryo One et le module de vision Niryo Vision.
Voici quelques-unes des fonctions principales de la bibliothèque PyNiryo Vision liée au bras robotique Niryo :
• Traitement d'images : PyNiryo Vision offre une gamme complète de fonctions de traitement d'image telles que la segmentation, la reconnaissance de formes, la reconnaissance de couleur, la détection de mouvement, etc. Ces fonctions permettent au robot de comprendre l'environnement dans lequel il évolue et de prendre des décisions en conséquence.
• Détection d'objets : La bibliothèque PyNiryo Vision peut être utilisée pour détecter des objets spécifiques dans l'environnement du robot. Cette fonctionnalité est utile pour la manipulation d'objets, où le robot doit être en mesure de localiser les objets, de les saisir et de les déplacer vers un emplacement prédéfini.
• Suivi de mouvement : La bibliothèque permet de suivre les mouvements des objets dans l'environnement en temps réel. Cette fonctionnalité est utile pour suivre les mouvements des objets qui sont en mouvement et pour les saisir avec précision.
• Système de coordonnées : La bibliothèque PyNiryo Vision fournit un système de coordonnées pour le module de vision Niryo. Ce système permet de connaître la position et l'orientation des objets dans l'environnement du robot. Cette information est essentielle pour la planification des mouvements et la saisie d'objets.
En utilisant ces fonctions, les développeurs peuvent créer des applications de robotique avancées pour le bras robotique Niryo One qui utilisent la perception visuelle pour des tâches de manipulation d'objets plus complexes.
Rapport d'avancement
18/01/2023:
Création d’un compte github pour héberger le projet
Essais de codage de l’interface en python grâce à tkinter : Test de l’utilisation de la librairie opencv pour le traitement d’image : simple à lier à l'interface grâce à une importation du module cv2 Création du dossier S8 contenant ce rapport d’avancement ainsi que le cahier des charges
Code du contrôle du robot en orienté objet dans l’interface : On a développé une classe robot et construit des méthodes qui permettent de contrôler le robot grâce à la librairie PyNyrio depuis des boutons de l’interface. De même on a élaboré des classes dédiées à la capture d’image et de vidéos que nous avons liées à notre interface. Pour le moment notre affichage des images à traiter est permis grâce à 2 panels. Nous avons également associées différentes méthodes de traitement d’image de OpenCV a des boutons pour faire office d’exemple et d’onglet de découverte des différentes manières de modifier une image.
Malheureusement notre robot a été pris par le deuxième groupe de projet travaillant sur Nyrio et le deuxième robot à un problème, il ne démarre pas correctement ce qui nous empêche de tester cette partie du travail. Apparemment le problème viendrait de la sim du robot selon l’autre groupe.
20/01/2023:
Mise en place d’un IDLE (Integrated Development and Learning Environment) Python via Tkinter que l’on souhaiterait éventuellement ajouter a notre interface pour permettre une interaction pédagogique avec l’utilisateur : En effet, un IDLE permettrait aux étudiants de coder et tester leur propres algorithmes de traitement d’image en python.
Développement d’un petit programme exemple montrant la marche à suivre aux futurs utilisateurs pour traiter des images via l’IDLE et leur présentant un exemple simple de traitement d’image, le négatif de l’image. Programme réalisé dans l’optique d'être le programme chargé par défaut au lancement de l’IDLE par l’utilisateur.
25/01/2023:
Au cours de cette séance nous avons décidé d’adapter note cahier des charges suite à l’échange qu’on a eu avec notre tuteur lors de la présentation. Nous avons également avancé sur le développement de l’interface. Nous avons commencé à implémenter les fonctions de contrôle du robot sur l’interface de manière à ce que le contrôle soit simplifié par l’actionnement des boutons. De plus, nous avons maintenant un robot sous la main à cette séance, ce qui nous a permis de tester quelques fonctions. En outre nous avons réussi a afficher comme nous le souhaitions des images aux abord de l’IDLE (notre tentative pour interaction pédagogique traitement d’image) ce qui va peut être nous permettre d’obtenir le résultat espéré, l’affichage des images est géré par l’interface et l'élève n’a plus qu'à coder via l’IDLE.
01/02/2023:
Travail sur le panneau de contrôle du robot. Construction d’une fonction “position initiale” servant à calibrer les moteurs du robot et à renvoyer celui-ci à sa position initiale, de manière à pouvoir avoir un retour facile a la position initiale pour des questions d’optimisation du temps. Cette fonction est associée à un bouton dans l’interface panneau de contrôle. Réflexions associés aux fonctions à coder pour modéliser le déplacement du robot par l’utilisateur
08/02/2023:
Avancée sur le panneau de contrôle et 1ère version
En ce qui concerne l’interface de contrôle du robot: Yatil besoin de laisser à l'utilisateur le choix de bien ou mal calibrer le robot? l’interface ne devrait-elle pas s’en charger elle-même et permettre à l'utilisateur de naivement contrôler uniquement le mouvement du robot? peut être moyen de mieux représenter les 6 entrées pour la command move joints Homepose, utile mais à étudier car la notion de home pose existe en vision avec le robot via observation_pose, la pose servant de repère au robot pour déterminer la position d’objets qu’il peut repérer grâce à une caméra Ajout des fonctions Grasp et Release Gripper Ajout des fonctions Get_Image pas encore complètement fonctionnelles
De plus, nous avons également avancé sur l’interface de traitement d’image en y ajoutant plus de fonctionnalités qui sont: La sélection d’image La sauvegarde d’image Difficultés rencontrées pour que l’utilisateur de l’interface retrouve le résultat attendu
15/02/2023 :
Panneau de contrôle du robot : grosses avancées au niveau du panneau de contrôle résolution des erreurs au niveau des fonctions d’utilisation des outils tel que le gripper ajout de nouvelles fonctions pour le learning mode, mais aussi pour arrêter la connection avec le robot de manière propre travail mais problèmes pour récupérer l’image du robot via les fonctions de vision de pyniryo, get_img_compressed() ne semble pas fonctionnelle.
Reflexion pour trouver des parades à cette difficulté technique : 1.utiliser d’autres librairies que pyniryo pour tenter de récupérer l’image a distance 2. transmettre via notre interface des instructions au robot en ssh ou via ROS pour récupérer des images
IDLE de traitement d’image : progression importante également nous avons réussi a trouver une alternative permettant de visualiser les images avant et apres le traitement proposé dans l’IDLE, ce qui permet a l’utilisateur d’avoir un retour direct des résultats de son traitement d’image, visuel et directement intégré a l’interface
Premiers essais de détection d’objets via les fonctions de traitement d’image de PyNiryo en utilisant une image deja existante tirée de la documentation
On constate que ce premier essai était plutot fructueux, toutefois les objets censés etre detectés a cause de leur couleur rouge sont en réalité détectés a cause de leur couleur bleu, nous pensons que cela est du au format de l’image qui est considérée RGB par pyniryo alors qu’elle est en réalité encodée en BGR par la librairie images que nous avons utilisé pour les premiers essais.
01/03/2023 :
Nous avons dans un premier temps travaillé sur le visuel de l’interface afin de la rendre plus présentable et plus professionnelle. Nous avons également songé à ajouter une fonctionnalité pour passer d’un thème à l’autre. Ensuite nous avons travaillé sur la possibilité de suivre un stream (display) vidéo de la webcam branchée au robot PyNiryo à partir de l’interface de contrôle. Enfin nous avons commencé sur la possiblité dans un premier temps d’afficher un maximum d’images par secondes ainsi que de réaliser des captures d’images de ce stream dans l’optique de traiter cette image.
06 et 08/03/2023:
Panneau de contrôle : (grosses avancées)
Travail pour intégrer le flux video obtenu grâce à la caméra du robot à l’interface du panneau de controle. Dans cet objectif création d’un label (composant tkinter) voué à contenir les images du stream vidéo
Problèmes rencontrés : Nécessité d’utiliser pyniryo1 et ROS pour obtenir les images de la caméra du robot conflit de librairies pyniryo 1 et 2 besoin de nouvelles fonctionnalités sur le label déstiné a afficher le stream de la caméra car le label tkinter classique ne permet pas ce que l’on souhaite
Solution : Création d’une nouvelle classe video_label Cela nous a permit de dissocier le code nécéssaire au stream du reste de l’interface en le placant dans la classe video_label : On evite ainsi les conflits de librairies pyniryo
En outre, développement de nouvelles méthodes __init__, __start_stream__ et __stop_stream__ permettant de gérer l’ouverture de la ROS instance qui permet d’avoir acces au fonctions de vision du robot, ainsi que sa fermeture.
Intégration de la fonction “Capture” à l’IDLE Afin de simplifier le traitement de l’image sur l’interface d’IDLE, cette fonction est indispensable
Création d’une interface globale liant les deux interfaces Nous avons réalisé une interface “frame” globale qui fait office de page d’accueil, à partir de laquelle on peut switch à volonté de l’IDLE à l’interface du contrôle du robot. L’interface de contrôle du robot a été intégrée sans soucis, il ne manque plus que l’intégration de l’IDLE en tant que page 2. Evidemment, une fois terminée, nous allons améliorer son rendu
Classe video_label :
Développement également d’une fonction test pour le threading, étant donné que cette classe a été développée lors de notre temps libre on a donc dû trouver une manière alternative de la tester sans avoir accès au robot. Cette classe a été élaborée pour tester la récupération du flux image par image et via un thread, toutefois nous ne sommes pas surs qu’il s’agisse de la meilleure solution car tkinter et les threads non générés par tkinter ne sont pas de grands amis.
Nous avons enfin créé des boutons permettant de contrôler ce nouveau morceau de notre interface, avec open caméra, end stream, et enregistrer l’image.
Résultat obtenu au niveau du panel :
Nous comptions aujourd’hui en séance tester et valider le fonctionnement du video_stream avec le robot mais malheureusement les robots nous n’avons pas accès au robots durant les premières heures de séance.
Finalement nous avons pu trouver un robot auprès de notre tuteur de projet et tester le stream vidéo qui fonctionne plus ou moins bien, nous pratiquerons plus de tests la semaine prochaine. On obtient un stream fonctionnel à l'exception d’une sorte de clignotement lorsque le changement d’image a lieu dans le label. Ce problème doit pouvoir être amélioré. Si nous n’y arrivons pas, nous prévoyons de gérer l’affichage image par image et de demander à l'utilisateur d'updater l’image par lui-même, utilisant ainsi moins de mémoire et de puissance de calcul même si le résultat est moins intéressant pour l’utilisateur. A réfléchir.
15/03/2023 :
Control panel :
Continuation du travail de la semaine dernière :
Probleme de clignotement toujours present : par la classe videolabel, la mise a jour du canvas a chaque image récupérée via les methodes associées a la classe canvas ne fonctionnent pas comme nous l’aimerions : entre chaque changement d’image on entrevoit le background du widget ce qui n’est pas l’objectif.
Comme dit a la derniere seance nous envisagions deux options pour ce probleme, résoudre le clignotement ou passer a un affichage image par image sollicitant l’utilisateur.
Tentative de la séance, designer une nouvelle classe qui n’utiliserai pas de thread car on a compris que tkinter utilise beaucoup de thread pour gérer ses widgets et interagit donc généralement assez mal avec la gestion de threads supplémentaires. Ainsi nous avons pensé a réécrire une classe gérant le widget affichant le stream video, mais qui au lieu d’etre actualisé via une instruction depuis l’interface control panel, s’actualiserait elle même via une methode __update_image()__, dont l’appel se trouve dans l’initialisation de la classe video_canvas. Celle-ci s’actualise donc par elle-même grace au combo __update_image__ placée dans l’initialisation et la méthode after de tkinter qui se charge de relancer l’appel proprement a l’infini, jusqu'à ce que l’on ferme l’interface control panel. De plus, on a décidé de laisser l’instance ROS en permanence pour éviter les difficultés pour la lancer plusieurs fois successivement.
En s’inspirant d’autres classes dédiée à l’affichage de stream video, nous avons rédigé la classe video_canvas suivante :
Nous en avons également profité pour procéder a la conversion BGR vers RGB pour obtenir un affichage en couleur cohérent.
Au cours de la séance nous avons pu tester cette classe et optimiser son fonctionnement combiné avec le control panel, et ainsi nous avons pu nous débarrasser du clignotement provoqué par la classe précédente.
Nous obtenons donc un résultat appréciable, avec un taux de rafraichissement correct et ajustable et pas de clignotement, l’objectif du stream video de la caméra du robot est donc validé!
03/04/2023 :
Interface globale :