Système de contrôle industriel temps réel pour machine rapide
Publié le 15 mars 2024

Contrairement à l’IT classique, la performance d’une machine industrielle ne vient pas de la vitesse du CPU, mais de son déterminisme absolu.

  • Windows, par sa conception, introduit une gigue temporelle (jitter) inacceptable pour toute synchronisation précise.
  • Les OS temps réel (RTOS) et les FPGA sont les seules solutions garantissant des exécutions prédictibles à la milliseconde près.

Recommandation : Abandonnez la pensée « puissance brute » au profit d’une architecture où chaque tâche critique respecte son échéance, sans exception.

Pour un développeur logiciel issu de l’informatique de gestion ou du web, le concept de « machine rapide » est souvent associé à la puissance de calcul brute : des processeurs multi-cœurs, une mémoire RAM abondante et des disques SSD véloces. Dans cet univers, une latence de quelques dizaines de millisecondes est une nuisance, mais rarement une catastrophe. Pourtant, lorsque l’on bascule dans le monde du contrôle industriel, cette perception s’effondre. Piloter une machine-outil, un robot ou une ligne d’emballage ne requiert pas seulement de la vitesse, mais une qualité bien plus exigeante et contre-intuitive : le déterminisme.

L’idée de piloter un système industriel avec un OS familier comme Windows est séduisante. L’interface est connue, les outils de développement sont légion et l’écosystème logiciel est immense. Cependant, cette approche est un piège fondamental. L’architecture même des systèmes d’exploitation généralistes, conçus pour la bureautique et le multimédia, est l’antithèse des besoins du temps réel. Ils sont optimisés pour le confort de l’utilisateur et le partage équitable des ressources, pas pour la ponctualité d’une boucle de contrôle moteur qui doit s’exécuter toutes les millisecondes, sans faute. La véritable question n’est donc pas « mon PC est-il assez rapide ? », mais « mon système d’exploitation est-il capable de garantir une réponse dans un délai imparti, à chaque cycle, des millions de fois par jour ? ».

Cet article se propose de déconstruire ce paradigme. Nous n’allons pas seulement affirmer que Windows est inadapté ; nous allons disséquer les raisons techniques fondamentales de cette inadéquation, de la gigue de l’ordonnanceur à l’imprévisibilité des pilotes. Plus important encore, nous explorerons les alternatives robustes — des systèmes d’exploitation temps réel (RTOS) aux logiques déportées sur FPGA — qui constituent la véritable fondation d’une machine précise et fiable. Il s’agit d’un changement de perspective essentiel pour tout développeur IT qui aborde l’industrie : passer de la culture de la performance moyenne à l’exigence du déterminisme absolu.

Pour aborder ce sujet technique de manière structurée, cet article explore les concepts clés qui différencient une architecture IT classique d’un système de contrôle industriel fiable. Chaque section s’attaque à un problème spécifique et présente la solution adaptée.

Gigue (Jitter) : l’ennemi invisible de la précision de votre machine

Le concept de gigue, ou « jitter » en anglais, est familier dans le monde de la VoIP ou du streaming vidéo. Il désigne la variation de la latence dans la réception des paquets de données. Pour ces applications, un seuil de gigue acceptable est d’environ 30 ms avant que la qualité perçue ne se dégrade. Pour un développeur IT, c’est une métrique de qualité de service. Pour un ingénieur en automatisme, c’est un facteur de destruction de process. Dans le contrôle machine, la gigue n’est pas la variation de latence d’un réseau, mais la variation du temps de cycle d’une tâche de contrôle. Si une boucle de régulation est censée s’exécuter toutes les 1 millisecondes (ms), une gigue de 0.5 ms signifie qu’elle s’exécutera parfois à 1 ms, parfois à 1.5 ms, parfois à 0.5 ms. Ce comportement, invisible à l’œil nu, est catastrophique pour la stabilité d’un système asservi.

