----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ATTENTION, ne surtout pas mettre de tiret - dans le nom de l'application -> fonctionne sur le simulateur mais fait planter le controleur pour activer plusieurs vues 3D: clic droit sur le bandeau gris dans vue3D->Réglage affichage->scinder la vue en 2 Pour renommer l'application, dans cellule->controller->clic droit sur l'application->enregistrer l'application sous, donner un nom puis effacer l'ancienne application IL FAUT DESACTIVER le wifi de rapid pour se connecter en filaire sur gommette bleue Feuille de binome et d'appel: https://docs.google.com/spreadsheets/d/1UY4FyJ0ZlzJ971lHx_A7kPHWoY10todP0sRvFmsUyME/edit#gid=0 Projet simplissime pour tester le robot: https://bvdp.inetdoc.net/files/iut/staubli/projets_SRS/Cellule_helloworld_bvdp.zip Projet pré-rempli à récupérer pour intégrer la gestion des capteurs: https://bvdp.inetdoc.net/files/iut/staubliiut/projets_srs/Demo_vissage_bvdp-nettoye-simple-sans-capteurs.zip édition de pages utilisateur: https://bvdp.inetdoc.net/files/iut/staubliiut/robot_srs_et_controleur/Manuel%20SRS.PDF#page=46 sur pc a coté du robot, je travaille dans: d:\travail\bertrand Accueil->Outils de transfert envoyer TOUTES les applications sur la cible je vois que les contrôleur du projet et de la cible ne sont pas les même! assistant nouvelle cellule version de destination s8.11Cs9_BS2229 dans le projet->Controler1 click droit configuration du contoleur: impossible de changer graphiquement. j'édite le texte Controler1\Controller1.controller : s8.8.4Cs9_BS1737 TX2_60-HB-WS et change en ce fichier que j'aui récupéré en créant un controleur à partir du robot réel: s8.11Cs9_BS2229 et je compose pour faire: s8.11Cs9_BS2229 TX2_60-HB-WS Faire Accueil->Debugguer sur->emulateur ET c'est pas bon!!!! ----------------------------------- copie du dossier Controller1 de projet from controleur à la place de celui de mon projet, effacement des usrapp récupérées depuis le controleur remise de mon usrapp depuis mon projet initial (changement de nom?) dans cellule->controleur (qui est devenu vide) clic droit et ouvrir l'application choisir le pjx et c'est bon je peux fermer l'application, renommer le dossier et les fichiers dtx et pjx , dans le fichier pjx changer le nom du fichier dtx D:\travail\bertrand\Projet08-Demo_JPO\Projet08-Demo_JPO\CELL_IUT0\Controller1\usr\usrapp\Demo_vissage_bvdp\Demo_vissage_bvdp.pjx (1 hit) Line 10: et rouvrir! ---------------------------------- en mode jog, mode joint, double cliquer sur un jBrasLeve pour faire apparaitre la fenetre qui dit appuyer sur pause pour déplacer val3->memoire->cliquere sur le projet puis stylo->bBoolSaccade-> false JE PEUX MEME LE FAIRE PENDANT LE FONCTIONNEMENT en mode auto Todo: identifier ce qui peux/doit être des variables locales (compteurs etc.. et préfixer par l_) 2022/01/27: installation sous windows en 2022: file:///C:/Program%20Files/Staubli/SRS%202022/readme.pdf 4.25Go dans C:\Users\All Users\BlueStacks_nxt +1.91Go dans C:\Program Files\Staubli2022 JE N'AI PAS LA LICENCE 2022!!!! Je zippe l'installateur qui a été téléchargé pour le stocker: SRS2022.1.0_Full.zip pacesp désinstallation copie de version 2019 de virtualbox rapid\programmes\staubli vers le Bureau\SRS2019 ne trouve pas le moteur de rendu 3D finalement j'ai l'installeur de staubli 2019.5.1 sur HD4TO1; j'installe TOUT! file:///C:/Program%20Files/Staubli/SRS%202019/readme.pdf puis ouvrir un projet, clic droit sur le controller et faire "Télécharger et installer l'émulateur" à gauche, sélectionner la ligne s8.11Cs9_BS2229 et cliquer sur Télécharger ----------------------------------------------------------------------- Outils en simu, illustrer movej vers jBrasHaut={00000}; puis movel bloque En mode manuel, presser en continu le bouton Pause pour faire executer la simu (cela remplace la poiognée de l'homme mort). Pour passe en mode automatique: sur le pendant: Menu Jog, en bas cliquer sur la main puis sur automatique, appuyer sur le bouton mise sous tension pour qu'il devienne violet puis une fois sur pause programme Kapla cédric: begin pPrise1=pPrise trPrise={0,0,0,0,0,0} pPose1=pPose trPose={0,0,0,0,0,0} nb=0 nb1=0 resetMotion(jHome) popUpMsg("début programme") for nprise=1 to 8 popUpMsg("prise numero:"+toString(".3",nprise)) movej(appro(pPrise1,trAppro),tPince,mNomSpeed) movel(pPrise1,tPince,mNomSpeed) waitEndMove() dDoCLOSE=true tPince.gripper=false delay(0.4) movel(appro(pPrise,trAppro),tPince,mNomSpeed) trPrise={nprise*30,0,0,0,0,0} pPrise1=compose(pPrise,fprise,trPrise) if nprise==3 nb=-1 nb1=1 elseIf nprise==5 nb=-2 nb1=0 elseIf nprise==7 nb=-3 nb1=1 endIf trPose={power(-1,nprise)*(-nb1+1)*50,nb1*power(-1,nprise)*50,nb*22.5,0,0,nb1*90} pPose1=compose(pPose,fPose,trPose) movej(appro(pPose1,trAppro),tPince,mNomSpeed) movel(pPose1,tPince,mNomSpeed) waitEndMove() dDoOPEN=true tPince.gripper=true delay(0.4) movel(appro(pPose1,trAppro),tPince,mNomSpeed) endFor movej(jHome,tPince,mNomSpeed) waitEndMove() end Programme LPROB Cédric: begin resetMotion(jHome) movej(appro(pL[0],trApproche),tStylo,mNomSpeed) movel(pL[0],tStylo,mNomSpeed) movel(pL[1],tStylo,mNomSpeed) movel(pL[2],tStylo,mNomSpeed) movej(appro(pL[2],trApproche),tStylo,mNomSpeed) movej(appro(pP[0],trApproche),tStylo,mNomSpeed) movel(pP[0],tStylo,mNomSpeed) movel(pP[1],tStylo,mNomSpeed) movel(pP[2],tStylo,mNomSpeed) movec(pP[3],pP[4],tStylo,mNomSpeed) movel(pP[5],tStylo,mNomSpeed) movej(appro(pP[5],trApproche),tStylo,mNomSpeed) movej(appro(pR[0],trApproche),tStylo,mNomSpeed) movel(pR[0],tStylo,mNomSpeed) movel(pR[1],tStylo,mNomSpeed) movel(pR[2],tStylo,mNomSpeed) movec(pR[3],pR[4],tStylo,mNomSpeed) movel(pR[5],tStylo,mNomSpeed) movel(pR[4],tStylo,mNomSpeed) movel(pR[6],tStylo,mNomSpeed) movej(appro(pR[6],trApproche),tStylo,mNomSpeed) movej(appro(pO[0],trApproche),tStylo,mNomSpeed) movel(pO[0],tStylo,mNomSpeed) movel(pO[1],tStylo,mNomSpeed) movec(pO[2],pO[3],tStylo,mNomSpeed) movel(pO[4],tStylo,mNomSpeed) movec(pO[5],pO[0],tStylo,mNomSpeed) movej(appro(pO[0],trApproche),tStylo,mNomSpeed) movej(appro(pB[0],trApproche),tStylo,mNomSpeed) movel(pB[0],tStylo,mNomSpeed) movel(pB[1],tStylo,mNomSpeed) movel(pB[2],tStylo,mNomSpeed) movec(pB[3],pB[4],tStylo,mNomSpeed) movel(pB[5],tStylo,mNomSpeed) movel(pB[4],tStylo,mNomSpeed) movec(pB[6],pB[7],tStylo,mNomSpeed) movel(pB[0],tStylo,mNomSpeed) movej(appro(pB[0],trApproche),tStylo,mNomSpeed) movej(jHome,tStylo,mNomSpeed) waitEndMove() end expliquer qu'on démarre le programme par une commande en articulaire vers une position connue et pareil pour la fin du programme le programme fait 1 cycle et revient à sa position de départ; on peut le relancer en cliquant sur le pendant sur VAL3 bouton Play expliquer pour les move en cartésien qu'il faut privilégier same pour éviter les changements (mais vérifier que c'est possible) todo: gérer modeles pince ouverte/fermée transformer le bouchon en piece mobile et regler son handle pour pouvoir le déplacer avec la pince dans le projet vide, ->nouvelle application et donner des noms différents il faut effacer les fichiers dans C:\Users\B\Desktop\srs_cedric\CELL_IUT0\CELL_IUT0\CAD quand on réimporte un fichier stl modifié Scene->Robot->Controleur->Base->Controleur click droit et configuration d'outils dans le dossier CAD, regarder CELL_IUT0.kxml qui décrit la scène. Certains liens de fichiers sont en absolu.... rechercher et les fichiers qui ne sont pas dans le dossier d'install de SRS pour que le projet soit exportable changer ce qui doit l’être en relative filename; ./ correspond au dossier CAD C:/Users/B/Desktop/srs_cedric/CELL_IUT0/CELL_IUT0/CAD/Chariot.wrl en ./Chariot.wrl à l'ouverture du projet en bas à gauche, cliquer sur Sortie fait apparaître: Flange: 0mm Dimensions du robot en convention DH : DH1: Alpha: -90° Beta: 0° Teta: 0° a: 0m d: 0m DH2: Alpha: 0° Beta: 8,99596713278989E-15° Teta: -90° a: 0,29m d: 0m DH3: Alpha: 90° Beta: 0° Teta: 90° a: 0m d: 0,02m DH4: Alpha: -90° Beta: 0° Teta: 0° a: 0m d: 0,31m DH5: Alpha: 90° Beta: 0° Teta: 0° a: 0m d: 0m DH6: Alpha: 0° Beta: 0° Teta: 0° a: 0m d: 0,07m /home/bvdp/files/staubliiut/FileZilla_3.57.0_win64-setup.exe https://bvdp.inetdoc.net/files/iut/staubliiut/FileZilla_3.57.0_win64-setup.exe /home/bvdp/files/staubliiut/PortableGit-2.35.0-64-bit.7z.exe https://bvdp.inetdoc.net/files/iut/staubliiut/PortableGit-2.35.0-64-bit.7z.exe 2021/01/06 : problème de version du controleur en v7.9.1 réinitialisation de la config du controleur je sauvegarde via filezilla l'arborescence du dossier /app/ du controleur dans https://bvdp.inetdoc.net/files/iut/staubli/backup_controlleur_janvier_2021_avant_remise_en_fonctionnement_suite_a_probleme_7.9.1.zip Puis remet ma version de sauvegarde (avec aucune application): https://bvdp.inetdoc.net/files/iut/staubli/backup_controller_apres_purge.zip il manque la configuration d'une passerelle via le pendant telle que décrit plus bas vers 192.168.3.4 via 192.168.0.13 ------------------------------------------ 2021/01/07 réglage de la date et de l'heure sur le contrôleur: Tableau de bord->Date&heure Adresse mac du controleur AIP: 00:c0:3a:60:04:01 je voudrais bien que le serveur de données capteur indique qui fait les demandes de données mais il ne voit pas l'adresse mac du client (qui est sur un autre réseau local à travers la passerelle, donc il faut plutot utiliser l'adresse IP du controleur: 192.168.0.112 ------------------------------------------ 2021/01/14 Enfin affichage 3D avec SRS2019 sous virtual box: Il faut démarrer windows en mode sans Echec (F8) puis insérer disque des Additions Invitées; lancer l'installation et COCHER SUPPORT DIRECT 3D EXPERIMENTAL, puis redémarrer! ------------------------------------------ export et découpage de modèle 3D du robot vider la scène pour ne garder que le robot, puis clic droit dans Vue3D Exporter Tout (STL et WRL) rx60 aip: https://bvdp.inetdoc.net/files/iut/staubli/stl/rx60-ascii.zip tx60 iut: à mettre comme le rx60 ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ =====TP Robot Staubli à l'IUT===== ====Présentation du projet==== L'objectif de ce projet est de vous familiariser avec l'outils Staubli Robotic Suite afin de programmer une tâche robotique sur un robot manipulateur 6 axes. La tâche consiste à saisir un bouchon de bouteille et à venir le visser sur le goulot d'une bouteille. Afin de réaliser cette tâche, il aura fallu procéder à l'intégration d'une infrastructure de capteurs communicants comportant notamment: - Un capteur de couple (déjà étudié dans le module capteur) permettant la mesure du couple de serrage - Un système de vision 2D composé d'une caméra et d'un ordinateur sur carte Raspberry Pi permettant la localisation du bouchon dans l'espace de travail du robot. Pour le développement de cette tâche, vous procéderez d'abord à la configuration d'un projet et de la cellule robotique. Ensuite vous développerez votre programme en réalisant des simulations, et utiliserez à cette occasion des logiciels fournis pour simuler les capteurs, puis finalement vous pourrez tester sur le robot réel en fin de projets afin de procéder aux réglages fins permettant d'adapter les mouvements du robots à la configuration spatiale des éléments dans la cellule. Dans un premier temps, vous programmerez le robot sans utiliser les capteurs. Le capteur de couple sera intégré dans le cadre de ce projet dans un second temps et le capteur de vision sera intégré plus tard dans le cadre d'une séance dédiée. Dans le cadre de ce projet, les communications entre le robot et l'infrastructure se feront via des Sockets TCP et UDP à l'aide de chaînes de caractères ASCII et les autres entrées/sorties numériques et analogiques ne seront pas utilisées. Il faut que le dongle USB de licence monoposte (VERT) soir installé sur le poste près du robot et que le dongle de licence multiposte (ROUGE) soit installé sur un des postes étudiants avant que les étudiants ouvrent le projet avec SRS sinon les éléments 3D de la scène n’apparaissent pas. Vidéo de la simulation sur un autre robot: https://youtu.be/o6v0avbkwQ4 ====Planning prévisionnel==== planning 2022: ^ durée ^ Tâches^ | 2h |Présentation de la manip et organisation en différentes étapes:| | |-Vissage en boucle ouverte avec un préhenseur type pince.| | |-Vissage en boucle fermée en utilisant un préhenseur doté d'un capteur de couple.| | |-Intégration de la vision pour localiser le bouchon à saisir.| | |Lecture de la documentation du langage VAL3: types et différentes fonctions à utiliser dans le projet.| | 4h |Configuration du projet, import et placement des éléments de la cellule (préhenseur et différents objets), positionnement et configuration du robot en Programmation Hors Ligne pour qu'il puisse faire la tâche.| | |Simultanément, démonstration (en petits groupes) par l'enseignant de la commande manuelle du robot réel en articulaire et en cartésien à l'aide du pendant, détermination des repères World et Flange, présentation des modes (manuel, auto et auto déporté) et des éléments de sécurité (détection ouverture de portes). Discussion au sujet des différentes entrées/sorties.| | |Programmation du mouvement de saisie du bouchon et de transport jusqu'au goulot de la bouteille à l'aide d'un mouvement de type 'cycle en U' utilisant les modes de mouvement point à point et linéaire.| | |Utilisation du simulateur pour exécution en continu ou en mode Débug pas à pas.| | |Tests sur le robot réel des mouvements de saisie et de vissage saccadé et apprentissage des points dans l'environnement réel.| | 4h |Poursuite du développement.| | |Installation et configuration de l'application simulant un capteur, explication du serveur de capteur et des fonctions de communication par socket en VAL3.| | |Développement et intégration du capteur de couple.| | 4h |Ajout d'une tâche parallèle à l’exécution des mouvements du robot pour envoyer la configuration du robot en temps réel (il se comporte alors comme un capteur).| | |Modification du programme pour des mouvements non saccadés en utilisant la File d'ordres et l'interruption/vidage lorsque le couple de vissage est atteint.| | |Intégration d'une position variable pour la saisie du bouchon dans un premier temps issue d'un simulateur de capteur (en préparation de la localisation par vision industrielle). Pour cela, utilisation de fonctions VAL3 permettant de tester si la tâche est réalisable.| | 4h |Terminer le travail des séances précédentes | | |Optimisation des temps de cycles en adaptant les descripteurs de mouvements.| | |Petits projets personnalisés.| =====Consignes pour l'évaluation du projet===== Durant le projet, vous travaillerez en binôme, et serez normalement évalués conjointement, à moins que l'enseignant juge que le travail n'a pas été réparti équitablement. Vous devrez produire un rapport avec le code commenté (notamment par des messages affichés sur l'interface utilisateur) et des captures d'écran (Pour faire des captures d'écran avec Windows 10: SHIFT+WINDOWS+S ). Vous fournirez également une archive zip du projet contenant les informations de suivi de version GIT. Vous veillerez à ne pas casser le matériel et dans le cas contraire, cela pourra être pris en compte dans la notation. ====Informations sur la structure d'un programme VAL3 et sur les types utilisés=== L'enseignant vous guidera au cours du projet dans la lecture de la documentation du langage VAL3 utilisé par SRS pour programmer le robot. Ouvrez cette documentation dans une autre fenêtre de navigateur pour la consulter pendant tout le TP, elle est disponible à l'adresse: https://bvdp.inetdoc.net/files/iut/staubli/documentations/Val3.PDF ====Informations sur l'infrastructure de capteurs communicants=== =====Outil de gestion de versions GIT===== Durant le projet, nous utiliserons un outils pour suivre les changements effectués sur les fichiers au fur et à mesure du développement. Ceci nous permettra éventuellement de revenir en arrière en cas de problème et vous montrera le code nécessaire pour chaque nouvelle fonctionnalité. ===Installation de GIT en version portable pour Windows et configuration=== Récupérer et exécuter: https://github.com/git-for-windows/git/releases/download/v2.35.0.windows.1/PortableGit-2.35.0-64-bit.7z.exe Installer l'application dans le dossier D:\PortableGit Créer dans D:\ un fichier alias.txt git=D:\PortableGit\bin\git $* gitk=D:\PortableGit\cmd\gitk Charger ce fichier à chaque ouverture d'une console en copiant collant dans une fenêtre cmd Doskey /MACROFILE=D:\alias.txt Pour lister les paramètres de configurations de l'outils, copier-coller dans une console Windows: git config --list --show-origin Pour configurer votre identité, copier-coller dans une console Windows en adaptant: git config --global user.name "Bertrand Vandeportaele" git config --global user.email secret@meninblack.jupiter ===Consigne d'utilisation=== Vous devrez d'abord faire ce qui est indiqué dans la partie "Récupération du projet SRS de départ et configuration" avant de faire ce qui est indiqué ici, mais les informations concernant GIT sont regroupées pour plus de lisibilité. GIT sera utilisé depuis la console Windows (que vous garderez ouverte) en utilisant des copier-coller de commandes présentées ci dessous, que vous adapterez en fonction des besoins. Vous pourrez, si vous le souhaitez, consulter les documentations: https://git-scm.com/book/fr/v2/D%C3%A9marrage-rapide-Param%C3%A9trage-%C3%A0-la-premi%C3%A8re-utilisation-de-Git https://www.atlassian.com/git/tutorials/gitk https://git-scm.com/download/gui/windows https://www.atlassian.com/fr/git/tutorials/undoing-changes La commande git doit être lancée depuis un dossier contenant un dépôt (un ensemble de fichiers permettant le suivi). Dans notre cas ce dossier sera celui dans lequel vous aurez décompressé le projet SRS, pour aller dans ce dossier saisir à chaque début de séance (vous pourrez utiliser la touche Tabulation pour auto-compléter les noms de dossiers): R: cd R:\lprob\"nom_prenom"\CELL_IUT0 ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ mince le dossier cd R:\lprob\%username%\CELL_IUT0 ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ La première fois, il faut initialiser le dépôt en copiant-collant: git init et créer une version initiale stockant l'état des fichiers tels que vous les aurez récupéré. Habituellement on ne fait pas l'ajout de tous les fichiers mais comme ici VAL3 est un langage interprété, on peut suivre tous les fichiers. Cette commande sera à refaire si vous ajoutez de nouveaux fichiers au projet: git add * Ensuite, il faut enregistrer cette version en faisant un "commit", associé à un commentaire qui vous permettra d'indiquer ce qu'il fait (voyez cela comme un commentaire temporel). La première fois, vous saisirez: git commit -m"ajout de tous les fichiers en version initiale" Les fois suivantes, vous saisirez: git commit -a -m"Whaou! mon programme arrive à faire un truc super: l exercice 2!!!" Vous utiliserez l'outils gitk (que vous garderez ouvert pendant toute la séance, en pressant "F5" pour rafraîchir l'affichage) pour visualiser les différentes version en copiant-collant: gitk En cas de problème, et après accord du professeur, pour ramener vos fichiers à l'état du dernier commit en annulant toutes les modifications locales non commitées, fermer SRS puis copier coller: git reset --hard ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ VRAC: C:\Users\%username%\Downloads\PortableGit\bin\git add test.txt C:\Users\%username%\Downloads\PortableGit\bin\git commit -m"premier test" C:\Users\%username%\Downloads\PortableGit\bin\git status C:\Users\%username%\Downloads\PortableGit\bin\git add Controller1\usr\usrapp\Kapla\start.pgx C:\Users\%username%\Downloads\PortableGit\bin\git commit -m"programme Kapla de Cédric" C:\Users\%username%\Downloads\PortableGit\bin\git add * C:\Users\%username%\Downloads\PortableGit\bin\git commit -m"ajout bouchon" ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ =====Récupération du projet SRS de départ et configuration====== Télécharger et décompresser le fichier: https://bvdp.inetdoc.net/files/iut/staubli/projets_SRS/Cellule_depart_staubli_vide.zip Version avec cellule jolie mais LOURDE: https://bvdp.inetdoc.net/files/iut/staubliiut/projets_srs/CELL_IUT0_projet_depart_etudiants.zip Vous devez dézipper le dossier CELL_IUT0 afin qu'il soit dans le dossier R:\lprob\"votrelogin"\CELL_IUT0 Il est temps d'initialiser le dépot git tel que montré plus haut. Ensuite, lancer le programme SRS en cliquant sur: Menu Démarrer->Tous les programmes->Staubli Robotic Suite 2019->Staubli Robotic Suite 2019.10.1 et ouvrir le projet. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ A l'AIP on faisait: =====Configuration d'un projet de départ===== Durant tous le projet, vous travaillerez sur des fichiers stockés en réseau sur un disque auquel vous pouvez accéder depuis différents ordinateurs. ====Création d'un projet utilisant les IO physiques de l'armoire de commande=== L'armoire de commande dispose de cartes d'entrées/sorties (IO, liens série, lien sockets etc...). Pour que ces cartes soient accessibles depuis le projet, il faut que le projet soit configuré lors de la création de la cellule en récupérant les informations matérielles depuis l'armoire de commande. - Dans SRS, cliquer en haut à gauche sur l'icone de bras jaune. - Cliquer sur "Nouvelle-> Assistant nouvelle cellule" - Donner un nom au projet, ici vous utiliserez "CellStaubliAIP", saisir dans Chemin: "L:\Staubli\SRS" - S'assurer que l'armoire de commande est sous tension et démarrée depuis 2 minutes - Cliquer sur "Ajouter ... à partir d'un contrôleur distant" - Choisir l'adresse IP de l'armoire de commande: 192.168.0.112 - La version de l'émulateur s7.9.1 n'est pas installée, il faut donc sélectionner la 7.10 - Cliquer sur "Suivant" Si problème lors du téléchargement des infos depuis le controleur à la création de la cellule, il faut faire le ménage sur le controleur avec FTP et ne laisser que camera, cognex, cognexComm7en, commCamera2 et EntreeSortie. TODO: automatiser le ménage (sauvegarde et effacement) En cas de problème pour créer la cellule, vous pouvez, après accord de l'enseignant, télécharger le fichier zip suivant en remplacement: https://bvdp.inetdoc.net/files/iut/staubli/projets_SRS/CellStaubliAIPVide.zip Toutes les cartes ne sont pas automatiquement ajoutées au projet. Il faut: - Choisir l'onglet Cellule dans la fenêtre de droite - Cliquer sur la flèche à gauche du nom de la cellule pour faire apparaître "Controller1 [s7.10]" - Cliquer droit sur "Controller1 [s7.10]" puis cliquer gauche sur "Configuration du contrôler" - Sélectionner le bon type de bras (sinon par défaut un Scara sera choisi). Choisir "RX60B, Fixation Sol, Horizontal base cable outlet, UL Certified arm power on light" - cliquer sur l'onglet I/O et cocher "BIO" ainsi que "BIO2/MIO", puis "Ok" - Si l'onglet "IO physiques-Controller1" est ouvert, il faut le fermer et l'ouvrir à nouveau pour que les modifications soient visibles. ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ Dans la vue 3D vous devez voir la cellule. Vous pouvez cliquer à gauche sur Cameras->Camera pour sélectionner la vue perspective telle que visible ci dessous: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_Cellule_vide.PNG}} Le contrôleur du robot est configuré dans le projet fourni, il faut maintenant créer une nouvelle application, pour cela: - Choisir l'onglet Cellule dans la fenêtre de droite - Cliquer sur la flèche à gauche du nom de la cellule pour faire apparaître "Controller1 [s8...]" - Cliquer droit sur "Controller1 [s8...]" puis cliquer gauche sur "Nouvelle application" - Saisir un nom: "Projet" suivi d'un numéro sur 2 chiffres qui vous sera attribué en début de séance et que vous conserverez durant toutes les séances. Il est important que vous ayez chacun un nom de projet différent pour pouvoir identifier votre programme une fois chargé sur le contrôleur du robot! - Cliquer sur Ok Il faut maintenant configurer l'outils du robot, pour cela: - Choisir l'onglet Géométrie dans la fenêtre de droite - Cliquer sur la flèche à gauche du nom de la cellule pour faire apparaître "Controller1 [s8...]" puis faire de même pour votre Projet - Cliquer droit sur "Flange" (qui signifie Bride en français, soit l'emplacement où fixer l'outils) puis cliquer gauche sur "Nouvelle donnée" - Saisir un nom pour l'outils, ou laisser le nom par défaut (tTool) puis cliquer sur Ok - Vérifier que tTool apparaît maintenant en cliquant sur la flèche à coté de "flange[0]" ===Edition du programme=== - Cliquer sur l'onglet "Accueil" puis sur "Afficher la vue 3D" - Choisir l'onglet Cellule dans la fenêtre de droite - Cliquer sur la flèche à gauche du nom de la cellule pour faire apparaître "Controller1 [s8...]" puis "Projet" puis double cliquer sur "start()" pour ouvrir la fenêtre d'édition du programme. Afin d'organiser la disposition des sous fenêtres pour permettre de voir simultanément le programme et le simulateur 3D du robot, cliquer gauche longuement sur l'onglet Projet-start puis, tout en maintenant le clic déplacer la flèche vers le carré de droite qui vient d'apparaître, relâcher alors le clic gauche. Vous devriez obtenir un affichage ressemblant à: {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS-disposition.PNG}} ===Navigation dans la vue 3D=== La vue 3D utilise les mêmes principes que Catia pour naviguer: * molette vers le haut pour dézoomer et vers le bas pour zoomer (ils sont tordus les mécanos...) * clic molette maintenu pour déplacer la caméra * clic molette + clic droit maintenus pour orienter la caméra En fonction de la position de départ du mouvement de souris, la rotation obtenue n'est pas la même. Pour afficher le disque délimitant les zones de départ, il faut cliquer sur l'icone rotation en bas à droite à coté de zoom. Il peut être nécessaire de désactiver l'affichage du plancher car il fait buguer l'application. Pour cela, cliquer droit sur la vue 3D, "réglages affichage" et décocher "afficher plancher". Le programme propose par défaut un certain nombres de vues (de face, de coté, etc...). Il peut être intéressant d'ajouter des caméras fixes dans l'environnement pour observer les mouvements du robot depuis des points de vues particuliers. Pour cela, configurer la vue à l'aide de la souris puis dans l'arbre à gauche de la vue 3D, cliquer droit sur la vue 3D et sélectionner Caméras->ajouter une camera pour la vue courante. Il suffira de double cliquer sur la caméra créée dans l'arbre pour revenir sur cette vue. Dans certains cas l'affichage de trièdres est trop petit pour être visible. Pour changer leur taille, aller dans l'onglet Simulation->réglage affichage->taille des trièdres (en pixel). Lorsqu'il est nécessaire de définir un repère à l'aide de clics de souris, l'ordre de clics des points définit l'orientation du 3° axe par la règle de la main droite (aussi appelée du tire-bouchon). ===Modification de la configuration du robot=== Pour modifier la configuration du robot, double cliquer sur Scène->Robot->Controller dans l'arbre, ce qui fait apparaître des disques permettant de contrôler chaque articulation. Cliquer gauche maintenu sur un des disque pour faire tourner l'articulation. Il est également possible de modifier la configuration du robot en cartésien en jouant sur le trièdre placé au niveau de la bride du robot. Cliquer droit sur le robot pour faire apparaître le menu et clic gauche sur "déplacement manuel" pour faire apparaître la fenêtre de configuration du robot qui permet un réglage fin et la visualisation des valeurs extrémales atteintes par chaque articulation et le pilotage manuel en cartésien: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_articulaire_et_cartesien.PNG}} L'affichage de l'espace de travail (righty ou lefty) est obtenu en sélectionnant Scène->Robot->Controller dans l'arbre, puis clic droit sur le robot et afficher l'espace de travail... Il s'agit du volume atteignable par le milieu de l'axe 5 du robot, ce sont juste 2 sphères calculées statiquement à partir du modèle du robot, mais elle permette de se faire un idée pour positionner les différents éléments dans la cellule. ====Configuration de la cellule==== ===Import du modèle 3D de la cellule=== Récupérer le modèle: https://bvdp.inetdoc.net/files/iut/staubli/stl/cellule_simplifiee.wrl - Importer le modèle dans le projet - Onglet Modeleur->Ajouter un modèle CAO - Chercher le fichier cellule_simplifiee.wrl à l'aide du bouton ... - Régler la résolution sur Standard et cocher l'option "Copier et insérer le fichier" et "importer comme un assemblage" - Dans la vue 3D, dans Scène->Géométrie->cellule_simplifiee_1.wrl, clic droit puis "éditer la postion" Editer la position absolue suivante: 63.3 -68.2 550.45 0 0 -90 ===Import du modèle de pince=== Récupérer le modèle STL de la pince Schunk et du préhenseur de bouchon: https://bvdp.inetdoc.net/files/iut/staubli/stl/adaptateur_pince_bouchon_iut2021_open.stl Le modèle téléchargé est déjà référencé correctement pour faciliter le positionnement du Handler (point saisisseur) et du Handle (base: point de saisie). La bride du robot (Flange) est un Handler en Val3, et nous allons connecter ce Handler au Handle de l'outils pince. Il est important de respecter scrupuleusement les étapes suivantes sinon l'outils ne sera pas correctement ajouté au robot! L'image suivante montre le repère du handler du robot c'est à dire sa bride (Flange en anglais):{{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_handler_robot.PNG}} Pour ajouter la pince au robot: - Si un outils est déjà attaché au handler du robot: Scene->Robot->Controleur->Base->Controleur click droit et Détacher - masquer le robot-> cliquer droit sur l'arborescence de scène sur Controller et décocher "Afficher le robot" - Onglet Modeleur->Ajouter un modèle CAO - choisir Copier et insérer le fichier - l'objet apparaît dans l'arbre en tant que Géométrie, cliquer droit dessus et faire "nouvel outils" - NE PAS déplacer l'outils (car il est normalement bien positionné) - choisir dans l'arbre l'outils et son handle - cliquer sur "Edition" sous la barre de menu - cliquer droit sur handle et "Editer la position" - Régler tout à 0 dans la position absolue - cliquer droit sur handler et "Editer la position" - Régler tout à 0 dans la position absolue sauf Z à 140.00 - Sortir du mode Edition - Cliquer droit sur Tool1 dans l'arborescence, attacher à et choisir le handler du robot - réactiver l'affichage du robot Ensuite il faut associer l'outils à la variable tTool, pour cela: - Sélectionner le Tool1 dans l'arborescence puis faire CTRL+C - pour utiliser un outils de la géométrie graphique vers une variable val3, il faut clic gauche sur le handler de l'outils, CTRL+C et coller dans la ligne de la variable tTool[0] dans l'onglet données. Vous devriez obtenir un vecteur dont toutes les composantes sont à 0 à l’exception du champ Z à 140.00. Ensuite, cliquer droit sur le handler de l'outils puis définir comme TCP (Tool Center Point= Centre De l'Outils) pour pouvoir déplacer l'outils. Vous devriez voir la pince solidaire de la bride du robot, comme sur la figure suivante, dans laquelle le repère du haut est le handler du robot connecté au handle de la pince (sur la bride), alors que le repère du bas est le handler de la pince, situé au centre des mors: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_handle_outil.PNG}} ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ Optionnel: importer le modèle de gripper adapté au bouchon depuis https://bvdp.inetdoc.net/files/iut/staubli/stl/adaptateur_pince_bouchon_ouvert.stl et le rajouter à la pince en configurant son handler et son handle correctement. Pour cet outils, le handler et le handle doivent être distant de 10mm selon Z. Faire clic droit sur l'adaptateur puis "attacher à" et sélectionner le handler du Tool1. Après avoir attaché ce nouvel outils au précédent, vous devriez obtenir: {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS_adaptateur_pince_bouchon_ouvert.PNG}} ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ===Ajout des éléments dans la cellule=== Pour ajouter un objet dans l'espace de travail du robot: - Onglet Modeleur->Ajouter un modèle CAO - Télécharger le fichier et aller le chercher dans l'arborescence avec le bouton "..." - Choisir Copier et insérer le fichier - L'objet apparaît dans l'arbre en tant que Géométrie Insérer dans l'espace de travail du robot: - le support de bouteille: https://bvdp.inetdoc.net/files/iut/staubli/stl/support_bouteille_cristaline_lr.stl - la bouteille: https://bvdp.inetdoc.net/files/iut/staubli/stl/bouteille_cristaline.stl - le bouchon: https://bvdp.inetdoc.net/files/iut/staubli/stl/bouchon_cristaline.stl Vous devez positionner les éléments pour obtenir une configuration proche de celle du robot réel (vous adapterez les positions plus tard en relevant avec le pendant la configuration cartésienne du robot lorsqu'il est en position de saisie et de dépose du bouchon). Vous devez obtenir un espace de travail tel que celui visible sur la figure suivante: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_espace_travail.PNG}} ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ Valeurs qui vont bien pour simu: position absolue pour support bouteille: 500,0,196 position absolue pour bouteille: 500,-17,285 position absolue pour bouchon: 500,100,200 ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ===Configuration de l'outils=== Dans le données, sélectionner la variable tTool de type tool, et double cliquer pour l'éditer. Vérifiez que vous avez bien comme changement de repère {0,0,140,0,0,0}, et que le gripper est bien réglé à FastIO\fOut1 . Saisir 1 pour les 2 champs suivants qui permettent de régler les durées de délais en seconde(s) pour que la pince s'ouvre et se ferme après que la commande lui soit envoyée. ===Activation de la détection de collision=== Pour activer la détection de collisions dans le simulateur, il faut griser le bouton Simulation->Collision + choisir les événements qui déclenchent les collisions + activer la gestion des collisions dans chaque objet (Propriétés F4). ===Ajout d'un sous programme d'affichage bien pratique=== Dans la fenêtre cellule->Controller1->Projet...-> * clic droit et "Ajouter nouveau programme" * Nom: logMsgBlock * Sauver tout (icone à plusieurs disques) * Télécharger le fichier suivant dans le dossier CELL_IUT0\Controller1\usr\usrapp\ en écrasant le fichier qui vient d'être créé par SRS Dans la fenêtre cellule->Controller1->Projet...-> * cliquer droit sur Projet... * cliquer gauche sur "recharger l'application" * vous devriez voir apparaître le programme ainsi que ses paramètres =====Démarche de développement et de simulation===== ====Structure du programme==== Vous veillerez à bien structurer votre programme en utilisant des sous programmes lorsque cela est judicieux. Au démarrage de votre programme, le fichier "start.pgx" et exécuté. Vous veillerez à informer l'utilisateur du pendant de l'état de votre programme à l'aide de d'appel de fonction d'affichage, afin d'être capable d'identifier facilement la partie du programme en cours d’exécution etc... ====Nommage des variables==== Vous veillerez à respecter les règles de nommages des variables en fonction de leurs types (voici ce que nous manipulerons dans le projet): * variable bool (booléen) commençant par b * variable frame (repère) commençant par f * variable jointRx (configuration en articulaire) commençant par j * variable pointRx (configuration en cartésien) commençant par p * variable mdesc (descripteur de mouvement) commençant par m * variable num (valeur numérique) commençant par n * variable string (chaine de caractères) commençant par s * variable tool (outils) commençant par t * variable trsf (transformation) commençant par tr * variable sio (ressource de communication) commençant par si Ceci permettra notamment d'ajouter automatiquement une variable à partir du code en faisant clic droit sur la variable puis "ajouter donnée". Le type de la variable est alors inféré d'après la convention de nommage. Les noms des variables locales sont de plus préfixés par l_ à ajouter en tant que nouvelle variable locale (pas donnée) et les nom des paramètres sont préfixés par x_. Nous Utiliserons les variables locales pour les variables qui n'ont pas à être réglées depuis le pendant (par exemple les variables numériques de compteurs). Dans le projet, les variables locales n'apparaissent pas dans les "Données" mais dans "Cellule"->Controller1->Projet->start()->Variables locales. ====Gestion du temps==== Présentation au tableau de la gestion du temps par le contrôleur du robot. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ TODO: expliquer delay, waitEndMove, open, close, la file d'ordre et le lissage de trajectoire dans un premier temps, mouvements saccadés puis lissés ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ====Programmation des mouvements de saisie et de transport du bouchon==== Nous allons mettre en place un mouvement semblable à celui présenté page 144 de la documentation pour saisir le bouchon et l'amener en face du goulot de la bouteille. Les fonctions de mouvement utilisables sont: * movej(): mouvement en point à point, la trajectoire entre les points optimise la vitesse de déplacement en interpolant sur le coordonnées articulaires * movel(): mouvement linéaire dans l'espace de travail * movec(): mouvement circulaire dans l'espace de travail Selon le descripteur de mouvement passé en paramètre à la fonction move, un lissage est possible, et celui-ci peut se faire en interpolant sur les coordonnées articulaires ou cartésiennes. ====Simulation==== La simulation peut se faire en mode "exécution continue" ou en mode "Debug". ===Mode "Debug"=== Dans le mode "Debug", il est possible de positionner des points d'arrêt dans le programme, d’exécuter des instructions en pas à pas, ou fonction par fonction, et d'espionner la valeurs de variables. Presser la touche F9 pour activer ou désactiver un point d'arrêt sur une ligne d'un programme. Un point rouge apparaît à gauche de la ligne pour indiquer la présence du point d'arrêt. Pour synchroniser l'affichage 3D avec le simulateur: - Onglet "Simulation", cliquer sur icone "PLAY" triangle bleu (Démarrer la synchro) Pour lancer le Debug du programme - Dans l'onglet Cellule, ouvrir le Controller1->Projet et cliquer gauche sur "start()" pour choisir le programme - Onglet "Val3", cliquer sur "Démarrer et Debugguer l'application" (CTRL+R,D). On doit alors observer une flêche jaune sur la ligne du premier point d'arrêt visité Pour éxecuter en pas à pas: - Onglet "Déboguer", "Pas principal" (raccourci F10) Observer dans la fenêtre "Emulator Controller" les affichages utilisateurs (au besoin cliquer sur l'onglet "User") Amener la souris sur le "?" de la fenêtre de l'émulateur pour voir les raccourcis clavier. Arrivé à l’exécution de l'instruction WaitEndMove(), le simulateur semble bloqué, ceci est dû au fait que le robot est par défaut en mode "Hold" - Dans la fenêtre "Emulator Controller", il faut: - Choisir le mode automatique en cliquant sur le bouton rond blanc jusqu'à ce que l'icone "auto" soit en bleu - Mettre le robot sous puissance: cliquer sur le bouton rond avec un trait noir vertical pour le faire devenir vert - cliquer sur l'onglet "Move" (qui devient "Hold") (SHIFT+F7) pour autoriser le robot à bouger Pour arrêter un Debug en cours et recommencer: - Onglet "Deboguer" Arrêt du débogueur. (CTRL+D,S abbrégé de Débugguer Stop) . - Onglet Val3, cliquer sur "Démarrer et Debugguer l'application" (CTRL+R,D abbrégé de Run Débugguer ) - Fenêtre "Emulator Controller", cliquer sur "Move" ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ TODO : expliquer espions sur variables locales et globales ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ===Mode "Exécution continue" === L’exécution en mode "exécution continue" est accessible depuis le bouton "Démarrer l'application" dans l'onglet "VAL3" ( raccourci (CTRL+R,X)). A part cela, la synchronisation avec l'affichage 3D et l'émulateur de contrôleur se passent comme pour le mode "Debug". Les points d'arrêt éventuellement présents dans le programme sont ignorés. ===Réglage manuel de la configuration du robot=== Pour pouvoir configurer la pose du robot en cliquant sur la vue 3D il faut cliquer sur Onglet Simulation, icone "STOP" afin d’arrêter la synchronisation entre de simulateur et la vue 3D. Dans le cas contraire, c'est le programme qui pilote le robot. ====Affichage d'informations pour l'utilisateur du robot===== Vous veillerez à afficher avec **call logMsgBlock(sString "...",bBool block)** ce que fait le robot après chaque commande **move?()** pour pouvoir le visualiser sur le pendant. Nous pourrions utiliser le mode debug pas à pas sur le pendant mais ce n'est pas pratique pour le test sur le robot réel. De plus ces commandes d'affichage permettent de documenter le code. Les affichages sont faits dans l'onglet Journal/Info du pendant (ne sélectionner que Info et désélectionner Critique,Erreur et Attention). Pour afficher une valeur numérique, vous pourrez la convertir en chaîne et la concaténer à une autre chaîne en faisant par exemple: call logMsgBlock("prise numéro:"+toString(".3",nprise),true) ===viré=== Durant le développement, vous pourrez, afin d'afficher sur le pendant l'action en cours du robot utiliser la forme de code suivante. Elle commence par faire un délai d'une seconde pour s'assurer que l'affichage aura bien lieu, puis fait l'affichage et le mouvement correspondant, et interrompt l’exécution du programme tant que le robot n'est pas arrivé à la destination souhaitée. Plus tard, lorsque l'on souhaite lisser les trajectoires, il suffit d'affecter false à la variable bBoolSaccade. (et les affichages s'enchaînent alors, en avance sur la position du robot). if bBoolSaccade==true delay(1) endIf popUpMsg("prise numéro:"+toString(".3",nprise)) move.... if bBoolSaccade==true waitEndMove() endIf ===Utilisation du mode automatique déporté=== Il est également possible d'utiliser le mode automatique déporté (remote) pour simuler l'application. Dans ce mode, le bouton de mise en marche de la puissance du robot du pendant n'est pas utilisable. Pour débugger, dans le pendant virtuel, changer le mode en automatique déporté à l'aide du bouton blanc. Une tentative d'exécution de votre programme provoquera l'affichage d'une erreur "Demande de mise sous puissance du bras refusée: la baie est en mode déporté ou invalide". Pour débloquer cette situation, il suffit d'appeler la fonction VAL3 **enablePower()** au début de votre programme. Grâce à cela vous n'aurez plus à agir sur le bouton "Move/Hold" et mise sous puissance du pendant virtuel. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ todo: regarder les réglages des butées du poignet ====Configuration du robot pour permettre le vissage sur une plus grande plage angulaire du poignet==== Le poignet du robot est configuré par défaut avec des butées logicielles pour pouvoir tourner le poignet de -270° à +270°, afin de ne pas détériorer les flexibles pneumatiques permettant de piloter la pince. Dans notre manip, nous pourrons être amené à débrancher ces flexibles et utiliserons alors un plus grand débattement pour le poignet, qu'il va falloir configurer, sur le pendant virtuel ainsi que sur le pendant réel (sur ce dernier, ce sera fait par l'enseignant). Le poignet du robot RX60 peut faire une rotation de +- 18000°. Afin d'accéder à la configuration du pendant, il faut utiliser le "profil de maintenance": sur l'émulateur, presser: SHIFT + F11 + F3 sur le vrai pendant, presser: SHIFT+USER choisir "maintenance" (au lieu de "default", en faisant entrée puis en sélectionnant avec les flêches), mot de passe: spec_cal, (caractère "_" obtenu par SHIFT+M) puis F8 pour OK pour encore plus de choix, choisir "staubli" (au lieu de "default", en faisant entrée puis en sélectionnant avec les flêches), mot de passe: aristote, (caractère "_" obtenu par SHIFT+M) puis F8 pour OK Il faut ensuite régler les butées du bras et de la cellule. cela va modifier les fichiers arm.cfx et cell.cfx Pour cela, aller dans Menu->tableau de bord->Etat du contrôleur->Limites bras, et régler J6min à -18000 et J6max à +18000 puis F8 L'image suivante montre la configuration des butées sur le pendant virtuel: {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS_limites.PNG}} Revenir au profil "staubli" après que la modification ait été effectuée. Pour que la modification soit prise en compte, il faut que le programme soit en cours d'exécution mais que le robot ne soit pas en train de bouger. On peut pour cela par exemple exécuter le programme en mode debug, avec un point d'arrêt actif dans le programme sur un appel à la fonction delay(...) Les limites de la cellule sont automatiquement mises à jour à partir des limites du bras. ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ====Intégration des capteurs==== La communication via Socket proposée par SRS ne fait pas de distinction entre les numéros de ports local et distant. Il n'est donc pas possible de faire communiquer directement l'émulateur de robot tournant sur votre PC de développement avec une application émulant un capteur sur le même PC. Nous utiliserons donc une autre machine (dotée d'une adresse IP permettant de l'identifier) appelée "serveur de capteurs" qui sera en charge de centraliser les données issues des différents capteurs réels ou simulés. SRS pourra communiquer avec ce serveur car il dispose d'une adresse IP différente de celle de votre PC. De plus la lecture de données via socket depuis SRS fonctionne de manière bloquante avec timeout, donc le fait d'avoir le pc serveur qui puisse répondre à des requêtes même si le capteur n'a pas fourni de valeur permet par exemple d'indiquer qu'il n'y a pas de donnée disponible rapidement sans que le robot soit bloqué en attente du capteur. Python 3.9.7 est installé sur les PC Windows. Vous devrez télécharger/modifier un programme python émulant un capteur à l'aide d'une interface graphique. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ===Installation de pyQT sur les postes étudiants=== Télécharger le fichier suivant: https://bvdp.inetdoc.net/files/iut/staubli/PyQt4-4.11.4-cp37-cp37m-win_amd64.whl sur le L:\, Puis saisir dans un terminal en faisant Touche Windows+R puis taper “cmd” et entrée, puis copier coller la ligne suivante: pip install L:\PyQt4-4.11.4-cp37-cp37m-win_amd64.whl Pour la salle Groix, la version de python installée est python3.4 dans c:\Python34\Scripts> . Pour installer le paquet QT nécessaire, faire: c:\Python34\Scripts\pip install L:\PyQt4-4.11.4-cp37-cp37m-win_amd64.whl c:\Python34\Scripts>echo %UserProfile% C:\Users\bvande En cas de problème (par exemple pyqt4 déjà installé par un autre utilisateur sur la machine), on peut le désinstaller en faisant: pip uninstall Desktop\PyQt4-4.11.4-cp37-cp37m-win_amd64.whl ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ =====Mise en oeuvre sur le robot===== Le chargement du programme sur le robot se fait depuis soit le poste situé à coté du robot soit depuis votre poste. ====Mise sous tension de l'armoire de commande=== Fermer les différents portes équipées de capteur d'ouverture (sinon il y aura un message User ES1-2 indiquant que le capteur porte ouverte empêche le robot de démarrer) Mettre l'interrupteur rotatif gris clair à gauche de l'armoire de commande en position "flêche vers le haut" pour alimenter le robot. Ne surtout jamais rallumer le robot juste après l'avoir éteint sans attendre au moins une dizaine de secondes. Choisir parmi les 3 modes en tournant la clef: - En mode manuel, le robot s'arrête si l'utilisateur n'exerce pas de pression sur le bouton de l'homme mort et qu'il ne presse pas en continu le bouton Move/Hold. Ce sera le mode à utiliser pendant les tests et réglages sur le robot afin de pouvoir - En mode automatique... ===Cas particulier du retour de vacances==== Si l'alimentation de l'armoire a été coupée pendant longtemps, la batterie de l'armoire n'est pas suffisante pour conserver les paramètres de calibrage du robot, il faut donc refaire le calibrage. Pour cela, amener le robot en position de référence (les marqueurs traits noirs des différentes articulations doivent être en face les uns par rapport aux autres) en utilisant les mouvements manuels en mode Joint et faire sur le pendant: - Bouton Menu - Calibrage - Presser le bouton Cal - Presser le bouton Ok ===Création d'une ressource Socket depuis le pendant=== Cette opération a déjà été réalisée par l'enseignant pour les 2 ressources socket UDP et TCP mais est indiquée ici pour référence: Sur le pendant: - Tableau de bord - ES -> - Socket -> - Socket UDP, bouton "Nouveau" - donner un nom: "siSocketUDP" puis cliquer sur "Ok" - Editer, bouton "entrée" pour choisir les paramètres à modifier - filtre IP: 192.168.3.4 - port: 10000 -temps maxi: 5s (permet de régler la durée au bout de laquelle une tentative de lecture sur le socket n'ayant pas aboutie fera planter le programme VAL3 - caractère fin de chaine: 13 (identifie le caractère ASCII devant se trouver à la fin de toutes les chaines échangées via sockets) Les ressources de communication sockets ajoutées sur le contrôleur sont importées dans le projet SRS créé à partir du contrôleur. Il faudra néanmoins créer la variable de type sio correspondante et l'associer via la fenêtre "IO physiques". ====Chargement de l'application dans l'armoire de commande==== S'assurer que l'armoire de commande du robot est sous tension. - Dans SRS, sélectionner la fenêtre du programme start - cliquer sur l'onglet VAL3, puis cliquer sur le bouton Télécharger l'application vers la cible La fenêtre suivante apparaît, indiquant l'adresse IP et le numéro de port utilisé pour communiquer avec l'armoire de commande: {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS_prog_robot.PNG}} - Cliquer sur OK - Une fenêtre apparaît demandant si l'on souhaite écraser l'ancien programme sur l'armoire, cliquer sur Oui Avec le pendant: - Bouton "Menu" - Choisir "Gestionnaire d'applis" et valider avec le bouton Flèche droite - Choisir "Application Val3" et valider avec le bouton Flèche droite - Choisir "Disque" et valider avec le bouton Flèche droite - Choisir newProject1 (ou le nom de votre projet) et valider avec le bouton Ok - Pour que le programme s’exécute, mettre le bras sous tension en appuyant sur le bouton vert de mise sous tension tout en exerçant une pression modérée sur la poignée de l'homme mort - Pour autoriser les mouvements du robot, appuyer sur le bouton Move/Hold - Pour visualiser les messages utilisateurs sur l'écran du pendant, appuyer sur le bouton User ===Gestion des fichiers sur l'armoire de commande avec winSCP ou FileZilla=== il est également possible d'utiliser logiciel client FTP pour accéder aux fichiers du contrôleur (p15 de SRS-ManuelUtilisation2.PDF). L'armoire de commande héberge les différents programmes sur un serveur FTP. Il est possible d'utiliser un client FTP tel que winSCP (téléchargeable en version portable à l'adresse: https://winscp.net/download/WinSCP-5.15.9-Portable.zip )pour gérer les fichiers sur ce serveur. On pourra supprimer sur le contrôleur toutes les applications, sauf: Cognex CognexComm7en commCamera2 EntreesSortie Il faut être connecté en filaire au réseau local (pas via passerelle wifi). La connexion se fait à: ftp://defaut@192.168.0.112 mot de passe vide il faut accéder au dossier distant: /usr/ ===Redémarrage de l'application=== Pour exécuter à nouveau le programme sur l'armoire: - Presser le bouton Stop - Presser le bouton Run ===Rechargement d'une application depuis le PC=== Pour pouvoir recharger une application depuis le PC, il faut tout d'abord que l'armoire de commande arrête son exécution. Pour cela, à l'aide du pendant: - Presser le bouton Stop - Presser le bouton Menu - choisir gestionnaire d'applis - Presser le bouton Fer (F4) Ensuite charger la nouvelle version de l'application en suivant les consignes de la section: "Chargement de l'application dans l'armoire de commande" ===Arrêt de l'application en cours d’exécution=== Pour arrêter l'application en cours depuis le pendant: - bouton STOP - bouton Menu - Gestionnaire des tâches flêche droite - choisir la tache et cliquer sur "Ter" ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ====Adaptation du robot pour la scène réelle==== Télécharger votre application vers l'armoire de commande. L'adaptation consiste à déplacer manuellement le robot à l'aide du pendant et à affecter des valeurs "correctes" aux variables de votre programme. Il faut tout d'abord ouvrir l'application avec le pendant EN MODE MANUEL (sélectionné avec la clef). ===Apprentissage d'une configuration articulaire=== Pour déplacer le robot à une configuration articulaire donnée: * arrêter l'application en cours * aller dans le menu Jog * choisir le mode "Joint" * régler une vitesse faible à l'aide de la touche +/- du haut, surtout si une partie du robot est proche d'un obstacle. * utiliser les autres touches +/- pour modifier la position de chaque articulation * relever les valeurs pour les écrire dans votre programme ( il est également possible d'enregistrer la configuration dans une variable puis de la rapatrier sur le PC de développement) ===Apprentissage d'une configuration cartésienne=== Pour déplacer le robot à une configuration cartésienne donnée: * arrêter l'application en cours * aller dans le menu Jog * choisir le mode "Outil" * régler une vitesse faible à l'aide de la touche +/- du haut, surtout si une partie du robot est proche d'un obstacle. * par défaut, le pendant en mode outils utilise l'outils flange[0] (bride), il faut gérer la translation en z pour avoir le repère du handler de l'outils. * Pour choisir le projet, en haut cliquer sur les 3 petits traits à droite de l'outils * Pour choisir l'outils dans ce projet, cliquer sur les 3 petits traits en dessous et sélectionner tTool[0] * Pour choisir le repère de référence , cliquer en dessous sur les petits traits pour sélectionner le repère world[0] du projet * Vous devez voir les coordonnées de tTool[0] exprimées dans le repère world[0] * utiliser les autres touches +/- pour modifier la position/orientation du repère outils (dessiné sur la pince) * relever les valeurs pour les écrire dans votre programme ( il est également possible d'enregistrer la configuration dans une variable puis de la rapatrier sur le PC de développement) Vous pouvez vous entraîner à faire ces opérations sur le PC de développement en simulation à l'aide du pendant virtuel: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_apprentissage_points.PNG}} ==Rapatriement des données apprises de l'armoire de commande vers le projet SRS=== Dans le gestionnaire de téléchargement, cocher à droite Projet->Projet->Données et faire télécharger. Le fichier Projet.dtx (xml) est mis à jour sur le PC mais SRS ne s'en rend pas compte, il faut faire clic droit dans l'onglet "Données"->Cell2->Controller1->Projet puis "Recharger l'application". L'enseignant expliquera en séance la démarche de pilotage manuel du robot et de mise à jour des variables du programme ainsi que du téléversement des valeurs numériques vers le programme. En cas de problème pour récupérer ces valeurs, il sera possible de relever manuellement les configurations du robot et de les affecter dans les variables correspondantes du programme (c'est l'approche préférée par l'enseignant car les informations apparaissent dans le code) avec des instructions telles que: //configuration des points en articulaire par programme //position bras levé jBrasHaut={0, 0, 0, 0, 0, 0} //position bras vers le bas jBrasBas= //exemple d'affichage call logMsgBlock((" déplacement vers jBrasBas: "+toString(".3",jBrasBas.j1)+" , "+ toString(".3",jBrasBas.j2)+" , "+toString(".3",jBrasBas.j3)+" , "+toString(".3",jBrasBas.j4)+" , "+toString(".3",jBrasBas.j5)+" , "+toString(".3",jBrasBas.j6),true) delay(3) //définition des position des points en cartésien //en une ligne pSaisieBouchon={{0,0,0,0,0,0},{sfree,efree,wfree}} //ou champ par champ pSaisieBouchon.trsf.x= pSaisieBouchon.trsf.y= pSaisieBouchon.trsf.z= pSaisieBouchon.trsf.rx= pSaisieBouchon.trsf.ry= pSaisieBouchon.trsf.rz= pSaisieBouchon.config.shoulder= pSaisieBouchon.config.wrist= pSaisieBouchon.config.elbow= pVissageBouchon.trsf.x= pVissageBouchon.trsf.y= pVissageBouchon.trsf.z= pVissageBouchon.trsf.rx= pVissageBouchon.trsf.ry= pVissageBouchon.trsf.rz= pVissageBouchon.config.shoulder= pVissageBouchon.config.wrist= pVissageBouchon.config.elbow= ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ Solution //configuration des points en articulaire par programme //position bras levé jBrasHaut={0, 0, 0, 0, 0, 0} //position bras vers le bas //jBrasBas={0, -50, -90, 0, -40, 0} //position bras vers le bas vers la fenêtre jBrasBas={-50,-50,-60,0,-70,0} //exemple d'affichage call logMsgBlock((" déplacement vers jBrasBas: "+toString(".3",jBrasBas.j1)+" , "+ toString(".3",jBrasBas.j2)+" , "+toString(".3",jBrasBas.j3)+" , "+toString(".3",jBrasBas.j4)+" , "+toString(".3",jBrasBas.j5)+" , "+toString(".3",jBrasBas.j6),true) delay(3) //définition des position des points en cartésien pSaisieBouchon.trsf.x=-137.74 pSaisieBouchon.trsf.y=510.87 pSaisieBouchon.trsf.z=-303.78 pSaisieBouchon.trsf.rx=-0.02 pSaisieBouchon.trsf.ry=179.95 pSaisieBouchon.trsf.rz=66.93 pSaisieBouchon.config.shoulder= pSaisieBouchon.config.wrist= pSaisieBouchon.config.elbow= pVissageBouchon.trsf.x=72.04 pVissageBouchon.trsf.y=477.2 pVissageBouchon.trsf.z=-110.92 pVissageBouchon.trsf.rx=-0.02 pVissageBouchon.trsf.ry=179.94 pVissageBouchon.trsf.rz=66.93 pVissageBouchon.config.shoulder= pVissageBouchon.config.wrist= pVissageBouchon.config.elbow= ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ =====Communication via Sockets===== ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ projet créé en récupérant les sockets depuis le controleur: https://bvdp.inetdoc.net/files/iut/staubliiut/projets_srs/Cell1-december.sav2 config socket 2021_12_13.zip projet quasi vide créé en configurant manuellement les sockets dans SRS: https://bvdp.inetdoc.net/files/iut/staubliiut/projets_srs/CELL_IUT0_socket_UDP_TCP.zip à la maison, créer les sockets avec ip serveur: if(sioCtrl(siSocketUDP, "target", "192.168.1.41")!=0) ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ Dans ce projet, l'échange d'information entre le contrôleur du robot et son environnement (notamment des capteurs) est réalisé par réseau ethernet et wifi à l'aide des Sockets. Vous devez dans un premier temps configurer deux sockets dans votre projet SRS pour pouvoir dialoguer (et nous utiliserons ici deux types de sockets, qui seront illustrés en cours de réseau) ====Création et configuration des sockets dans le projet==== ===Socket UDP=== - cliquer sur le contrôleur dans l'arborescence du projet - cliquer sur l'onglet Accueil - cliquer sur l'onglet IO Physiques - clic droit sur "Sockets" puis gauche sur "Editer la carte" - clic gauche sur "+" - choisir "UDP" - régler les paramètres et valider - Nom: siSocketUDP - Port: 10000 - Description: Emission etat robot - Timeout: 1 - Fin de chaine: 13 - IP du serveur: 172.16.6.59 - créer une nouvelle donnée de type sio nommée siSocketUDP ===Socket TCP=== - cliquer sur le contrôleur dans l'arborescence du projet - cliquer sur l'onglet Accueil - cliquer sur l'onglet IO Physiques - clic droit sur "Sockets" puis gauche sur "Editer la carte" - clic gauche sur "+" - choisir "TCP client" - régler les paramètres et valider - Nom: siSocketTCP - Port: 30000 - Description: requete donnee capteur - Timeout: 1 - Fin de chaine: 13 - IP du serveur: 172.16.6.59 - créer une nouvelle donnée de type sio nommée siSocketTCP ===Association des variables Val3 sio aux Sockets=== - cliquer sur l'onglet Accueil - cliquer sur l'onglet IO Physiques - cliquer sur le petit "+" à gauche de "Sockets" pour faire apparaître le détail des sockets - glisser/déposer chacune des variables sio pour l'associer au Socket correspondant (en déposant la variable dans la colonne VAL3 et en attendant que l'icone "Link with" apparaisse avant de relâcher le bouton (Si cela ne marche toujours pas après 10 secondes, changer de marque de robot ou de métier.) Vous devriez obtenir un affichage identique à: {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/SRS_configuration_IO_sockets.PNG}} ====Programme python de simulation d'un capteur==== Nous allons maintenant ajouter un capteur simulé (via un programme) afin que vous puissiez l'utiliser depuis votre PC et accéder à ces données depuis SRS. Pour cela, enregistrer dans le dossier R:\lprob\"nom_prenom" le code du programme suivant (en faisant clic droit sur le nom puis enregistrer sous) #!/usr/bin/python3 # -*- coding: utf-8 -* #Bertrand Vandeportaele 2022 import os import sys debug=True global numeroPremiereDonneeCapteur #TODO: donner une valeur à cette variable en fonction de votre numéro d'étudiant numeroPremiereDonneeCapteur=156 global destIP global portOut global etatBouton etatBouton=0 global slider1Value slider1Value=0 global slider2Value slider2Value=0 global led0Button ######################################## #https://stackoverflow.com/questions/1051254/check-if-python-package-is-installed #install automatically watchdog if not already installed import subprocess import sys reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) installed_packages = [r.decode().split('==')[0] for r in reqs.split()] if 'PyQt5' in installed_packages: if debug: print('PyQt5 pip package already installed') else: if debug: print('PyQt5 pip package missing, lets install it') import pip pip.main(['install','PyQt5']) ######################################## from PyQt5.QtGui import * from PyQt5.QtNetwork import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5 import * import re #pour découpage chaine comme sur https://stackoverflow.com/questions/2175080/sscanf-in-python ################################################################################ def close(): print('close') exit(0) ################################################################################ def commutTimer(): global timer print('commutTimer') if timer.isActive(): timer.stop() commutTimerButton.setText('start stream sensor') else: timer.start() commutTimerButton.setText('stop stream sensor') ################################################################################ def slider1ValueChanged( value ): #label.setText( str( value ) global numeroPremiereDonneeCapteur global labelSlider1Value global slider1Value slider1Value=value labelSlider1Value.setText( str( numeroPremiereDonneeCapteur+5)+" : {:6d}".format(slider1Value) ) #print('changed') ################################################################################ def slider2ValueChanged( value ): #label.setText( str( value ) global numeroPremiereDonneeCapteur global labelSlider2Value global slider2Value slider2Value=value labelSlider2Value.setText( str( numeroPremiereDonneeCapteur+6)+" : {:6d}".format(slider2Value) ) #print('changed') ################################################################################ def bouton0(): global numeroPremiereDonneeCapteur global labelButtonValue global led0Button global etatBouton etatBouton=(etatBouton+1)%2 if etatBouton==0: led0Button.setText('Activer la sortie TOR') else: led0Button.setText('Desactiver la sortie TOR') labelButtonValue.setText( str( numeroPremiereDonneeCapteur+2)+" : {:6d}".format(etatBouton) ) print('etatBouton: '+ str(etatBouton) +" \n"); ################################################################################ def sendUDP(i): global udpSocket global destIP global portOut DestIP = QHostAddress(destIP); global slider1Value global slider2Value global etatBouton global numeroPremiereDonneeCapteur # chaine=str(slider1Value)+ " " + str(slider2Value) #ajout @MAC bidon # chaine="00:00:00:00:00:00 "+str(slider1Value)+ " " + str(slider2Value) #ajout champs vides pour être compatible avec le joystick wifi #@MAC: BC:DD:C2:FE:6F:F0 num: 0 0 -> 529.0 , 1 -> 534.0 , 2 -> 0.0 , 3 -> 0.0 , 4 -> 0.0 , 5 -> -73.0 , 6 -> 63.0 , chaine="00:00:00:00:00:00 "+str(numeroPremiereDonneeCapteur)+" 0 0 "+str(etatBouton)+" 0 0 "+str(slider1Value)+ " " + str(slider2Value) #chaines bidons pour générer erreur de parsing sur le serveur # chaine="00:00:00:00:00:00 0 0 0 "+"687f"+" 0 0 "+str(slider1Value)+ " " + str(slider2Value) chaine=chaine+chr(13)+chr(10) print("la chaine envoyée vers ip: "+str(destIP)+":"+str(portOut) +" est: "+chaine) udpSocket.writeDatagram(chaine.encode('utf-8'),DestIP, portOut); ################################################################################ def timerUpdate(): sendUDP(0) ################################################################################ global led0Button #destIP='192.168.1.50' #pc simulateur #destIP='192.168.0.112' #pc simulateur #destIP='192.168.1.49' #pc serveur rapid connecté en filaire à réseau AIP #destIP='127.0.0.1' #pc serveur sur la boucle locale #destIP='192.168.3.5' #pc serveur rapid connecté en wifi à réseau AIP #destIP='192.168.3.4' #pc serveur rapid connecté en ethernet à réseau AIP #destIP='127.0.0.1' #ip locale #destIP='10.6.11.62' #un pc de la salle u2 IUT destIP='172.16.6.59' #rapid connecté sur gommette bleu portOut=10000 posx=100 posy=100 sizex=500 sizey=150 ################################################################################ app = QApplication(sys.argv) w=QDialog() statusLabel =QLabel('En attente de datagrammes UDP depuis le PIC32') commutTimerButton=QPushButton('stop stream sensor') quitButton = QPushButton('&Quit') led0Button = QPushButton('Activer la sortie TOR') udpSocket =QUdpSocket() udpSocket.bind(portOut, QUdpSocket.ShareAddress) quitButton.clicked.connect(close) commutTimerButton.clicked.connect(commutTimer) led0Button.clicked.connect(bouton0) #led1Button.clicked.connect(bouton1) #led2Button.clicked.connect(bouton2) #app.connect(quitButton,QtCore.SIGNAL('clicked()'), close) #app.connect(commutTimerButton, QtCore.SIGNAL('clicked()'), commutTimer) #app.connect(led0Button,QtCore.SIGNAL('clicked()'), bouton0) buttonLayout =QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(quitButton) buttonLayout.addWidget(commutTimerButton) buttonLayout.addStretch(1) global labelButtonValue labelButtonValue=QLabel( ) labelButtonValue.setGeometry(250, 50, 50, 35) #labelButtonValue.setText( "x: "+str(0 ) ) labelButtonValue.setText( str( numeroPremiereDonneeCapteur+2)+" : {:6d}".format(0) ) button1Layout =QHBoxLayout() button1Layout.addStretch(1) button1Layout.addWidget(labelButtonValue) button1Layout.addStretch(1) button1Layout.addWidget(led0Button) button1Layout.addStretch(1) ####################################################"" #http://koor.fr/Python/CodeSamplesQt/PyQtSlider.wp slider1 = QSlider(Qt.Horizontal); amplitude=1800; slider1.setMinimum(int(-amplitude/2)) slider1.setMaximum(int(amplitude/2)) slider1.setGeometry( 10, 10, 600, 40 ) slider1.valueChanged.connect(slider1ValueChanged ) slider1.setValue( 0 ) global labelSlider1Value labelSlider1Value=QLabel( ) labelSlider1Value.setGeometry(250, 50, 50, 35) #labelSlider1Value.setText( "x: "+str(0 ) ) labelSlider1Value.setText( str( numeroPremiereDonneeCapteur+5)+" : {:6d}".format(0) ) slider1Layout =QHBoxLayout() slider1Layout.addWidget(labelSlider1Value) slider1Layout.addWidget(slider1) #labelSlider1Value=QLabel( ) #labelSlider1Value.setGeometry(250, 50, 50, 35) #labelSlider1Value.setText( str( slider1.getValue() ) ) sliderLayout =QHBoxLayout() sliderLayout.addStretch(1) sliderLayout.addWidget(slider1) sliderLayout.addStretch(1) #sliderLayout.addWidget(labelSlider1Value) #sliderLayout.addStretch(1) slider2 = QSlider(Qt.Horizontal); slider2.setMinimum(int(-amplitude/2)) slider2.setMaximum(int(amplitude/2)) slider2.setGeometry( 10, 10, 600, 40 ) slider2.valueChanged.connect(slider2ValueChanged ) slider2.setValue( 0 ) global labelSlider2Value labelSlider2Value=QLabel( ) labelSlider2Value.setGeometry(250, 50, 50, 35) #labelSlider2Value.setText( "Y: "+str(0 ) ) labelSlider2Value.setText( str( numeroPremiereDonneeCapteur+6)+" : {:6d}".format(0) ) slider2Layout =QHBoxLayout() slider2Layout.addWidget(labelSlider2Value) slider2Layout.addWidget(slider2) sliderLayout.addWidget(slider2) sliderLayout.addStretch(1) mainLayout = QVBoxLayout() mainLayout.addLayout(buttonLayout) mainLayout.addLayout(button1Layout) mainLayout.addLayout(slider1Layout) mainLayout.addLayout(slider2Layout) mainLayout.addWidget(statusLabel) w.setLayout(mainLayout) chaine='@BVDP2022: Port Em '+str(portOut) +' vers IP: '+str(destIP) print(chaine) w.setWindowTitle(chaine) #timer adapted from example 1 of https://www.programcreek.com/python/example/52106/PyQt4.QtCore.QTimer timer = QtCore.QTimer() #app.connect(timer, QtCore.SIGNAL('timeout()'), timerUpdate) timer.timeout.connect(timerUpdate) timer.setInterval(100) timer.start() w.setGeometry(posx,posy,sizex,sizey) #donne le focus au bouton 1 led0Button.setDefault(True) w.show() app.exec_() Sauver ce fichier sur le disque R:\ dans le dossier R:\lprob\nom_prenom Exécuter une première fois ce programme pour télécharger les librairies en copiant collant dans une console: R: cd lprob cd nom_prenom python simu_sensor_2_joystick_qt5.py Editer ce fichier avec idle pour l'adapter selon les consignes données en séance en modifiant la variable **numeroPremiereDonneeCapteur** au début du programme pour qu'elle vaille 100x le numéro du projet qui a été attribué à votre binome, en tapant dans la commande windows: C:\"Program Files"\Python39\Lib\idlelib\idle simu_sensor_2_joystick_qt5.py Après édition, sauver le fichier et quitter idle puis lancer ce programme en faisant Touche Windows+R puis taper "cmd" et entrée, puis saisir en adaptant les lignes suivantes: R: cd R:\lprob\nom_prenom py simu_sensor_2_joystick_qt5.py Si besoin, à la première utilisation, exécuter deux fois la dernière commande puis ignorer les messages de pare feu! Agir sur les curseurs et bouton de l'application et observé dans la fenêtre de texte les chaines de caractères émises via Socket. ====Le robot en tant que capteur==== Nous allons maintenant faire en sorte que le robot se comporte comme un capteur qui informe de son état (articulaire et cartésien). Pour cela, il va envoyer via socket UDP des chaines de caractères comme le fait l'application python. Ceci va être réalisé par une tâche périodique en VAL3 qui envoie en UDP la pose courante du robot T,R, et joint à intervalle régulier dans un programme qui s’exécute en parallèle du programme start. Présentation au tableau de la gestion de l'émission de l'état du robot via socket UDP. La variable socket est normalement déjà configurée, mais il est possible la configurer au début du programme à l'aide de: //configuration du socket UDP clearBuffer(siSocketUDP) if(sioCtrl(siSocketUDP, "target", "172.16.6.59")!=0) call logMsgBlock("probleme sioCtrl(siSocketUDP, target, 172.16.6.59)", true) endIf //"endOfString" num (Pour ligne série, client et serveur UDP) Code ASCII pour le caractère de fin de chaîne à utiliser avec les opérateurs '=' (dans la plage [0, 255]) if(sioCtrl(siSocketUDP, "endOfString", 13)!=0) call logMsgBlock("probleme sioCtrl(siSocketUDP, endOfString, 13)",true) endIf //port 10000 utilisé par socket UDP if(sioCtrl(siSocketUDP, "port", 10000)!=0) call logMsgBlock("probleme sioCtrl(siSocketUDP, port, 10000)",true) endIf //0 pour configurer les lectures sur socket bloquante, //une autre valeur en seconde sinon if(sioCtrl(siSocketUDP, "timeout",1)!=0 ) call logMsgBlock("probleme sioCtrl(siSocketUDP, timeout,1)",true) endIf La programmation de la tache périodique doit être faite une fois dans le programme start avec: //programmation de la tache périodique //emissionEtat est un programme créé, et exécuté à une périodicité de 0.1s taskCreateSync "emissionEtat",.1,bOverRun,emissionEtat() call logMsgBlock("Tache periodique emission Etat lancee",true) Ajouter la variable bOverRun en tant que nouvelle donnée. Ensuite, ajouter un programme dans le projet: Cellule->Projet->clic droit->Ajouter->Nouveau programme. Saisir le nom "emissionEtat" puis y copier le code suivant: begin //il faut une boucle car taskCreateSync ne réappelle pas le programme, juste il lui donne la main périodiquement while true l_pHereEtat=here(tTool,world) l_jHereEtat=herej() //déclarer une variable string et utiliser la fonction tostring pour formater //adresse mac puis numéro de la première donnée capteur émise l_sEtat="DC:4F:22:00:00:00 50" l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.x) l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.y) l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.z) l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.rx) l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.ry) l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].trsf.rz) //l_sEtat=l_sEtat+" "+toString(".6",l_pHereEtat[0].config.shoulder) //shoulder n'est pas un numero, si je veux l'envoyer il faut faire une correspondante avec numéros siSocketUDP=l_sEtat //envoi en 2 temps de la config du robot, car sinon la chaine est tronquée car trop longue (>128 octets) //envoyer les paramètres suivants avec un offset par rapport aux précédents //adresse mac puis numéro de la première donnée capteur émise l_sEtat="DC:4F:22:00:00:00 56" l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j1) l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j2) l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j3) l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j4) l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j5) l_sEtat=l_sEtat+" "+toString(".6",l_jHereEtat[0].j6) siSocketUDP=l_sEtat //en cas de doute décommenter la ligne suivante pour afficher des messages indiquant l'exécution de la tache periodique //popUpMsg("emissionEtat") //Il faut un delay de la periodicité de la tâche sinon les données s'accumulent dans la variable l_sEtat et le controleur plante delay(0.1) endWhile end Remplacer les valeurs 50 et 56 de ce programme par les valeurs de numeroProjet*100+10 et numeroProjet*100+16, par exemple 910 et 916 pour le projet numéro 9. Ajouter les variables nécessaires dans votre projet en tant que variables LOCALES pour que ce nouveau programme puisse fonctionner. Tester le programme et vérifier avec l'enseignant que l'état de votre robot est bien envoyé au serveur. ====Récupération des données capteurs depuis le serveur via Socket TCP==== La variable socket est normalement déjà configurée, mais il est possible la configurer au début du programme à l'aide de: clearBuffer(siSocketTCP) if(sioCtrl(siSocketTCP, "target", "172.16.6.59")!=0) call logMsgBlock("probleme sioCtrl(siSocketTCP, target, 172.16.6.59)",true) endIf //"endOfString" num (Pour ligne série, client et serveur TCP) Code ASCII pour le caractère de fin de chaîne à utiliser avec les opérateurs '=' (dans la plage [0, 255]) if(sioCtrl(siSocketTCP, "endOfString", 13)!=0) call logMsgBlock("probleme sioCtrl(siSocketTCP, endOfString, 13)",true) endIf //port 30000 utilisé par socket TCP if(sioCtrl(siSocketTCP, "port", 30000)!=0) call logMsgBlock("probleme sioCtrl(siSocketTCP, port, 30000)",true) endIf //0 pour configurer les lectures sur socket bloquante, //une autre valeur en seconde sinon if(sioCtrl(siSocketTCP, "timeout",1)!=0 ) call logMsgBlock("probleme sioCtrl(siSocketTCP, timeout,1)",true) endIf Tester la boucle du programme suivant en la copiant collant avant la boucle de votre programme. Il vous faut remplacer les numéros des champs dans la chaîne par les numéros de champs de données émises par votre programme Python: begin while(true) //exemple d'envoi d'une requete pour obtenir les donnees capteurs 10 11 et 12 siSocketTCP = "r 10 11 12" //receptionne la reponse et la met dans la donnée sMsg, arrêt du programme si la reponse n'est pas recue avant le timeout l_sMsg = siSocketTCP //affiche sur l'ecran la chaine recue call logMsgBlock(l_sMsg,true) //il vous reste a convertir les donnees depuis la chaine endWhile end Si vous ne l'avez pas déjà fait, créer la variable **siSocketTCP** (attention à bien choisir le type sio, car le type automatiquement choisi risque d'être string) et l'associer la variable à la ressource sio, pour cela aller dans Accueil->IO Physique->Socket->siSocketTCP puis glisser déposer la variable **siSocketTCP[0]** dans la colonne VAL3 du lien physique **siSocketTCP**. Créer la variable locale **l_sMsg ** (de type string). Lancer le programme VAL3 alors que le programme python est lancé et vous devriez voir les valeurs des données capteurs s'afficher sur l'écran du pendant virtuel. Il vous reste maintenant à fusionner votre programme et cette boucle qui récupère les données capteurs pour que votre programme les utilise correctement. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ====Configuration à faire sur le contrôleur du robot==== Le PC sur lequel le serveur de capteur fonctionne n'est pas sur le réseau local du contrôleur du robot. Votre PC de développement et le simulateur du robot sont capables de communiquer avec le serveur car le PC connait le réseau local de l'AIP et les passerelles pour en sortir. Par contre, pour que le vrai robot soit capable de communiquer avec le serveur de capteurs, il faut configurer sur le contrôleur du robot une passerelle qui fait le lien entre les deux réseaux. Cela est normalement déjà réglé mais la procédure est indiquée ici pour référence: * Menu->Tableau de bords->Passerelles, puis * choisir destination, , faire "entrée" puis saisir l'ip 192.168.3.4 * choisir passerelle, faire "entrée" puis saisir l'ip 192.168.0.13 {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/configuration_passerelle.jpg}} {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/configuration_socket_pendant.jpg}} {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/configuration_socket_srs.jpg}} ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ =====Génération d'une trajectoire lisse pour le vissage===== Il est nécessaire de configurer un descripteur de mouvement imposant de passer exactement par les points programmés avec lissage en mode 'off' pour que les commandes s’enchainent tel que: mdescA.blend=off ou mdescA.leave=0 mdescA.reach=0 Ensuite, dans la boucle, vous devrez enchainer les **movej()** ou **movel()** sans **waitEndMove()**. La fin du vissage programmé est alors détectée non plus parce que les différentes itérations de la boucle qui génèrent les commandes move? ont été exécutées mais avec: // condition d'arrêt si la FIFO est vidée if isEmpty() bBoolVisFini=true call logMsgBlock("arret vissage fin de mouvement!",false) endIf Pour déterminer quel ordre de mouvement le robot est en train d’exécuter (et quel pourcentage par rapport au point suivant): nNumOrdreActuel[0]= getMoveId() call logMsgBlock("nNumOrdreActuel:"+toString(".3",nNumOrdreActuel[0]),false) Pour interrompre les mouvements programmés (lorsque le capteur de couple indique un couple supérieur au seuil souhaité): stopMove() resetMotion() =====Mesure des temps de cycles===== Vous pouvez mesurer le temps en secondes entre l’exécution de deux lignes du programme avec: //lecture de la date de départ: lancement chronomètre l_ndebut=clock() //instructions dont on souhaite mesurer la durée d'exécution //...... //lecture de la date de fin: arrêt du chronomètre et mesure de la durée écoulée l_nduree=clock()-l_ndebut Pour rappel, les instructions move. sont non bloquantes et leur durée d’exécution n'est pas la durée nécessaire au robot pour faire le mouvement. Pour mesurer le temps nécessaire au robot pour faire le mouvement, la lecture de date de fin doit être faite APRES une instruction waitEndMove(). Ceci peut être utilisé pour mesurer le temps d'un cycle et comparer plusieurs exécutions du programme en faisant varier des paramètres de la trajectoire. =====Étapes de développement===== Jusqu'à nouvel ordre, les commandes de mouvements doivent être suivies de **waitEndMove()** pour pouvoir tester en pas à pas et voir le robot effectuer les mouvements demandés. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 1: Configurer le projet SRS et insérer les éléments 3D dans l'environnement du robot. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 2: Programmer le mouvement pour faire sortir le bras de la configuration singulière (2 positions du robot en articulaire: jBrasLeve et jBrasBaisse). {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 3: Ajouter le cycle en U avec deux positions en cartésien (pSaisieBouchon et pDeposeBouchon), calculer les positions avec offset grâce à la fonction **appro(...)** 10cm au dessus des points. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 4: Préparer le vissage saccadé en boucle ouverte: définir deux variables nPasVissage (pas de vissage en mm/tour) et nDebAngulaire (débattement angulaire pour le vissage en degrés) Faire en sorte que le robot arrive au point d'approche pDeposeBouchon en contraignant l'articulation j6 pour qu'elle soit préparée pour le vissage en prédévissant la moitié de l'amplitude de vissage. ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ nPasVissage=9 (mm/tour) nDebAngulaire=120 (degrés) ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ Adapter la commande de déplacement linéaire du cycle en U pour que le robot descende sur le point pDeposeBouchon en conservant l'orientation du poignet déterminée précédemment. Ouvrir puis refermer la pince pour faire descendre le bouchon sur le pas de vis. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 5: Mettre en place le mouvement de vissage saccadé: Faire une boucle qui décompose en 8 étapes le vissage. Utiliser la fonction **appro()** pour calculer des offsets en cartésien par rapport à la position initiale pDeposeBouchon. Utiliser une boucle permettant de générer le mouvement interpolé en linéaire passant par ces 8 points à la suite. A la fin ouvrir la pince. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 6: Mettre en place le mouvement du cycle en U lissé: Régler le descripteur de mouvements pour autoriser le robot à approximer la trajectoire pour le cycle en U et à passer à 2cm des points fournis. Commenter les **waitEndMove()** correspondant (ou mieux utiliser une variable booléenne bLisssage pour désactiver les **waitEndMove()** si la variable vaut true) {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 7: Mettre en place le mouvement de vissage lissé: Régler le descripteur de mouvements pour obliger le robot à interpoler en cartésien et à passer exactement par les points fournis pour le vissage et retirer les **waitEndMove()** correspondant. La commande d'ouverture de la pince à la fin de la boucle contient un **waitEndMove()** et bloque donc l'exécution du programme jusqu'à ce que le mouvement soit achevé. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 8: Mettre en place la préparation d'une condition d'arrêt du vissage: Après la boucle qui fournit au contrôleur les différents points pour le vissage, ajouter une autre boucle qui affiche en continu l'état d'avancement dans l’exécution de la trajectoire. La sortie de cette boucle est dans un premier temps effectuée lorsque la file d'ordres du contrôleur est vide. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 9: Intégrer le capteur simulé pour interrompre le vissage: Installer et configurer l'application python émulant un capteur. Configurer le projet SRS pour pouvoir communiquer via socket TCP. Ajouter la condition d'arrêt correspondant au fait que le couple de serrage soit atteint, et dans ce cas interrompre l'exécution de la file d'ordre de mouvement du robot. Tester avec le préhenseur sans le capteur de couple et simuler le capteur de couple avec l'application python. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 10: Ajouter la tâche parallèle permettant au robot d'envoyer son état au serveur de données capteur. Visualiser l'affichage du robot en 3D sur le PC de l'enseignant. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 11: Adapter les descripteurs de mouvements pour régler une vitesse de déplacement plus importante pendant le trajet cycle en U et moindre pendant la saisie et le vissage du bouchon. (100% pendant les déplacements rapide et 10% pendant la saisie du bouchon le vissage). Ne pas utiliser la fonction **setMonitorSpeed()** dans le code car nous réglerons ce paramètre à l'aide du pendant. Ajouter des points intermédiaires pour l'approche du bouchon et de la bouteille pour réduire la vitesse à 3cm des objets à saisir. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 12: Après accord de l'enseignant et vérification des vitesses de déplacement, exécuter le programme en mode automatique AVEC L'ENSEIGNANT. Ne pas dépasser 75% de la vitesse sur le pendant. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 13: Déterminer la valeur du capteur de couple réel correspondant à un bouchon bien vissé et adapter la condition de fin de vissage dans votre programme. Adapter également votre programme pour qu'il utilise la donnée issue du capteur réel plutôt que celle issue du simulateur. Avec l'enseignant, monter le préhenseur doté du capteur de couple sur le robot. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 14: Utiliser le capteur de couple pour déterminer si le vissage a été bien effectué (couple de serrage atteint avant le débattement maximal) et indiquer sur le pendant l'information correspondante. {{https://bvdp.inetdoc.net/files/iut/tp_tns/TODO.jpg}} 15: Utilisez ce que vous avez appris dans la formation PHL pour faire en sorte que la simulation permette d'animer le bouchon. ------------------------------------ Bravo, vous êtes arrivé au bout de votre quête, Chevalier.... Maintenant il faut attendre la période suivante pour intégrer le capteur de vision au système afin de localiser automatiquement le bouchon. ------------------------------------ =====Annexes===== ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ====Informations réseau==== {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/reseauAIPManip.png}} ===IP et numéros de port=== - IP pc rapid hébergeant le serveur de données capteurs en filaire: 192.168.3.4 - IP pc rapid hébergeant le serveur de données capteurs en WIFI: 192.168.3.5 - IP pc rapid hébergeant le serveur de données capteurs en filaire si connecté sur le réseau AIP: 192.168.1.49 - IP pc Windows à coté de l'armoire de commande: 192.168.1.50 - IP de l'armoire de commande Staubli: 192.168.0.112 - IP du capteur de couple réel: 192.168.3.252 - IP du capteur joystick: 192.168.3.253 Configuration du pc Windows à coté de l'armoire de commande: IP: 192.168.1.50 Masque: 255.255.254.0 Passerelle: 192.168.1.13 Filtre Wireshark pour analyser le trafic UDP sur le réseau des capteurs: ip.addr==192.168.3.0/24 && udp Indices de données capteurs utilisés: - capteur de couple: indice 0 - capteur joystick: indice 0 aussi et .... TODO compléter et expliquer Petite subtilité pour le trafic: - Les capteurs esp8266 communiquent vers l'ip du wifi du pc serveur de capteurs. - Les capteurs simulés en python par les étudiant communiquent via l'ip ethernet du pc serveur de capteurs. ====Gestions des E/S TOR==== L'armoire est équipée de deux cartes DIO: -BASIC I/O -DIO MIO Pour les configurer dans le projet SRS: cliquer onglet cellule->prog1->Controller1, Acceuil, IO Physiques BasicIO-1 cliquer gauche pour cocher Entrée digital %I13 puis cliquer gauche importer dans l'onglet Données, Projet->dio doit contenir diB_13 ATTENTION Problème de numérotation sur le bornier, car les indices commencent à 1 Sortie doB_15 (numeroté 16) ne fonctionne pas putln("doB_12") while true doB_12[0]=true put("1") delay(1) doB_12[0]=false put("0") delay(1) {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS-ES.PNG}} {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS-ES2.PNG}} {{https://bvdp.inetdoc.net/files/iut/staubli/images_wiki/SRS-ES3.PNG}} ===Alimentation pour les E/S 24V=== Alimentation 24V pour les Entrées/Sorties à allumer (en bas sur cloison à coté robot staubli) ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ====Ressources du net==== vidéos Tuto: https://www.youtube.com/playlist?list=PLUDu1larmk8EB1ar2MTOhkf7iHOtTKb6j https://fr.readkong.com/page/tp-3-decouverte-du-robot-staubli-tx60-1715216 TP d'initiation robot staubli Picardie: https://home.mis.u-picardie.fr/~fabio/Eng/documenti/Teaching/INRO15-16/InitRob_TP3.pdf vidéo communication par socket: https://slideplayer.fr/slide/2666058/ l'émulateur de pendant utilise les ports 850-853 et 5660-5680 Socket\sCognex1 faire une string pour stocker les messages ====Réflexion sur l'infrastructure réseau==== routeur wifi banana pi RP2 avec 4 interfaces filaires + WIFI ajout d'une variable sSio ajout d'une variable string x_sMsg explication du protocole de comm cognex via socket dans le fichier C:\Users\bvande\Downloads\communication-EntreeSorties-mai2019_michel\communication-EntreeSorties-mai2019\Controller1\usr\usrapp\cognexComm7En\readme.pgx --------------------------- // You must declare this socket in the control panel of the controller as // followed : // - a client socket for each camera with // - IP address of camera // - Port : 1023 // - time out = 0 // - line end char = 13 chaque fichier .pgx est un sous programme example.pgx // This is an example for use this library. // This example writes two numerical values (int num and float num) and // reads a string value to/from three cells: --------------------------- sendCommand.pgx call writeSocket(x_nCamID,x_sCmd) call readSocket(x_nCamID,l_sMsgError,x_bError) call checkErrFormat(x_nCamID,l_sMsgError,l_bError) x_bError=l_bError if bDebugProgram //Displays error message //getFullError() replace getErrorCode() and getErrorMessage() call getFullError(x_nCamID,l_nErrorCode,l_sMsgError) ? "Cmd> "+l_sMsgError endIf --------------------------- writeSocket.pgx for i=0 to (len(x_sMsg)-1) sioSet(cCamera[x_nCamID].sSocket,asc(x_sMsg,i)) endFor sioSet(cCamera[x_nCamID].sSocket,13) sioSet(cCamera[x_nCamID].sSocket,10) if bDebugSocket ? "W Status code: "+x_sMsg endIf librairie récupérée de: C:\Users\bvande\Documents\communication-EntreeSorties-mai2019_michel\communication-EntreeSorties-mai2019\Controller1\usr\usrapp\cognexComm7En ----------------------------------------------- dans C:\Users\bvande\Documents\communication-EntreeSorties-mai2019_michel\communication-EntreeSorties-mai2019\Controller1\usr\usrapp\cognexComm7En\login.pgx sioLink(cCamera[x_nCamID].sSocket,x_sioSocket) call readSocket(x_nCamID,l_sMsg,x_bError) //putln("finreadsoc") // Send user name call readLogin(x_nCamID,l_sMsg,x_bError) //putln("readlogin") call writeSocket(x_nCamID,x_sUser) // Send password call readLogin(x_nCamID,l_sMsg,x_bError) call writeSocket(x_nCamID,x_sPassword) // Read login result call readSocket(x_nCamID,l_sMsg,x_bError) x_bError=find(l_sMsg,"User Logged In")==-1 if x_bError cCamera[x_nCamID].nErrorCode=1 cCamera[x_nCamID].bConnected=false if bDebugProgram putln("Login : failed") endIf ------------------------------------------------------------------------ readsocket x_sMsg="" //putln("read socket") do l_nCount=sioGet(cCamera[x_nCamID].sSocket,l_nChar) //-1 : timeout for input communication has been reached //putln("sio") if (l_nCount>-1) and (l_nChar>=32) x_sMsg=x_sMsg+chr(l_nChar) endIf x_bError=l_nCount<=-1 until (l_nChar==13) or x_bError //Displays error message if bDebugSocket ? "R Status code> "+x_sMsg endIf ------------------------------------------------------------------------ writesocket for i=0 to (len(x_sMsg)-1) sioSet(cCamera[x_nCamID].sSocket,asc(x_sMsg,i)) endFor sioSet(cCamera[x_nCamID].sSocket,13) sioSet(cCamera[x_nCamID].sSocket,10) if bDebugSocket ? "W Status code: "+x_sMsg endIf ------------------------------------------------------------------------ ====Python==== Installation python sur machine windows: https://pypi.anaconda.org/ales-erjavec/simple/pyqt4/4.11.4/PyQt4-4.11.4-cp34-none-win_amd64.whl cd \Python34\Scripts pip install QtGui pip3 install C:\Users\bvande\Downloads\PyQt4-4.11.4-cp34-none-win_amd64.whl C:\Python34\Scripts>pip3 install tk Downloading/unpacking tk Downloading tk-0.1.0-py3-none-any.whl Installing collected packages: tk Successfully installed tk Cleaning up... C:\Python34\Scripts>pip3 install matplotlib Downloading/unpacking matplotlib Running setup.py (path:C:\Users\alimen\AppData\Local\Temp\pip_build_alimen\mat plotlib\setup.py) egg_info for package matplotlib Beginning with Matplotlib 3.1, Python 3.6 or above is required. This may be due to an out of date pip. Make sure you have pip >= 9.0.1. Complete output from command python setup.py egg_info: Beginning with Matplotlib 3.1, Python 3.6 or above is required. This may be due to an out of date pip. Make sure you have pip >= 9.0.1. ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 in C:\Users\alimen\App Data\Local\Temp\pip_build_alimen\matplotlib Storing debug log for failure in C:\Users\alimen\pip\pip.log C:\Python34\Scripts> ====Programmes Bertrand==== ------------------------------------------ begin //B.Vandeportaele 2019 //activation puissance pour mode deporte enablePower() //effacement écran USER cls() //selection écran USER userPage() //putln( "démarrage application") put("date: ") putln(getDate(" %d/%m/%Y %H:%M:%S")) nNum[0]=0 put(nNum[0]) //affichage compte à rebours gotoxy(0,1) put("départ dans: ") for nNum[0]=1 to 0 step -1 gotoxy(13,1) put(nNum[0]) putln(" s ") delay(1) endFor nNum[0]=0 gotoxy(0,2) putln(" KABOUM2 !!!!!!! ") //TODO faire un sous programme qui teste la communication //avec les différentes adresses (via timeout) call initSockets() bOverRun=false //emissionEtat est un programme créé, et éxecuté à une périodicité de 0.01s //taskCreateSync "emissionEtat",.01,bOverRun,emissionEtat() taskCreateSync "emissionEtat",1,bOverRun,emissionEtat() putln("Tache periodique emission Etat lancee") /////////////////////////////////////////////////////// //configuration des points en articulaire par programme //position bras levé A={0, 0, 0, 0, 0, 0} //position bras vers le bas B={0, -50, -90, 0, -40, 0} //impose une vitesse faible pour les premiers déplacements du robot //on ne peut que ralentir la vitesse avec le programme, c'est à l'utilisateur de l'augmenter avec Emulator Controller ou avec le pendant //attention cette vitesse est prise en compte par l'armoire de commande en mode automatique //setMonitorSpeed(10) //positionnement du bras dans une configuration initiale connue en donnant une consigne articulaire (joint) putln("positionnement du bras dans une configuration initiale connue en donnant une consigne articulaire (joint) ") //bras vers le haut movej( A,tTool, mdescA) waitEndMove() //bras vers le bas movej( B,tTool, mdescA) waitEndMove() putln("positionnement du bras atteinte") /////////////////////////////////////////////////////// if(true) //Cette instruction renvoie un point modifié par transformation géométrique. La transformation est définie par rapport aux axes du centre outil d'entrée. //Le repère de référence et la configuration du point renvoyé sont ceux du point d'entrée. //Une erreur d'exécution est générée si aucun repère de référence n'est défini pour pPosition. // Approche :Mouvement d'approche à 100 mm au-dessus du point (axe Z) // movej(appro(pDestination,{0,0,-100,0,0,0}), flange, mNomDesc) // Aller au pointmovel(pDestination, flange, mNomDesc) while(true) putln("Approche pour la saisie du bouchon") movej(appro(pPointSaisieBou[0],{0,0,-100,0,0,0}), tTool, mdescA) //waitEndMove() //Attendre que la position du robot se stabilise while(isSettled()==false) putln(".") endWhile putln("saisie du bouchon") movej(pPointSaisieBou[0], tTool, mdescA) putln("Eloignement après la saisie du bouchon") movej(appro(pPointSaisieBou[0],{0,0,-100,0,0,0}), tTool, mdescA) waitEndMove() putln("Approche pour le vissage du bouchon") //100mm au dessus movej(appro(pPointVisBou[0],{0,0,-100,0,0,0}), tTool, mdescA) waitEndMove() //baisser la vitesse //setMonitorSpeed(10) putln("vissage du bouchon") mdescA.blend=off mdescA.leave=0 mdescA.reach=0 movej(pPointVisBou[0], tTool, mdescA) bBoolVisFini=false //il faut activer le lissage en mode 'joint' pour que les commandes s'enchainent mdescA.blend=joint mdescA.leave=0 mdescA.reach=0 for nNum[0]=0 to 10 step 1 put("itération: ") put(nNum[0]) put(" -> ") movej(appro(pPointVisBou[0],{0,0,nNum[0]*2.6*3/8,0,0,nNum[0]*45}), tTool, mdescA) endFor nNum[0]=0 while bBoolVisFini==false // // movej(appro(pPointVisBou[0],{0,0,nNum[0]*1.2,0,0,nNum[0]*90}), tTool, mdescA) // waitEndMove() if(false) jJointActuel=herej() put("jJointActuel[0]: ") put(jJointActuel[0].j1) put(", ") put(jJointActuel[0].j2) put(", ") put(jJointActuel[0].j3) put(", ") put(jJointActuel[0].j4) put(", ") put(jJointActuel[0].j5) put(", ") put(jJointActuel[0].j6) putln(" ") endIf // condition d'arrêt si la fifo est vidée if isEmpty() bBoolVisFini=true putln("arret vissage fin de mouvement!") endIf nNumOrdreActuel[0]= getMoveId() put("nNumOrdreActuel: ") putln(nNumOrdreActuel[0]) //ajouter une condition sur le capteur de couple //if nNum[0]>=10 //émission chaine complète cClient_socket="r 5 6 2" x_sMsg=cClient_socket putln("chaine recue:") put(x_sMsg) x_sMsg= toNum(x_sMsg, nNum, bBool) x_sMsg= toNum(x_sMsg, nNum2, bBool) x_sMsg= toNum(x_sMsg, nNum3, bBool) if nNum3==1 bBoolVisFini=true stopMove() resetMotion() putln("arret vissage capteur!") endIf if bBoolVisFini==false nNum[0]=nNum[0]+1 endIf //endFor endWhile //remonter la vitesse, ne fonctionne pas si l'utilisateur peut régler manuellement la vitesse //setMonitorSpeed(25) // il faut garder l'angle de vissage sinon l'outils va devisser en remontant putln("Eloignement après le vissage du bouchon") //recupère la pose courante en cartésien pPointActuel[0]=here(tTool,fFrame[0]) //remonte de 100 par rapport à la position courante 100mm au dessus movej(appro(pPointActuel[0],{0,0,-100,0,0,0}), tTool, mdescA) waitEndMove() // problème, en cartésien, les tours faits pour le vissage ne sont pas défaits.... putln("Dévissage pour revenir au 0") jJointActuel=herej() jJointActuel[0].j6=0 movej( jJointActuel[0], tTool, mdescA) waitEndMove() endWhile endIf if true while true put("*") //sioSet(cUdpsock,asc(x_sMsg) ) //nNum[0]=ioStatus(cClient_socket) //0 L'entrée-sortie fonctionne. //1 L'entrée-sortie fonctionne mais elle est verrouillée par l'opérateur. Les entrées ont alors une valeur fixe (contrôlée par l'opérateur) qui peut être différente de la valeur matérielle. Les sorties ont alors une valeur //fixe contrôlée par l'opérateur : l'écriture sur la sortie n'a aucun effet. Le mode de verrouillage est un moyen de débogage. //2 L'entrée-sortie est simulée (entrée-sortie logicielle, sans effet sur le matériel). //-1 L'entrée-sortie ne fonctionne pas parce que le lien (adresse physique) n'est pas défini. //-2 L'entrée-sortie ne fonctionne pas parce que le lien (adresse physique) ne correspond à aucune entrée-sortie du système. Le matériel correspondant à l'adresse physique n'est pas installé ou n'a pas pu être initialisé. //-3 L'entrée-sortie ne fonctionne pas parce que le dispositif d'entrée-sortie est en erreur. //putln("envoi") //émission chaine complète cClient_socket="r 5 6 2" //putln("requete0") //émission chaine caractère par caractère // for nNum[0]=0 to(len(x_sMsg)-1) // sioSet(cUdpsock,asc(x_sMsg, nNum[0])) // endFor // sioSet(cUdpsock,13) // sioSet(cUdpsock,10) //tentative de reception d'un caractère, bloquant jusqu'au timeout // nNum[0]=sioGet(cUdpsock, nCarRecu[0]) // if nNum[0]>0 // put(chr(nCarRecu[0])) // endIf //reception d'une chaine de caractère d'un seul coup, devant se terminer par "endOfString" x_sMsg=cClient_socket // x_sMsg="70" putln("chaine recue:") put(x_sMsg) if false ///pour débugage; affichage des codes ascii recus putln("chaine en ascii decimal:") for nNum= 0 to len(x_sMsg)-1 put(nNum) put(" : ") put(asc(x_sMsg,nNum)) putln("") endFor endIf //parsing, il ne faut pas que la chaine se termine par la valeur numérique à parser, ajouter un espace à la fin // x_sMsg="70" //x_sMsg=x_sMsg+". " x_sMsg= toNum(x_sMsg, nNum, bBool) if(bBool==true) put("décodé:") put(nNum) else put("erreur décodage") endIf putln("") x_sMsg= toNum(x_sMsg, nNum2, bBool) if(bBool==true) put("décodé:") put(nNum2) else put("erreur décodage") endIf putln("") x_sMsg= toNum(x_sMsg, nNum3, bBool) if(bBool==true) put("décodé:") put(nNum3) else put("erreur décodage") endIf putln("") //delay(1) //true pour commande en articulaire //false pour commande en cartesien if false nNum=nNum/100 nNum2=nNum2/100 nNum3=nNum3*50 //A[0]=nNum A={nNum, nNum2, nNum3, -0, 0, 0} //vérification que le point visé soit atteignable pour //ne pas faire planter dans le cas contraire if isInRange(A) putln("atteignable ") movej( A,tTool,mdescA) waitEndMove() else putln("non atteignable") //delay pour avoir le temps de voir delay(1) endIf else nNum=nNum/10 nNum2=nNum2/10 nNum3=nNum3*50 // Aj[0]= {157, 84, -50, -206, -41, -51} //MGD Ac[0]=jointToPoint(tTool,fFrame[0], B) put("Ac[0]: ") put(Ac[0].trsf.x) put(", ") put(Ac[0].trsf.y) put(", ") put(Ac[0].trsf.z) put(", ") put(Ac[0].trsf.rx) put(", ") put(Ac[0].trsf.ry) put(", ") put(Ac[0].trsf.rz) putln(", ") if(Ac[0].config.shoulder==righty) put("shoulder righty") endIf if(Ac[0].config.shoulder==lefty) put("shoulder lefty") endIf //put(pPointRx[0].config.shoulder) //putln(", ") //put(pPointRx[0].config.shoulder) //putln(", ") //put(pPointRx[0].config.wrist) //putln(", ") //put(pPointRx[0].config.elbow) putln(" ") //position de travail en articulaire //movej( B,tTool, mdescB) //waitEndMove() Ac=here(tTool,fFrame[0]) put("pPointRx[0]: ") put(Ac[0].trsf.x) put(", ") put(Ac[0].trsf.y) put(", ") put(Ac[0].trsf.z) put(", ") put(Ac[0].trsf.rx) put(", ") put(Ac[0].trsf.ry) put(", ") put(Ac[0].trsf.rz) //putln(", ") //put(Ac[0].config.shoulder) //putln(", ") //put(Ac[0].config.shoulder) //putln(", ") //put(Ac[0].config.wrist) //putln(", ") //put(Ac[0].config.elbow) putln(" ") //génère un nombre aléatoire suivant //call rand(0) //xObj=-200+seed%400 //call rand(0) //yObj=-200+seed%400 //injecte la consigne issue du capteur Ac[0].trsf.x=-400+nNum Ac[0].trsf.y=49+nNum2 Ac[0].trsf.z=-116-nNum3 // Ac[0].trsf.x=Ac[0].trsf.x+1 //vérification que le point visé soit atteignable pour //ne pas faire planter dans le cas contraire if pointToJoint(tTool,herej(),Ac[0],B[0]) putln("atteignable ") // if isInRange(() movej( Ac,tTool, mdescA) waitEndMove() else putln("non atteignable") //delay pour avoir le temps de voir delay(1) endIf // pPointRx=here(tTool,fFrame[0]) // put("pPointRx[0]: ") // put(pPointRx[0].trsf.x) // put(", ") // put(pPointRx[0].trsf.y) // put(", ") // put(pPointRx[0].trsf.z) // put(", ") // put(pPointRx[0].trsf.rx) // put(", ") // put(pPointRx[0].trsf.ry) // put(", ") // put(pPointRx[0].trsf.rz) putln(" ") endIf endWhile endIf /////////////////////////////////////////// //test des sockets UDP x_sMsg="Bonjour de la part de RX60" //"endOfString" num (Pour ligne série, client et serveur TCP) Code ASCII pour le caractère de fin de chaîne à utiliser avec les opérateurs '=' (dans la plage [0, 255]) if(sioCtrl(cUdpsock, "endOfString", 13)!=0) putln("probleme D") endIf if(sioCtrl(cUdpsock, "port", 10000)!=0) putln("probleme A") endIf if(sioCtrl(cUdpsock, "target", "192.168.3.4")!=0) putln("probleme B") endIf //0 pour configurer les lectures sur socket bloquantes, //une autre valeur en seconde sinon if(sioCtrl(cUdpsock, "timeout", 10)!=0 ) putln("probleme C") endIf if true while true put(".") //sioSet(cUdpsock,asc(x_sMsg) ) nNum[0]=ioStatus(cUdpsock) //0 L'entrée-sortie fonctionne. //1 L'entrée-sortie fonctionne mais elle est verrouillée par l'opérateur. Les entrées ont alors une valeur fixe (contrôlée par l'opérateur) qui peut être différente de la valeur matérielle. Les sorties ont alors une valeur //fixe contrôlée par l'opérateur : l'écriture sur la sortie n'a aucun effet. Le mode de verrouillage est un moyen de débogage. //2 L'entrée-sortie est simulée (entrée-sortie logicielle, sans effet sur le matériel). //-1 L'entrée-sortie ne fonctionne pas parce que le lien (adresse physique) n'est pas défini. //-2 L'entrée-sortie ne fonctionne pas parce que le lien (adresse physique) ne correspond à aucune entrée-sortie du système. Le matériel correspondant à l'adresse physique n'est pas installé ou n'a pas pu être initialisé. //-3 L'entrée-sortie ne fonctionne pas parce que le dispositif d'entrée-sortie est en erreur. //émission chaine complète cUdpsock="requete0" //émission chaine caractère par caractère // for nNum[0]=0 to(len(x_sMsg)-1) // sioSet(cUdpsock,asc(x_sMsg, nNum[0])) // endFor // sioSet(cUdpsock,13) // sioSet(cUdpsock,10) //tentative de reception d'un caractère, bloquant jusqu'au timeout // nNum[0]=sioGet(cUdpsock, nCarRecu[0]) // if nNum[0]>0 // put(chr(nCarRecu[0])) // endIf //reception d'une chaine de caractère d'un seul coup, devant se terminer par "endOfString" x_sMsg=cUdpsock put(x_sMsg) //delay(1) endWhile endIf putln("doB_15") while true doB_15[0]=true put("1") delay(1) doB_15[0]=false put("0") delay(1) endWhile if(false) putln("lecture capteur par socket") while true put(".") //émission chaine complète cUdpsock="lecture capteur 1" x_sMsg=cUdpsock put(x_sMsg) endWhile else putln("lecture capteur par IO TOR diB_13") while true put(".") nNum[0]=ioStatus(diB_13, x_sMsg, x_sMsg2) put( "ioStatus= ") putln (nNum[0]) if nNum[0]<0 putln("Signal "+x_sMsg2+ "en erreur") putln("Description :"+x_sMsg) endIf if(diB_13==true) x_sMsg="1" doB_15=true else x_sMsg="0" doB_15=false endIf put(x_sMsg) delay(1) endWhile endIf //fermer la connexion ??? (vider les buffers nNum[0]=clearBuffer(cUdpsock) end begin bServeurTrouve=false //nombre de serveurs définis nNum=3 while bServeurTrouve==false clearBuffer(cClient_socket) //"endOfString" num (Pour ligne série, client et serveur TCP) Code ASCII pour le caractère de fin de chaîne à utiliser avec les opérateurs '=' (dans la plage [0, 255]) if(sioCtrl(cClient_socket, "endOfString", 13)!=0) putln("probleme sioCtrl(cClient_socket, endOfString, 13)") endIf //port 30000 utilisé par socket UDP if(sioCtrl(cClient_socket, "port", 30000)!=0) putln("probleme sioCtrl(cClient_socket, port, 30000)") endIf //0 pour configurer les lectures sur socket bloquante, //une autre valeur en seconde sinon if(sioCtrl(cClient_socket, "timeout",1)!=0 ) putln("probleme sioCtrl(cClient_socket, timeout,2)") endIf // if(sioCtrl(cClient_socket, "nagle",false)!=0 ) // putln("probleme sioCtrl(cClient_socket, nagle,false)") // endIf if nNum==0 putln("Serveur NON TROUVE, on recommence le scan") nNum=3 endIf switch(nNum) //le scan fonctionne mais il faut que toutes les adresses soient joignables. //si une adresse balayée n'est pas joignable, une adresse suivante ne pourra pas être jointe //dans ce cas mettre manuellement l'adresse du bon serveur en premier case 3 //rapid en filaire à la maison et a l'aip (meme adresse) sAdrIPServeur="192.168.1.49" //sAdrIPServeur="192.168.1.254" // sAdrIPServeur="192.168.43.14" break case 2 //rapid en filaire // sAdrIPServeur="192.168.1.49" //rapid en wifi à l'aip sur WIFI AIP ROBOT sAdrIPServeur="192.168.3.5" //test bidon google //sAdrIPServeur="8.8.8.8" break case 1 //rapid en wifi via huawei GR5 sAdrIPServeur="192.168.43.14" break endSwitch put("essai serveur: ") putln(sAdrIPServeur) if(sioCtrl(cClient_socket, "target", sAdrIPServeur)!=0) putln("probleme sioCtrl(cClient_socket, target, sAdrIPServeur)") endIf delay(2) //nNum2=13 //if(sioSet(cClient_socket,nNum2)==-1) //if(sioSet(cClient_socket,nNum2)<1) //fait une requette bidon sEtat="r 5 6 2" //redimensionne nNum2 pour traduire la chaine vers un tableau de caractères resize(nNum2,1,len(sEtat)+1) for nNum3=0 to len(sEtat) nNum2[nNum3]=asc(sEtat,nNum3) endFor nNum2[len(sEtat)]=13 // delay(1) //resize(nNum2,1,128) nNum3=5 //for nNum4=0 to 30 while nNum3>0 and bServeurTrouve==false put("tentative: ") putln(nNum3) if(sioSet(cClient_socket,nNum2)!=-1) bServeurTrouve=true put("serveur capteur trouve: ") putln(sAdrIPServeur) //delay(3) endIf nNum3=nNum3-1 endWhile nNum=nNum-1 endWhile //test des sockets TCP x_sMsg="Bonjour de la part de RX60" /////// CONFIGURATION SOCKET UDP ///////// //"endOfString" num (Pour ligne série, client et serveur TCP) Code ASCII pour le caractère de fin de chaîne à utiliser avec les opérateurs '=' (dans la plage [0, 255]) if(sioCtrl(cUdpsock, "endOfString", 13)!=0) putln("probleme D") endIf if(sioCtrl(cUdpsock, "port", 10000)!=0) putln("probleme A") endIf if(sioCtrl(cUdpsock, "target", sAdrIPServeur)!=0) putln("probleme B") endIf //0 pour configurer les lectures sur socket bloquantes, //une autre valeur en seconde sinon if(sioCtrl(cUdpsock, "timeout", 10)!=0 ) putln("probleme C") endIf //// FIN CONFIGURATION SOCKET UDP /////// end begin while true pHereEtat=here(tTool,world) jHereEtat=herej() // putln(pHereEtat[0].trsf.x) //émission chaine complète //déclarer une variable string et utiliser la fonction tostring pour formater //adresse mac??? //cUdpsock="DC:4F:22:00:00:00 0 191.000000 6 0" sEtat="DC:4F:22:00:00:00 100 " +toString(".6",pHereEtat[0].trsf.x) sEtat=sEtat+" "+toString(".6",pHereEtat[0].trsf.y) sEtat=sEtat+" "+toString(".6",pHereEtat[0].trsf.z) sEtat=sEtat+" "+toString(".6",pHereEtat[0].trsf.rx) sEtat=sEtat+" "+toString(".6",pHereEtat[0].trsf.ry) sEtat=sEtat+" "+toString(".6",pHereEtat[0].trsf.rz) //sEtat=sEtat+" "+toString(".6",pHereEtat[0].config.shoulder) //ce n'est pas un numero cUdpsock=sEtat //envoi en 2 temps de la config du robot, car sinon la chaine est tronquée car trop longue (>128 octets) //envoyer les paramètres suivants avec un offset par rapport aux précédents sEtat="DC:4F:22:00:00:00 106 " +toString(".6",jHereEtat[0].j1) sEtat=sEtat+" "+toString(".6",jHereEtat[0].j2) sEtat=sEtat+" "+toString(".6",jHereEtat[0].j3) sEtat=sEtat+" "+toString(".6",jHereEtat[0].j4) sEtat=sEtat+" "+toString(".6",jHereEtat[0].j5) sEtat=sEtat+" "+toString(".6",jHereEtat[0].j6) cUdpsock=sEtat delay(0) endWhile end ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ #!/usr/bin/python3 import time # https://docs.python.org/fr/3/library/time.html #https://realpython.com/python-sockets/ import socket HOST = '172.16.6.59' # The server's hostname or IP address PORT = 30000 # The port used by the server ######################################################################################################################## if __name__ == '__main__': try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) while True: s.sendall(b'r 1 2 3') data = s.recv(1024) # print('Received', repr(data)) print(repr(data)) time.sleep(0.01) except KeyboardInterrupt: print("bye") ====Téléchargement sur le controleur du robot==== IP du cs9: 172.16.8.250 utilisateur: default mdp: default ====Sous programme pour tester si un point est atteignable==== ====Sous programme afficher la valeur d'un point sur le pendant==== while true call logMsgBlock("ici",true) pSaisieBouchon.trsf..x = l_xBouchon pSaisieBouchon.trsf..y = l_yBouchon call isReachable(pSaisieBouchon,l_batteignable) if l_batteignable call logMsgBlock("pSaisieBouchon atteignable",true) endIf call isReachable(appro(pSaisieBouchon,trAppro),tPince,mNomSpeed),l_batteignable) if l_batteignable call logMsgBlock("appro(pSaisieBouchon,trAppro) atteignable",true) endIf endWhile ====Apprentissage de repère==== Pour voir le repère world, il faut cacher le robot car il est à l'intersection de j1 et j2, dans le robot On peut faire "aller à" à un repère (ou point) pour amener le repère outils à l'origine du repère frame p127 p79 phl.pptx: un frame (bleu) et un point (rouge) relatif à ce frame, lorsque le frame est déplacé avec le Positionneur Cartésien, ses coordonnées sont mises à jour et le point se déplace avec le frame. On peut donner une couleur aux points et frame dans la fenêtre propriétés Clic gauche sur un frame ou un point puis clic droit puis "Gros plan" pour centrer la vue: Le gros plan permet de centrer la vue 3D sur une variable géométrique VAL 3, ainsi que de la sélectionner (pratique lorsque le point/frame vient d’être créé et se trouve au centre de l’épaule du robot) Tous les Positionneurs d’objet peuvent ensuite être utilisés sur les points et frames VAL 3 pour les positionner graphiquement (exemple : la méthode Origine, X, Y permet de positionner un frame sur un objet 3D de manière identique à la méthode VAL 3 de définition de frame). ====Frames==== - Définir un Tableau de point pFrame1 de dimension 3 - On peut apprendre les points avec le pendant et récupérer les valeurs vers le projet SRS et on peut aussi le faire avec SRS en bougeant le robot et en faisant "ici" sur chaque case du tableau - Créer une donnée fFrame1 tableau sans taille - Dans données->frame, la variable frame a un Père (par exemple world) - Pareil pour les données->pointRx, ils ont un père - Le frame peut être déplacé manuellement, (ouvrir une fenêtre données pour voir les valeurs) - Sélectionner le pFrame1[0] dans données, puis clic droit et gros plan, ensuite onglet modeleur ->Origine X,Y et cliquer successivement sur les 3 points (Si le frame est déjà à la bonne position mais pas la bonne orientation, le déplacer manuellement avant) - Créer un point pDansFrame1[0], puis AVANT DE L'EDITER, pour l'attacher au repère pFrame1[0]: - Sélectionner la vue Géométrie (à coté de Cellule et Données), et glisser-déposer pDansFrame1 sur fFrame1[0], ceci permet de régler le parent à pFrame1[0], et pDansFrame1 apparait sous fFrame1[0] dans l'arborescence géométrie - Déplacer pFrame1[0] déplace également les points de pDansFrame1 - Régler le point avec le robot avec "ici avec config" NB: lors du changement de repère de référence pour un point dans l'arborescence de géométrie, le point est déplacé erratiquement. Il faut le régler APRES l'avoir lié à un repère. Pour déplacer des points et frames, les sélectionner dans la vue géométrie et faire clic droit puis "Gros plan" ou sélectionner dans la vue 3D". Dans la fenêtre "Editer la position": * position relative règle la position dans le repère du point (pas de son frame parent), ou du frame lui même pour un frame. La donnée est mise à jour et les cordonnées relatives remises à 0 quand on sélectionne à nouveau le point dans la vue 3D. * position absolue règle la position dans le repère cellule (-375mm en Z par rapport au repère robot) Dans la fenêtre d'édition de données: * position du point ou du frame dans le frame parent NB: c'est bizarre le repère world[0] devrait avoir sa position absolue en z=+375, or srs affiche 0.... (mais ce n'est pas éditable...) ===Utilisation des frames pour points variables locales=== //avec la fonction appro: //la transformation est exprimée dans le repère de référence du point //pas besoin de calculer sa valeur dans world link(l_pVariableDansFrame1,fFrame1) movej(appro(l_pVariableDansFrame1,{0,0,0,0,0,0}),tTool,mNomSpeed) waitEndMove() for l_nNum=0 to 100 movej(appro(l_pVariableDansFrame1,{(l_nNum%10)*10,roundDown(l_nNum/10)*10,0,0,0,0}),tTool,mNomSpeed) if roundDown(l_nNum%10)==0 waitEndMove() endIf endFor ====Animer un déplacement de pièce==== Bouger le robot pour libérer la vue 3D: ( Données->jBrasLeve[0]->Aller à ) Transformer un objet 3D en pièce: clic droit sur la pièce puis "Nouvelle pièce" pour promouvoir la géométrie en pièce qui peut être déplacée Créer un handle pour une pièce: Scene->.wrl-> clic droit éditer le repère de référence Le faire correspondre avec le repère handle quand l'outil est sur la pièce Puis Scene->.wrl-> clic droit éditer le repère de référence pour désactiver l'édition Simulation->enregistrer toutes les positions initiales (il faut selectionner les pieces avec CTRL) Pour tester, déplacer la piece puis "Amener tout sur les positions initiales" Clic droit sur l'outil->configuration de l'outil Créer une machine à état de pince sur Tool1.handler Déclencheur->FastIO->sorties digitales->fOut1 (qui est liée à tTool[0]) et selectioner "On" Dans la fenêtre configuration d'outil: Handler->état de saisie->closed, tel quel, distance de saisie 10mm Positionner etat 1:opened: correspond au déclencheur fOut1 à état On Positionner etat 2:closed: correspond au déclencheur fOut1 à état Off Délais de transition, mettre 500ms pour les 2 ====Raccourcis clavier utiles==== F6 : vérifie syntaxe CTRL+R X : Exécution Pour le mode DEBUG: F9 : (des)active un point d'arrêt sur la ligne courante CTRL+R D : Run Debogueur CTRL+S D : Stop Debogueur F5 : continue jusqu'au point d'arrêt F10 : exécute la ligne sans rentrer dans les appels F11 : exécute la ligne en entrant dans les appels SHIFT+F11 : exécute tout pour sortir de cet appel ====Installer SRS 2019.10.1==== https://bvdp.inetdoc.net/files/softs/Installer_SRS_2019.10.1_Full.zip ===Emulateur à installer dans SRS 2019=== Il faut ajouter l'émulateur de controleur version s8.11Cs9_BS2229 Fichier->Aide->Ouvrir l'outils de mise à jour en ligne (afficher les mises à jour Emulateur/robot) et télécharger +installer {{https://bvdp.inetdoc.net/files/iut/staubliiut/images/install_srs_cs9.png?1280}} ----------------------------------------------------------------------------------\\ Début visible par prof seulement \\ ----------------------------------------------------------------------------------\\ ====solution vissage simple==== /media/HD500GO/clef_staubli/2022_11_recupDrobot/Projet08-Demo_JPO/Projet08-Demo_JPO/CELL_IUT0/Controller1/usr/usrapp/Projet_N-8  ----------------------------------------------------------------------------------\\ Fin visible par prof seulement \\ ----------------------------------------------------------------------------------\\ \\ ====Cours de robotique BUT2 AII==== https://bvdp.inetdoc.net/files/iut/staubliiut/cours_ROBOTIQUE_BVDP_2023.pdf ====lien vers TP de PHL==== https://bvdp.inetdoc.net/files/iut/PHL/ Lien vers moodle: https://moodle.iut-tlse3.fr/course/view.php?id=7183 ====Fichier zip pour réparer SRS==== à dézipper sur D: https://bvdp.inetdoc.net/files/softs/SRS%202019%20fonctionnel%20u2.zip ====Logo BUTAII==== https://bvdp.inetdoc.net/files/iut/staubli/stl/BUTAII.scad et https://bvdp.inetdoc.net/files/iut/staubli/stl/BUTAII.stl Pour apprendre les points, utiliser le robot en le cachant, et en amenant le repère outils sur les points. ===autre logo=== https://bvdp.inetdoc.net/files/iut/staubliiut/projets_srs/appliLogo/ ====PHL Kapla==== sujet: https://bvdp.inetdoc.net/files/iut/PHL/01%20LP%20ROB%20TP%20PHL%20SRS.pdf#PAGE=4 solution Cédric: https://bvdp.inetdoc.net/files/iut/PHL/Prog%20KAPLA.pdf support: https://bvdp.inetdoc.net/files/iut/PHL/support%20Kapla%20horizontal.pdf Fichiers CAD à récupérer: https://bvdp.inetdoc.net/files/iut/staubliiut/kapla/kapla.scad https://bvdp.inetdoc.net/files/iut/staubliiut/kapla/kapla.stl https://bvdp.inetdoc.net/files/iut/staubliiut/kapla/support_kapla.stl fichier cad du kapla dans CAD.zip kapla.igs autre sujet: tapis roulant->palette: https://bvdp.inetdoc.net/files/iut/PHL/prog%20paletisation%20%C3%A9tudiants.pdf