:lang: fr
:toc:

= Les composants temps réel 

[[cha:Composants-temps-reel]] (((composants-temps-reel)))


[[sec:Stepgen]]
== Stepgen
(((stepgen)))

Ce composant fournit un générateur logiciel d'impulsions de pas
répondant aux commandes de position ou de vitesse. En mode position, il
contient une boucle de position pré-réglée, de sorte que les réglages
de PID ne sont pas nécessaires. En mode vitesse, il pilote un moteur à
la vitesse commandée, tout en obéissant aux limites de vitesse et
d'accélération. C'est un composant uniquement temps réel, dépendant de
plusieurs facteurs comme la vitesse du CPU, etc, il est capable de
fournir des fréquences de pas maximum comprise entre 10kHz et 50kHz.
La figure <<fig:Diagramme-bloc-stepgen,ci-dessous>> montre trois schémas
fonctionnels, chacun est un simple générateur d'impulsions de pas. Le
premier diagramme est pour le type _0_, (pas et direction). Le second
est pour le type _1_ (up/down, ou pseudo-PWM) et le troisième est pour
les types 2 jusqu'à 14 (les différentes séquences de pas). Les deux
premiers diagrammes montrent le mode de commande _position_ et le
troisième montre le mode _vitesse_. Le mode de commande et le type de
pas, se règlent indépendamment et n'importe quelle combinaison peut
être choisie.

[[fig:Diagramme-bloc-stepgen]]
.Diagramme bloc du générateur de pas stepgen
(((Diagramme bloc stepgen)))

image::images/stepgen-block-diag.png[]


=== L'installer
----
halcmd: loadrt stepgen step_type=<type-array> [ctrl_type=<ctrl_array>] 
----

_<type-array>_ est une série d'entiers décimaux séparés par des
virgules. Chaque
chiffre provoquera le chargement d'un simple générateur d'impulsions de
 pas, la valeur de ce chiffre déterminera le type de pas.
_<ctrl_array>_ est une série de lettres _p_ ou _v_ séparées par
des virgules, qui spécifient le mode pas ou le mode vitesse. 
_ctrl_type_ est optionnel, si il est omis, tous les générateurs de pas 
seront en mode position. Par exemple, la commande:
----
halcmd: loadrt stepgen step_type=0,0,2 ctrl_type=p,p,v 
----

va installer trois générateurs de pas. Les deux premiers utilisent le
type de pas _0_ (pas et direction) et fonctionnent en mode position. Le
dernier utilise le type de pas _2_ (quadrature) et fonctionne en mode
vitesse. La valeur par défaut de _<config-array>_ est _0,0,0_ qui va
installer trois générateurs de type _0_ (step/dir). Le nombre
maximum de générateurs de pas est de 8 (comme définit par MAX_CHAN dans
stepgen.c). Chaque générateur est indépendant, mais tous sont
actualisés par la même fonction(s), au même instant. Dans les
descriptions qui suivent, _<chan>_ est le nombre de générateurs
spécifiques. La numérotation des
générateurs commence à 0.

=== Le désinstaller
----
halcmd: unloadrt stepgen
----

=== Pins

Chaque générateur d'impulsions de pas n'aura que certaines de ces
pins, selon le type de pas et le mode de contrôle sélectionné.

 - _(float) stepgen.<chan>.position-cmd_ -- Position désirée du
   moteur, en unités de longueur (mode position seulement).
 - _(float) stepgen.<chan>.velocity-cmd_ -- Vitesse désirée du moteur,
   en unités de longueur par seconde (mode vitesse seulement).
 - _(s32) stepgen.<chan>.counts_ -- Rétroaction de la position en
   unités de comptage, actualisée par la fonction _capture_position()_.
 - _(float) stepgen.<chan>.position-fb_ -- Rétroaction de la position
   en unités de longueur, actualisée par la fonction _capture_position()_.
 - _(bit) stepgen.<chan>.step_ -- Sortie des impulsions de pas 
(type de pas 0 seulement).
 - _(bit) stepgen.<chan>.dir_ -- Sortie direction (type de pas 0 seulement).
 - _(bit) stepgen.<chan>.up_ -- Sortie UP en pseudo-PWM 
(type de pas 1 seulement).
 - _(bit) stepgen.<chan>.down_ -- Sortie DOWN en pseudo-PWM 
(type de pas 1 seulement).
 - _(bit) stepgen.<chan>.phase-A_ -- Sortie phase A 
(séquences de pas 2 à 14 seulement).
 - _(bit) stepgen.<chan>.phase-B_ -- Sortie phase B 
(séquences de pas 2 à 14 seulement).
 - _(bit) stepgen.<chan>.phase-C_ -- Sortie phase C 
(séquences de pas 3 à 14 seulement).
 - _(bit) stepgen.<chan>.phase-D_ -- Sortie phase D 
(séquences de pas 5 à 14 seulement).
 - _(bit) stepgen.<chan>.phase-E_ -- Sortie phase E 
(séquences de pas 11 à 14 seulement).