Cette gigue est une caractéristique intrinsèque des OS non-temps réel comme Windows ou les distributions Linux standards. Leur ordonnanceur (scheduler) est conçu pour être « équitable » : il alloue du temps CPU à de multiples processus de priorités diverses (mouvement de la souris, mise à jour de l’antivirus, rafraîchissement de l’interface graphique, etc.). Votre tâche de contrôle, même si vous lui donnez une « haute priorité », peut être préemptée à tout moment par une interruption matérielle ou une autre tâche jugée prioritaire par le système. Il n’existe aucune garantie que votre code s’exécutera à l’instant T. Le système garantit qu’il s’exécutera « éventuellement », ce qui est l’exact opposé du déterminisme requis.

L’illustration ci-dessous montre visuellement ce phénomène. Un signal d’horloge parfait a des fronts montants parfaitement équidistants. Un signal affecté par la gigue présente des fronts qui « vacillent » autour de leur position idéale, créant une incertitude temporelle qui se propage dans toute la chaîne de contrôle.

En conséquence, un asservissement de position calculé sur la base d’un cycle de 1 ms mais exécuté avec une gigue importante se comportera comme s’il recevait des consignes incohérentes. Cela peut entraîner des vibrations, des oscillations, une usure prématurée des composants mécaniques, et dans les cas extrêmes, une instabilité complète du système. Le premier pas vers un contrôle fiable est donc d’éradiquer la gigue en choisissant une plateforme d’exécution déterministe.

Quand le processeur est trop lent : déporter la boucle rapide dans un FPGA

Même avec un système d’exploitation temps réel (RTOS), il existe des scénarios où la latence logicielle reste un obstacle. Les boucles de contrôle ultra-rapides, comme la modulation de largeur d’impulsion (PWM) pour un variateur de moteur ou le traitement d’un flux de vision à très haute cadence, exigent des temps de réaction qui se mesurent en microsecondes, voire en nanosecondes. À ce niveau, la simple exécution des instructions par un processeur, même optimisé, peut devenir le goulot d’étranglement. La solution ultime pour le déterminisme est alors de sortir du monde logiciel pour entrer dans le monde matériel : le FPGA (Field-Programmable Gate Array).

Un FPGA n’est pas un processeur qui exécute des instructions les unes après les autres ; c’est un circuit intégré dont la logique interne peut être reconfigurée pour créer un circuit matériel dédié à une tâche spécifique. Au lieu d’écrire un programme, on décrit un circuit. Cette distinction est fondamentale. Une fois configuré, un FPGA exécute sa tâche en parallèle, avec une latence qui est uniquement fonction du chemin des signaux dans le silicium. Le résultat est un déterminisme quasi parfait, avec des temps de traitement qui peuvent descendre à l’ordre de la nanoseconde. Comme le souligne le bureau d’études AESTECHNO, spécialisé en conception embarquée :

Le FPGA traite les flux pixel par pixel en pipeline, sans la latence inhérente à un OS

– AESTECHNO, Bureau d’études en conception de cartes FPGA

Pour un développeur IT, l’analogie serait de passer d’un script interprété à un circuit ASIC gravé sur mesure, mais avec la flexibilité de pouvoir le reprogrammer. Déporter une fonction critique dans un FPGA, c’est la graver dans le marbre (ou plutôt, le silicium). La boucle de contrôle s’exécute indépendamment du processeur principal, qui peut alors se consacrer à des tâches moins critiques comme la communication, la supervision ou la gestion des recettes. Cette architecture hybride, combinant un CPU pour la flexibilité et un FPGA pour les contraintes temporelles dures, est la norme dans les applications de haute performance comme la simulation temps réel (HIL) ou le contrôle d’électronique de puissance.

Tâche cyclique vs Tâche de fond : comment ne pas bloquer le process critique par l’envoi d’un email ?

La clé d’un système temps réel ne réside pas seulement dans l’exécution rapide, mais dans la hiérarchisation stricte des tâches. Dans un OS généraliste, toutes les tâches sont plus ou moins en compétition pour les ressources. Dans un RTOS, une hiérarchie de priorités non-négociable est établie. On distingue fondamentalement deux types de tâches : les tâches cycliques à contrainte dure (hard real-time) et les tâches de fond ou apériodiques (soft real-time ou non real-time).

