2. Conception Assistée par Ordinateur (CAO)#
L’objectif de ce deuxième module est de designer, modéliser et documenter un kit de construction de type “FlexLinks” grace à un logiciel de conception 3D pour pouvoir le construire lors du module suivant en utilisant des imprimantes 3D. L’idée sera de designer les éléments du kit de façon paramétrique afin de pouvoir facilement en adapter les dimensions en fonction des caractéristiques des matériaux utilisés et de la machine utilisée. Le travail effectué sera par la suite muni d’une license. Pour compléter mon kit, j’utiliserai également une pièce designée par un de mes camarades, dont je créditerai le travail dans le respect de la license qu’il a choisie.
Modélisation paramétrique d’un kit FlexLinks#
Dans ce module, je modéliserai de façon paramétrique un kit de construction “FlexLinks” en vue de l’imprimer en 3D ultérieurement. Il s’agit de kits contenant des mécanismes flexibles. La modélisation paramétrique est un outil puissant en ça qu’elle permet de modifier très rapidement les dimensions et caractéristiques d’une pièce. En effet, lorsque des paramètres sont définis et que toutes les dimensions et caractéristiques de la pièce sont déterminées à partir de ces paramètres, modifier la valeur des paramètres suffira à modifier complètement l’aspect de la pièce. Il est donc primordial de bien choisir ses paramètres.
Choix du logiciel de conception 3D#
Avant de commencer le design du kit, il faut d’abord déterminer quel logiciel de conception 3D nous utiliserons. De nombreux logiciels de conception sont disponibles en ligne, certains sont payants et d’autres, gratuits. Dans ce cours, l’idée étant d’utiliser un maximum les outils OpenSource. Les principaux outils de conception 3D OpenSource présentés sont FreeCAD et OpenSCAD.
FreeCAD permet de modéliser des pièces 3D en fixant les degrés de libertés de ces derniers via des paramètres pour aboutir à des pièces bien définies. Il présente une interface graphique intuitive et assez simple d’utilisation.
OpenSCAD permet de modéliser des pièces 3D via du code dont les instructions réalisent des formes élémentaires (cube, sphère, cylindre, polyèdre) sur lesquels des opérations graphiques et logiques peuvent etre appliqués pour en modifier la forme, la taille, l’orientation, etc.
Etant habitué à travailler avec du code, mon choix s’est rapidement porté sur OpenSCAD.
Modélisation 3D avec OpenSCAD#
Avant de commencer à modéliser il faut choisir un kit à reproduire en 3D. Pour ce faire, j’ai utilisé le site vers lequel le professeur nous a renvoyé. Ce site présente de nombreux exemples de kits FlexLinks avec des liens renvoyant vers des sites contenant des fichiers de conception permettant d’imprimer directement la pièce voulue. Évidemment, l’exercice étant de modéliser nous-memes la pièce, nous n’utiliserons pas ces fichiers. Nous utiliserons néanmoins les images et le rendu du kit que nous voulons reproduire afin de déterminer comment modéliser notre kit. Personnellement, je me suis inspiré d’un “LEGO Compatible Bistable Compliant Mechanism” réalisé par “BYU_CMR” pour mon kit. Vous pouvez retrouver le kit original ici. Afin d’en avoir une vue en 3D complète, j’ai téléchargé le fichier de rendu du kit.
Après avoir téléchargé le fichier “.stl”, je l’ouvre avec “Paint 3D”, l’application par défaut de Windows pour ce type de fichier. Je sélectionne alors “affichage 3D” dans le haut de la fenêtre pour avoir une vue 3D de la pièce. Pour changer de points de vue, je maintiens clic droit et je bouge curseur en fonction de l’angle de vue que je veux avoir sur la pièce.
Une fois l’analyse de la pièce terminée, il est temps de commencer la modélisation sur OpenSCAD. Vous pourrez télécharger OpenSCAD en vous rendant sur ce site. Choisissez la version qui correspond aux spécifications de votre machine et de votre système exploitation (pour ma part Windows 10 64-bit). Le plus simple est de télécharger l’installateur “.exe” et de suivre tout simplement l’installation comme avec vos programmes habituels.
Une fois installé, il faut lancer le programme et créer un nouveau fichier. La fenêtre OpenSCAD se présente avec à gauche la fenêtre d’edition dans laquelle vous pouvez écrire votre code et à droite la fenêtre d’aperçu de l’objet généré à partir du code que vous avez écrit.
Vous pouvez retrouver l’essentiel des fonctions que vous pouvez utiliser pour générer votre objet 3D dans la cheat sheet d’OpenSCAD. Je vous conseille de garder cette page dans vos favoris, car vous y reviendrez souvent. En cliquant sur le nom d’une fonction ou de tout autre élément de la syntaxe d’OpenSCAD, vous serez redirigés vers la documentation associée qui vous expliquera avec des exemples comment utiliser cet élément dans votre code. Je vous conseille de prendre en main OpenSCAD en commençant par reproduire les exemples fournis par la documentation, par exemple en générant un cube et en jouant avec les paramètres (taille de l’objet, position, nombre de polygones, etc.) ça vous aidera à rapidement comprendre comment marche l’outil. Vous pourrez ensuite essayer d’appliquer des opérations logiques (union, intersection, difference etc) entre plusieurs formes.
Pour visualiser dans la fenêtre de droite le résultat de votre code, vous devez cliquer sur “calculer l’aperçu” (ou F5) en haut de la fenêtre de gauche. L’option “calculer le rendu” (F6) quant à elle, calculera le rendu final de la pièce. Ceci peut prendre un temps considérablement plus long que calculer l’aperçu, surtout si vous utilisez un grand nombre de polygones. Je vous conseille donc de ne faire cette étape qu’une seule fois lorsque votre pièce sera terminée. Le calcul de ce rendu vous permettra par la suite d’exporter le rendu en fichier “.stl” (F7). Ceci sera nécessaire ensuite pour le slicer que nous utiliserons pour générer le code dont a besoin l’imprimante 3D pour imprimer votre pièce.
Identification des paramètres de la pièce#
Avant de commencer à générer votre pièce, il faut identifier les paramètres dont vous aurez besoin pour la modéliser. Pour ce faire vous devez d’abord réfléchir aux différentes parties qui composent votre pièce et comment les réaliser à l’aide des formes élémentaires fournies par OpenSCAD.
Pour la pièce que j’ai choisie, j’ai déterminé qu’il me faudrait d’abord un parallélépipède rectangle pour le support principal. Puisque la pièce présente un creux au centre, je devrais alors creuser ce support avec un autre parallélépipède plus petit en longueur et largeur et de meme hauteur au centre. Ceci pourra etre réalisé grâce à l’opération différence entre le support principal et le plus petit parallélépipède. En effet, cette opération a pour effet d’enlever d’une pièce le volume d’une deuxième pièce. C’est exactement ce dont nous avons besoin pour creuser notre pièce. À ce stade, je peux donc identifier qu’il me faudra des paramètres pour la position, la longueur, la largeur et la hauteur du support principal et des paramètres pour la position, la longueur et la largeur de la deuxième pièce (la hauteur des 2 pièces devant etre la meme).
Ma pièce présente également une brique centrale, que je réaliserai également avec un parallélépipède rectangle placé dans le creux précédemment creusé. Il me faudra donc aussi des paramètres pour ses dimensions et sa position. Pour réaliser des parallélépipèdes, il suffit d’utiliser la fonction “cube” avec les valeurs voulues pour la longueur, la largeur et la hauteur.
Il faut également des pièces cylindriques à base elliptique de part et d’autre de la brique centrale. Il faut en déterminer le nombre, les dimensions de ces pièces (demi-grand et demi petit-axe de l’ellipse et hauteur du cylindre), l’espacement entre deux pièces consecutives, l’espacement entre le bord du support et la première pièce (position de la première pièce), leur orientation (angle par rapport aux axes x, y et z), etc. Ce sont autant de paramètres dont nous aurons besoin pour réaliser ces pièces. Pour réaliser ces pièces cylindriques, nous pouvons utiliser la fonction “cylinder” en mentionnant la hauteur voulue et une valeur pour la longueur du rayon de la base. En faisant ça, nous obtiendrons un cylindre usuel à base circulaire. Mais en faisant précéder la fonction cylinder d’une fonction scale nous pouvons adapter les dimensions x et y du rayon pour obtenir une forme elliptique.
Finalement et pas des moindres, il faudra rajouter les parties flexibles de part et d’autre des pièces cylindriques. Puisque ces pièces ont la forme de tiges ayant la hauteur des supports, nous pouvons utiliser la fonction “cube” avec une dimension x ou y longue et l’autre très fine et utiliser comme dimension z la hauteur des supports. Il faudra également leur donner la meme orientation que les pièces cylindriques associées. Nous devrons en paramétriser l’épaisseur (la dimension la plus fine) et la longueur.
Puisque la pièce se présente sous la forme de lego, elle est munie de nombreux cylindres situés par-dessus chacun des supports (support principal, brique centrale et pièces cylindriques). Il faut donc en paramétriser le nombre pour chaque support, les dimensions (rayon, hauteur), l’espacement entre deux cylindres consecutifs sur une meme pièce, l’espacement entre les bords de la pièce et le premier cylindre. Pour s’assurer que les cylindres ne dépassent pas la pièce, il faut en fixer le nombre en fonction de la longueur du diamètre de cylindre voulu et de l’espacement entre cylindre.
Notez que OpenSCAD travaille avec des polygones pour faire des formes arrondies. Je veux dire par là qu’il ne dessine pas exactement des disques dans le cas des cylindres par exemple. Il en approxime les bords à l’aide de petits segments de droites reliés entre eux de façon concentrique (formant ainsi un polygone). Vous pouvez jouer sur le nombre de segments avec le paramètre “$fn” pour obtenir une forme plus ou moins lisse. Sachez qu’au plus grand est ce nombre au plus le rendu obtenu sera lisse, mais le temps nécessaire pour le rendu final augmentera aussi beaucoup. À vous donc de déterminer le bon compromis entre un nombre trop bas (rendu peu lisse, mais rapide à produire) et trop élevé (très lisse, mais trop long à produire) en fonction des performances de votre ordinateur et de la précision voulue. Personnellement j’ai fixé ce paramètre “nbpolygones” à 100.
L’ensemble des paramètres dont j’ai eu besoin sont repris dans le code ci-dessous
//Paramètres généraux
eps = 0.1;
nbpolygones = 100;
longueur = 14;
largeur = 9;
hauteur = 1.5;
deltalongueur = 2;
deltalargeur = 4;
nbbriques = 6;
deltabriqueinterne = 0.5;
x0 = 0;
y0 = 0;
z0 = 0;
nb_row_cynlinders_h = 2;
horizontal_gap = 1.0;
vertical_gap = 1.0;
horizontal_offset = 0.1;
vertical_offset = 0.2;
hauteur_cylindre = 0.5;
rayon_cylindre = 0.3;
//Paramètres des elements flexibles
nbcylinders = 2;
nbpieces = 3;
rotation_angle = 10;
epaisseur_tige = 0.1;
scalefactor = 0.5;
nbpoly = 1000;
rayon_central = 0.9;
xoffset = 0.47;
vgap = 1.5;
//Paramètres des éléments flexibles de droite
xr = 3.5;
yr = -1.5;
zr = 0;
//Paramètres généraux
xinitial = (longueur/2) - 0.45;
yinitial = (largeur/2) - 0.2;
zinitial = hauteur/2;
longinterne = longueur - deltalongueur;
largeinterne = largeur - deltalargeur;
hauteurinterne = hauteur+eps;
decalagebrique = deltabriqueinterne/2.5;
longueurbrique = largeinterne - deltabriqueinterne;
largeurbrique = longinterne/nbbriques;
hauteurbrique = hauteur;
//Paramètres des elements flexibles
tigelong = (longinterne-largeurbrique)/(2*cos(10));
//Paramètres des éléments flexibles de gauche
longtigegauche = tigelong + 0.5;
xl = -xr+0.5;
yl = yr;
zl = zr;
Construction du support principal#
Comme annoncé précédemment, j’ai construit le support principal en faisant la différence logique entre 2 pièces. Je place un premier cube (le plus grand) au centre et je lui donne les dimensions fixées par des paramètres (longueur, largeur, hauteur). J’en soustrais ensuite un second cube plus petit ayant les dimensions du creux souhaitées (longinterne, largeinterne, hauteurinterne).
//Creation du support creux par la difference de 2 cubes
difference(){
cube(size = [longueur,largeur,hauteur], center = true);
cube(size = [longinterne,largeinterne,hauteurinterne], center = true);
}
Placement de la brique centrale#
Ensuite, je rajoute la brique centrale à une position déterminée par des coordonnées x, y et z définis par des paramètres et je leur donne des dimensions qui sont également des paramètres.
//placement de la brique centrale
translate([x0,-decalagebrique,z0])
cube(size = [largeurbrique, longueurbrique, hauteurbrique], center = true);
Ajout des cylindres sur le support principal#
Je rajoute ensuite les cylindres sur les 4 faces du support principal (face supérieure, inférieure, gauche et droite). Pour ce faire je dois déterminer le nombre de cylindres à placer le long de la face en question et le nombre de lignes de cylindres à placer. Ceci a été déterminé au préalable à partir de la longueur de la face, du rayon d’un cylindre et de l’espacement voulu entre chaque cylindre. En effet, pour placer i cylindres sur la longueur de la face, il faut une longueur de 2 * rayon_cylindre * i + (i-1) * gap . Il faudra donc calculer i en fonction des paramètres choisis pour le rayon et l’espacement des cylindres.
La meme logique s’applique pour le nombre de cylindres qu’on peut placer sur une colonne. Il suffit alors de considérer la largeur de la forme plutôt que sa longueur. Une fois ces paramètres déterminés, il faudra utiliser 2 boucles imbriquées pour disposer les cylindres respectivement sur la ligne et la colonne voulue. La coordonnée x d’un cylindre donnée vaudra x0 + i * horizontal_gap et sa coordonnée y vaudra y0 + j * vertical_gap. Dans ces expressions, i et j indiquent respectivement la ligne et la colonne sur laquelle se trouve le cylindre, les gaps indiquent les espacements horizontaux et verticaux choisis entre 2 cylindres, x0, y0 désignent les coordonnées du premier cylindre.
La boucle extérieure s’exécutera autant de fois qu’il y a de lignes et la boucle intérieure s’exécutera autant de fois qu’il y a de colonnes de cylindres. La coordonnée z vaudra z0 pour tous les cylindres, car ils sont tous situés à la meme hauteur. Un raisonnement analogue s’applique pour chacune des faces, il faut seulement adapter la position du premier cylindre et le sens dans lequel on rajoute des espacements horizontaux et verticaux.
//placement des cylindres sur la face inférieure
translate([x0,decalagebrique,z0])
translate([-xinitial,-yinitial,zinitial])
for(i = [0:longueur-1]){
for(j = [0: nb_row_cynlinders_h-1]){
translate([x0,j*vertical_gap,z0])
translate([i*horizontal_gap,y0,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre, r = rayon_cylindre, center = false);
}
}
//placement des cylindres sur la face de droite
translate([xinitial-horizontal_offset,-yinitial+vertical_offset,zinitial])
for(i = [0:largeur-1]){
translate([x0,i*vertical_gap,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre, r = rayon_cylindre, center = false);
}
//placement des cylindres sur la face de gauche
translate([-xinitial,-yinitial+
vertical_offset,zinitial])
for(i = [0:largeur-1]){
translate([x0,i*vertical_gap,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre, r = rayon_cylindre, center = false);
}
//Placement des cylindres sur la face supérieure
translate([xinitial-horizontal_offset,-yinitial+vertical_offset+largeur-2,zinitial])
for(i = [0:longueur-1]){
for(j = [0: nb_row_cynlinders_h-1]){
translate([x0,j*vertical_gap,z0])
translate([-i*horizontal_gap,y0,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre, r = rayon_cylindre, center = false);
}
}
Ajout des cylindres sur la brique centrale#
Après avoir rajouté des cylindres sur le support principal, je rajoute des cylindres sur la brique centrale. Ceci est fait en suivant le meme principe que pour le support principal.
//Placement des cylindres sur la brique centrale
translate([0.45, -1.7, zinitial])
for(i = [0:deltalongueur-1]){
for(j = [0: deltalargeur-1]){
translate([x0,j*vertical_gap,z0])
translate([-i*horizontal_gap,y0,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre, r = rayon_cylindre, center = false);
}
}
Ajout des éléments flexibles#
Finalement, je rajoute les éléments flexibles à gauche et à droite. Pour ce faire, j’utilise une boucle qui commence par placer une pièce cylindrique au sein du creux du support principal. Des cylindres sont ensuite rajoutés par-dessus la pièce cylindrique. Dans le code ci-dessous, je dispose 2 cylindres de part et d’autre du centre de la pièce cylindrique. J’ajoute enfin une tige flexible qui joint la pièce cylindrique aux bords intérieurs du support principal. L’ensemble (pièce cylindrique, cylindres et tige flexible) est orienté grâce à une rotation autour de l’axe z avec un angle fixé par le paramètre “rotation_angle”. Ces pièces sont distribuées dans le creux du support principal avec un espacement défini par le paramètre “vgap”. Le nombre de pièces est déterminé par le paramètre “nbpieces”.
//Placement des elements flexibles à gauche
translate([xr, yr, zr])
for(i = [0:nbpieces-1]){
translate([x0,vgap*i,z0]){
rotate(a=-rotation_angle, v=[0,0,1]){
translate([x0,y0,-hauteur/2])
//placement des pieces centrales du mécanisme flexible
scale([1, scalefactor]) cylinder($fn = nbpoly, h = hauteur, r = rayon_central, center = false);
//placement des cylindres sur les pieces centrales
for(t = [0:nbcylinders]){
translate([xoffset*pow(-1,t),y0,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre + (hauteur/2), r = rayon_cylindre, center = false);
}
//placement des tiges flexibles
translate([x0,y0,z0])
cube(size = [longtigegauche,epaisseur_tige,hauteur], center = true);
}
}
}
//Placement des elements flexibles à droite
translate([xl, yl, zl])
for(i = [0:nbpieces-1]){
translate([x0,vgap*i,z0]){
rotate(a=rotation_angle, v=[0,0,1]){
translate([x0,y0,-hauteur/2])
//placement des pieces centrales du mécanisme flexible
scale([1, scalefactor]) cylinder($fn = nbpoly, h = hauteur, r = rayon_central, center = false);
//placement des cylindres sur les pieces centrales
for(t = [0:nbcylinders]){
translate([xoffset*pow(-1,t),y0,z0])
cylinder($fn = nbpolygones, h = hauteur_cylindre + (hauteur)/2, r = rayon_cylindre, center = false);
}
//placement des tiges flexibles
translate([-0.5,y0,z0])
cube(size = [tigelong,epaisseur_tige,hauteur], center = true);
}
}
}
Réutilisation de la pièce d’un collègue#
Pour compléter mon kit, je réutilise ici le code d’un lego écrit par Soufiane Ajouaou. Puisque je veux inclure son travail dans le mien je dois le citer et faire un usage de son code conforme à celui défini par la license dont il a muni son code. Puisqu’il a choisi la “license” CC0 1.0 (domaine public) je pourrais utiliser son code comme bon me semble, me l’approprier, le modifier, en faire un usage commercial, etc. Ici, je décide de le citer, car dans la plupart des cas, nous sommes tenus d’au minimum citer l’auteur du travail qu’on réutilise.
Ici, j’ai récupéré le code de Soufiane qui construisait un lego unique et je l’ai modifié pour l’inclure dans mon code sous forme d’un module “lego” qui prend en paramètre 3 coordonnées (x, y, z) et qui place un lego dont les dimensions correspondent aux cylindres de mon kit à la position correspondant aux paramètres fournis. Pour l’exercice, j’utilise ce module pour placer un lego en bas à gauche sur le support principal.
cylinder_size = rayon_cylindre*2;
size = (4/3)*cylinder_size;
cylinder_height = hauteur_cylindre;
module lego(xlego, ylego, zlego){
mirror(v=[0,0,1]){
union(){
translate([xlego,ylego,zlego-cylinder_height])
cylinder(h = cylinder_height,d = cylinder_size, $fn=nbpolygones, center = false);
difference(){
translate([xlego-(size/2),ylego-(size/2),zlego])
cube(size);
translate([xlego,ylego,zlego+cylinder_height])
cylinder(h = cylinder_height,d = cylinder_size, $fn=nbpolygones);
translate([xlego,ylego,zlego+cylinder_height])
cylinder(h = cylinder_height,d = cylinder_size, $fn=nbpolygones);
}
}
}
}
lego(-xinitial, -yinitial+0.2, zinitial-hauteur-hauteur_cylindre-0.3);
Une fois la modélisation terminée, je calcule le rendu final et j’exporte le rendu obtenu dans un fichier “.stl”. Cette étape est nécessaire, car le programme (slicer) que nous utiliserons par la suite pour générer les instructions pour l’imprimante 3D, a besoin du fichier “.stl” en entrée.
Ajout d’une license#
Pour terminer, je rajoute une license à mon travail. Il existe de nombreuses licenses qui imposent diverses conditions à respecter lors de la réutilisation de votre travail. Je vous renvoie vers le site indiqué par le professeur. Vous y trouverez les dénominations de différentes licenses fréquemment utilisées ainsi que leurs descriptions. Comme je veux que mon travail soit du domaine public, j’ai choisi la “licence” CC0 1.0. Afin de rajouter une license à mon travail, je crée un fichier LICENSE.md dans lequel j’inclus les lignes suivantes :
File : Lego.scad
Author : Mohamed Ouamar
Date : 05 November 2023
License : Creative Commons CC0 1.0 Universal [CC0 1.0](https://creativecommons.org/licenses/by-sa/4.0/)
Credits : A part of the code (the lego module) is attributed to Soufiane Ajouaou, shared under the CC0 1.0 license.
Je répète également ces lignes dans l’entête de mon fichier “.scad” que j’ai nommé “Lego.scad”. Dans ces lignes, je précise mon nom, la date à laquelle j’ai rédigé le fichier, les spécifications de la license que j’ai choisie ainsi qu’une section “Credits” indiquant que j’ai réutilisé le code d’un autre, l’auteur du travail et la license qu’il a utilisée.