Aller au contenu

Magik Chess

Le but de ce projet est de réaliser un jeu d’échecs personnalisé manipulé par un bras robotique, sans intervention humaine. Ce bras devra déplacer les pièces en fonction d’algorithmes ou de commandes vocales données au programme. Il s’inscrit dans le module Makers car pour réaliser Magik Chess, nous avons besoin de nombreux outils du FabLab :

  • Une imprimante 3D, pour la création du plateau et des pièces
  • La découpe Laser, pour le socle du jeu d’échecs
  • Un bras articulé Braccio
  • Une arduino, pour contrôler le bras

Objectifs initiaux du projet

Nous avons décidé dès le début du projet de fixer différentes tâches pour organiser le travail sur Magik Chess :

  • Comprendre le fonctionnement du Braccio
    • Récupérer la bibliothèque contrôlant le Braccio
    • Assimiler la bibliothèque
    • Faire les premiers mouvements du robot
  • Créer le plateau de jeu et les pièces
    • Modélisation du plateau et de pièces
    • Fixation du Braccio au plateau
  • Faire jouer le Braccio
    • Saisir des pièces
    • Segmenter l’échiquier en cases
  • Rendre le projet automatique
    • Commandes vocales et/ou interface

La réalisation de tout ces objectifs devrait nous permettre d’obtenir un bras articulé capable de jouer aux échecs, sans aucune intervention humaine. Mais que signifie jouer aux échecs ? Le robot ne doit pas seulement se saisir de pièces et les déposer, il doit aussi pouvoir retirer les pièces mortes et comprendre l’état du plateau à chaque instant. Enfin, l’objectif est d’automatiser complètement le programme en permettant au bras articulé d’être commandé via la voix humaine avec par exemple des instructions simples comme « Cavalier en A5 » ou « Fou en B7 ». Une autre alternative est de rentrer les coups via l’invite de commande.

Comprendre le fonctionnement du Braccio

Assimiler la bibliothèque contrôlant le Braccio

La première étape est d’installer la bibliothèque du Braccio. Elle est disponible à l’adresse https://github.com/arduino-libraries/Braccio. Elle va permettre de contrôler les 6 moteurs du bras, régissant ses 5 degrés de liberté. Les moteurs 1, 2 et 3 permettent la rotation de la base, de l’épaule (shoulder) et du coude (elbow) respectivement. Le moteur 4 et 5 permettent la rotation et le mouvement du poignet (wrist) et finalement, le moteur 6 permet de contrôler la pince (gripper). Chacun des moteurs sont connectés au shield du Braccio, fournis avec le bras, et lui-même connecté à l’arduino Dès lors, il est possible de faire bouger les moteurs du Braccio.

Photo du Braccio

La première méthode de la bibliothèque est Braccio.begin. C’est une méthode d’initialisation permettant de positionner le bras dans une position relativement stable. Il est obligatoire d’utiliser cette fonction, sans quoi le bras ne fonctionnera pas.

La seconde méthode est Braccio.ServoMovement. Cette méthode permet de positionner chacun des angles des moteurs ainsi qu’un temps pour déterminer la vitesse du mouvement. Nous avons commencer par nous familiariser avec cet environnement pour obtenir des mouvements, plus ou moins précis.

A ce moment du projet, nous nous sommes heurtés à deux problèmes.

  • Premièrement, la documentation du Braccio ne correspond pas à celle de la bibliothèque. En effet, les valeurs des angles des moteurs indiqués par la documentation sont faux comparés à l’initialisation faîtes par le Braccio.begin. Il faut donc bien faire attention à considérer à l’initialisation les valeurs de la bibliothèque.
  • Deuxièmement, la pince était défectueuse par rapport aux angles maximums et minimums prodigués par la bibliothèque. Il était pratiquement impossible d’ouvrir la pince, elle ne pouvait que s’entrouvrir d’un faible angle. Pour corriger ce problème, nous avons du démonter le pince et recalibrer le moteur comme présenté sur l’image ci-dessous.

