Rapport P42 Senellart Zalczer
Rapport P42 Senellart Zalczer
Rapport P42 Senellart Zalczer
Remerciements
Nous tenons à remercier Thierry Flamen pour son expertise et son aide lors de la
réparation des contrôleur moteur et de la fixation de la tête de préhension.
Nous remercions aussi les Fab. Manager pour le prêt de l’imprimante ainsi que pour
le temps qu’ils nous ont accordé et l’aide apportée lors de l’utilisation de la découpeuse
laser.
SOMMAIRE 2
Sommaire
Introduction 3
1 Présentation du projet 4
1.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Préparation 5
2.1 Analyse du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 Analyse des concurrents . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.2 Questions difficiles . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Cahier des charges et choix technologiques . . . . . . . . . . . . . . . . . . 7
2.2.1 Partie matérielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.2 Partie logicielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Gestion de projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Réalisation du projet 9
3.1 Partie Informatique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.1 Application : arborescence, framework et gestion des plugins . . . . 9
3.1.2 Application : le backend . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.3 Application : partie fonctionnelle . . . . . . . . . . . . . . . . . . . 13
3.1.4 Imprimante : génération et envoi du G-Code . . . . . . . . . . . . . 15
3.2 Partie mécanique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1 Réparation de l’imprimante . . . . . . . . . . . . . . . . . . . . . . 16
3.2.2 Adaptation de l’imprimante . . . . . . . . . . . . . . . . . . . . . . 17
3.2.3 Modélisation 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Mise en commun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.1 Le firmware Marlin . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.2 Tests et calibration . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Conclusion 21
Bibliographie 22
Introduction 3
Introduction
Notre projet à pour but d’aider les gens à gagner du temps lors du montage de leur
Lego. En effet, nous nous sommes rendu compte qu’ils ont de moins en moins de temps
à consacrer aux petites briques en plastique. Notre ambition est de permettre aux gens
de pouvoir consacrer plus de temps à leur passion en leur proposant une machine pour
les assister dans leurs constructions. Cette idée est née de la passion pour les Lego de
Justine et nous l’avons adoptée car nous avons jugé que ce projet abordait de nombreuses
problématiques liées à IMA. En effet, nous avons du établir une interface entre un système
électromécanique tel qu’une imprimante 3D et un système informatique.
Nous nous sommes inspirés d’une construction réalisée à l’aide des robots de Lego : les
Mindstorm. Nous avons cherché un moyen d’améliorer ce projet et de le construire dans
des matériaux plus solides et durables que les Lego. Le projet dont on s’est inspiré est le
Bricasso 1 qui est un scanner à Lego : il est capable de lire un dessin en pixel art pour le
reproduire en Lego.
4
Chapitre 1
Présentation du projet
1.1 Description
L’idée de notre projet est simple. À l’aide d’une base d’imprimante 3D récupérée au
Fabricarium, communiquant avec une application hébergée sur Raspberry Pi, nous avons
voulu créer un système capable de monter des objets en LEGO. Pour ce faire, nous avons
modifié la tête d’impression de façon à ce qu’elle puisse se saisir de pièces LEGO et les
placer sur une plaque LEGO classique. Du côté de l’application, notre but était de fournir
à l’utilisateur un moyen facile pour designer et imprimer un modèle simple en LEGO.
1.2 Objectifs
L’objectif global du projet est de faire en sorte que l’imprimante monte des Lego sur
une couche tout en respectant un modèle entré par un utilisateur sur une application Web.
Pour cela on peut décomposer le projet en plusieurs objectifs :
— Créer une "tête d’impression" pour agripper les Lego.
— Réaliser un réservoir à pièce pour stocker les pièces Lego.
— Modifier le plateau de manière à pouvoir y placer une plaque Lego et le réservoir.
— Réaliser une application Web pour la gestion du modèle et du réservoir.
— Adapter le firmware de l’imprimante et le G-code pour notre utilisation.
5
Chapitre 2
Préparation
Les choix technologiques de notre projet ont été guidés par la simplicité, la compati-
bilité et la facilité d’interfaçage des différents éléments du projet. En choisissant d’utiliser
JavaScript pour toutes les parties de l’application, nous nous sommes ouverts à une utilisa-
tion facile du format JSON, et avons évité un temps important de montée en compétence
sur un éventuel autre langage. En détail, nous avons effectué les choix suivants :
— Backend
— Node.js : API RESTful
— PostgreSQL : Base de données projets et utilisateurs
2.3. GESTION DE PROJET 8
— Frontend
— HTML5/CSS3/JS natif
— Utilisation de la balise canvas pour la conception du schéma.
— Envoi des données en JSON
— Imprimante
— Serveur Node.js sur Raspberry Pi
— Utilisation du firmware Marlin
Nous nous sommes aperçus assez rapidement que nous allions devoir révoir à la baisse
notre cahier des charges, ce qui nous a forcés à prendre des décisions et à communiquer
efficacement. Toutes ces décisions ont été prises assez facilement et sans désaccord. Elles
ont été causées principalement par de mauvaises évaluations du temps nécessaire pour
certains travaux et des limites techniques notamment pour la diversité des pièces.
Pour toute la gestion de notre projet, nous avons utilisé la plateforme Gitlab de Po-
lytech Lille. Cela nous a permis notamment de transférer facilement notre code entre
la Raspberry Pi du projet, nos PC personnels et les Zabeth en salles E304/306. Notre
utilisation de la plateforme est restée minimaliste, car nous n’avons pas travaillé sur les
mêmes parties du projet et avons principalement utilisé une seule branche. Nous avons
néanmoins fini par créer une branche dev pour la version du code non définitive. Nous
nous sommes attachés à nommer correctement nos commits pour que l’arborescence reste
compréhensible.
9
Chapitre 3
Réalisation du projet
Pour la gestion des routes de notre API, nous avons utilisé le framework Express qui
a l’avantage d’être bien documenté et rapide à mettre en place. Il nous permet de gé-
rer simplement les différentes routes, les méthodes HTTP, les codes de réponse et bien
d’autres éléments essentiels du projet. En terme de plugins, nous avons tenté de rester
minimalistes car les plugins npm ont tendance à prendre beaucoup de place et à causer
des problèmes de compatibilité. Les plugins que nous avons utilisés sont les suivants :
— ejs 2.5.7 : pour le rendu des pages HTML.
— express 4.16.2 : le framwork Express.
— pg 7.4.1 : plugin de gestion de base de données Postgres.
— body-parser 1.18.2 : parsing des requêtes HTTP.
Pour la partie imprimante, nous avons également utilisé le plugin serialport qui
permet, comme son nom l’indique, d’accéder au port série de la Raspberry Pi et de
déclencher l’impression. Nous avons du nous contraindre à utiliser une version de Node
3.1. PARTIE INFORMATIQUE 11
assez ancienne (8.10.0 contre 10.1.0 actuellement) car le plugin n’est pas compatible avec
les dernières versions de Node sur Raspberry Pi.
Celui-ci est constitué de quatre tables. La première table permet de sauvegarder les pro-
jets. Une seconde contient la liste des pièces disponibles (1x1, 1x2, 2x2). Cette dernière
n’est plus utilisée dans la version actuelle du projet car seules les pièces de dimensions
1x1 sont supportées, cependant nous avons décidé de laisser ouvert le point d’entrée API
pour une éventuelle future version. La troisième table fait la relation entre les projets et
les pièces et enregistre le contenu de chaque projet. Enfin, la quatrième table est à part
et contient la liste des couleurs de pièces possibles. La première version de cette table
contenait la totalité des couleurs LEGO existantes, mais nous avons décidé de réduire
cette liste à 16 valeurs pour faciliter l’expérience utilisateur.
Les points d’entrée de l’API sont les suivants. Tous les résultats sont renvoyés en JSON
à l’exception de la page HTML :
— GET / : renvoie la page principale du projet, rendue grâce au framework Express.
— GET /project : renvoie la liste des projets.
— PUT /project : crée un nouveau projet. La requête doit alors contenir le nom du
projet à créer, ainsi que les dimensions du canvas.
— GET /project/([0-9]+) : renvoie le projet correspondant à l’identifiant donné.
— PUT /project/([0-9]+) : sauvegarde le projet correspondant à l’identifiant donné.
— DELETE /project/([0-9]+) : supprime le projet correspondant à l’identifiant
donné.
— GET /pieces : renvoie la liste des pièces disponibles. Ce point d’accès n’est plus
utilisé depuis que nous avons décidé de gérer uniquement des pièces de taille 1x1.
— GET /colors : renvoie la liste des couleurs possibles pour les pièces.
La structure de notre API, comme nous l’avons précisé plus haut, est divisée entre les
fichiers legoRoutes.js et legoControllers.js. Nous pouvons analyser une petite partie du
code pour comprendre son fonctionnement.
1 ’ use strict ’;
2 module . exports = function ( app ) {
3 var lego = require ( ’ ../ controllers / legoControllers ’) ;
4
5 // todoList Routes
6 app . route ( ’/ ’) . get ( lego . mainpage ) ;
7
8 app . route ( ’/ project ’)
9 . get ( lego . list_projects )
10 . put ( lego . create_project ) ;
11
12 app . route ( ’/ project /: project_id ’)
13 . get ( lego . open_project )
14 . put ( lego . save_project )
15 . delete ( lego . delete_project ) ;
16
17 app . route ( ’/ pieces ’)
18 . get ( lego . list_pieces ) ;
19
20 app . route ( ’/ colors ’)
21 . get ( lego . list_colors ) ;
22
23 };
Les routes et les protocoles sont déclarés de façon très claire et en très peu de code
grâce au method chaining de JavaScript qui permet d’appeler plusieurs méthodes sur le
même objet en une même ligne.
Pour les controllers, nous étudierons seulement le point d’accès open_project qui per-
met comme son nom l’indique de charger les données d’un projet. Cette fonction a l’avan-
tage d’être assez courte (elle n’utilise qu’une seule requête SQL) et de bien démontrer le
fonctionnement d’Express.
3.1. PARTIE INFORMATIQUE 13
1 ’ use strict ’;
2
3 var pg = require ( ’ ../../ lib / postgres ’) ;
4
5 exports . open_project = function ( req , res ) {
6 var sql = ’ SELECT * FROM PLACED_PIECES , PIECES WHERE project_id = $1
AND PLACED_PIECES . type = PIECES . type ’;
7 pg . client . query ( sql , [ req . params . project_id ] , function ( err ,
results ) {
8 if ( err ) {
9 console . error ( err ) ;
10 res . statusCode = 500;
11 return res . json ({ errors : [ ’ Could not open project ’] }) ;
12 }
13 res . statusCode = 200;
14 console . log ( results . rows ) ;
15 return res . json ( results . rows ) ;
16 }) ;
17 };
Les paramètres de l’URL sont récupérés via le mot-clé $1 qui, comme en bash, per-
met d’accéder au premier paramètre. Le contenu de la requête GET est lui récupéré
depuis l’objet req.params. La requête SQL est générée et envoyée grâce à la méthode
pg.client.query, et la réponse HTTP renvoyée prend en compte le résultat de la requête
et renvoie un message facilement affichable à l’utilisateur.
parties de l’application. La première chose à mettre en place était bien entendu l’inter-
face entre l’application et l’API, et particulièrement déterminer la façon dont les données
seraient envoyées de l’un vers l’autre. Nous avons eu quelques problèmes qui nous ont
amenés à revoir le MCD une fois ou deux, et nous avons utilisé du JSON pour la simpli-
cité d’interprétation, le serveur et le client étant tous les deux en Javascript.
Une fois que nous avions déterminé définitivement le modèle de données utilisé, nous
avons commencé à implémenter les interfaces graphiques permettant à l’utilisateur d’ac-
céder aux différents points API. Nous avons choisi d’utiliser un système simple à base de
fenêtres pop-up. Au lancement du projet, l’utilisateur choisit sur une première fenêtre s’il
souhaite créer un nouveau projet ou en ouvrir un déjà existant. Le reste de la page est
alors grisé et non éditable. Une fois que l’utilisateur a choisi une option valide, la fenêtre
se ferme et laisse la place à l’édition. Une autre fenêtre s’ouvre lorsque l’utilisateur sou-
haite lancer une impression, que nous avons implémentée bien plus tard. Cette dernière
a deux objectifs : demander à l’utilisateur de rentrer l’adresse IP de l’imprimante, et de
renseigner la position des pièces de différentes couleurs dans le réservoir de l’imprimante.
Probablement la dernière partie de l’application dont nous nous sommes occupés était
le design. Jusqu’à la semaine 11, la page était constituée uniquement de boutons et de
texte en plus des canvas, sans vrai design. De plus, des parties de la page étaient devenues
inutiles. Nous avons donc créé un design simple rendant l’application plus agréable à uti-
liser. Le fait de faire ce design nous a également permis de nous rendre compte de certains
manques ou problèmes dans l’application, que nous avons corrigés par la suite. Dans la
version en développement du code, on peut trouver plusieurs vestiges de fonctionnalités
que nous avons envisagé d’implémenter avant de nous raviser, notamment la possibilité
d’annuler/refaire avec Ctrl+Z et Ctrl+Y. Néanmoins, la version de production sur la
branche master a normalement été nettoyée du code mort et correctement commentée.
La génération du G-Code est en fait un processus assez simple. Ce dernier est généré
dans sa totalité avant d’être envoyé à l’imprimante afin d’éviter une impression partielle
en cas d’erreur de génération. Nous avions dans un premier temps commencé par travailler
en coordonnées relatives, puis nous sommes repartis en coordonnées absolues par simpli-
cité. La première ligne de G-Code envoyée est systématiquement la commande G28 afin
de ramener la tête d’impression à sa position initiale avant de commencer l’impression.
Puis, le mouvement est décomposé en six parties :
— Montée de la tête d’impression de 15 unités.
— Déplacement vers la position du réservoir.
— Baisse puis remontée de la tête d’impression.
— Déplacement vers la position où déposer la pièce.
— Baisse de la tête d’impression.
— Mouvement de deux centimètres en X pour détacher la pièce.
Ce code forme une boucle qui peut se répéter jusqu’à arriver à la fin du modèle. Une fois
généré, le gcode est retourné par la fonction et peut alors être envoyé vers l’imprimante. A
chaque ligne de G-Code envoyée et exécutée avec succès, l’imprimante retourne le message
3.2. PARTIE MÉCANIQUE 16
"ok". Nous pouvons alors envoyer la ligne suivante. L’imprimante dispose d’un buffer
permettant d’envoyer plusieurs commandes à la fois, cependant sa taille est assez limitée
(16 par défaut) et il est donc plus raisonnable d’envoyer les commandes une par une.
A l’origine, nous souhaitions utiliser le code de retour de la requête XHR pour signifier
à l’utilisateur si l’impression s’était bien déroulée ou non. Cependant, étant donné la
durée d’une impression, cela n’a pas été possible car nous aurions reçu un timeout. Le
seul contrôle pouvant s’effectuer depuis l’application est l’ouverture du port série, ce qui
permet d’afficher un message à l’utilisateur si l’imprimante est mal connectée.
été de revisser toutes les vis et d’en changer quelques unes qui avaient été sciées et ne
pouvaient pas être revissées. Une fois que l’imprimante était dans un état un peu plus
solide, nous avons refait des tests pour les moteurs et nous nous sommes rendus compte
que les capteurs de fin de course qui étaient fixés avec des zip étaient entraînés par les
moteurs et n’étaient pas tout le temps activés. Nous avons donc dû réaliser des supports
pour les différents capteurs de fin de course 6 qui ont été réalisés en impression 3D.
Une autre pièce de l’imprimante à dû être réalisée : des clips de maintien de la courroie7 .
La dernière pièce à réaliser était un support sur lequel on vient caler la plaque Lego
ainsi que le réservoir. Il nous a fallu trouver un moyen de fixer corrctement la plaque et
le réservoir de manière à ce qu’ils soient toujours au même endroit tout en pouvant les
enlever et les remettre assez facilement. Nous avons donc découpé des sortes de rails en
bois qui ont été placés avec très peu de jeu pour assurer la stabilité.
3.2.3 Modélisation 3D
La plupart des pièces réalisée pour ce projet ont été faites en impression 3D. Le logiciel
utilisé est freeCAD 8 qui est un modeleur 3D permettant de réaliser des objets en prenant
des formes de base (cube, cylindre, sphère ...) qui peuvent être modifiés à souhait pour
former l’objet désiré. Nous n’avions jamais fait de modélisation 3D auparavant, la prise en
3.3. MISE EN COMMUN 19
main du logiciel n’a donc pas été des plus évidente et les premières pièces ont été difficiles
à réaliser. Nous avons commencé par le réservoir qui reste une pièce assez simple à créer
en combinant des carrés et des cylindres pour la pente. La réalisation de cette pièce à tout
de même nécessité plusieurs essais pour obtenir le comportement désiré mais elle nous a
permis d’acquérir des compétences nous permettant de réaliser plus rapidement les pièces
suivantes. Pour réaliser la tête d’impression il a fallu comprendre comment fonctionne
l’impression 3D notamment l’utilisation de support pour la réalisation d’une articulation
en une pièce. Suite à la réalisation de ces pièces nous sommes maintenant capables de
modéliser des pièces simples en 3D.
Conclusion
Le but de notre projet était de pouvoir placer une couche de pièces de Lego sur une
plaque à l’aide d’une imprimante 3D recyclée en respectant un modèle dessiné par un uti-
lisateur sur une application web. En l’état actuel, nous sommes capables d’aller récupérer
des pièces Lego dans le réservoir à l’aide de la tête de préhension que nous avons réalisée
et d’effectuer les mouvements pour placer les pièces aux endroits désignés par l’utilisateur.
Cependant, nous ne sommes pas en mesure de déposer les pièces sur la plaque. Globa-
lement, nous avons respecté notre cahier des charges : seule la partie de l’application
permettant de gérer le remplissage du réservoir n’a pas du tout était traitée.
Nous avons rencontré plusieurs problèmes lors de la réalisation de ce projet, tant sur
la partie mécanique avec des pièces qui ont dû être réalisées plusieurs fois pour obtenir
quelque chose d’utilisable que sur la partie informatique, notamment pour les règles de
placement et la gestion des requêtes cross-origin. Le problème qu’il reste à régler pour
pouvoir placer correctement les pièces serait de modifier la tête de préhension car l’arti-
culation n’est pas solide et la pièce bouge lorsque l’on essaye de la mettre sur la plaque
ce qui entraine un décalage par rapport aux tenons.
Ce projet nous a permis d’acquérir des compétences dans des domaines liés à l’infor-
matique ainsi qu’à la mécanique et la gestion de projet. Ils nous a dans un premier temps
fallu définir les tâches à réaliser et répartir la quantité de travail. La partie mécanique
nous a permis d’acquérir des compétences globales sur les imprimantes 3D et la modé-
lisation 3D et la partie informatique une meilleure compréhension de l’architecture REST.
Pour aller plus loin, si ce projet devait être repris, il serait possible d’améliorer la partie
mécanique notamment la tête de préhension ainsi qu’améliorer l’application pour pouvoir
gérer le remplissage du réservoir. Il serait également possible de reprendre la partie du
cahier des charges indiquant que les pièces pourraient être posées sur plusieurs couches. En
revanche, la gestion de différentes formes de pièces demanderait un mécanisme totalement
différent et paraît un objectif peu réaliste, même si l’application le permet déjà.
Bibliographie 22
Bibliographie
Notes
1
Bricasso : http://jkbrickworks.com/lego-mosaic-printer/
2
Marlin : http://marlinfw.org/
3
G-code : http://marlinfw.org/meta/gcode/
4
Prusa i3 : https://www.prusa3d.fr/
5
Imprimante à chocolat : https://projets-ima.plil.fr/mediawiki/index.php/Imprimante_3D_
%C3%A0_chocolat
6
Support endstop x : https://www.thingiverse.com/thing:784801
7
Clip courroie : https://www.thingiverse.com/thing:820510/
8
freeCAD : https://www.freecadweb.org/?lang=fr