=== Paramètres

 - _(float) stepgen.<chan>.position-scale_ -- Pas par unité de longueur. 
   Ce paramètre est utilisé pour les sorties et les rétroactions.
 - _(float) stepgen.<chan>.maxvel_ -- Vitesse maximale, en unités de
   longueur par seconde. Si égal à 0.0, n'a aucun effet.
 - _(float) stepgen.<chan>.maxaccel_ -- Valeur maximale
   d'accélération, en unités de longueur par seconde
   au carré. Si égal à 0.0, n'a aucun effet.
 - _(float) stepgen.<chan>.frequency_ -- Fréquence des pas, en pas par seconde.
 - _(float) stepgen.<chan>.steplen_ -- Durée de l'impulsion de pas
   (types de pas 0 et 1) ou durée minimum
   dans un état donné (séquences de pas 2 à 14), en nanosecondes.
 - _(float) stepgen.<chan>.stepspace_ -- Espace minimum entre deux
   impulsions de pas (types de pas 0 et 1 seulement), en nanosecondes.
 - _(float) stepgen.<chan>.dirsetup_ -- Durée minimale entre un
   changement de direction et le début de la
   prochaine impulsion de pas (type de pas 0 seulement), en nanosecondes.
 - _(float) stepgen.<chan>.dirhold_ -- Durée minimale entre la fin
   d'une impulsion de pas et un
   changement de direction (type de pas 0 seulement), en nanosecondes.
 - _(float) stepgen.<chan>.dirdelay_ -- Durée minimale entre un pas
   dans une direction et un pas dans la
   direction opposée (séquences de pas 1 à 14 seulement), en nanosecondes.
 - _(s32) stepgen.<chan>.rawcounts_ -- Valeur de comptage brute
   (count) de la rétroaction, réactualisée par la fonction _make_pulses()_. 

En mode position, les valeurs de maxvel et de maxaccel sont utilisées
par la boucle de position interne pour éviter de générer des trains
d'impulsions de pas que le moteur ne peut pas suivre. Lorsqu'elles sont
réglées sur des valeurs appropriées pour le moteur, même un grand
changement instantané dans la position commandée produira un mouvement
trapézoïdal en douceur vers la nouvelle position. L'algorithme
fonctionne en mesurant à la fois, l'erreur de position et l'erreur de
vitesse, puis en calculant une accélération qui tende à réduire vers
zéro, les deux en même temps. Pour plus de détails, y compris les
contenus de la boîte _d'équation de contrôle_, consulter le code
source.

En mode vitesse, maxvel est une simple limite qui est appliquée à la
vitesse commandée, maxaccel est utilisé pour créer une rampe avec la
fréquence actuelle, si la vitesse commandée change brutalement. Comme
dans le mode position, des valeurs appropriées de ces paramètres
assurent que le moteur pourra suivre le train d'impulsions généré.
[[sub:Stepgen-sequences-de-pas]]

=== Séquences de pas

Le générateur de pas supporte 15 différentes _séquences de pas_. Le
type de pas 0 est le plus familier, c'est le standard pas et direction
(step/dir). Quand stepgen est configuré pour le type 0, il y a quatre
paramètres supplémentaires qui déterminent le timing exact des signaux
de pas et de direction. Voir la figure <<fig:StepDir-timing, ci-dessous>> 
pour la signification de ces paramètres. Les paramètres sont en nanosecondes,
mais ils doivent être arrondis à un entier, multiple de la période du
thread qui appelle _make_pulses()_. Par exemple, si _make_pulses()_ 
est appelée toutes les 16µs et que _steplen_ est à 20000, alors
l'impulsion de pas aura une durée de 2 x 16 = 32µs. La valeur par
défaut de ces quatre paramètres est de 1ns, mais l'arrondi automatique
prendra effet au premier lancement du code. Puisqu'un pas exige d'être
 haut pendant _steplen_ ns et bas pendant _stepspace_ ns, la
fréquence maximale est 1.000.000.000 divisé par _(steplen+stepspace)_.
Si _maxfreq_ est réglé plus haut que cette limite, il sera abaissé
automatiquement. Si _maxfreq_ est à zéro, il restera à zéro, mais la
fréquence de sortie sera toujours limitée.

[[fig:StepDir-timing]]
.Timing pas et direction

(((Timing pas et direction)))

image::images/stepgen-type0.png[]

Le type de pas 1 a deux sorties, up et down. Les impulsions
apparaissent sur l'une ou l'autre, selon la direction du déplacement.
Chaque impulsion a une durée de _steplen_ ns et les impulsions sont
séparées de _stepspace_ ns. La fréquence maximale est la même que pour
le type 0. Si _maxfreq_ est réglé plus haut que cette limite il sera
abaissé automatiquement.
Si _maxfreq_ est à zéro, il restera à zéro, mais la fréquence de sortie
sera toujours limitée.

Les séquences 2 jusqu'à 14 sont basées sur les états et ont entre deux
et cinq sorties. Pour chaque pas, un compteur d'état est incrémenté ou
décrémenté. Les figures suivantes:

 - <<fig:Trois-phases-quadrature,Trois phases en quadrature>>, 
 - <<fig:Quatre-phases,Quatre phases>>, 
 - <<fig:Cinq-phases,Cinq phases>>

montrent les différentes séquences des sorties en fonction de l'état du 
compteur. La fréquence maximale est 1.000.000.000 (1*10^9^) divisé par 
_steplen_ et comme dans les autres séquences, _maxfreq_ sera abaissé si 
il est au dessus de cette limite.

[[fig:Trois-phases-quadrature]]
.Séquences de pas à trois phases
(((Trois phases)))

image::images/stepgen-type2-4.png[]

[[fig:Quatre-phases]]
.Séquences de pas à quatre phases
(((Quatre phases)))

image::images/stepgen-type5-10.png[]