Dès lors, nous avons donc un bras fonctionnel qui peut attraper des pièces. Il faut maintenant les modéliser.

Créer le plateau de jeu et les pièces

Modélisation

Pour construire le plateau et les pièces, nous utilisons l’imprimante 3D et nous modélisons les pièces sur OnShape . Dans un premier temps, nous avons commencé par prendre un modèle classique de pièce d’échecs mais il a fallut abandonner cette idée car le bras n’est pas adapté pour se saisir d’une telle pièce. En effet, avec sa pince, il n’est pas vraiment possible de se saisir de la base d’une pièce mais plutôt du haut d’une pièce. Dès lors, nous avons créer un nouveau design spécialement pour qu’il soit facile au robot d’attraper une pièce avec un haut arrondi, attrapable par la pince.

Pion de jeu

Un autre problème auquel il a fallut réfléchir est la précision du lâcher de pièce. Lorsqu’on déplace une pièce, le robot n’est jamais exactement placé au centre de la case. Pour éviter que les pièces chutent irrémédiablement, nous avons designé une base de pyramide inversé. De cette façon, en creusant avec la même forme les cases de l’échiquier, les pièces ont tendance à glisser dans la case et non à tomber sur le côté. Pour commencer, nous avons d’abord construit un plateau 2X2 avec 1 pion puis plus tard, un plateau 4X4 avec 8 pions.

Fixation du robot

Maintenant que le plateau est crée, il faut fixer le Braccio à celui-ci. Pour cela, nous avons utilisé la découpe laser pour créer un socle. Ce socle permet de stocker à la fois le Braccio, le plateau et la case de stockage. La case de stockage est une case où l’on dépose le pion qui doit être saisi. Effectivement, nous avons fait le choix de désigner une case précise où les pions sont placés plutôt que des rangées de pions car il aurait fallut encoder la position de chacune des cases. Cependant, cela amène également un désavantage : il faut positionner systématiquement sur la case le pion et donc le bras n’est plus automatique à 100%.

L’avantage d’avoir crée un socle au lieu de fixer le robot directement sur le plateau est de permettre de retirer le robot (pour d’autres projets par exemple) ou de pouvoir changer de jeu avec un nouveau plateau.

Faire jouer le Braccio

Ségmenter les cases

