TP – Régulation du niveau d'une cuve
GEII 2e année · Programmation en C · Communication MQTT
1. Objectif
Vous devez écrire un programme en C qui maintient le niveau d'eau d'une cuve autour d'une consigne, en commandant quatre pompes à distance. Votre programme dialogue avec un simulateur par l'intermédiaire d'un broker MQTT. Chaque étudiant dispose de sa propre cuve et de ses propres pompes, mais tous les étudiants ont exactement le même système et le même scénario : vos résultats sont donc comparables, et un classement sera établi.
2. Le système à réguler
- Une cuve de hauteur limitée peut contenir de l'eau. Si le niveau dépasse la hauteur de la cuve, elle déborde ; si elle se vide, elle est à sec.
- Un capteur unique mesure la hauteur d'eau, en mètres. C'est la seule information dont vous disposez.
- La cuve se vide en permanence avec un débit de sortie imposé par le scénario. Ce débit peut varier au cours du temps et vous ne le connaissez pas.
- Quatre pompes remplissent la cuve. Chaque pompe est commandée en tout ou rien : marche ou arrêt. Quand elle tourne, elle fournit un débit nominal fixe.
La difficulté est que l'entrée est discrète (vous ne pouvez pas régler finement le débit d'entrée) alors que la sortie est fluctuante.
Ce que les pompes ne vous disent pas
Les quatre pompes sont différentes et leurs caractéristiques ne vous sont pas communiquées. Elles ont notamment :
- des débits nominaux différents ;
- une latence : un ordre de marche ou d'arrêt n'a d'effet qu'après un certain délai ;
- une montée progressive du débit vers sa valeur nominale après le démarrage, et une descente progressive à l'arrêt ;
- une limite d'usure : après un certain nombre de démarrages ou un certain temps de fonctionnement, la pompe s'arrête définitivement et ne peut plus être redémarrée.
Le simulateur ne signale pas qu'une pompe est hors service : c'est à vous de le déduire de l'évolution du niveau. Vous devrez donc découvrir par l'expérience le comportement des pompes, et tenir compte de leur usure.
3. Communication MQTT
Votre programme communique avec le simulateur par des messages texte. Dans les noms de topics, <id> est votre identifiant (il vous est donné par l'enseignant).
| Topic | Sens | Contenu |
|---|---|---|
cuve/<id>/go | vous → simulateur | numéro du scénario, par exemple 1 |
cuve/<id>/pompe/<n>/cmd | vous → simulateur | 1 pour mettre la pompe n en marche, 0 pour l'arrêter (n de 1 à 4) |
cuve/<id>/consigne | simulateur → vous | consigne de niveau, en mètres |
cuve/<id>/niveau | simulateur → vous | niveau d'eau mesuré, en mètres, publié régulièrement |
cuve/<id>/fin | simulateur → vous | bilan de fin de scénario |
Les valeurs sont des nombres écrits en texte, par exemple 0.873.
4. Déroulement d'une exécution
- Vous lancez votre programme avec votre identifiant et le numéro du scénario.
- Votre programme envoie le message Go au simulateur.
- Le simulateur initialise votre cuve avec un niveau de départ, arrête toutes les pompes, charge le scénario et vous envoie la consigne puis le niveau.
- À chaque nouveau niveau reçu, votre programme décide quelles pompes doivent tourner et envoie les ordres correspondants.
- À la fin du scénario, le simulateur vous envoie un bilan et enregistre vos résultats.
Le temps de la simulation est accéléré par rapport au temps réel : n'utilisez pas vos propres temporisations (sleep) pour cadencer la régulation, laissez-vous cadencer par l'arrivée des mesures. Relancer votre programme envoie un nouveau Go et remet votre cuve à zéro.
5. Travail demandé
Un programme de départ, regulation_cuve.c, gère déjà la connexion, l'envoi du Go et la réception des messages. Vous devez écrire le contenu de la fonction regulation(), appelée à chaque nouvelle mesure du niveau. Pour commander une pompe, utilisez commande_pompe(n, etat).
Le programme fourni ne suffit pas à tenir la consigne : il commande uniquement la pompe 1, avec une hystérésis.
Exercice 1 – Débit de sortie constant (scénario 1)
Le débit de sortie de la cuve est constant. Concevez une régulation qui maintient le niveau le plus près possible de la consigne pendant tout le scénario.
Pour cela, vous devrez notamment :
- identifier, par des essais, le comportement des pompes (laquelle est la plus puissante ? laquelle réagit le plus vite ?) ;
- trouver une combinaison de pompes qui compense le débit de sortie ;
- limiter le nombre de démarrages et le temps de marche de chaque pompe pour qu'elles ne tombent pas en panne avant la fin.
Exercice 2 – Débit de sortie sinusoïdal (scénario 2)
Le débit de sortie varie maintenant de façon sinusoïdale autour d'une valeur moyenne. Adaptez votre régulation pour suivre ces variations.
Pensez à anticiper : à cause de la latence et de l'inertie des pompes, réagir seulement quand le niveau s'écarte de la consigne est souvent trop tard. Observez la tendance du niveau (sa dérive d'une mesure à l'autre).
6. Évaluation
À la fin de chaque exécution, le simulateur calcule un bilan, que vous recevez dans le message fin. Votre régulation est jugée sur :
| Critère | Ce qu'il mesure |
|---|---|
iae | écart cumulé entre le niveau et la consigne (plus c'est petit, mieux c'est) |
ecart_max | écart maximal à la consigne, en mètres |
dans_tolerance | pourcentage du temps passé dans la zone de tolérance autour de la consigne |
demarrages | nombre total de démarrages de pompes (à limiter) |
debordement_s | temps pendant lequel la cuve a débordé (à éviter) |
a_sec_s | temps pendant lequel la cuve était à sec (à éviter) |
pompes_hs | nombre de pompes tombées en panne (à éviter) |
7. Compilation et lancement
Pour compiler :
clang -Wall -o regulation_cuve regulation_cuve.c -lmosquitto -lm
Pour lancer le programme :
./regulation_cuve <identifiant> <numéro du scénario>
Par exemple : ./regulation_cuve dupont 1.
Les paramètres de connexion au broker (MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASS) sont lus dans les variables d'environnement ; ils vous sont fournis par l'enseignant.
8. Conseils
- Faites d'abord des essais simples (une seule pompe, puis deux…) en affichant les niveaux pour comprendre les pompes avant de concevoir votre régulation.
- Affichez dans votre programme ce que vous décidez et pourquoi : cela facilite la mise au point.
- Une hystérésis évite les démarrages et arrêts incessants, qui usent les pompes.
- Les pompes ne sont pas interchangeables : ne les sollicitez pas toutes de la même façon.
- Pour observer les messages ou envoyer une commande à la main, vous pouvez utiliser
mosquitto_subetmosquitto_pubsi ces outils sont installés.