[[fig:Cinq-phases]]
.Séquence de pas à cinq phases
(((Cinq phases)))

image::images/stepgen-type11-14.png[]

=== Fonctions

Le composant exporte trois fonctions. Chaque fonction agit sur tous
les générateurs d'impulsions de pas. Lancer différents générateurs dans
différents threads n'est pas supporté.

 - _(funct) stepgen.make-pulses_ -- Fonction haute vitesse de
   génération et de comptage des impulsions (non flottant).
 - _(funct) stepgen.update-freq_ -- Fonction basse vitesse de
   conversion de position en vitesse, mise
   à l'échelle et traitement des limitations.
 - _(funct) stepgen.capture-position_ -- Fonction basse vitesse pour
   la rétroaction, met à jour les latches et les mesures de position.

La fonction à grande vitesse _stepgen.make-pulses_ devrait être
lancée dans un thread très rapide, entre 10 et 50us
selon les capacités de l'ordinateur. C'est la période de ce thread qui
 détermine la fréquence maximale des pas, de _steplen_, _stepspace_,
_dirsetup_, _dirhold_ et _dirdelay_, tous sont arrondis au multiple
entier de la période du thread en nanosecondes. Les deux
autres fonctions peuvent être appelées beaucoup plus lentement.

[[sec:PWMgen]]
== PWMgen
(((pwmgen)))

Ce composant fournit un générateur logiciel de PWM (modulation de
largeur d'impulsions) et PDM (modulation de densité d'impulsions).
C'est un composant temps réel uniquement, dépendant de plusieurs
facteurs comme la vitesse du CPU, etc, Il est capable de générer des
fréquences PWM de quelques centaines de Hertz en assez bonne
résolution, à peut-être 10kHz avec une résolution limitée.

=== L'installer
----
halcmd: loadrt pwmgen output_type=<config-array>
----

_<config-array>_ est une série d'entiers décimaux séparés par des
virgules. Chaque
chiffre provoquera le chargement d'un simple générateur de PWM, la
valeur de ce chiffre determinera le type de sortie.

.Exemple avec pwmgen
----
halcmd: loadrt pwmgen output_type=0,1,2
----

va installer trois générateurs de PWM. Le premier utilisera une sortie
de type _0_ (PWM seule), le suivant utilisera une sortie de type 1 (PWM
et direction) et le troisième utilisera une sortie de type 2 (UP et
DOWN). Il n'y a pas de valeur par défaut, si _<config-array>_ n'est
pas spécifié, aucun générateur de PWM ne sera installé. Le
nombre maximum de générateurs de fréquences est de 8 (comme définit par
MAX_CHAN dans pwmgen.c). Chaque générateur est indépendant, mais tous
sont mis à jour par la même fonction(s), au même instant. Dans les
 descriptions qui suivent, _<chan>_ est le nombre de générateurs
spécifiques. La numérotation des
générateurs de PWM commence à 0.

=== Le désinstaller
----
halcmd: unloadrt pwmgen
----

=== Pins

Chaque générateur de PWM aura les pins suivantes:

 - _(float) pwmgen.<chan>.value_ -- Valeur commandée, en unités
   arbitraires. Sera mise à l'échelle par
   le paramètre d'échelle (voir ci-dessous).
 - _(bit) pwmgen.<chan>.enable_ -- Active ou désactive les sorties du
   générateur de PWM.

Chaque générateur de PWM aura également certaines de ces pins, selon
le type de sortie choisi:

 - _(bit) pwmgen.<chan>.pwm_ -- Sortie PWM (ou PDM), (types de sortie 0
   et 1 seulement).
 - _(bit) pwmgen.<chan>.dir_ -- Sortie direction (type de sortie 1 seulement).
 - _(bit) pwmgen.<chan>.up_ -- Sortie PWM/PDM pour une valeur positive
   en entrée (type de sortie 2 seulement).
 - _(bit) pwmgen.<chan>.down_ -- Sortie PWM/PDM pour une valeur
   négative en entrée (type de sortie 2 seulement).

=== Paramètres

 - _(float) pwmgen.<chan>.scale_ -- Facteur d'échelle pour convertir
   les valeurs en unités
   arbitraires, en coefficients de facteur cyclique.
 - _(float) pwmgen.<chan>.pwm-freq_ -- Fréquence de PWM désirée, en
   Hz. Si égale à 0.0, la modulation
   sera PDM au lieu de PWM. Si elle est réglée plus haute que les limites
   internes, au prochain appel de la fonction _update_freq()_ elle sera
   ramenée aux limites internes. Si elle est différente de
   zéro et si _le lissage_ est faux, au prochain appel de la fonction
   _update_freq()_ elle sera réglée au plus proche entier multiple de la
   période de la fonction _make_pulses()_.
 - _(bit) pwmgen.<chan>.dither-pwm_ -- Si vrai, active le lissage pour
   affiner la fréquence PWM ou le
   rapport cyclique qui ne pourraient pas être obtenus avec une pure PWM.
   Si faux, la fréquence PWM et le rapport cyclique seront tous les deux
   arrondis aux valeurs pouvant être atteintes exactement.
 - _(float) pwmgen.<chan>.min-dc_ -- Rapport cyclique minimum compris
   entre 0.0 et 1.0 (Le rapport
   cyclique sera à zéro quand il est désactivé, indépendamment de ce
   paramètre).
 - _(float) pwmgen.<chan>.max-dc_ -- Rapport cyclique maximum compris
   entre 0.0 et 1.0.
 - _(float) pwmgen.<chan>.curr-dc_ -- Rapport cyclique courant, après
   toutes les limitations et les
   arrondis (lecture seule).

