Je ne sais pas trop si ça intéresse du monde que j'explique ce que j'ai fait dans mon système.
J'aimerai aussi avoir l'avis des pros, parce que j'ai pas toujours trouvé de publications scientifiques pour avoir le boulot pré-mâché, du coup j'ai un peu inventé.
La vitesse de l'outil
Le Feedrate est donné en mm/min^1, l'accélération maximale est donnée en mm.s^-2 donc gaffe aux unités. Perso, dans mon code, "feedRate" est en mm.min^1, mais "speed" est en mm.s^-1 (j'ai pas encore eu de calcul qui nécessitait des unités internationales).
L'algo de planification de la vitesse le plus intuitif est celui de l'accélération maximale : accélérateur à fond ou frein à fond, comme un jeune dans une 205GTI. J'ai pris la même accélération pour l'augmentation ou la diminution de la vitesse j'espère que c'est pas trop grave. Le planificateur de vitesse ne sait faire que 3 choses : accélérer à fond, garder sa vitesse et freiner à fond. Il existes d'autres algorithmes plus malins, qui limitent les chocs (dérivée de l'accélération trop importante) dans la machine, mais ils sont plus compliqués, et je suis un peu limite en maths.
En ligne droite
Imaginons une ligne droite géante (on parlera des virages plus tard), que l'utilisateur veut parcourir à des vitesses différentes. Prenons la courbe de la vitesse en fonction de la position, ça fait des créneaux de hauteur différente. L'ordinateur a pour tache de suivre cette vitesse, sans jamais dépasser l'accélération maximale et sans jamais aller plus vite que l'utilisateur ne le veut. Les seules marges sont d'aller moins vite et de freiner plus tôt.
Ok, mais notre cher utilisateur il a des désirs que la mécanique ne peut pas suivre (en réalité il le sait mais c'est à l'ordinateur de faire les calculs), il y aura sur certains segments des vitesses qui ne seront jamais atteintes.
Donc en fonction de l'accélération maximale de la machine, l'utilisateur ne lui a peut-être pas laissé assez de longueur d'envol pour atteindre la vitesse voulue sur le segment. Pareil au freinage, il a demandé une vitesse trop grande sur un segment et on arrivera pas à freiner pour rentrer dans le segment suivant assez lentement.
l'approche que j'ai prise est assez simple: je passe une fois sur la courbe en accélérant et une fois sur la courbe à l'envers en freinant. Dans la phase d'accélération, si j'ai le temps d'accélérer jusqu'à la vitesse de l'utilisateur, je note qu'à la fin du segment je serai à la bonne vitesse, sinon, je note la vitesse maximale que j'ai pu atteindre. Au segment suivant, je pars de la vitesse max atteinte au précédent et je tente d'accélérer jusqu'à la nouvelle vitesse. Si le segment avait une vitesse inférieure, je laisse sa vitesse, on s'occupera du freinage plus tard. j'avance comme ça jusqu'au bout à tenter d'accélérer.
Ensuite, je pars de la droite, et j'applique le même algorithme en freinant. A la fin la vitesse est toujours 0, au dernier segment je regarde si j'arrive à freiner de la vitesse max au 0, si oui je garde la vitesse max, sinon je regarde quelle aurait été la vitesse max qui m'aurait permis de freiner à temps et je la garde comme nouvelle vitesse max. De l'avant-dernier au dernier, si l'avant dernier et plus rapide que le dernier, je tente de freiner à l'avant dernier pour rentrer dans le dernier à sa vitesse max, si ça passe, c'est bon, sinon je calcule quelle était la vitesse max d'où j'aurai du partir. etc.
voici le résultat (toujours en fonction de la distance parcourue), j'ai généré aléatoirement des vitesses et des longueurs de segments:
en rouge ce que l'utilisateur a rentré, en vert les vitesses max réellement atteintes, et en bleu la vitesse qu'on va faire en tenant compte des accélérations.
Par curiosité, voici la position de l'outil par rapport au temps:
C'est nettement moins intéressant, vu que l'outil est resté très longtemps dans un segment lent (ça vient de ma génération aléatoire du graphe-au dessus).
En arc de cercle
Comme nos profs nous l'expliquaient, aller en ligne droite à vitesse constante n'implique aucune accélération, mais pour pour changer le vecteur vitesse (en norme ou en direction), il faut de l'accélération. Un arc de cercle, même à feedrate constant, ça tourne le vecteur vitesse, ça utilise de l'accélération.
Avec l'arc de cercle, on a de la chance, c'est un virage à norme d'accélération constante (si la norme de la vitesse est constante), avec une b-spline ou un bézier, c'est une frankeinaccélération qu'il faut calculer.
Donc pour calculer la vitesse dans un arc de cercle il y a une première chose à vérifier : que parcourir l'arc de cercle à la vitesse demandée est possible, qu'on est pas en train de dépasser l'accélération max admissible simplement en tournant. Mécaniquement ça voudrait dire qu'on est en train de dépasser la force centrifuge acceptable (la masse en X et en Y du chariot n'est pas la même donc on y va à la louche avec un max pour tout le monde, y compris Z, avec ou sans force de coupe).
Ok, maintenant plus dur: si on veut accélérer dans un arc ? Une partie de l'accélération disponible est "prise" par la forme du mouvement, il ne reste pour faire varier la norme de la vitesse qu'une partie de l'accélération. Et si on est à la vitesse maximale possible pour la machine, on a plus d'accélération disponible pour freiner sans sortir de la trajectoire, donc il faut limiter la vitesse. C'est là que mes compétences en math ont atteint leur max :
http://math.stackexchange.com/questions/351699/time-equation-of-acceleration-along-an-arc . La solution qui n'utilise pas toute l'accélération disponible mais est plus simple niveau maths consiste à planifier une accélération angulaire contante qui fasse atteindre la vitesse demandée sans jamais que sa projection ne dépasse l'accélération max de la machine. Normalement, si on utilisait bien toute l'accélération linéaire "disponible" l'accélération angulaire devrait varier, car seule l'accélération linéaire instantanée nous intéresse. J'ai fait cette partie de manière assez scolaire avec des équations, donc je n'ai pas trop d'explication intuitive à donner.
Suite à la simplification, on voit les oreilles de batman sur la courbe d'accélération :
(code live :
http://nraynaud.github.io/webgcode/?code=G2%20X1%20Y0%20I0.5%20J0%20F300 )
Donc maintenant on est capable de planifier la vitesse pour des segments et des arcs, on peut calculer les directions de mouvement en entrée et en sortie des arcs, regarder si le mouvement en sortie d'un arc et co-linéaire avec le mouvement d'entrée du segment qui suit, si c'est le cas, on peut faire une chaine. On fait une chaine de mouvements colinéaires aussi longue que possible, et on planifie leur vitesse globalement et en calcul formel, sans avoir encore utilisé le pas de la machine. Reste la géométrie qu'on verra une autre fois.
J'espère que ça vous intéresse, si vous relevez des erreurs, dites-le svp, j'utilise ce code pour ma faiseuse :p
Si vous voyez des améliorations, go. Pas sûr que j'implémente toutes les suggestions car j'ai pas mal de taf sur le reste de la chaine CNC.