18 Commits

Author SHA1 Message Date
822367ada8 fix: drain pymavlink directement dans monitor_telemetry et dans status
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 <noreply@anthropic.com>
2026-06-21 17:29:27 +02:00
1b47ce124d fix: drainer pymavlink dans le thread principal sans run_in_executor
run_in_executor + blocking=False retournait None dans un thread
séparé sans rien peupler dans mav.messages. Drain direct dans
la boucle asyncio avec while recv_match() pour vider tout le
buffer à chaque tick de 50ms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:26:37 +02:00
7979619c38 fix: drain pymavlink en tâche de fond pour que mav.messages soit peuplé
recv_match(blocking=False) ponctuel ratait les heartbeats car aucun
appel continu ne drainait le buffer pymavlink. Ajout d'une tâche
drain_pymavlink() qui appelle recv_match() toutes les 50ms pour
remplir mav.messages, et lecture du mode via mav.messages.get()
qui retourne le dernier heartbeat reçu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:24:49 +02:00
943aa3d70e fix: lire le mode de vol via pymavlink (custom_mode ArduCopter) au lieu de MAVSDK
MAVSDK flight_mode() retourne UNKNOWN pour les modes ArduCopter non
mappés dans son enum PX4. Lecture directe du champ custom_mode depuis
les HEARTBEAT pymavlink avec dictionnaire de mapping ArduCopter complet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:20:39 +02:00
8ce340a573 fix: heartbeat GCS initial pour enregistrer l'adresse pymavlink auprès de mavp2p
En udpout, mavp2p (udps) ignore le client tant qu'aucun paquet
n'a été émis depuis lui. L'envoi d'un heartbeat GCS dès la
connexion force mavp2p à mémoriser l'adresse de retour et à
relayer le flux H743 vers pymavlink.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 16:49:19 +02:00
37012179cf Fix saturation event loop : monitor_telemetry en polling 1s
3 streams gRPC infinis en asyncio.gather() saturaient l'event
loop et empêchaient uvicorn d'accepter des connexions HTTP.
- monitor_telemetry : boucle while + async for...break + sleep(1)
  au lieu de 3 streams continus en gather
- monitor_armed : await sleep(0) pour céder après chaque update
- ensure_future → create_task (API recommandée Python 3.7+)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 16:26:07 +02:00
24100aea4d SYSTEM_PROMPT : descriptions des actions pour guider Gemini
Sans description, Gemini mappait "position gps" sur position
au lieu de position_gps. Chaque action a maintenant un libellé
explicite, position_gps précise horodatage + fix + satellites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:09:51 +02:00
579bec5abd Fix : get_running_loop() au lieu de get_event_loop() (déprécié Python 3.10)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:04:38 +02:00
0d2f485c57 Fix position_gps : GPS info en cache, plus de blocage async
- gps_fix et gps_sats ajoutés à telemetry_cache
- monitor_telemetry surveille aussi gps_info() en continu
- position_gps lit depuis le cache (comme battery/mode)
  et ne risque plus de bloquer sur async for ... break

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:00:30 +02:00
1d095cd233 Fix TypeError altitude null + erreurs affichées dans l'UI
- float(cmd.get("altitude") or 15) : gère altitude=null retourné
  par Gemini pour les commandes sans altitude (land, rtl, status…)
- /command attrape les exceptions et retourne JSON 500 avec le
  message d'erreur, évite le "Erreur réseau" opaque dans la page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:49:22 +02:00
f7a096c6a7 Fix langue et altitude relative dans SYSTEM_PROMPT
- Ajout instruction explicite : message toujours en français
- Nouveau champ delta dans le schéma JSON : "monte de 5m" → delta=5,
  "descend de 3m" → delta=-3, null pour altitude absolue
- takeoff et altitude calculent target_alt = current_alt + delta
  quand delta est présent, sinon utilisent altitude absolue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:46:28 +02:00
f019470749 Ajout commandes altitude et position_gps
- altitude : change la hauteur en vol via goto_location,
  ou décollage depuis le sol si alt < 2m
- position_gps : position complète avec horodatage HH:MM:SS,
  fix GPS et nombre de satellites via telemetry.gps_info()
- SYSTEM_PROMPT et message d'accueil mis à jour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:31:32 +02:00
6024655a50 Fix event loop bloqué + /status non-bloquant
- init_pymavlink() passe en run_in_executor : ne bloque plus
  l'event loop asyncio pendant le démarrage de uvicorn
- Ajout monitor_telemetry() : batterie et mode mis à jour en
  continu en cache (même logique que monitor_armed)
- /status et action status lisent telemetry_cache directement,
  plus aucun async for bloquant dans les route handlers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:22:02 +02:00
bcda9cf334 Ajout serveur web FastAPI sur port 8765
- wireclaw_core : expose drone comme global, extrait init()
  depuis main() pour permettre l'import par web_server.py ;
  corrige aussi le bug drone_armed manquant global dans init
- web_server.py : FastAPI avec process(text) générique
  (interpret_command → execute_command), routes GET / POST /command
  GET /status, page HTML sobre avec statut temps réel (2s)
  et historique des commandes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:54:54 +02:00
32a9713e36 Fix takeoff en vol : changer l'altitude au lieu de bloquer
Quand Gemini mappe "monte à Xm" sur takeoff et que le drone est
déjà en vol, on recalcule l'altitude absolue MSL et on utilise
goto_location pour atteindre la nouvelle altitude à position fixe.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:08:31 +02:00
f7c4a7221b Fix takeoff : vérifier l'altitude réelle au lieu de drone_armed
drone_armed reste True après une session précédente même si le drone
est au sol. Le guard utilise désormais current_pos["alt"] < 2.0
comme goto et orbit, avec un refresh_position préalable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 13:03:29 +02:00
93a7013ad0 Add commande position GPS 2026-06-01 10:29:26 +02:00
17c2ae5ce8 Initial commit — WireClaw SITL fonctionnel 2026-05-30 10:35:15 +02:00