URL:     https://linuxfr.org/users/unetanche/journaux/alternative-libre-a-matlab
Title:   Alternative libre à MATLAB
Authors: uneTanche
Date:    2026-10-07T12:08:27+02:00
License: CC By-SA
Tags:    python et matlab
Score:   8


# Avant-propos

Je ne suis pas un spécialiste de l'automatique, au mieux un amateur éclairé. J'ai eu besoin de mettre au point différents régulateurs pour des projets de contrôle moteur et je trouvais qu'il manquait d'exemples/retour d'expérience sur les alternatives à MATLAB (en français). C'est dans ce cadre que je vous propose cette synthèse subjective des solutions que j'ai testées.

L'article original est disponible [ici](https://www.ylbn.fr/blog/automatique_pycontrol/)

# Intro

Dans cet article, je dresse un bilan de ma recherche de solution
alternative à [matlab/simulink](https://fr.wikipedia.org/wiki/Simulink) pour la simulation d'algorithme de contrôle/régulation.

> **Pourquoi simuler?**
>La mise au point d'asservissement ou de régulation comporte des risques. Il y a notamment un risque d'instabilité qui peut entraîner la destruction du  système. Ce qui peut s'avérer coûteux et même parfois dangereux pour l'opérateur. Donc pour limiter les risques lors de la conception, on réalise sa mise au point via **une simulation numérique**.

Commençons par une petite mise en contexte. Si vous n'avez aucune idée de ce qu'est l'**automatique**, je vous laisse aller lire [l'article wikipédia](https://fr.wikipedia.org/wiki/Automatique). C'est un vaste domaine qui couvre notamment, l'asservissement et la régulation de systèmes.

Un exemple: le fait d'attraper un objet avec ses doigts peut-être représenté
comme un montage en *asservissement*. Le capteur est l'oeil, l'actionneur le
bras et le cerveau le centre de calcul. La méthode classique pour documenter
ce type de fonctionnement est de le représenter sous la forme d'un **schéma fonctionnel**:

![Schéma fonctionnel de la prise d'un objet avec la main](https://www.ylbn.fr/blog/automatique_pycontrol/prise_objet.png)

Ce type de schéma permet de mettre en évidence les boucles de rétro-action ainsi que les différents éléments composant le système et leur interface avec le monde extérieur.

Pour prendre un autre exemple, plus concret, on va s'intéresser à la régulation en vitesse d'un moteur DC. Il servira aussi de référence tout au long de cet article. Son schéma fonctionnel est le suivant:

![Schéma fonctionnel moteur DC](https://www.ylbn.fr/blog/automatique_pycontrol/diag-motordc.png)


# La simulation en automatique

Commençons par définir nos attentes quant aux solutions de simulation. Pour ma part, j'ai deux critères principaux:

 1. De bien simuler! Là c'est le rôle du solveur. Ce n'est pas vraiment mon    domaine alors je ne rentre pas dans les détails
 2. D'être lisible. Comme on l'a dit en introduction, en automatique beaucoup de choses sont représentées sous la forme de schéma fonctionnel. Donc il est nécessaire de pouvoir rapidement faire la correspondance entre le code et le schéma

On pourrait aussi citer la rapidité, l'observabilité ou encore la facilité
d'itération/modification, mais tous ces points sont plus ou moins liés au solveur et son interface.

Pour effectuer une comparaison des différentes solutions, on va se baser sur notre exemple d'asservissement et régulation en vitesse d'un moteur DC. Un cas d'application concret pourrait être le pilotage du moteur de brosse d'un
aspirateur sans fil.

On représente ce pilotage par le schéma suivant:

![Schéma fonctionnel moteur DC](https://www.ylbn.fr/blog/automatique_pycontrol/diag-motordc.png)

On définit la fonction de transfert du moteur dans le domaine de *Laplace* tel que:

$$I(s) = \frac{U(s) - Ke\Omega_m}{Ls+R}$$

Avec:
 - I: le courant traversant le moteur (A)
 - U: la tension aux bornes du moteur (V)
 - Ke: la force électromotrice (V/rad/s)
 - Ohmega_m: la vitesse de l'arbre du moteur (rpm)
 - L: l'inductance du moteur (H)
 - R: la résistance du moteur (Ohm)

$$Cem = Kt \times I(s)$$

Avec:
 - Kt: la constante de couple (N.m/A)

$$\frac{\Omega_m}{Cem - Cr}=\frac{1}/{Js+Kf}$$


Avec:
 - Cem: le couple électromagnétique (N.m)
 - J: le moment d'inertie (kg.m²)
 - Kf: les frottements visqueux (N.m.s)

On en profite pour définir aussi la fonction de transfert du régulateur PID:

$$PID = Kp+ \frac{Ki}{s} + sKd$$

Je ne rentre pas dans les détails de ces fonctions de transferts, ni même sur ce qu'est une fonction de transfert. Dans notre cas, on peut la considérer comme le modèle virtuel de notre moteur. En les intégrant au schéma fonctionnel précédent on obtient le schéma suivant:

![Schéma fonctionnel détaillé moteur DC](https://www.ylbn.fr/blog/automatique_pycontrol/diag-fulldc.png)

Maintenant que nous avons défini notre exemple, nous allons implémenter ce système avec différents outils et en comparer l'utilisation. Vu que le logiciel MATLAB/simulink est la référence dans le domaine, on va commencer par lui.

## Matlab/simulink

Commençons par quelques définitions.

- *MATLAB* c'est le nom d'un langage de script, mais aussi celui de son environnement de développement. *MATLAB* a été conçu pour manipuler des matrices et afficher des courbes
- *Simulink* est un logiciel de modélisation de système dynamique reposant    sur *MATLAB*. Il permet de créer des programmes sous la forme de schéma/ blocs

Pour schématiser grossièrement, MATLAB est le moteur et simulink l'interface
utilisateur.

Maintenant que les présentations sont faites, passons à la mise en place de
notre exemple. *MATLAB* n'étant pas un logiciel libre, une licence est requise pour son utilisation. Heureusement pour moi, l'éditeur propose une offre découverte gratuite à utiliser via une interface web (utilisation limitée à 20h/mois). Donc on ouvre MATLAB, on lance simulink et on rentre l'équivalent schéma fonctionnel précédent, ce qui nous donne:

![Régulation moteur avec simulink](https://www.ylbn.fr/blog/automatique_pycontrol/mathlab_motor_note.png)

L'annotation en rouge est un ajout de ma part. Mais on remarque tout de suite l'un des points forts de *simulink*, son interface permet de faire un *programme* ayant une mise en forme proche du diagramme fonctionnel.

Un exemple de résultat de simulation, en jaune la consigne de vitesse et en bleu la vitesse du moteur. On peut visualiser ces valeurs grâce à la sonde nommée "*Visualisation*" sur notre schéma.

![Résultas simulation](https://www.ylbn.fr/blog/automatique_pycontrol/mathlab_simu.png)

> **Remarque**
>Dans notre capture d'écran, l'on peut voir que nous avons utilisé des variables (kt, L, R...) dans les blocs que fonction de transfert. Un des inconvénients de MATLAB est que ces variables ne peuvent pas être facilement définies dans *simulink*. Le plus simple étant de créer un "*workspace*" dans MATLAB dans lequel on définit et assigne nos variables. Il faudra simplement penser à activer ce workspace avant de lancer notre simulation à la prochaine ouverture de MATLAB.
>![MATLAB workspace](https://www.ylbn.fr/blog/automatique_pycontrol/workspace.png)

## Scilab/xcos

Lorsque l'on cherche une alternative open source à *MATLAB/simulink* [Scilab](https://www.scilab.org/) est LA solution évidente. En effet, ces deux solutions ont une interface utilisateur très proche ainsi qu'un langage de script assez similaire. Puisqu'une image vaut mille mots l'implémentation de notre exemple via *scilab/xcos* sera sans doute plus parlant:

![Régulation moteur avec Xcos](https://www.ylbn.fr/blog/automatique_pycontrol/scilab_motor.png)

La ressemblance avec *simulink* est frappante même si à l'utilisation les deux interfaces ne sont pas strictement identiques. Un avantage qu'offre *xcos*, est d'intégrer la gestion du contexte (les variables comme Ke, L ou R) directement dans le fichier de schéma-blocs. Pas besoin de créer de workspace comme sous MATLAB.

Cette solution est donc parfaitement viable.  Cependant, *xcos* souffre d'un bug particulièrement pénible: [l'instabilité des liaisons entre les blocs](https://gitlab.com/scilab/scilab/-/work_items/17373). Il n'est pas rare de rouvrir un projet de découvrir qu'une ou plusieurs liaisons ne suivent plus le routage original mais ont été remplacés par une liaison directe entre les
points d'encrage. Ceci rend le schéma nettement moins lisible, nous obligeant à refaire les liaisons lorsque ça arrive...

![bug xcos](https://www.ylbn.fr/blog/automatique_pycontrol/bug_xcos.png)

Une autre limite de cette solution, par rapport à *MATLAB*, est la petitesse
de sa bibliothèque de blocs comparée aux bibliothèques disponibles sur simulink. Mais tous ces défauts ne sont pas immuables et seront sans doute corrigés à l'avenir.

## Python/Jupyter

Avec cet outil, je vous propose une autre approche, plutôt que d'écrire un
programme par schéma-bloque afin qu'il ressemble au schéma fonctionnel de la
documentation, nous allons intégrer le code dans la documentation. Ou la
documentation dans le code c'est vous qui voyez!

Cette alternative repose sur un ensemble de logiciels dont les principaux sont:
 - [pyton](https://python.org) le langage de programmation
 - [Jupyter](https://jupyter.org) l'interface graphique
 - [control](https://python-control.readthedocs.io/),
   [numpy](https://numpy.org) et [mathplotlib](https://matplotlib.org/)
   les bibliothèques scientifiques permettant
   de résoudre les équations, manipuler et afficher les données

### Présentation
Comme je le disais en introduction, le principe de cette solution est de
mélanger documentation et code. Pour être honnête, c'est le principe même de
Jupyter, mais on va voir comment l'appliquer dans notre cas.
On va donc enchaîner les parties documentations au format markdown et le code en python (on peut d'ailleurs utiliser d'autres langages, mais je n'ai pas étudié cette possibilité).

![Présentation](https://www.ylbn.fr/blog/automatique_pycontrol/jupyter_1.png)

Dans cet exemple, on commence par un petit texte permettant de contextualiser le projet (1). On enchaîne ensuite avec l'importation des bibliothèques python nécessaires au projet (2). S'ensuit des explications plus précises quant au projet et le schéma fonctionnel permettant de le représenter (3). Enfin on termine la mise en contexte par la définition des différentes variables (4).


### Modélisation du moteur DC
Cette approche a un gros inconvénient, elle est bien moins intuitive que
la programmation par blocs. Cependant, elle offre d'autres avantages, comme
une plus grande évolutivité et une plus grande souplesse dans la conception.
Elle permet aussi de tester/valider des sous-ensembles sans devoir refaire le programme.

Par exemple, plutôt que d'écrire le code pour l'ensemble de la simulation,
on peut commencer par faire *super-bloc* moteur qui inclut ses différents
composants:

![Super-bloc moteur](https://www.ylbn.fr/blog/automatique_pycontrol/super-bloc-moteur.png)

On remarque tout de suite que la courbe d'apprentissage de la bibliothèque
`control` est plus raide que celle de *simulink* ou *xcos*. En particulier lorsqu'il s'agit de connecter les blocs entre eux (fonction `ct.interconnect(...)`).

Mais une fois cette difficulté surmontée, nous disposons maintenant un composant `moteur` ayant pour entrées `U` et `Cr` et pour sortie `vitesse` et que nous pouvons réutiliser à notre guise.

On peut donc facilement valider le comportement du moteur en boucle ouverte
lorsqu'on le soumet à un échelon de tension de 10V:

![Moteur DC en boucle ouverte](https://www.ylbn.fr/blog/automatique_pycontrol/jupyter_motor_openloop.png)

Pour faire cet essai dans *simulink* ou *xcos* nous aurions dû créer un
nouveau projet et y intégrer les blocs moteur, la commande de tension et
une sonde de mesure et ensuite alterner entre les projets en fonction des
modifications/validations à réaliser.

Cette modularité est donc très appréciable. Pour aller plus loin, on pourrait créer un fichier python séparé dans lequel on placerait notre composant moteur. Ainsi nous pourrions facilement le réutiliser dans différents projets.

### Modélisation du régulateur
On peut maintenant passer au bloc du régulateur PID, enfin dans notre cas c'est seulement un PI, le terme dérivé étant nul.

![Bloc de régulation PI](https://www.ylbn.fr/blog/automatique_pycontrol/jupyter_pi.png)

### Simulation complète

Nous avons maintenant tous les sous-ensembles nécessaires à la simulation de la régulation en vitesse du moteur DC. On commence donc par faire un rappel du système avec un schéma fonctionnel sans détails (1). Puis, on passe à la connexion des blocs et des entrées/sorties en python (2).

![Régulation moteur](https://www.ylbn.fr/blog/automatique_pycontrol/jupyter_total.png)

Enfin on peut afficher la réponse à un échelon de notre système. Dans notre exemple nous allons observer le comportement du moteur+asservissement pour une commande de vitesse de 1000 tr/min avec un couple résistant à zéro. Notre simulation durera une seconde avec un pas de temps 100 µs.

![Réponse du système](https://www.ylbn.fr/blog/automatique_pycontrol/jupyter_result.png)

Ce notebook est disponible [sur codeberg](https://codeberg.org/tanche/DemoPyControl).

# Bilan

Après avoir testé trois solutions différentes pour faire de l'automatique, quel est le bilan ?

 - MATLAB/Simulink
   - Avantages:
     - Standard de l'industrie
     - Programmation graphique proche du schéma fonctionnel
     - Large bibliothèque de composants
     - Nombreux exemples disponibles
   - Inconvénients:
     - Non open source
     - Nouveau langage à apprendre (MATLAB)
     - format fichier peu adapté au versionnage (simulink)
 - Scilab/Xcos
   - Avantages:
     - Open Source
     - Programmation graphique proche du schéma fonctionnel
   - Inconvénients:
     - Nouveau langage à apprendre
     - versionnage
     - Bugs sur les liens (xcos) pénibles
 - Jupyter/control
   - Avantages:
     - langage python
     - Modularité, on peut facilement faire ses bibliothèques de composants
     - Open source
     - simple fichier texte, facile à versionner
   - Inconvénients:
     - Courbe d'apprentissage plus raide
     - Moins visuel, relecture plus difficile
     - Communauté plus petite, donc moins de ressources

Avec cet article, je souhaitais partager mon expérience sur la recherche d'une solution open source pour l'automatique. Il y a évidemment l'incontournable Scilab/Xcos mais pas seulement. Pour les personnes qui, comme moi, sont plus à l'aise avec du texte qu'avec une interface graphique, d'autres solutions existent. Ici par exemple, on arrive en combinant l'éditeur *Jupyter* et quelques bibliothèques python, à avoir une solution offrant documentation et calculs.

Cette solution n'est pas sans inconvénients, notamment l'intégration de matplotlib dans jupyter qui n'est pas trivial... Mais elle offre aussi de nombreux avantages. Comme la facilité de créer des bibliothèques de composants, versionner efficacement le code et la documentation ...

Pour ce qui est du versionnage, le code des bibliothèques est en python, la question ne se pose même pas et la partie *notebook* quant à elle est un fichier JSON, donc du texte. Cette solution vous permettra donc de gérer finement le versionnage de vos projets.

# Autres pistes

Il existe encore d'autres solutions aux trois que j'ai étudiées ici, j'en ai trouvé une qui me convient alors je ne me suis pas attardé dessus mais si vous êtes intéressé voici une liste de celle que j'ai trouvées:

 - [OpenModelica](https://openmodelica.org/)
 - [octave](https://octave.org/)
 - [Julia](https://julialang.org/)

Il existe certainement encore d'autres solutions que je ne connais pas...

