2025-01-11
Implémenter la communication inter-modules pour que le sequencer demande automatiquement un autofocus au module focus lorsque le filtre change pendant une séquence d'imagerie.
Le sequencer ne pouvait pas communiquer avec le focus car les connexions directes entre modules étaient commentées dans controller.cpp.
A. Modification de controller.cpp (CRITIQUE)
- Fichier :
OST/src/controller.cpp - Lignes 185-186 décommentées :
connect(othermodule, &Basemodule::moduleEvent, mod, &Basemodule::OnExternalEvent);
connect(mod, &Basemodule::moduleEvent, othermodule, &Basemodule::OnExternalEvent);- Impact : Active la communication directe entre tous les modules
B. Modification de sequencer
Fichiers modifiés :
OST-modules/src/modules/sequencer/sequencer.hOST-modules/src/modules/sequencer/sequencer.cppOST-modules/src/modules/sequencer/sequencer.json
Fonctionnalités ajoutées :
- Détection de changement de filtre dans
StartLine() - Paramètre configurable
autofocusonfilterchange(bool, défaut: false) - Paramètre configurable
focusmodule(string, défaut: "focus") pour choisir l'instance - Variable
mWaitingForFocuspour bloquerShoot()pendant le focus - Méthode
requestFocus()émettant événement"requestautofocus" - Méthode
OnFocusDone()recevant événement"focusdone" - Vérification
&& !mWaitingForFocusdansupdateProperty()etnewProperty()pour bloquer shoot
C. Modification de focus
Fichier modifié :
OST-modules/src/modules/focus/focus.cpp
Fonctionnalités ajoutées :
- Traitement de l'événement
"requestautofocus"dansOnMyExternalEvent() - Appel direct à
startCoarse()sans passer par le mécanisme setValue() - Émission de l'événement
"focusdone"dansSMFocusDone()avec résultats (HFR, position)
Fichiers créés/modifiés :
OST-modules/SEQUENCER_IMPROVEMENTS.md: Documentation complète de la fonctionnalitéOST/CLAUDE.md: Section "Module Communication" mise à jour avec explications critiquesOST-modules/RESUME_SESSION.md: Ce fichier (résumé de session)
Symptôme : Le sequencer déclenchait le focus mais shootait immédiatement après changement de filtre, sans attendre.
Cause : Les callbacks updateProperty() et newProperty() appelaient Shoot() dès que FILTER_SLOT == IPS_OK, même si focus en cours.
Solution : Ajout de && !mWaitingForFocus dans les conditions (lignes 157 et 197 de sequencer.cpp).
Symptôme : Le sequencer émettait l'événement mais le focus ne répondait pas.
Causes multiples :
- Connexions manquantes : Lignes 185-186 de controller.cpp commentées → modules non connectés
- Mauvais format d'événement : Utilisation de
"Flupdate"avec setValue() qui échouait car élément déjà àfalse
Solutions :
- Décommenter lignes 185-186 de controller.cpp (fait par Gilles)
- Créer événement personnalisé
"requestautofocus"qui appelle directementstartCoarse()
Symptôme : Le focus démarrait correctement, mais le sequencer terminait la séquence ("Sequence completed") alors que le focus tournait encore.
Cause : Dans newBLOB(), quand currentCount == 0, le code appelait immédiatement StartLine() sans vérifier mWaitingForFocus. Résultat : le sequencer incrémentait currentLine et si c'était la dernière ligne, affichait "Sequence completed".
Solution : Ajout de condition if (!mWaitingForFocus) avant StartLine() (ligne 138 de sequencer.cpp).
Symptôme : Pendant que le focus prenait 10+ images pour trouver la meilleure position, le sequencer recevait et traitait ces images comme si c'étaient ses propres images de séquence.
Cause : newBLOB() ne vérifiait pas si on était en attente du focus avant de traiter les images.
Solution : Ajout de && !mWaitingForFocus dans la condition d'entrée de newBLOB() (ligne 105 de sequencer.cpp).
Symptôme : Hypothétique - pas confirmé en production.
Cause potentielle : Dans SMFocusDone(), pMachine->stop() était appelé AVANT l'émission de l'événement. Si stop() interrompait le handler onExit, l'événement n'aurait jamais été émis.
Solution préventive : Déplacement de pMachine->stop() APRÈS emit moduleEvent() (lignes 588-591 de focus.cpp).
1. StartLine() détecte : previousFilter (Ha) ≠ currentFilter (OIII)
↓
2. Vérifie autofocusonfilterchange == true
↓
3. Change filtre physique via INDI
↓
4. mWaitingForFocus = true
↓
5. emit moduleEvent("requestautofocus", "focus", "", {})
↓
6. Focus reçoit événement (grâce aux connexions directes)
↓
7. Focus appelle startCoarse()
↓
8. Filtre wheel termine → FILTER_SLOT = IPS_OK
↓
9. updateProperty() vérifie mWaitingForFocus → NE PAS shooter
↓
10. Focus trouve meilleure position (state machine)
↓
11. SMFocusDone() émet "focusdone"
↓
12. Sequencer reçoit OnFocusDone()
↓
13. mWaitingForFocus = false
↓
14. Appelle Shoot() → séquence reprend
La solution supporte plusieurs instances de modules focus :
- Paramètre
focusmoduleest un string libre (pas une liste prédéfinie) - L'utilisateur entre le nom exact de l'instance :
"focus","focus1","focus_widefield", etc. - Pas de validation → si nom incorrect, événement perdu silencieusement
- Documentation inclut exemples multi-instances et guide de dépannage
-
controller.cpp lignes 185-186 DOIVENT être décommentées
- Sans cela, RIEN ne fonctionne
- Vérifier avec :
grep -n "connect(othermodule, &Basemodule::moduleEvent" OST/src/controller.cpp - Doit retourner la ligne (pas commentée)
-
Recompiler dans l'ordre
cd OST/build && cmake .. && make && sudo make install cd ../../OST-modules/build && cmake .. && make && sudo make install
-
Tester avec logs
- Message sequencer :
"Filter changed - requesting autofocus from module: focus" - Message focus :
"Autofocus requested by another module - starting" - Message sequencer :
"Autofocus completed - resuming sequence"
- Message sequencer :
Court terme :
- Timeout pour autofocus (5 min max)
- Validation existence instance focus avant émission événement
- Message erreur si instance introuvable
- Indicateur visuel "Waiting for focus" dans UI
- Liste déroulante dynamique des instances focus disponibles
Moyen terme :
- Retry automatique si focus échoue (max 3×)
- Refocus périodique (toutes les N images)
- Support multi-modules focus (load balancing)
- Statistiques : temps focus moyen, nb succès/échecs
Long terme :
- Prédiction offset focus par filtre (modèle ML)
- Compensation température automatique
- Focus asynchrone (overlapping avec download image)
- Focus pendant slew (si goto avant séquence)
# Trouver toutes les émissions d'événements
grep -rn "emit moduleEvent" OST-modules/src/modules/
# Trouver tous les traitements d'événements
grep -rn "OnMyExternalEvent" OST-modules/src/modules/
# Vérifier connexions directes activées
grep -A2 -B2 "connect(othermodule, &Basemodule::moduleEvent" OST/src/controller.cpp# Compiler seulement sequencer
cd OST-modules/build
make ostsequencer
sudo cp libostsequencer.so /usr/lib/
# Compiler seulement focus
make ostfocus
sudo cp libostfocus.so /usr/lib/# Lancer avec logs verbeux
ostserver --verbose
# Surveiller logs en temps réel
tail -f /tmp/ost.log # (si configuré)
# Vérifier modules chargés
ps aux | grep ostserver
lsof -p $(pidof ostserver) | grep ".so$"-
Architecture OST : Les modules peuvent communiquer de deux façons :
- Via Controller (toujours actif)
- Directement entre eux (nécessite connexions explicites)
-
Pattern setValue() : Ne pas utiliser pour communication inter-modules
- setValue() retourne true uniquement si valeur CHANGE
- Pour événements externes, créer événements personnalisés
-
Synchronisation : Flag booléen simple suffit (Qt event loop single-threaded)
- Pas besoin de mutex ou conditions complexes
- Vérification du flag dans callbacks INDI
-
Instances multiples : String libre plus flexible que liste prédéfinie
- Évite dépendances complexes
- Cohérent avec sélection devices INDI
- Nécessite validation côté utilisateur
Pour questions ou reprendre le développement :
- Voir
SEQUENCER_IMPROVEMENTS.mdpour détails techniques complets - Voir
CLAUDE.mdsection "Module Communication" pour architecture - Tous les changements documentés avec numéros de ligne précis
Version : 0.3 Dernière mise à jour : 2025-10-12 Sessions : 2025-01-11 (implémentation initiale), 2025-10-12 (debug synchronisation) Développeurs : Claude Code + Gilles
SESSION_2025-10-12.md: Rapport détaillé de la session de debug du 12 octobre 2025SEQUENCER_IMPROVEMENTS.md: Documentation technique complète de la fonctionnalitéCLAUDE.md: Architecture générale du projet OST