Aller au contenu

Assistant pour jouer aux cartes

Présentation du projet :

Contexte

  • C’est dans le but d’améliorer les conditions de travail des personnes en situation de handicap que ce projet a été conçu.
  • Projet de programmation sur 2 mois
  • Stage de 2 mois pour le finir

But/objectifs

  • Il pourra, dans le cadre de ce projet, jouer aux cartes en indiquant sur l’interface la carte à prendre et la déposer sur une table.
  • établir une connexion entre un bras robotisé et l’ordinateur
  • se déplacer entre deux points prédéfinis:
    • Grâce à la connaissance de sa position, il pourra calculer les rotations nécessaires au déplacement d’un point A à un point B.
  • saisir et soulever des objets légers avec une pince
  • Interface graphique pour permettre à l’utilisateur de donner les commandes au bras
  • Scénario???

Ce qui a été réalisé

  • Utilisation d’un modèle déjà existant fabricreator, pensé pour être contôler à l’aide d’un smartphone
  • Toute les pièces sont en polymère thermoplastique (PLA) et sont imprimées en 3D. De plus plusieurs composants électroniques ont été ajoutés ainsi qu’une carte électronique Arduino afin qu’il puisse se déplacer selon la programmation prédéfinie.
  • Developpement d’une API capable de calculer une position d’arrivée à partir de positions prédéfinies ainsi que les rotations nécessaire aux différents mouvement à exécuter. Pour cela la géométrie inverse a été utilisée, elle désigne l’ensemble des méthodes de calcul des positions et rotations d’un modèle articulaire.
  • Utilisation des langages de programmation Python version 3 et C pour Arduino. Le langage C a été imposé puisqu’il s’agit du langage lu par les cartes Arduino. Le langage Python a été choisi car il a une syntaxe simple et une structure organisée, ce qui simplifie l’implémentation des différents calculs.
  • interface graphique permettant de choisir la carte à jouer a été implémentée. L’utilisateur clique sur un bouton représentant une carte et le bras se déplace vers une position définie, attrape la carte puis la dépose sur le plateau de jeu et revient en position de repos.
  • licence libre, auteurs passés/présents
  • photos / vidéos

Comment reproduire l’objet

  • guide d’utilisation
  • liens vers plans, spécifications (datasheets), vidéos de montage/utilisation etc
  • liste de matériel

Conception et théorie

  • Explications des plans élec etc
  • Architecture logiciel
    • image architecture –> à mettre à jour
    • Il a été choisi d’utiliser la bibliothèque tkinter pour créer cette interface car elle est simple d’utilisation. Elle permet également de modifier la taille des boutons, ce qui est un avantage car cela a permis de faire de grands boutons, la précision du pointeur de souris ne sera pas un problème pour l’utilisateur.
  • Modélisation pyplot

Maths

Géométrie directe

La géométrie directe permet d’amener l’extrémité du bras robotisé à un point précis T calculable grâce aux rotations connues des articulations du robot.
Il est donc nécessaire de connaître les paramètres du bras tels que les degrés de liberté, les axes de rotation et les longueurs entre chaque articulation.
Ici le bras possède 5 degrés de liberté, le dernier moteur n’est pas compté dedans puisqu’il ne servira qu’à ouvrir et fermer la pince. Chaque articulation est définie par un axe de rotation qui lui est propre, toutes les articulations sont positionnées le long d’un axe z, ce qui facilite les calculs des positions de ces dernières les unes par rapport aux autres.

La figure ci-dessus montre qu’il y a deux types de rotation possibles, pour l’axe z et pour l’axe x. Ici, le bras est en position de repos, tous les angles sont à 0 radian, c’est-à-dire 90° pour les servo moteurs. Le moteur de la pince n’a pas été représenté puisqu’il n’agit pas sur le mouvement du bras.
Ces deux rotations x et z sont définies par des matrices de rotations. Ces matrices, multipliées par les vecteurs définissant les différents axes, donnent des positions d’arrivées si les angles de rotation de chacun sont connus.

\(\small T = O + \left(\begin{array}{c}0\\ 0 \\ L0\end{array}\right) +\left(\begin{array}{c}0\\ 0 \\ L1\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L2\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L3\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L4\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L5\end{array}\right)\) \(\small T = O + \left(\begin{array}{c}0\\ 0 \\ L0\end{array}\right) +\left(\begin{array}{c}0\\ 0 \\ L1\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L2\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L3\end{array}\right)+ \left(\begin{array}{c}0\\ 0 \\ L4\end{array}\right)+ R_{x,\theta_{5}} \times \left(\begin{array}{c}0\\ 0 \\ L5\end{array}\right)\) \(\small T = O + \left(\begin{array}{c}0\\ 0 \\ L0\end{array}\right) +\left(\begin{array}{c}0\\ 0 \\ L1\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L2\end{array}\right)+\left(\begin{array}{c}0\\ 0 \\ L3\end{array}\right)+ R_{z,\theta_{4}} \times \left[\left(\begin{array}{c}0\\ 0 \\ L4\end{array}\right)+ R_{x,\theta_{5}} \times \left(\begin{array}{c}0\\ 0 \\ L5\end{array}\right)\right]\) \(\small T = O + \begin{bmatrix}0\\0\\L0\end{bmatrix} + R_{z,\theta_{1}} \times \begin{bmatrix}0\\0\\L1\end{bmatrix} + R_{x,\theta_{2}} \times \begin{bmatrix}0\\0\\L2\end{bmatrix} + R_{x,\theta_{3}} \times \begin{bmatrix}0\\0\\L3\end{bmatrix} + R_{z,\theta_{4}} \times \begin{bmatrix}0\\0\\L4\end{bmatrix} + R_{x,\theta_{5}} \times \begin{bmatrix}0\\0\\L5\end{bmatrix}\) $latex \text{Avec } R_{z,\theta_{n}}= \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1\end{bmatrix} \text{ et }R_{x,\theta_{n}}=\begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos{\theta} & -\sin{\theta} \\ 0 & \sin{\theta} & \cos{\theta} \end{bmatrix}, L_{n} les longueurs entre les différents joints du bras, O l’origine du bras et T le bout du bras$