Une tâche cyclique est le cœur de la machine : la boucle de régulation du moteur, l’acquisition d’un capteur, la mise à jour d’une consigne. Elle doit s’exécuter à une fréquence fixe (ex: toutes les 2 ms) et se terminer avant son échéance. Manquer une seule échéance peut compromettre tout le process. Une tâche de fond, en revanche, est tout ce qui n’est pas temporellement critique : l’envoi d’un email de rapport, la mise à jour de l’IHM, l’archivage de données dans une base. Ces tâches doivent s’exécuter, mais un retard de quelques centaines de millisecondes est sans conséquence.

Un RTOS est conçu pour garantir que la tâche de plus haute priorité s’exécutera toujours, quitte à préempter (interrompre) instantanément une tâche de plus basse priorité. Si la tâche « Contrôle Moteur » (priorité 1) doit s’exécuter et que la tâche « Envoi Email » (priorité 10) est en cours, cette dernière est immédiatement mise en pause. Le contrôle moteur s’exécute, se termine, et seulement alors, l’envoi de l’email peut reprendre. Windows, par sa nature, ne peut offrir cette garantie absolue. Il pourrait décider de terminer une opération disque liée à l’email avant de donner la main à votre tâche de contrôle. Cette gestion des priorités est la différence fondamentale entre un système fiable et un système imprévisible.

Étude de Cas : Simulation HIL d’électronique de puissance

Dans le domaine de la simulation Hardware-in-the-Loop (HIL) pour l’électronique de puissance, le déterminisme est vital. Les systèmes basés sur FPGA, comme ceux décrits par Opal-RT, illustrent parfaitement ce principe. Le jitter d’ordonnancement est éliminé : les commandes de commutation PWM atteignent les convertisseurs simulés sans aucune variation temporelle. En retour, les mesures de courant arrivent précisément à temps pour rester synchronisées avec le cycle d’échantillonnage. Plus important encore, un chemin de protection (par exemple, une surintensité) se déclenche exactement au même instant à chaque exécution, garantissant un comportement déterministe et reproductible, chose impossible à garantir avec un ordonnanceur non-temps réel.

Synchroniser 10 axes sur Ethernet : pourquoi le protocole NTP ne suffit pas (vive IEEE 1588) ?

Lorsqu’une machine complexe implique plusieurs variateurs, capteurs et contrôleurs qui doivent collaborer, la problématique du temps réel s’étend du contrôleur unique au réseau tout entier. La question devient : comment s’assurer que 10 moteurs démarrent leur mouvement exactement au même instant ? L’approche IT classique serait d’utiliser le protocole NTP (Network Time Protocol) pour synchroniser les horloges de chaque appareil sur un serveur de temps. Pour de la synchronisation de serveurs de fichiers, c’est parfait. Pour du contrôle d’axes, c’est totalement insuffisant.

NTP offre typiquement une précision de l’ordre de quelques millisecondes sur un réseau local bien géré. Ce « quelques millisecondes » est une éternité en contrôle de mouvement. Un décalage de 2 ms entre deux axes qui doivent suivre une trajectoire coordonnée (interpolation) se traduit par une erreur de contour inacceptable. Le problème de NTP est qu’il ne compense pas la latence de manière déterministe et ne prend pas en compte les délais de traitement variables dans les piles réseau des différents appareils. La solution industrielle se nomme IEEE 1588, aussi connu sous le nom de PTP (Precision Time Protocol).

Ce protocole, au cœur de bus de terrain comme EtherCAT, PROFINET IRT ou Sercos III, est conçu pour la synchronisation de haute précision. Grâce à un mécanisme d’estampillage temporel (timestamping) au niveau matériel, PTP peut compenser les retards de propagation et de traitement avec une précision extrême. Les protocoles industriels basés sur ce standard, comme EtherCAT avec son mécanisme d’horloges distribuées (Distributed Clocks), atteignent une synchronisation sur l’ensemble du réseau de l’ordre de la nanoseconde. Cela signifie que tous les esclaves du réseau partagent une base de temps commune avec une gigue inférieure à la microseconde.

