Fix captures 2/3 perdues + miroir + stabilite camera post-prise
- post_capture_grace=10 : ignore les erreurs -52 transitoires juste apres une prise (Canon EOS a besoin ~1s pour stabiliser le capteur) - Threshold abandon capture : 3 -> 8 erreurs consecutives - Threshold reconnexion : 5 -> 10 erreurs consecutives - Avant chaque prise : eosviewfinder=1 pour garantir miroir leve - Apres prise : viewfinder relance + sleep 1s + drain 8 evenements - Sim auto-detect : pas de USB reset (evite boucle -52), verification fonctionnelle avec un capture_preview() avant de valider la camera - Sim poll : 15s au lieu de 10s Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -753,22 +753,30 @@ class PB:
|
||||
# ── Thread caméra ────────────────────────────────────────────────────────
|
||||
def _cam_loop(self):
|
||||
errs = 0
|
||||
post_capture_grace = 0 # frames de grâce après une prise (ignore erreurs transitoires)
|
||||
while True:
|
||||
# En simulation : tentative de connexion automatique toutes les 10s
|
||||
# En simulation : tentative de connexion automatique toutes les 15s
|
||||
# Pas de USB reset ici — reset seulement en cas de reconnexion
|
||||
if self.sim:
|
||||
time.sleep(10)
|
||||
_usb_reset_done()
|
||||
time.sleep(15)
|
||||
for _ in range(2):
|
||||
try:
|
||||
c = gp.Camera(); c.init()
|
||||
# Vérification fonctionnelle : un preview doit réussir
|
||||
_f = c.capture_preview(); _bytes = bytes(_f.get_data_and_size())
|
||||
if self.cam:
|
||||
try: self.cam.exit()
|
||||
except: pass
|
||||
self.cam = c; self.sim = False; self.prev_actif = True
|
||||
surf = pygame.image.load(io.BytesIO(_bytes))
|
||||
surf = pygame.transform.scale(surf, (W, H))
|
||||
with self.flock: self.frame = surf
|
||||
print("DSLR détecté automatiquement")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"Auto-detect caméra: {e}")
|
||||
try: c.exit()
|
||||
except: pass
|
||||
time.sleep(1)
|
||||
continue
|
||||
if self.prev_actif:
|
||||
@@ -776,8 +784,15 @@ class PB:
|
||||
if self.cam is None:
|
||||
raise RuntimeError("camera None")
|
||||
if self.cap_demande:
|
||||
# Déclenchement sans mouvement miroir :
|
||||
# eosremoterelease garde le LV actif sur Canon EOS
|
||||
# Avant la prise : activer le viewfinder EOS (miroir levé, liveview ON)
|
||||
try:
|
||||
cfg_c = self.cam.get_config()
|
||||
vf = cfg_c.get_child_by_name('eosviewfinder')
|
||||
vf.set_value(1)
|
||||
self.cam.set_config(cfg_c)
|
||||
time.sleep(0.2)
|
||||
except: pass
|
||||
# Déclenchement obturateur seul via eosremoterelease
|
||||
triggered = False
|
||||
try:
|
||||
cfg_c = self.cam.get_config()
|
||||
@@ -805,21 +820,42 @@ class PB:
|
||||
rl.set_value('None')
|
||||
self.cam.set_config(cfg_c)
|
||||
except: pass
|
||||
# Relance le viewfinder et laisse le capteur se stabiliser
|
||||
try:
|
||||
cfg_c = self.cam.get_config()
|
||||
vf = cfg_c.get_child_by_name('eosviewfinder')
|
||||
vf.set_value(1)
|
||||
self.cam.set_config(cfg_c)
|
||||
except: pass
|
||||
time.sleep(1.0) # stabilisation capteur Canon entre deux prises
|
||||
# Drainer les événements résiduels
|
||||
for _ in range(8):
|
||||
try:
|
||||
self.cam.wait_for_event(50)
|
||||
except: break
|
||||
self.cap_result=ch; self.cap_demande=False; self.cap_done.set()
|
||||
errs = 0
|
||||
errs = 0; post_capture_grace = 10
|
||||
else:
|
||||
f=self.cam.capture_preview(); data=bytes(f.get_data_and_size())
|
||||
surf=pygame.image.load(io.BytesIO(data))
|
||||
surf=pygame.transform.scale(surf,(W,H))
|
||||
with self.flock: self.frame=surf
|
||||
errs = 0
|
||||
if post_capture_grace > 0:
|
||||
post_capture_grace -= 1
|
||||
except Exception as e:
|
||||
if post_capture_grace > 0:
|
||||
# Erreurs transitoires post-capture normales sur EOS — on ignore
|
||||
post_capture_grace -= 1
|
||||
print(f"cam post-capture ({post_capture_grace} restants): {e}")
|
||||
time.sleep(0.2)
|
||||
else:
|
||||
errs += 1
|
||||
print(f"cam erreur ({errs}): {e}")
|
||||
if self.cap_demande and errs >= 3:
|
||||
# abandon de la capture en cours
|
||||
if self.cap_demande and errs >= 8:
|
||||
# abandon de la capture seulement après 8 erreurs consécutives
|
||||
self.cap_result=None; self.cap_demande=False; self.cap_done.set()
|
||||
if errs >= 5:
|
||||
if errs >= 10:
|
||||
# reconnexion automatique
|
||||
print("Caméra perdue — tentative de reconnexion...")
|
||||
self.prev_actif = False
|
||||
@@ -839,11 +875,10 @@ class PB:
|
||||
except Exception as re:
|
||||
print(f"Reconnexion échouée ({_nb_retry+1}): {re}")
|
||||
else:
|
||||
# 10 tentatives échouées → bascule en simulation
|
||||
self.sim = True
|
||||
print("Caméra introuvable → mode simulation")
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.2)
|
||||
else:
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user