include /*Certaines fonctions utilisées dans ce fichier sont définies dans le fichier math.scad. Notamment la développante de cercle et la fonction permettant de calculer son point d'intersection avec un cercle. Pour des détails et explications il faut donc regarder dans le fichier math.scad*/ /**************ENGRENAGE DROIT************** **************DÉFINITIONS************** le cercle de pied, qui est le cercle passant par la base des dents ; le cercle de tête, qui passe par le sommet des dents ; le cercle de base, qui est celui qui sert à générer le profil des dents (les dents sont des développantes de ce cercle) ; le cercle primitif : les cercles primitifs des roues dentées d'un engrenage ont la même vitesse tangentielle ; ils passent à peu près au milieu des dents. **************NOTATIONS************** diamètre primitif => d diamètre de pied => df diamètre de tête => da diamètre de base => db angle de pression => alpha module => m pas (distance entre 2 dents sur le cercle primitif) => p saillie => ha creux => hf hauteur de dent => h nombre de dents => z largeur de la dent sur le cercle primitif => l angle d'une dent sur le cercle primitif => la **************RELATIONS************** d = m*z p = m*pi ha = m si m<=1.25 hf = 1.40*m sinon hf = 1.25*m si m<=1.25 h = 2.40*m sinon h = 2.25*m h = ha + hf <=> ha = h - hf <=> ha = 2.25m - 1.25m = m ha = m da = d + 2*ha = d + 2*m df = d - 2*hf = d -2.5*m db = d*cos(alpha) l = pi*m/2 = pi/2 * d/z = (pi * d)/(2 * z) = pi*r/z = p/2 deport de denture calcul de la largeur d'une dent avec déport : http://www.sidermeca.com/ficheconseil.php?fiche=1 /*************ATTENTION************* la différence entre le nombre de dents de 2 roues est limité dans certains cas si Za=13, Zbmax=16 si Za=14, Zbmax=26 si Za=15, Zbmax=45 si Za=16, Zbmax=101 si Za=17, Zbmax=sans limite de préférence choisir des nombres premiers entres eux */ $fn = 200; /*FONCTION EXPERIMENTALE*/ //function recherche_limite(limite = 6, etape = 0, x = 0, y = 0, angle = 0) = //limite == etape ? atan(x) : //etape%2 == 0 ? recherche_limite(limite = limite, etape = etape + 1, x = y + rad(angle), y = y, angle = angle) : //recherche_limite(limite = limite, etape = etape + 1, x = x, y = rad(atan(x)), angle = angle); function creux(m = 1) = m <= 1.25 ? 1.4*m : 1.25*m; module evider(diam_int = 15, diam_ext = 50, larg = 8, nbr = 6) { facteur = 1.7; offset(r = larg/facteur) { difference() { circle(d = diam_ext -0.1); union() { for(i = [0:nbr - 1]) { rotate([0, 0, i*360/nbr]) {square([diam_ext - larg/2, facteur*larg], center = true);} } difference() { circle(d = diam_ext); circle(d = diam_ext - 2*larg); } } } } } module dent_cremaillere_2D(m = 1, alpha = 20) { //hauteurs hf = creux(m); ha = m; h = hf + ha; //pas p = m*pi; //vecteurs /*calcul des points de la dents 1) Premier point [0, 0] En partant de l'origine, on monte jusqu'à y = h suivant un angle alpha. On notera l la longueur de la dent. On peut donc écrire : l*sin(alpha) = decalage_x l*cos(alpha) = h en faisant la première ligne divisé par la seconde on obtient : l*sin(alpha) / l*cos(alpha) = decalage_x / h Or l se simplifie et sin/cos = tan, on obtient donc : tan(alpha) = decalage_x / h et donc decalage_x = h*tan(alpha) 2) Deuxième point : [h*tan(alpha), h] Pour le troisième point il faut connaitre la largeur de la dent. Pour y = hf, la largeur de la dent vaut p/2, la largeur de la base est donc : largeur_base = hf*tan(alpha) + p/2 + hf*tan(alpha) <=> largeur_base = 2*hf*tan(alpha) + p/2 3) Troisième point : [largeur_base - h*tan(alpha), h] Le quatrième point lui est simplement la largeur de la dent avec y = 0 4) Quatrième point : [largeur_base, 0] */ largeur_base = 2*hf*tan(alpha) + p/2; polygon([ [0, 0], [h*tan(alpha), h], [largeur_base - h*tan(alpha), h], [largeur_base, 0] ]); } module cremaillere_2D(z = 10, m = 1, alpha = 20, largeur = 10) { //hauteurs hf = creux(m); //pas p = m*pi; union() { //corps de la crémaillère translate([0, -largeur, 0]) {square([p* (z - 1) + p/2 + 2*hf*tan(alpha), largeur]);} //dents de la crémaillère for(i=[0:z-1]) { translate([p*i, 0, 0]) {dent_cremaillere_2D(m, alpha);} } } } module cremaillere_3D(z = 10, m = 1, alpha = 20, largeur = 10, epaisseur = 3) { linear_extrude(epaisseur) {cremaillere_2D(z, m, alpha, largeur);} } module roue_dentee_2D(z = 40, m = 1, alpha = 20, deport = 0, evider = false) { //hauteurs hf = creux(m) - deport; ha = m + deport; //pas p = m*pi; //calcul des diamètres d = m * z; db = d * cos(alpha); df = d - 2*hf; da = d + 2*ha; //calcul de l'angle entre 2 dents angle_dent = 360 / z; //largeur de la dent sur le cercle primitif //l = pi*d/(2*z) + 2*deport*sin(alpha); l = p/2 + 2*deport*sin(alpha); //angle de la dent sur le cercle primitif la = degre(2*l/d); //paramètre d'intersection de la developpante avec le cercle primitif //Id = intersect(db/2, d/2); équivalent à : Id = intersect(db, d); Idx = developpante_x(db/2,Id); Idy = developpante_y(db/2,Id); //angle entre la base de la dent et l'intersection avec le cercle primitif angle = atan2(Idy, Idx); //angle de la dent à sa base angle_base = la + 2*angle; //paramètre d'intersection de la developpante avec le cercle de tête //Ida = intersect(db/2, da/2); équivalent à : Ida = intersect(db, da); //GENERATION DE LA DENT /*Lors d'un déport de denture trop prononcé les développantes de cercles se croisent donnant lieu à un "petit triangle" sur la pointe de la dent. Pour éviter ça il faut déterminer l'angle à ne pas dépasser. La développante de cercle ne devrait jamais croiser l'axe de symétrie de la dent. On en déduit donc que la droite passant par l'origine O et faisant un angle de "angle_base/2" avec l'axe x est la limite. On note I le point d'intersection de cette droite avec la développante de cercle et T un point du cercle de base (angle positif) tel que IT soit une tangente. CARACTÉRISTIQUES CONNUES DE LA FIGURE : 0) L'angle xOI est angle_base/2 1) L'angle IOT sera appelé alpha 2) L'angle xOT est le paramètre de la développante de cercle, on le notera a. 3) De part sa construction le triangle OIT est rectangle en T. 4) OT est un rayon du cercle de base, on notera sa longueur r 5) La longueur IT est proportionnelle à r et à l'angle xOT. Avec a en radiant on obtient : IT = ra 6) D'après le théorème de pythagore OI² = IT² + TO² 7) Dans un triangle rectangle : hypothénuse * cos(alpha) = coté adjacent DÉDUCTIONS : OI² = IT² + TO² OI² = r²a² + r² = r² * (1 + a²) OI = sqrt(r² * (1 + a²) ) OI = r * sqrt(1 + a²) Or OI est l'hypoténuse on peut dont écrire : OI * cos(alpha) = r r * sqrt(1 + a²) * cos(alpha) = r sqrt(1 + a²) * cos(alpha) = 1 cos(alpha) = 1 / sqrt(1 + a²) alpha = acos( 1 / sqrt(1 + a²) ) Dans le cas où la developpante de cercle est tracé jusqu'au point I alors on a : a = angle_base/2 + alpha Le paramètre a ne doit donc pas dépasser cette valeur. */ A = [ for(i=[0: ceil(Ida)]) if( i < angle_base/2 + acos( sqrt( 1/(1 + rad(i) * rad(i)))) ) [developpante_x(db/2,i), developpante_y(db/2,i)] ]; Matrice_de_rotation = [ [cos(angle_base), -sin(angle_base)], [sin(angle_base), cos(angle_base)] ]; //Pour continuer le polygone il faut parcourir les valeurs dans l'autre sens B = [ for(i=[floor(-Ida):0]) if( i > -angle_base/2 - acos( sqrt( 1/(1 + rad(i) * rad(i)))) ) Matrice_de_rotation*[developpante_x(db/2,i), developpante_y(db/2,i)] ]; C = concat(A, B); difference() { union() { //pied de la dent circle(d=df); for(j = [0:1:z-1]) { rotate([0, 0, j*angle_dent]) {polygon(C);} } } if(evider) {evider(diam_int = 3*da/10, diam_ext = 9*da/10, larg = 1.2*da/10, nbr = 6);} } } module roue_dentee_3D(z = 20, m = 5, alpha = 20, epaisseur = 2, deport = 0, evider = false) { linear_extrude(epaisseur) {roue_dentee_2D(z,m,alpha, deport, evider);} } module roue_dentee_3D_globoide(z = 20, m = 5, alpha = 20, epaisseur = 2, deport = 0, evider = false) { /*pour créer une roue globoïde on coupe les dents de la roue avec un tore le rayon R du cercle qui engendre le tore par révolution peut être calculer en considérant que les extrémités d'une dent forment une corde de ce cercle. https://fr.wikipedia.org/wiki/Segment_circulaire l'angle theta peut être trouvé en traçant la bissectrice de cet angle, on obtient un triangle rectangle avec des cotés ayant pour longueur h et c/2. B angle beta |\ h| \ __|__\A c/2 l'angle beta peut se calculer en utilisant la tangente : tan(beta) = (c/2)/h beta = atan(c/2h) Or le triangle ABO, avec O le centre du cercle est isocèle, et l'angle en 0 est theta/2 On en déduit que 2*beta + theta/2 = 180 et donc que : theta/2 = 180 - 2*beta En remplaçant dans la relation c = 2*R*sin(theta/2) on obtient : c = 2*R*sin(180 - 2*beta) or sin(180 - x) = sin(x) c = 2*R*sin(2*beta) on peut maintenant déduire R : R = c / 2*sin(2*beta) = c / 2*sin( 2*atan(c/2h) ) Dans le cas de notre roue dentée : c = epaisseur h = (da - d)/2 On en conclue que : R = epaisseur / 2*sin(2*atan(epaisseur/(da-d)) On peut également utiliser la fonction atan2 R = epaisseur / 2*sin(2*atan2(epaisseur, (da-d)) */ d = m*z; da = d + 2*m; difference() { linear_extrude(epaisseur) {roue_dentee_2D(z,m,alpha, deport, evider);} rayon = epaisseur / (2*sin(2*atan2(epaisseur, (da-d)))); translate([0, 0, epaisseur/2]) { rotate_extrude() { translate([d/2 + rayon, 0, 0]) {circle(rayon);} } } } } /**************ENGRENAGE HELICOÏDAL**************/ /*Dans un engrenage hélicoïdal la denture est "penchée", on distingue donc 2 profiles -Le profil réel, qui correspond à une coupe droite de la dent, une coupe par un plan perpendiculaire aux arêtes, module réel noté mr (noté parfois mn) -Le profil apparent, qui correspond à une coupe selon un plan perpendiculaire à l'axe du cylindre, module apparent : ma (noté parfois mt) le module réel "mr" et le module apparent "ma" sont lié par : mr = ma*cos(beta) beta étant l'angle que fait la dent avec l'axe de rotation **************RELATIONS************** relation pas - module : p = pi*m relation pas réel - pas apparent : pa = pr/cos(beta) relation module apparent - module réel : ma = mr/cos(beta) relation angle de pression réel - angle de pression apparent : tan(alpha_r) = tan(alpha_a)*cos(beta) alpha_a = arctan(tan(alpha_r)/cos(beta)) diamètre primitif : d = Z*mr / cos(beta) d = Z*ma diamètre de tête D = d + 2*mr nombre de dent : Z = d*cos(beta)/mr */ module roue_dentee_helicoidale(z = 40, m = 1, alpha = 20, beta = 60, epaisseur = 10, deport = 0, evider = false) { /*le paramètre twist est le nombre de degrés effectué pendant l'extrusion pour un schéma détaillé voir : http://www.zpag.net/Machines_Simples/engrenage_droit_dent_helicoidale.htm ATTENTION !! Pour engrainer les différentes roues dentées doivent avoir : - le même MODULE RÉEL !! - Le même angle Bêta, pour un contact extérieur : beta1 = -beta2 pour un contact intérieur : beta1 = beta2 Or roue_dentee_2D correspond à la coupe transversale de la roue dentée, dans ce plan là il s'agit du module apparent. La conversion se fait grâce à la relation : mr = ma*cos(beta); */ //CALCUL DES PARAMETRES APPARENTS ma = m/cos(beta); alpha_a = atan2(tan(alpha),cos(beta)); //CALCUL DU TWIST /*Dans la suite tous les paramètres seront sur le cercle primitif. Pour calculer l'angle de rotation pendant l'extrusion il faut résoudre 2 triangles. Le premier est celui qui part du bord d'une dent à la base de la roue dentée (point A), monte à la verticale sur surface supérieure (point B) et termine sur le point équivalent au point A mais sur la surface supérieure (point C). Le deuxième triangle est OBC avec O le centre de la roue dentée. CARACTÉRISTIQUES CONNUES DE LA FIGURE : 0) l'angle BAC = beta 1) la distance AB est l'épaisseur de la roue dentée 2) les distances OB et OC sont le rayon du cercle primitif DÉDUCTIONS : Sachant que AB*tan(beta) = BC et que BC est une corde du cercle alors si on nomme l'angle BOC theta on peut écrire : 2*OC*sin(theta/2) = BC. En égalisant les deux relations on obtient : AB*tan(beta) = 2*OC*sin(theta/2) AB*tan(beta)/(2*OC) = sin(theta/2) asin(AB*tan(beta)/(2*OC)) = theta/2 2*asin(AB*tan(beta)/(2*OC)) = theta Theta est notre angle de twist. Les notations du script sont : AB = epaisseur beta = beta 2*OC = d = z*ma theta = angle On obtient donc : angle = 2*asin(epaisseur * tan(beta) / (z*ma)); Cependant lorsque l'épaisseur devient trop importante alors on sort du domaine de définition de la fonction asin et le résultat devient incohérent. Pour palier à ce problème on va considérer que notre roue dentée est une succession de couches, comme lors d'une impression 3D. De ce fait on peut calculer l'angle entre 2 couches et par une règle de 3 on obtient le twist total. */ h = 0.01; //couches fines gamma = 2*asin(h * tan(beta) / (z*ma)); angle = epaisseur*gamma/h; linear_extrude(height = epaisseur, twist = angle) {roue_dentee_2D(z, ma, alpha_a, deport, evider);} } module roue_dentee_helicoidale_globoide(z = 40, m = 1, alpha = 20, beta = 60, epaisseur = 10, deport = 0, evider = false) { //CALCUL DES PARAMETRES APPARENTS ma = m/cos(beta); d = ma*z; da = d + 2*ma; difference() { roue_dentee_helicoidale(z, m, alpha, beta, epaisseur, deport, evider); rayon = epaisseur / (2*sin(2*atan2(epaisseur, (da-d)))); translate([0, 0, epaisseur/2]) { rotate_extrude() { translate([d/2 + rayon, 0, 0]) {circle(rayon);} } } } } module roue_dentee_helicoidale_globoide_vis(z = 40, m = 1, alpha = 20, vis_diam = 10, deport = 0, evider = false) { //Calcul de l'angle beta /*C'est la vis qui va imposer son angle beta, car il dépend à la fois de son pas et de son diamètre, alors que pour la roue dentée il peut posséder n'importe quelle valeur. Si on développe une vis sans fin les filets seront des lignes droites espacées du pas de la vis. Par conséquent, la longueur d'un de ces filet vérifie : l*cos(beta) = 2*pi*r = pi*d l*sin(beta) = p avec r le rayon de la vis on en déduit que : p/(pi*d) = tan(beta) beta = atan(p/pi*d) */ //CALCUL DES PARAMETRES APPARENTS beta = -atan(m/vis_diam); ma = m/cos(beta); d = ma*z; da = d + 2*ma; epaisseur = 2*sqrt( pow(vis_diam/2, 2) - pow(vis_diam/2 - ma, 2)); difference() { roue_dentee_helicoidale(z, m, alpha, beta, epaisseur, deport, evider); translate([0, 0, epaisseur/2]) { rotate_extrude() { #translate([ d/2 + vis_diam/2, 0, 0]) {circle(r=vis_diam/2);} } } } } module roue_dentee_chevron(z = 40, m = 1, alpha = 20, beta = 60, epaisseur = 10, deport = 0, evider = false) { //CALCUL DES PARAMETRES APPARENTS ma = m/cos(beta); //CALCUL DU TWIST h = 0.1; //couches fines gamma = 2*asin(h * tan(beta) / (z*ma)); angle = epaisseur*gamma/h; roue_dentee_helicoidale(z, m, alpha, beta, epaisseur/2, deport, evider); translate([0, 0, epaisseur/2]) { rotate([0, 0, -angle/2]) {roue_dentee_helicoidale(z, m, alpha, -beta, epaisseur/2, deport, evider);} } } module roue_dentee_couronne_2D(z = 10, m = 1, alpha = 20, deport = 0, marge = 10) { d = m * z; ha = m + deport; da = d + 2*ha; difference() { circle(d = da + marge); roue_dentee_2D(z, m, alpha, deport); } echo("diamètre de la couronne = ", da + marge); } /**************ENGRENAGE PLANÉTAIRE**************/ function rayon_satellites(m, zp, zs) = m*(zp + zs)/2; function nbr_max_satellites(R, da) = floor(180/asin(da/(2*R))); function nbr_satellites_equilibre(zp, zs, nbr) = ceil((zp + zs)/nbr) == (zp + zs)/nbr ? nbr : nbr_satellites_equilibre(zp, zs, nbr - 1); module planetaire_2D(zp = 33, zs = 27, m = 1, alpha = 26, deport = 0, marge = 10) { /*DÉFINITIONS : Planétaires : roue dentée tournant autour d'un axe fixe Satellites : roue dentée tournant autour d'un axe mobile La roue dentée centrale est appelée : planétaire La roue dentée extérieure est appelée : couronne Ce module génère un engrenage planétaire (de type 1) à partir du nombre de dent du planétaire et des satellites, respectivement zp et zs Comme pour tous engrenages, les différentes roues engrènent au niveau de leurs cercles primitifs d. En ce plaçant dans le cas d'un engrenage planétaire composé d'un planétaire, de 2 satellites et d'une couronne, on comprend que le diamètre de la couronne est égale au diamètre du planétaire (dp) plus 2 fois le diamètres d'un satellite (ds). dc = dp + 2*ds Pour que les roues engrènent il est nécessaire qu'elles aient le même module, la formule générale qui lie le diamètre et le nombre de dent est : d = m*z On en déduit : dc = dp + 2*ds <=> m*zc = m*zp + 2*m*zs <=> m*zc = m*(zp + 2*zs) <=> zc = zp + 2*zs CONTRAINTES : 1)Pour maximiser le couple transmis, il faut maximiser le nombre de satellites. Cependant il existe une limite pour laquelle les satellites se chevaucheront. Pour touver le nombre de satellites maximum il faut comparer le diamètre de tête d'un satellite, avec la longueur du coté du polygone régulier crée par le centre des satellites. La longueur d'un coté du polygone est : l = 2*R*sin(180/n) avec R le rayon du cercle circonscrit n le nombre de cotés du polygone qui est égal à nbr_satellites Sachant que l > da on peut en déduire : <=> 2*R*sin(180/nbr_satellites) > da <=> sin(180/nbr_satellites) > da/(2*R) <=> 180/nbr_satellites > asin(da/(2*R)) <=>180/asin(da/(2*R)) > nbr_satellites <=> nbr_satellites = floor(180/asin(da/(2*R))) On trouve ainsi le nombre maximum de satellites qui permet au train de continuer de fonctionner. 2)Connaitre le nombre maximum de satellites possible n'est pas suffisant, faut-il encore que l'engrenage soit équilibré. Pour se faire il faut respecter : (zp + zs)/nbr_satellites = k, avec k un nombre entier Cette condition permet de déterminer toutes les configurations possible. Exemple : zp = 20, zs = 20 La condition nous indique la possibilité d'utiliser : 1, 2, 4, 5, 10 ou même 20 satellites. En combinant les 2 conditions on est capable de déterminer le nombre de satellites maximum pour générer un système équilibré. La formule de Willis permet de calculer le rapport de réduction, dans le cas d'un engrenage de type 1 : lambda = zs*zc/zs*zp = zc/zp */ zc = zp + 2*zs; dp = m*zp; ds = m*zs; dc = m*zc; //calcul du rayon sur lequel circulent les satellites rayon = (dp + ds)/2; rapport1 = zc/zp + 1; rapport2 = zc/zs - 1; //on commence par placer le planétaire //les calculs qui suivent permettent d'orienter correctement la roue dentée l1 = pi*dp/(2*zp) + 2*deport*sin(alpha); la1 = 2*degre(l1/dp); db1 = dp * cos(alpha); Idp = intersect(db1, dp); angle1 = atan2( developpante_y(db1/2,Idp), developpante_x(db1/2,Idp)); angle_base1 = la1 + 2*angle1; rotate([0, 0, 360*(rapport1)*$t - angle_base1/2.0 + la1 + 180*(zs/zp + 2)]) { roue_dentee_2D(z = zp, m = m, alpha = alpha, deport = deport); } //puis les satellites //pareil ici l2 = pi*ds/(2*zs) + 2*deport*sin(alpha); la2 = 2*degre(l2/ds); db2 = ds * cos(alpha); Ids = intersect(db2, ds); angle2 = atan2( developpante_y(db2/2,Ids), developpante_x(db2/2,Ids) ); angle_base2 = la2 + 2*angle2; nbr_satellites = nbr_satellites_equilibre(zp, zs, nbr_max_satellites(rayon_satellites(m, zp, zs), m*zs+2*(m+deport))); if( ceil((zp + zs)/nbr_satellites) == (zp + zs)/nbr_satellites) { for(i=[1:nbr_satellites]) { translate([ rayon*cos(360*$t + 360*i/nbr_satellites), rayon*sin(360*$t + 360*i/nbr_satellites), 0]) { rotate([0, 0, -360*rapport2*$t - angle_base2/2 - 360*i/nbr_satellites * rapport2]) {roue_dentee_2D(z = zs, m = m, alpha = alpha, deport = deport);} } } } //et enfin on place la couronne //et pareil là lc = pi*dc/(2*zc) + 2*deport*sin(alpha); lac = 2*degre(lc/dc); dbc = dc * cos(alpha); Idc = intersect(dbc, dc); anglec = atan2( developpante_y(dbc/2,Idc), developpante_x(dbc/2,Idc) ); angle_basec = lac + 2*anglec; rotate([0, 0, -angle_basec/2]) {roue_dentee_couronne_2D(z = zc, m = m, alpha = alpha, deport = deport, marge = marge);} echo("nombre de dent de la couronne = ", zc); echo("rapport = ", zc/zp); echo(nbr_satellites = nbr_satellites); }