Grâce à cette synchronisation, il devient possible de déclencher des actions (comme l’acquisition d’une mesure ou le démarrage d’un mouvement) à un instant précis sur l’ensemble des équipements. C’est ce qui permet de réaliser des applications de « Motion Control » complexes avec une coordination parfaite, chose impensable avec des technologies réseau IT standards.

Surcharge processeur : comment optimiser le code pour repasser sous les 80% de charge ?

Dans un système temps réel, la charge CPU n’est pas qu’un indicateur de performance, c’est un indicateur de stabilité. Une règle empirique courante est de ne jamais dépasser 80% de charge CPU dans le pire des cas. Au-delà, le risque de manquer une échéance (deadline) augmente de façon exponentielle, car l’ordonnanceur n’a plus aucune marge de manœuvre pour gérer les interruptions ou les tâches imprévues. Si votre application flirte avec cette limite, l’optimisation n’est pas une option, c’est une nécessité. Pour un développeur IT, cela passe souvent par l’optimisation d’algorithmes (passer de O(n²) à O(n log n)) ou l’ajout de cache. En embarqué, les techniques sont différentes et plus proches du matériel.

Une des optimisations les plus efficaces concerne l’arithmétique. Les CPU des systèmes embarqués sont souvent dépourvus d’unité de calcul en virgule flottante (FPU) matérielle, ou celle-ci est moins performante que l’unité de calcul sur les entiers (ALU). Les calculs en virgule flottante (avec `float` ou `double`) sont alors émulés par logiciel, ce qui est extrêmement coûteux en cycles d’horloge. La solution est de passer à une arithmétique en virgule fixe. Cela consiste à représenter des nombres décimaux en utilisant des entiers, en définissant implicitement la position de la virgule. Bien que cela demande plus de rigueur au développeur (gestion des dépassements, mise à l’échelle), le gain est spectaculaire. Le passage de la virgule flottante à la virgule fixe peut rendre une opération arithmétique de 10 à 50 fois plus rapide.

D’autres techniques incluent le « loop unrolling » (dérouler les boucles pour éviter les sauts conditionnels coûteux), l’utilisation de tables de consultation (look-up tables) pour remplacer des calculs complexes (comme `sin` ou `cos`), ou encore l’optimisation des accès mémoire pour maximiser l’efficacité du cache du processeur. L’objectif n’est pas seulement de rendre le code plus rapide en moyenne, mais de réduire son WCET (Worst-Case Execution Time), c’est-à-dire le temps d’exécution maximal dans le pire scénario possible. C’est cette valeur qui détermine si votre tâche respectera toujours son échéance.

Plan d’action : Audit d’optimisation de la charge CPU

  1. Profilage : Utilisez un profiler pour identifier les fonctions qui consomment le plus de temps CPU. Ne devinez pas, mesurez.
  2. Analyse de l’arithmétique : Listez toutes les opérations en virgule flottante dans les boucles critiques. Évaluez la faisabilité de leur conversion en virgule fixe.
  3. Analyse des algorithmes : Pour les fonctions coûteuses, recherchez des alternatives. Une table de consultation peut-elle remplacer un calcul trigonométrique ? Un filtre IIR peut-il être remplacé par un filtre FIR plus simple ?
  4. Optimisation compilateur : Vérifiez les options d’optimisation de votre compilateur (-O2, -O3). Assurez-vous qu’elles sont activées et comprenez leur impact sur le code généré.
  5. Mesure du WCET : Utilisez des outils d’analyse statique ou des mesures sur cible pour estimer le WCET de vos tâches critiques après optimisation et vérifier qu’il reste inférieur à la période de la tâche.

Le réglage de gain (Tuning) : comment supprimer le sifflement du moteur à l’arrêt ?

Un symptôme classique d’un problème de temps réel dans une boucle d’asservissement est un moteur qui « siffle » ou « grésille » à l’arrêt. Le moteur est censé être immobile, maintenu en position par la boucle de régulation (généralement un PID), mais il émet un bruit aigu. Ce phénomène, souvent déroutant pour un néophyte, n’est pas un problème matériel, mais la manifestation physique de l’instabilité de la boucle de contrôle. Le contrôleur, essayant de corriger des erreurs de position fantômes, envoie des micro-commandes oscillantes au variateur, faisant vibrer le moteur à haute fréquence.

