LinuxCNC / Machinekit architecture
Posté : 10 févr. 2019, 22:23
Suite à une discussion avec Goldo, j'ouvre un sujet pour parler de l'architecture de LinuxCNC et Machinekit.
Voici ce que j'ai compris en utilisant LinuxCNC et MK sur mes machines, mais il y a peut-être des erreurs !
Pour mémoire, LinuxCNC (aka EMC2) est l'évolution de EMC (the Enhanced Machine Controller), projet du NIST (1993).
Machinekit est un fork de LinuxCNC, qui en conserve l'architecture, mais intègre une nouvelle couche de communication qui permet de fonctionner en mode distribué.
L'architecture d'origine de EMC est décrite ici : https://www.nist.gov/publications/enhan ... e-overview
L'évolution vers LinuxCNC est ici : http://linuxcnc.org/docs/2.6/html/code/ ... e_overview
Et ici un papier expliquant plutôt bien l'architecture : https://hrcak.srce.hr/file/165776
Le pilotage de la machine à partir du GCODE se fait via la chaîne suivante :
CGODE => Interpreter => Trajectory planer => Kinematics => Interpolator&PID <=> HW drivers
Le truc génial dans LinuxCNC , c'est HAL (Hardware Abstraction Layer).
C'est un langage pour décrire le câblage entre les composants qui vont implémenter la chaîne de traitement du GCODE aux interfaces physiques.
Il y a 2 types de composants:
Voici quelques exemples de composants :
Dans le langage HAL, on définit des fils qui vont connecter les entrées et sorties des différents composants.
Les signaux peuvent être de type boolean, float, S32 et U32. Ils existe des composants de conversion, par exemple entre float et S32.
HAL peut être configuré et visualisé en temps-réel grâce à la commande "haldcmd".
Voici un extrait de la sortie de "halcmd show" exécuté sur un simulateur de ma machine CNC-6040.
On peut voir la liste des composants chargés, le câblage et les valeurs des différents signaux.
Le truc sympa avec HAL est qu'il est possible de faire une configuration modulaire. J'utilise cette propriété pour avoir 2 versions de ma config :
A noter l'existence de différentes implémentations pour les même composants.
Par exemple, le composant "stepgen" permettant de piloter un moteur PAP existe en 2 versions :
Les 2 versions utilisent globalement les mêmes signaux pour la connexion vers "emcmot" : commande/feedback de position et commande/feedback de vitesse.
La présence du feedback peut surprendre pour des moteurs PAP. En fait, le "stepgen" va générer un train d'impulsions avec une accélération bornée par configuration. C'est cette information qui remonte dans le feedback. En pratique, il faut toujours veiller à ce que les accélérations max configurées dans les "stepgen" soient >= à celle données au trajectory planer.
A noter qu'il est tout à fait possible de configurer LinuxCNC pour utiliser des moteurs PAP et des encodeurs, comme pour un servo.
L'information de feedback pourra alors être utilisée, soit pour réaliser un asservissement en boucle fermée, soit pour seulement donner l'alarme en cas de problème "erreur following error".
Voilà, c'est tout pour aujourd'hui.
En espérant que ce premier poste aidera à mieux comprendre le fonctionnement de LinuxCNC et Machinekit !
Frédéric.
Voici ce que j'ai compris en utilisant LinuxCNC et MK sur mes machines, mais il y a peut-être des erreurs !
Pour mémoire, LinuxCNC (aka EMC2) est l'évolution de EMC (the Enhanced Machine Controller), projet du NIST (1993).
Machinekit est un fork de LinuxCNC, qui en conserve l'architecture, mais intègre une nouvelle couche de communication qui permet de fonctionner en mode distribué.
L'architecture d'origine de EMC est décrite ici : https://www.nist.gov/publications/enhan ... e-overview
L'évolution vers LinuxCNC est ici : http://linuxcnc.org/docs/2.6/html/code/ ... e_overview
Et ici un papier expliquant plutôt bien l'architecture : https://hrcak.srce.hr/file/165776
Le pilotage de la machine à partir du GCODE se fait via la chaîne suivante :
CGODE => Interpreter => Trajectory planer => Kinematics => Interpolator&PID <=> HW drivers
- Interpreter : interprétation du code GCODE, et calcul d'une trajectoire idéale
- Trajectory planer : transformation de la trajectoire idéale en trajectoire réaliste (tient compte de la puissance des moteurs, de la masse des pièces en mouvement)
Par exemple, c'est ici que le paramètre G64 est utilisé pour définir la tolérance acceptable dans le mouvement. Sur un parcours sinueux, la tolérance est utilisée pour accélérer le mouvement, sinon il faudrait aller tout doucement à cause de l'inertie et de la puissance limitée des moteurs. - Kinematics : transformation du mouvement de l'outil en consignes pour les axes. Pour une machine comme la Charly, c'est trivial. Pour une configuration delta, c'est plus compliqué car le repère cartésien ne correspondant pas à celui des actionneurs.
- Interpolator&PID : transformation de la trajectoire continue en une succession de points, avec asservissement en boucle fermée
- HW drivers : les drivers pour commander les différentes interfaces physiques vers les machines.
Le truc génial dans LinuxCNC , c'est HAL (Hardware Abstraction Layer).
C'est un langage pour décrire le câblage entre les composants qui vont implémenter la chaîne de traitement du GCODE aux interfaces physiques.
Il y a 2 types de composants:
- Les composants temps-réel, exécutés dans l'espace kernel pour LinuxCNC (via RTAI)
- Les composants moins contraignants, exécutés en userland
Voici quelques exemples de composants :
- trivkins : cinématique de base pour les machines type routeur X/Y/Z
- pwmgen : générateur de signaux PWM
- stepgen : générateur de signaux pour commander un moteur PAP
- encoder : décodage de signaux en quadrature venant d'un encodeur
- and2 : ET logique à 2 entrées
Dans le langage HAL, on définit des fils qui vont connecter les entrées et sorties des différents composants.
Les signaux peuvent être de type boolean, float, S32 et U32. Ils existe des composants de conversion, par exemple entre float et S32.
HAL peut être configuré et visualisé en temps-réel grâce à la commande "haldcmd".
Voici un extrait de la sortie de "halcmd show" exécuté sur un simulateur de ma machine CNC-6040.
On peut voir la liste des composants chargés, le câblage et les valeurs des différents signaux.
Code : Tout sélectionner
Loaded HAL Components:
ID Type Name PID State
38 User halcmd2379 2379 ready
39 RT oneshot ready
36 User camview 2352 ready
35 User probe 2353 ready
33 User pyngcgui_popupkeyboard 2355 ready
31 User vfd 2354 ready
29 User halio 2352 initializing
27 User gmoccapy 2345 ready
25 User inihal 2342 ready
24 User xhc-hb04 2336 ready
22 RT spindle_security ready
21 RT conv_s32_float ready
20 RT sum2 ready
19 RT comp ready
18 RT near ready
17 RT lowpass ready
16 RT limit2 ready
15 RT sim_spindle ready
14 RT and2 ready
13 RT hypot ready
12 RT ddt ready
11 RT __servo-thread ready
10 RT __base-thread ready
9 RT motmod ready
8 RT trivkins ready
7 User halui 2305 ready
5 User iocontrol 2303 ready
Component Pins:
Owner Type Dir Value Name
14 bit IN FALSE and2_0.in0 <== px
14 bit IN FALSE and2_0.in1 <== py
14 bit OUT FALSE and2_0.out ==> pxy
14 s32 OUT 4747 and2_0.time
14 bit IN FALSE and2_1.in0 <== pz
14 bit IN FALSE and2_1.in1 <== pxy
14 bit OUT FALSE and2_1.out ==> probe-in
14 s32 OUT 3626 and2_1.time
14 bit IN TRUE and2_2.in0 <== spindle-near
14 bit IN FALSE and2_2.in1 <== spindle-on
14 bit OUT FALSE and2_2.out ==> spindle-at-speed
14 s32 OUT 3763 and2_2.time
9 bit OUT TRUE axis.0.active
9 bit OUT TRUE axis.0.amp-enable-out
9 bit IN FALSE axis.0.amp-fault-in
9 float OUT 0 axis.0.backlash-corr
9 float OUT 0 axis.0.backlash-filt
9 float OUT 0 axis.0.backlash-vel
9 float OUT 121.2167 axis.0.coarse-pos-cmd
9 bit OUT FALSE axis.0.error
9 float OUT 0 axis.0.f-error
9 float OUT 0.25 axis.0.f-error-lim
9 bit OUT FALSE axis.0.f-errored
9 bit OUT FALSE axis.0.faulted
9 float OUT 121.2167 axis.0.free-pos-cmd
9 bit OUT FALSE axis.0.free-tp-enable
9 float OUT 0 axis.0.free-vel-lim
9 s32 OUT 0 axis.0.home-state
9 bit IN FALSE axis.0.home-sw-in <== Xhomesw
9 bit OUT FALSE axis.0.homed
9 bit OUT FALSE axis.0.homing
9 bit OUT TRUE axis.0.in-position
9 bit I/O FALSE axis.0.index-enable
9 s32 IN 0 axis.0.jog-counts <== jog-counts
9 bit IN FALSE axis.0.jog-enable <== jog-x
9 float IN 0 axis.0.jog-scale <== jog-scale
9 bit IN FALSE axis.0.jog-vel-mode
9 float OUT 121.2167 axis.0.joint-pos-cmd
9 float OUT 121.2167 axis.0.joint-pos-fb ==> x2
9 float OUT 0 axis.0.joint-vel-cmd
9 bit OUT FALSE axis.0.kb-jog-active
9 float OUT -121.2167 axis.0.motor-offset
9 float OUT 0 axis.0.motor-pos-cmd ==> Xpos
9 float IN 0 axis.0.motor-pos-fb <== Xpos
9 bit OUT FALSE axis.0.neg-hard-limit
9 bit IN FALSE axis.0.neg-lim-sw-in
....
bit FALSE safe-z
==> halui.mdi-command-10
<== xhc-hb04.button-safe-z
bit FALSE spindle-at-speed
<== and2_2.out
==> gmoccapy.spindle_at_speed_led
==> spindle-security.0.at-speed
float 0 spindle-cmd
==> limit_speed.in
<== motion.spindle-speed-out
==> near_speed.in1
bit FALSE spindle-index-enable
<=> motion.spindle-index-enable
<=> sim_spindle.index-enable
bit TRUE spindle-near
==> and2_2.in0
<== near_speed.out
bit FALSE spindle-on
==> and2_2.in1
<== motion.spindle-on
float 0 spindle-pos
==> motion.spindle-revs
<== sim_spindle.position-fb
float 0 spindle-rpm
==> gmoccapy.spindle_feedback_bar
==> motion.spindle-speed-in
==> near_speed.in2
<== spindle_mass.out
float 0 spindle-rps
<== motion.spindle-speed-cmd-rps
==> xhc-hb04.spindle-rps
bit FALSE spindle-security-override
==> spindle-security.0.override
<== vfd.hal_spindle_security_override-button
==> vfd.hal_spindle_security_override-light
float 0 spindle-speed-limited
<== limit_speed.out
==> sim_spindle.velocity-cmd
==> spindle_mass.in
Le truc sympa avec HAL est qu'il est possible de faire une configuration modulaire. J'utilise cette propriété pour avoir 2 versions de ma config :
- Une version avec les vrais drivers HW pour piloter la machine
- Une version avec des drivers simulés, permettant de tout mettre au point dans une VM, sans machine physique
A noter l'existence de différentes implémentations pour les même composants.
Par exemple, le composant "stepgen" permettant de piloter un moteur PAP existe en 2 versions :
- Une version entièrement soft (donc limitée en vitesse), destinée à commander une interface de puissance via des outputs comme un port // de PC
- Une version FPGA pour carte MESA appelée hostmot2 (http://linuxcnc.org/docs/2.6/html/drivers/hostmot2.html)
Les 2 versions utilisent globalement les mêmes signaux pour la connexion vers "emcmot" : commande/feedback de position et commande/feedback de vitesse.
La présence du feedback peut surprendre pour des moteurs PAP. En fait, le "stepgen" va générer un train d'impulsions avec une accélération bornée par configuration. C'est cette information qui remonte dans le feedback. En pratique, il faut toujours veiller à ce que les accélérations max configurées dans les "stepgen" soient >= à celle données au trajectory planer.
A noter qu'il est tout à fait possible de configurer LinuxCNC pour utiliser des moteurs PAP et des encodeurs, comme pour un servo.
L'information de feedback pourra alors être utilisée, soit pour réaliser un asservissement en boucle fermée, soit pour seulement donner l'alarme en cas de problème "erreur following error".
Voilà, c'est tout pour aujourd'hui.
En espérant que ce premier poste aidera à mieux comprendre le fonctionnement de LinuxCNC et Machinekit !
Frédéric.