Géométrie inverse

En sachant les positions de départ des axes et le point que l’extrémité du robot doit atteindre, alors il est possible de savoir quels angles atteindre. La cinématique directe va être utilisée par l’algorithme du gradient afin d’obtenir la cinématique inverse. Par de nombreuses itérations, il va suivre la direction de la pente la plus forte pour minimiser le plus rapidement une fonction d’erreur définie au préalable. Cette fonction d’erreur permet de donner des contraintes aux calculs. La première contrainte est que la position réellement atteinte par le bras doit être la plus proche de la position demandée. La deuxième contrainte est la direction d’arrivée du dernier segment du bras, la pince doit pouvoir prendre la carte par le haut pour plus de facilité. Une troisième contrainte a été ajoutée pour que les angles calculés ne dépassent pas la limite des moteurs qui est de 180 degrés en théorie et de 120 degrés en réalité.

  • première contrainte: minimise le résultat de la différence entre la cible et le point réellement atteint. L’erreur calculée doit être la plus proche de 0 pour que les angles calculés soient optimaux.
  • Deuxième contrainte: le dernier vecteur du bras, c’est-à-dire entre le dernier joint et le bout du bras, doit être colinéaire et de même sens qu’un vecteur \(\overrightarrow{u}\) défini en amont. Pour attraper une carte le vecteur de référence doit donc être \(\overrightarrow{u} \small \left(\begin{array}{c}x=0\\ y=0\\ z=-1\end{array}\right)\). Deux vecteurs issus de la normalisation des vecteurs de fin et de référence, \(\overrightarrow{n1}\) et \(\overrightarrow{n2}\) vont être définis. Lorsque ces vecteurs sont colinéaires leur produit vectoriel est égale à 1, ce résultat sera soustrait afin d’avoir une équation se rapprochant de 0. Il suffit alors de passer cela au carré pour avoir une minimisation du résultat. Formule pour l’erreur noté J:

\(J= \alpha \times || T_{n}-Cible ||² + \beta \times |\langle \overrightarrow{n1}|\overrightarrow{n2}\rangle-1 |²\) \text{avec $\alpha$ et $\beta$ deux coefficients donnant plus ou moins d’importance aux deux parties de l’équation} \text{et $\overrightarrow{n1}=\frac{T_{n}-T_{n-1}}{||T_{n}-T_{n-1}||}$ , $\overrightarrow{n2}=\frac{\overrightarrow{u}}{||\overrightarrow{u}||}$}$

Cette équation est testée grâce à la fonction de scipy optimize.minimize, le résultat retourné aura l’erreur la plus petite trouvée pour l’ensemble des tests.

Communication

La communication des angles calculés sont transmis à une carte Arduino qui envoie ensuite les signaux pwm correspondant aux moteurs.

Partie Python

Un fichier python se charge d’envoyer les angles à l’arduino, il envoie des données au port USB de l’ordinateur dont le nom est donné en paramètre du module Serial de la bibliothèque pyserial. Si la carte Arduino est branchée à ce port USB, elle reçoit les données bit par bit à une vitesse de 9600 bits par seconde et avec un temps d’attente de 1 seconde.

import serial
def write_read_angles(x):
    arduino = serial.Serial(port="/dev/ttyACM1", baudrate=9600, timeout=1)
    arduino.write(bytes(x, 'utf-8'))

Partie Arduino

La carte récupère bit par bit une chaîne de caractères qui va être stockée, elle sera composée d’un ou plusieurs arguments séparés par des espaces et dont le premier défini l’action à effectuer. Cela peut-être une lecture des angles actuels, l’application d’angles précis ou tout autre commande prédéfinie.

Une fonction décompose la chaîne de caractères ainsi reçue et met tous les éléments dans un tableau. Le nombre d’arguments est comparé aux commandes prédéfinies. Si l’une d’elles correspond alors le premier argument de la chaîne rçue est comparé caractère par caractère à la commande. Si la commande est reconnue, une action est réalisée.

Exemple: « moving \(~ \theta_{0} ~ \theta_{1} ~ \theta_{2} ~ \theta_{3} ~ \theta_{4} ~ \theta_{5}\) » , « moving » sera isolé et interpreté pour envoyer les angles voulus.

Correction et limites des angles

–> parler du traitement des angles dans le code

–> parler des tables de correspondance réalisées pour corriger les écarts des moteurs