=== Types de sortie

Le générateur de PWM supporte trois _types de sortie_.

* Le _type 0_ - A une seule pin de sortie. Seules, les commandes positives sont
acceptées, les valeurs négatives sont traitées comme zéro (elle seront affectées
par le paramètre _min-dc_ si il est différent de zéro).
* Le _type 1_ - A deux pins de sortie, une pour le signal PWM/PDM et une pour
la direction. Le rapport cyclique d'une pin PWM est basé sur la valeur absolue
de la commande, de sorte que les valeurs négatives sont acceptables. La pin de
direction est fausse pour les commandes positives et vraie pour les
commandes négatives. 
* Le _type 2_ - A également deux sorties, appelées _up_ et _down_. Pour
les commandes positives, le signal PWM apparaît sur la sortie _up_ et la sortie
_down_ reste fausse. Pour les commandes négatives, le signal PWM apparaît sur
la sortie _down_ et la sortie _up_ reste fausse. Les sorties de type 2 sont
appropriées pour piloter la plupart des ponts en H.

=== Fonctions

Le composant exporte deux fonctions. Chaque fonction agit sur tous les
générateurs de PWM, lancer différents générateurs dans différents
threads n'est pas supporté.

 - _(funct) pwmgen.make-pulses_ -- Fonction haute vitesse de
   génération de fréquences PWM (non flottant).
 - _(funct) pwmgen.update_ -- Fonction basse vitesse de mise à
   l'échelle, limitation des valeurs et traitement d'autres paramètres.

La fonction haute vitesse _pwmgen.make-pulses_ devrait être lancée
dans un thread très rapide, entre 10 et 50 us 
selon les capacités de l'ordinateur. C'est la période de ce thread qui
détermine la fréquence maximale de la porteuse PWM, ainsi que la
résolution des signaux PWM ou PDM. L'autre fonction peut être appelée
beaucoup plus lentement.

[[sec:Codeur]]
== Codeur
(((Codeur)))

Ce composant fournit, en logiciel, le comptage des signaux provenant
d'encodeurs en quadrature. Il s'agit d'un composant temps réel
uniquement, il est dépendant de divers facteurs comme la vitesse du
CPU, etc, il est capable de compter des signaux de fréquences comprises
entre 10kHz à peut être 50kHz. La figure ci-dessous représente le diagramme bloc 
d'une voie de comptage de codeur.

[[fig:Diagramme-bloc-du-codeur]]
.Diagramme bloc du codeur
(((Diagramme bloc du codeur)))

image::images/encoder-block-diag.png[]

=== L'installer
----
halcmd: loadrt encoder [num_chan=<counters>]
----

_<counters>_ est le nombre de compteurs de codeur à installer. Si
_numchan_ n'est pas spécifié, trois compteurs seront installés. Le nombre
maximum de compteurs est de 8 (comme définit par MAX_CHAN dans encoder.c). 
Chaque compteur est indépendant, mais tous sont mis à jour 
par la même fonction(s) au même instant. Dans les descriptions qui 
suivent, _<chan>_ est le nombre de compteurs spécifiques. La 
numérotation des compteurs commence à 0. 

=== Le désinstaller
----
halcmd: unloadrt encoder
----

=== Pins

 - _Encodeur <chan> counter-mode_ (bit, I/O) (par défaut: FALSE) -- Permet le
    mode compteur. Lorsque TRUE, le compteur compte chaque front montant de 
    l'entrée phase-A, ignorant la valeur de la phase-B. Ceci est utile pour 
    compter la sortie d'un capteur simple canal (pas de quadrature). Si FALSE, 
    il compte en mode quadrature.
  - _encoder.<chan>.counts_ (s32, Out) -- Position en comptage du codeur.
  - _encoder.<chan>.counts-latched_ (s32, Out) -- Non utilisé à ce moment.
  - _encoder.<chan> index-enable_ (bit, I/O) -- Si TRUE, _counts_ et 
    _position_ sont remis à zéro au prochain front montant de la phase Z. 
     En même temps, _index-enable_ est remis à zéro pour indiquer que le front
     montant est survenu. La broche _index-enable_ est bi-directionnelle. Si
    _index-enable_ est FALSE, la phase Z du codeur sera ignorée et le
     compteur comptera normalement. Le pilote du codeur ne doit jamais mettre
    _index-enable_ TRUE. Cependant, d'autres composants peuvent le faire.
  - _encoder.<chan>.latch-falling_ (bit, In) (par défaut: TRUE) -- Non utilisé 
    à ce moment.
  - _encoder.<chan>.latch-input_ (bit, In) (par défaut: TRUE) -- Non utilisé à 
    ce moment.
  - _encoder.<chan>.latch-rising_ (bit, In) -- Non utilisé à ce moment.
  - _encoder.<chan>.min-speed-estimate_ (Float, In) -- Effectue une estimation 
    de la vitesse minimale réelle, à partir de laquelle, la vitesse sera estimée 
    comme non nulle et la position interpolées, comme étant interpolée. Les 
    unités de vitesse _min-speed-estimate_ sont les mêmes que les unités 
    de _velocity_. Le facteur d'échelle, en compte par unité de longueur. 
    Régler ce paramètre trop bas, fera prendre beaucoup de temps pour que la 
    vitesse arrive à 0 après que les impulsions du codeur aient cessé d'arriver.
 - _encoder.<chan>.phase-A_ (bit, In) -- Signal de la phase A du codeur en 