La cause première est souvent une boucle de régulation mal réglée (gains du PID trop élevés). Cependant, même avec des gains corrects, la gigue du système d’exploitation peut être le coupable. Si le calcul du PID et l’envoi de la consigne n’interviennent pas à des intervalles parfaitement réguliers, le contrôleur réagit à des informations de position ou de vitesse qui ne sont pas « fraîches » ou qui sont décalées dans le temps. Le régulateur « sur-réagit » en permanence à ces incohérences temporelles, créant des oscillations. Le timing déterministe est donc un prérequis absolu pour un réglage de gain (tuning) stable et performant.

Déboguer ce type de comportement sur un système non-déterministe est un cauchemar. Le sifflement peut apparaître et disparaître en fonction de la charge CPU ou d’autres activités du système, rendant le problème non reproductible. C’est pourquoi le passage à un RTOS ou à une logique FPGA est souvent la seule solution viable. Dans un environnement déterministe, le comportement de la boucle de contrôle devient prévisible. Le réglage des gains P, I et D a un effet direct et reproductible sur le comportement du moteur. On peut alors se concentrer sur l’optimisation de la réponse du système (temps de montée, dépassement) sans être pollué par le bruit temporel généré par l’OS. Le silence du moteur à l’arrêt devient alors le premier signe d’un système temps réel sain.

Ladder, ST ou Grafcet : quel langage pour quelle fonction de la machine ?

Une fois la plateforme matérielle et le système d’exploitation choisis, le développeur doit sélectionner le bon outil pour programmer la logique applicative. Le monde de l’automatisme, standardisé par la norme IEC 61131-3, offre plusieurs langages, chacun avec ses forces et ses faiblesses. Choisir le mauvais langage pour une tâche donnée peut conduire à un code illisible, peu performant ou difficile à maintenir. Un développeur IT, habitué à des langages comme C++, Java ou Python, découvrira ici un nouvel univers.

Le Ladder Diagram (LD) est le langage historique des automaticiens. Visuel, il ressemble à un schéma électrique et est extrêmement efficace pour la logique booléenne simple (gestion de contacts, verrouillages de sécurité). Sa lisibilité est excellente pour le personnel de maintenance. Cependant, il est très mal adapté aux algorithmes complexes ou aux mathématiques. Le Grafcet, ou SFC (Sequential Function Chart), est également un langage graphique, idéal pour décrire des processus séquentiels (des cycles machine avec des étapes et des transitions). Il permet de visualiser l’état de la machine d’un seul coup d’œil.

Pour le développeur IT, le langage le plus familier sera le Structured Text (ST), ou Texte Structuré. C’est un langage de haut niveau, impératif, ressemblant au Pascal ou au C. C’est le langage de choix pour tout ce qui est algorithmique : boucles de régulation (PID), calculs de cinématique inverse pour les robots, filtrage de signaux, etc. Il offre la meilleure performance pour les tâches mathématiques intensives et permet d’implémenter des logiques complexes qui seraient cauchemardesques en Ladder. Enfin, les Function Blocks (FB) permettent de créer des composants logiciels réutilisables, encapsulant une logique (écrite en ST ou autre) dans une « boîte noire » avec des entrées et des sorties, un concept très proche de la programmation orientée objet.

Une architecture machine robuste n’utilise jamais un seul langage, mais une combinaison intelligente de plusieurs. Le tableau suivant synthétise les cas d’usage optimaux pour chaque langage.

Comparaison des langages IEC 61131-3 par fonction et performance
Langage Fonction optimale Lisibilité Performance temps réel Cas d’usage typique
Ladder (LD) Logique de sécurité simple Excellente (visuel) Moyenne Arrêts d’urgence, verrouillages
Grafcet/SFC Processus séquentiel Très bonne (graphique) Moyenne Cycles machines, enchaînement d’étapes
Structured Text (ST) Boucle de contrôle < 1ms Bonne (texte) Excellente PID, cinématique inverse, filtrage
Function Blocks (FB) Réutilisabilité Très bonne Bonne à excellente Encapsulation d’algorithmes complexes