Le Braccio étant maintenant fixé à un socle contenant un échiquier 4X4, nous souhaitons maintenant qu’il puisse se saisir de pièces. La première étape est d’utiliser la cinématique inverse pour ne plus avoir à contrôler les angles des 6 moteurs mais pour plutôt utiliser les coordonnées cartésiennes. Après recherches, nous avons trouvé une bibliothèque sur Github répondant à cette problématique avec la méthode InverseK.solve. (https://github.com/cgxeiji/CGx-InverseK.git)

Cette bibliothèque a l’avantage de ne faire bouger le robot que si les cordonnées (x, y et z) sont atteignables, ce qui permet d’éviter que le robot force pour atteindre une position impossible.

Par contre, elle n’est pas avantageuse sur d’autres points comme la précision : les axes x et y ne sont pas des angles logiques. En effet, on aurait pu imaginer que le développeur aurait choisi des axes à 0 degré et 90 degré. Or, il a fait le choix que chacun des angles soient à « environ » 45 et -45 degré. Cette définition est très embêtante, notamment pour calibrer les cases de l’échiquier car un simple décalage de valeurs fixes à partir d’une case originelle ne permet pas de trouver d’autres cases. De plus, nous avons pu remarquer que faire varier la coordonnée z inclut généralement des décalages sur les coordonnées (x, y) ce qui introduit irrémédiablement des imprécisions. Les angles des moteurs dépendent de leur position durant le montage du bras, ce qui rend les coordonnées en elles mêmes difficiles à utiliser par de la géométrie basique sur notre plateau d’échec. Malgré cela, cette bibliothèque était quand même avantageuse par rapport à celle initiale. Elle nous a permis d’obtenir nos premiers vrais résultats.

Vérifier la répétatibilité

Dès lors que nous accédons à une case plutôt précisément, nous avons tester la répétibilité. En effet, cette notion est capitale car si le Braccio n’est pas capable de répéter son mouvement selon des coordonnées, alors il sera impossible de jouer une partie.

Par chance, celui-ci reste assez précis sur une même case, même après une dizaine d’essai.

Impossibilité de créer le jeu d’échec

C’est à ce stade, en modélisant un échiquier 8×8 que nous nous sommes aperçus d’un problème.

Échiquier 8×8

Le robot a une portée limitée ce qui nous empêche de créer un grand plateau. De ce fait, nous ne pouvons pas créer un plateau 8×8 avec la taille des cases que nous avons choisi.

Une solution serait de diminuer la taille des cases et des pions. Cependant, avec la précision du robot, avoir des cases trop petites ne permet pas une saisie aisée des pièces et augmente les chances de faire tomber les pions adjacents.

Une seconde solution serait de créer deux plateaux 4×8, un côté pour les cases A1 à A4 et un autre pour les cases A5 à A8. Le robot tournerait alors de 90 degré pour atteindre l’autre côté de l’échiquier. Nous n’avons pas opté pour cette solution car il serait très complexe de jouer aux échecs en ayant seulement une moitié d’échiquier visible, notamment à cause des diagonales qui ne seraient pas lisibles.

Nouveau jeu

Nous avons donc fait le choix de nous tourner vers un nouveau jeu ! Nous avons conservé notre plateau 4×4 et immédiatement, nous avons pensé au Puissance-4. Dès lors, Magik Chess s’est transformé en Magik 4-Connect.

Nous avons implémenté les règles du jeu, en commençant notamment par obliger le robot a jouer un coup valide avec la méthode mooves_available(). Nous avons également implémenté une IA avec l’heuristique suivante:

  • Si le coup joué fait gagner une ligne, +100 points
  • Si le coup joué fait perdre une ligne ennemie de 3, +100 points
  • Si le coup joué touche un pion adjacent, +1 points
  • Si le coup joué est une ligne ou diagonale non occupée par l’ennemi (c’est à dire uniquement par nos propres pions ou du vide), +5 points

On récupère ensuite aléatoirement l’un des coups ayant le plus grand score. Cette IA peut jouer contre un bot aléatoire ou elle-même.

Interface joueur

Enfin, pour compléter notre Baccio, nous avons décidé d’implémenter une forme d’interface où deux joueurs pourraient s’affronter. Pour cela, nous avons utilisé l’invite de commande propre à l’Arduino. Chaque joueur peut écrire le coup qu’il souhaite jouer (par exemple « A2 ») et si le coup est légal, le coup est joué par le robot. C’est d’autant plus satisfaisant de pouvoir voir sa propre partie être joué par le robot au lieu d’une partie aléatoire. L’Arduino affiche également le plateau pour éviter de ne pas savoir où est le pion si par malchance, le robot le faisait tomber.

Poursuite du projet

Pour améliorer le projet, différentes pistes sont possibles :

  • Améliorer l’IA
  • Améliorer le Braccio (en essayant de récupérer les positions en rajoutant des composants)
  • Créer de nouveaux jeux via de nouveaux socles
  • Implémenter une commande vocale

Le code est disponible (https://github.com/Zaksley/MagikChess) et en libre accès pour quiconque souhaitant reprendre le projet et l’améliorer (ce que nous encourageons vivement!).

Remerciements

Merci au Fablab de l’ENSEIRB-MATMECA, Eirlab, pour nous avoir permis de travailler sur un projet qui nous tenait à cœur et pour nous avoir laissé utiliser le matériel nécessaire. Merci particulièrement à Julien Allali et à Sebastien Delpeuch ainsi qu’aux différents Fabmanagers qui ont suivi attentivement notre projet et nous ont toujours guidé en cas de problèmes.