quadrature.
 - _encoder.<chan>.phase-B_ (bit, In) -- Signal de la phase B du codeur en 
quadrature.
 - _encoder.<chan>.phase-Z_ (bit, In) -- Signal de la phase Z (impulsion d'index) 
    du codeur en quadrature.
 - _encoder.<chan>.position_ (float, Out) - Position en unités mises à l'échelle 
    (voir _position_ échelle).
 - _encoder.<chan>.position-interpolated_ (float, Out) - Position en unités mises
   à l'échelle, interpolées entre les comptes du codeur. _position-interpolated_
   tente d'interpoler entre les comptes du codeur, basée sur la mesure de vitesse
   la plus récente. Valable uniquement lorsque la vitesse est approximativement
   constante et supérieure à _min-speed-estimate_. Ne pas utiliser pour le
   contrôle de position, puisque sa valeur est incorrecte en basse vitesse, lors 
   des inversions de direction et pendant les changements de vitesse.
   Toutefois, il permet à un codeur à PPR faible (y compris les codeur à une 
   impulsion par tour) d'être utilisé pour du filetage sur tour et peut aussi 
   avoir d'autres usages.
 - _encoder.<chan>.position-latched_ (float, Out) -- Non utilisé à ce moment.
 - _encoder.<chan>.position-scale_ (float, I/O) -- Le facteur d'échelle, en
   comptes par unité de longueur. Par exemple, si _position-scale_ est à 500, 
   alors à 1000 comptes codeur, la position sera donnée à 2,0 unités.
 - _encoder.<chan>.rawcounts_ (s32, In) -- Le compte brut, tel que déterminé par 
   _update-counters. Cette valeur est mise à jour plus fréquemment que compte et 
    position. Il n'est également pas affecté par le reset ou l'impulsion d'index.
 - _encoder.<chan>.reset_ (bit, In) -- Si TRUE, force _counts_ et _position_ 
    immédiatement à zéro.
 - _encoder.<chan>.velocity_ (float, Out) -- Vitesse en unités mises à l'échelle 
   par secondes. _encoder_ utilise un algorithme qui réduit considérablement la 
   quantification du bruit comparé à simplement différencier la sortie _position_. 
   Lorsque la magnitude de la vitesse réelle est inférieure à 
   _min-speed-estimate_, la sortie _velocity_ est à 0.
 - _encoder.<chan>.x4-mode_ (bit, I/O) (par défaut: TRUE) -- Permet le mode
   x4. Lorsqu'il est TRUE, le compteur compte chaque front de l'onde en 
   quadrature (quatre compte par cycle complet). Si FALSE, il ne compte qu'une 
   seule fois par cycle complet. En mode compteur, ce paramètre est ignoré. 
   Le mode 1x est utile pour certaines manivelles électroniques.

=== Paramètres

 - _encoder.<chan>.capture-position.time (s32, RO)_ 
 - _encoder.<chan>.capture-position.tmax (s32, RW)_
 - _encoder.<chan>.update-counters.time (s32, RO)_
 - _encoder.<chan>.update-counter.tmax (s32, RW)_

=== Fonctions

Le composant exporte deux fonctions. Chaque fonction agit sur tous les
compteurs de codeur, lancer différents compteurs de codeur dans
différents threads n'est pas supporté.

 - _(funct) encoder.update-counters_ -- Fonction haute vitesse de
   comptage d'impulsions (non flottant).
 - _(funct) encoder.capture-position_ -- Fonction basse vitesse
   d'actualisation des latches et mise à l'échelle de la position.

[[sec:PID]]
== PID
(((pid)))

Ce composant fournit une boucle de contrôle Proportionnelle/Intégrale/Dérivée. 
C'est un composant temps réel uniquement. Par souci de simplicité, cette 
discussion suppose que nous parlons de boucles de position, mais ce composant 
peut aussi être utilisé pour implémenter d'autres boucles de rétroaction 
telles que vitesse, hauteur de torche, température, etc. La figure 
<<fig:Diagramme-bloc-PID,ci-dessous>> est le schéma fonctionnel d'une simple 
boucle PID.

[[fig:Diagramme-bloc-PID]]
.Diagramme bloc d'une boucle PID
(((Diagramme bloc PID)))

image::images/pid-block-diag.png[]

=== L'installer
----
halcmd: loadrt pid [num_chan=<loops>] [debug=1]
----

_<loops>_ est le nombre de boucles PID à installer. Si _numchan_ 
n'est pas spécifié, une seule boucle sera installée. Le nombre
maximum de boucles est de 16 (comme définit par MAX_CHAN dans pid.c).
Chaque boucle est complétement indépendante. Dans les descriptions qui
 suivent, _<loopnum>_ est le nombre de boucles spécifiques. La
numérotation des boucle PID
commence à 0.

Si _debug=1_ est spécifié, le composant exporte quelques paramètres
destinés au débogage et aux réglages. Par défaut, ces paramètres ne sont pas
exportés, pour économiser la mémoire partagée et éviter d'encombrer la
liste des paramètres.

=== Le désinstaller
----
halcmd: unloadrt pid
----

=== Pins

Les trois principales pins sont:

 - _(float) pid.<loopnum>.command_ -- La position désirée (consigne),
   telle que commandée par un autre composant système.
 - _(float) pid.<loopnum>.feedback_ -- La position actuelle (mesure),
   telle que mesurée par un organe de rétroaction comme un codeur de position.
 - _(float) pid.<loopnum>.output_ -- Une commande de vitesse qui tend
   à aller de la position actuelle à la position désirée. 

Pour une boucle de position, _command_ et _feedback_ sont en unités de
longueur. Pour un axe linéaire, cela pourrait être des pouces, mm,
mètres, ou tout autre unité pertinente. De même pour un axe angulaire,
ils pourraient être des degrés, radians, etc. Les unités sur la pin
_output_ représentent l'écart nécessaire pour que la rétroaction
coïncide avec la commande. Pour une boucle de position, _output_ est
une vitesse exprimée en pouces/seconde, mm/seconde, degrés/seconde,
etc. Les unités de temps sont toujours des secondes et les unités de
vitesses restent cohérentes avec les unités de longueur. Si la commande
et la rétroaction sont en mètres, la sortie sera en mètres par seconde.

Chaque boucle PID a deux autres pins qui sont utilisées pour
surveiller ou contrôler le fonctionnement général du composant.

 - _(float) pid.<loopnum>.error_ -- Egal à _.command_ moins
   _.feedback_. (consigne - mesure)
 - _(bit) pid.<loopnum>.enable_ -- Un bit qui active la boucle. Si
   _.enable_ est faux, tous les intégrateurs sont remis à zéro et les
   sorties sont forcées à zéro. Si _.enable_ est vrai, la boucle opère 
normalement.

Pins utilisé pour signaler la saturation. La saturation se produit lorsque 
la sortie de le bloc PID est à son maximum ou limiter au minimum.

 - _(bit) pid.<loopnum>.saturated_ -- True lorsque la sortie est saturée.
 - _(float) pid.<loopnum>.saturated_s_ -- Le temps de la sortie a été saturé.
 - _(s32) pid.<loopnum>.saturated_count_ -- Le temps de la sortie a été saturé.

=== Paramètres

Le gain PID, les limites et autres caractéristiques _accordables_ de
la boucle sont implémentés comme des paramètres.

 - _(float) pid.<loopnum>.Pgain_ -- Gain de la composante proportionnelle. 
 - _(float) pid.<loopnum>.Igain_ -- Gain de la composante intégrale. 
 - _(float) pid.<loopnum>.Dgain_ -- Gain de la composante dérivée.
 - _(float) pid.<loopnum>.bias_ -- Constante du décalage de sortie. 
 - _(float) pid.<loopnum>.FF0_ -- Correcteur prédictif d'ordre zéro 
(retour vitesse) sortie proportionnelle à la commande (position).
 - _(float) pid.<loopnum>.FF1_ -- Correcteur prédictif de premier ordre 
(retour vitesse) sortie proportionnelle à la dérivée de la commande (vitesse).
 - _(float) pid.<loopnum>.FF2_ -- Correcteur prédictif de second ordre 
(retour vitesse) sortie proportionnelle à la dérivée seconde de la 
commande (accélération).
footnote:[FF2 n'est actuellement pas implémenté, mais il pourrait l'être. 
Considérez cette note comme un “FIXME” dans le code.]
 - _(float) pid.<loopnum>.deadband_ -- Définit la bande morte tolérable.
 - _(float) pid.<loopnum>.maxerror_ -- Limite d'erreur. 
 - _(float) pid.<loopnum>.maxerrorI_ -- Limite d'erreur intégrale. 
 - _(float) pid.<loopnum>.maxerrorD_ -- Limite d'erreur dérivée. 
 - _(float) pid.<loopnum>.maxcmdD_ -- Limite de la commande dérivée. 
 - _(float) pid.<loopnum>.maxcmdDD_ -- Limite de la commande dérivée seconde. 
 - _(float) pid.<loopnum>.maxoutput_ -- Limite de la valeur de sortie.

Toutes les limites _max???,_ sont implémentées de sorte que si la
valeur de ce paramètre est à
zéro, il n'y a pas de limite.

Si _debug=1_ est spécifié quand le composant est installé, quatre
paramètres supplémentaires seront exportés:

 - _(float) pid.<loopnum>.errorI_ -- Intégrale de l'erreur.
 - _(float) pid.<loopnum>.errorD_ -- Dérivée de l'erreur.
 - _(float) pid.<loopnum>.commandD_ -- Dérivée de la commande.
 - _(float) pid.<loopnum>.commandDD_ -- Dérivée seconde de la commande. 

=== Fonctions

Le composant exporte une fonction pour chaque boucle PID. Cette
fonction exécute tous les calculs nécessaires à la boucle. Puisque
chaque boucle a sa propre fonction, les différentes boucles peuvent
être incluses dans les différents threads et exécutées à différents
rythmes.

 - _(funct) pid.<loopnum>.do_pid_calcs_ -- Exécute tous les calculs
   d'une seule boucle PID.

Si vous voulez comprendre exactement l'algorithme utilisé pour
calculer la sortie d'une boucle PID, référez vous à la figure 
<<fig:Diagramme-bloc-PID,PID>>, les commentaires au début du source
_linuxcnc/src/hal/components/pid.c_ et bien sûr, au code lui même. Les
calculs de boucle sont dans la fonction C _calc_pid()_.

[[sec:Codeur-simul]]
== Codeur simulé
(((sim-encoder)))

Le codeur simulé est exactement la même chose qu'un codeur. Il produit
des impulsions en quadrature avec une impulsion d'index, à une vitesse
contrôlée par une pin de HAL. Surtout utile pour les essais.

=== L'installer
----
halcmd: loadrt sim-encoder num_chan=<number>
----

_<number>_ est le nombre de canaux à simuler. Si rien n'est spécifié, un seul
canal sera installé. Le nombre maximum de canaux est de 8 (comme
défini par MAX_CHAN dans sim_encoder.c).

=== Le désinstaller
----
halcmd: unloadrt sim-encoder
----

=== Pins

 - _(float) sim-encoder.<chan-num>.speed_ -- La vitesse commandée pour
   l'arbre simulé.
 - _(bit) sim-encoder.<chan-num>.phase-A_ -- Sortie en quadrature.
 - _(bit) sim-encoder.<chan-num>.phase-B_ -- Sortie en quadrature.
 - _(bit) sim-encoder.<chan-num>.phase-Z_ -- Sortie de l'impulsion d'index. 

Quand _.speed_ est positive, _.phase-A_ mène _.phase-B_.

=== Paramètres

 - _(u32) sim-encoder.<chan-num>.ppr_ -- Impulsions par tour d'arbre.
 - _(float) sim-encoder.<chan-num>.scale_ -- Facteur d'échelle pour
   _speed_. Par défaut est de 1.0, ce qui signifie que _speed_ est en
   tours par seconde. Passer l'échelle à 60 pour des tours par
   minute, la passer à 360 pour des degrés par seconde, à 6.283185 pour
   des radians par seconde, etc.

Noter que les impulsions par tour ne sont pas identiques aux valeurs
de comptage par tour (counts). Une impulsion est un cycle complet de
quadrature. La plupart des codeurs comptent quatre fois pendant un
cycle complet.

=== Fonctions

Le composant exporte deux fonctions. Chaque fonction affecte tous les
codeurs simulés.

 - _(funct) sim-encoder.make-pulses_ -- Fonction haute vitesse de
   génération d'impulsions en quadrature
   (non flottant).
 - _(funct) sim-encoder.update-speed_ -- Fonction basse vitesse de
   lecture de _speed_, de mise à l'échelle et d'activation de
   _make-pulses_.

[[sec:Anti-rebond]]
== Anti-rebond
(((Anti-rebond)))

L'anti-rebond est un composant temps réel capable de filtrer les
rebonds créés par les contacts mécaniques. Il est également très utile
dans d'autres applications, où des impulsions très courtes doivent être
supprimées.

=== L'installer
----
halcmd: loadrt debounce cfg=<config-string>
----

_<config-string>_ est une série d'entiers décimaux séparés par des
espaces. Chaque
chiffre installe un groupe de filtres anti-rebond identiques, le
chiffre détermine le nombre de filtres dans le groupe. Par exemple:
----
halcmd: loadrt debounce cfg=1,4,2
----

va installer trois groupes de filtres. Le groupe 0 contient un filtre,
le groupe 1 en contient quatre et le groupe 2 en contient deux. La
valeur par défaut de _<config-string>_ est _1_ qui installe un seul
groupe contenant un seul filtre. Le nombre
maximum de groupes est de 8 (comme définit par MAX_GROUPS dans
debounce.c). Le nombre maximum de filtres dans un groupe est limité
seulement par l'espace de la mémoire partagée. Chaque groupe est
complétement indépendant. Tous les filtres dans un même groupe sont
identiques et ils sont tous mis à jour par la même fonction, au même
 instant. Dans les descriptions qui suivent, _<G>_ est le numéro du
groupe et _<F>_ est le numéro du filtre dans le groupe. Le premier
filtre est le
filtre 0 dans le groupe 0.

=== Le désinstaller
----
halcmd: unloadrt debounce
----

=== Pins

Chaque filtre individuel a deux pins.

 - _(bit) debounce.<G>.<F>.in_ -- Entrée du filtre _<F>_ du groupe _<G>_.
 - _(bit) debounce.<G>.<F>.out_ -- Sortie du filtre _<F>_ du groupe _<G>_.

=== Paramètres

Chaque groupe de filtre a un paramètre. footnote:[Chaque filtre
individuel a également une variable d'état interne.
C'est un switch du compilateur qui peut exporter cette variable comme
un paramètre. Ceci est prévu pour des essais et devrait juste être un
gaspillage de mémoire partagée dans des circonstances normales.]

 - _(s32) debounce.<G>.delay_ -- Délai de filtrage pour tous les filtres du 
groupe _<G>_.

Le délai du filtre est dans l'unité de la période du thread. Le délai
minimum est de zéro. La sortie d'un filtre avec un délai de zéro, suit
exactement son entrée, il ne filtre rien. Plus le délai augmente, plus
larges seront les impulsions rejetées. Si le délai est de 4, toutes les
impulsions égales ou inférieures à quatre périodes du thread, seront
rejetées.

=== Fonctions

Chaque groupe de filtres exporte une fonction qui met à jour tous les
filtres de ce groupe _simultanément_. Différents groupes de filtres
peuvent être mis à jour dans différents threads et à différentes
périodes.

 - _(funct) debounce.<G>_ -- Met à jour tous les filtres du groupe _<G>_.

[[sec:Siggen]]
== Siggen
(((siggen)))

Siggen est un composant temps réel qui génère des signaux carrés,
triangulaires et sinusoïdaux. Il est principalement utilisé pour les
essais.

=== L'installer
----
halcmd: loadrt siggen [num_chan=<chans>]
----

_<chans>_ est le nombre de générateurs de signaux à installer. Si
_numchan_ n'est pas spécifié, un seul générateur de signaux sera
installé. Le
nombre maximum de générateurs est de 16 (comme définit par MAX_CHAN
dans siggen.c). Chaque générateur est complétement indépendant. Dans
les descriptions qui suivent, _<chan>_ est le numéro d'un générateur
spécifique. Les numéros de générateur
commencent à 0.

=== Le désinstaller
----
halcmd: unloadrt siggen
----

=== Pins

Chaque générateur a cinq pins de sortie.

 - _(float) siggen.<chan>.sine_ -- Sortie de l'onde sinusoïdale.
 - _(float) siggen.<chan>.cosine_ -- Sortie de l'onde cosinusoïdale.
 - _(float) siggen.<chan>.sawtooth_ -- Sortie de l'onde en dents de scie.
 - _(float) siggen.<chan>.triangle_ -- Sortie de l'onde triangulaire.
 - _(float) siggen.<chan>.square_ -- Sortie de l'onde carrée.

Les cinq sorties ont les mêmes fréquence, amplitude et offset.

Trois pins de contrôle s'ajoutent aux pins de sortie:

 - _(float) siggen.<chan>.frequency_ -- Réglage de la fréquence en
   Hertz, par défaut la valeur est de 1 Hz.
 - _(float) siggen.<chan>.amplitude_ -- Réglage de l'amplitude de pic
   des signaux de sortie, par défaut, est à 1.
 - _(float) siggen.<chan>.offset_ -- Réglage de la composante continue
   des signaux de sortie, par défaut, est à 0.

Par exemple, si _siggen.0.amplitude_ est à 1.0 et _siggen.0.offset_
est à 0.0, les sorties oscilleront entre -1.0 et +1.0. Si
_siggen.0.amplitude_ est à 2.5 et _siggen.0.offset_ est à 10.0, les
sorties oscilleront entre 7.5 et 12.5.

=== Paramètres

Aucun. footnote:[Dans les versions antérieures à la 2.1, fréquence,
amplitude et offset
étaient des paramètres. Ils ont été modifiés en pins pour permettre le
contrôle par d'autres composants.]

=== Fonctions

 - _(funct) siggen.<chan>.update_ -- Calcule les nouvelles valeurs pour
   les cinq sorties.

[[sec:lut5]]
== lut5(((lut5)))

Le composant lut5 est un composant de logique à 5 entrées basé sur une table
de vérité.

* 'lut5' ne requiert pas un thread à virgule flottante.

.Installation

----
loadrt lut5 [count=N|names=name1[,name2...]]
addf lut5.N servo-thread | base-thread
setp lut5.N.function 0xN
----

.Calcul de la valeur de la fonction

Pour calculer la valeur hexadécimale de la fonction, démarrer par le haut et
entrer un 1 où un 0 pour indiquer si cette colonne devra être vraie où fausse.
Ensuite écrire les valeurs en dessous, d'abord dans la colonne de sortie en 
commençant par le haut puis en écrivant les valeurs correspondantes de la droite
vers la gauche. Le nombre binaire sera celui contenu dans la colonne de sortie.
Utiliser une calculette comme celle fournie sous Ubuntu, entrer ce nombre
binaire et le convertir en hexadécimal pour obtenir la valeur pour la fonction.

.Table de vérité
[width="50%",cols="6*^",options="header"]
|====================================
|Bit 4|Bit 3|Bit 2|Bit 1|Bit 0|Output
|0|0|0|0|0|
|0|0|0|0|1|
|0|0|0|1|0|
|0|0|0|1|1|
|0|0|1|0|0|
|0|0|1|0|1|
|0|0|1|1|0|
|0|0|1|1|1|
|0|1|0|0|0|
|0|1|0|0|1|
|0|1|0|1|0|
|0|1|0|1|1|
|0|1|1|0|0|
|0|1|1|0|1|
|0|1|1|1|0|
|0|1|1|1|1|
|1|0|0|0|0|
|1|0|0|0|1|
|1|0|0|1|0|
|1|0|0|1|1|
|1|0|1|0|0|
|1|0|1|0|1|
|1|0|1|1|0|
|1|0|1|1|1|
|1|1|0|0|0|
|1|1|0|0|1|
|1|1|0|1|0|
|1|1|0|1|1|
|1|1|1|0|0|
|1|1|1|0|1|
|1|1|1|1|0|
|1|1|1|1|1|
|====================================

.Un exemple de fonction.

Dans la table suivante nous avons sélectionné l'état de sortie pour chaque ligne
que nous souhaitons vraie.

.Table de vérité
[width="50%",cols="6*^",options="header"]
|====================================
|Bit 4|Bit 3|Bit 2|Bit 1|Bit 0|Output
|0|0|0|0|0|0
|0|0|0|0|1|1
|0|0|0|1|0|0
|0|0|0|1|1|1
|====================================

En regardant la colonne de sortie de notre exemple, nous voulons que la sortie
soit active quand le bit 0 OU le bit 0 ET le bit 1 soient actifs et rien d'autre.
Le nombre binaire est 'b1010' (rotation de la sortie de 90° en sens horaire).
Entrer ce nombre dans une calculette, le convertir en hexadécimal et le nombre
demandé pour cette fonction est '0xa'. Le préfixe '0x' étant celui des nombres
hexadécimaux.