À retenir

  • Le déterminisme (prédictibilité temporelle) est plus important que la vitesse brute pour le contrôle machine.
  • Les OS généralistes comme Windows génèrent une gigue (jitter) qui rend impossible la synchronisation précise.
  • Les solutions résident dans l’utilisation d’OS temps réel (RTOS), de logiques déportées sur FPGA et de protocoles réseau déterministes comme EtherCAT.

Chronomètre vs Log de l’automate : pourquoi vous ne mesurez pas la même chose que la machine ?

L’un des derniers pièges pour un développeur IT abordant le temps réel est la mesure de la performance. Habitué à utiliser des logs applicatifs ou des chronomètres pour mesurer le temps d’exécution d’une fonction, il pourrait appliquer la même méthode sur un automate. L’erreur est de croire que l’horodatage (`timestamp`) d’un log écrit par une tâche de fond sur un système de fichiers reflète la réalité temporelle de la machine. Entre le moment où un événement physique se produit et celui où son log est enregistré, une éternité s’est écoulée à l’échelle de la machine.

L’événement (ex: un capteur qui change d’état) est d’abord traité par le matériel d’E/S, puis par le bus de terrain. Un esclave EtherCAT, par exemple, traite une trame avec un délai inférieur à 100 nanosecondes. L’information remonte ensuite au contrôleur, qui exécute la tâche cyclique concernée. C’est seulement après tout cela qu’une tâche de fond, de basse priorité, pourra éventuellement récupérer cette information pour l’écrire dans un fichier de log. Ce processus peut prendre plusieurs millisecondes et est, par nature, non-déterministe. Le log vous dira quand le système a *su* que l’événement a eu lieu, pas quand il a *réellement* eu lieu.

La seule mesure fiable est celle effectuée au plus près de l’action, grâce aux mécanismes temps réel eux-mêmes. Les systèmes modernes permettent d’utiliser les horloges distribuées et synchronisées (via IEEE 1588) pour horodater les événements directement au niveau des modules d’E/S ou des variateurs. Un oscilloscope ou un analyseur de bus de terrain sont les seuls outils externes capables de visualiser la véritable chronologie des signaux électriques. Mesurer un temps de cycle avec un chronomètre manuel ou un log applicatif revient à essayer de mesurer l’épaisseur d’un cheveu avec une règle d’écolier : l’outil de mesure est des ordres de grandeur moins précis que le phénomène mesuré. Pour comprendre sa machine, il faut adopter ses outils et son échelle de temps : la microseconde.

En définitive, la transition du développement IT vers le contrôle industriel est moins une question d’apprendre un nouveau langage qu’un changement complet de paradigme. Il faut abandonner l’obsession de la puissance brute pour embrasser la discipline du déterminisme. Pour mettre en pratique ces concepts, l’étape suivante consiste à auditer votre application avec une grille d’analyse temps réel, en vous focalisant sur la gigue, le respect des échéances et la hiérarchisation des tâches.

Questions fréquentes sur le pilotage temps réel

Quelle est la principale différence entre un OS temps réel (RTOS) et Windows ?

La différence fondamentale est la prédictibilité. Un RTOS garantit qu’une tâche de haute priorité s’exécutera avant une échéance définie, en préemptant toute tâche moins prioritaire. Windows est conçu pour le partage équitable des ressources et ne fournit aucune garantie temporelle, ce qui génère de la gigue (jitter) et le rend inadapté au contrôle machine précis.

Puis-je rendre Windows temps réel ?

Non, pas nativement. L’architecture de son noyau, de ses pilotes et de son ordonnanceur n’est pas conçue pour le déterminisme. Il existe des extensions tierces (comme des hyperviseurs temps réel) qui exécutent un RTOS à côté de Windows, dédiant des cœurs de processeur au temps réel. Dans ce cas, ce n’est plus Windows qui pilote la machine, mais bien le RTOS qui s’exécute en parallèle.

Rédigé par Thomas Le Gall, Architecte système et expert en convergence IT/OT, spécialisé dans l'interconnexion des automates et l'Industrie 4.0.