LinuxCNC / Machinekit architecture

Règles du forum
Cette section est dédié a vos projets, descriptions et demandes d'aide.
Merci de limiter le nombre de sujet par projets.
Lorsqu'un sujet deviens long vous pouvez éditer le premier message pour maintenir à jour le descriptif et garder en lisibilité
Avatar de l’utilisateur
F1OAT
Electrolab::Membre
Messages : 93
Enregistré le : 04 mars 2017, 19:28
Contact :

LinuxCNC / Machinekit architecture

Messagepar F1OAT » 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

  • 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 :

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.

Retourner vers « Les Projets »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité