From 822367ada86315daa4d6be16d579ca4ed78a7fc5 Mon Sep 17 00:00:00 2001 From: nicoboy Date: Sun, 21 Jun 2026 17:29:27 +0200 Subject: [PATCH] fix: drain pymavlink directement dans monitor_telemetry et dans status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La tâche drain_pymavlink() séparée ne tournait jamais car input() bloque l'event loop. Drain et lecture du HEARTBEAT directement dans monitor_telemetry() et en fallback dans l'action status pour garantir la lecture du custom_mode ArduCopter. Co-Authored-By: Claude Sonnet 4.6 --- wireclaw_core.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/wireclaw_core.py b/wireclaw_core.py index 240ae56..91252e4 100644 --- a/wireclaw_core.py +++ b/wireclaw_core.py @@ -82,13 +82,6 @@ async def monitor_armed(drone): drone_armed = is_armed await asyncio.sleep(0) # cède le contrôle après chaque mise à jour -async def drain_pymavlink(): - """Draine pymavlink en boucle pour peupler mav.messages (dernier msg par type).""" - while True: - while mav.recv_match(blocking=False) is not None: - pass - await asyncio.sleep(0.05) - async def monitor_telemetry(drone): """Sonde batterie, mode et GPS par polling — pause 1s entre chaque cycle pour ne pas saturer l'event loop asyncio avec des streams gRPC continus.""" @@ -98,7 +91,13 @@ async def monitor_telemetry(drone): raw = bat.remaining_percent telemetry_cache["battery"] = abs(raw) * 100 if abs(raw) <= 1 else abs(raw) break - hb = mav.messages.get('HEARTBEAT') + hb = None + while True: + msg = mav.recv_match(blocking=False) + if msg is None: + break + if msg.get_type() == 'HEARTBEAT': + hb = msg if hb: telemetry_cache["mode"] = ARDUCOPTER_MODES.get(hb.custom_mode, f"UNKNOWN({hb.custom_mode})") async for gps in drone.telemetry.gps_info(): @@ -139,6 +138,15 @@ async def execute_command(drone, cmd): elif action == "status": await refresh_position(drone) + hb = None + while True: + m = mav.recv_match(blocking=False) + if m is None: + break + if m.get_type() == 'HEARTBEAT': + hb = m + if hb: + telemetry_cache["mode"] = ARDUCOPTER_MODES.get(hb.custom_mode, f"UNKNOWN({hb.custom_mode})") return (f"\nPosition : {current_pos['lat']:.6f}, {current_pos['lon']:.6f}\n" f"Altitude : {current_pos['alt']:.1f}m (AGL)\n" f"Abs alt : {current_pos['abs_alt']:.1f}m\n" @@ -287,7 +295,6 @@ async def init(): drone_armed = is_armed print(f"Etat initial : {'arme' if drone_armed else 'desarme'}") break - asyncio.create_task(drain_pymavlink()) asyncio.create_task(monitor_armed(drone)) asyncio.create_task(monitor_telemetry(drone)) break