Skip to content

Robotlar Yürüdü, Şimdi Uçuyor: AirVLA → Neon 🚁🤖

Published: March 29, 2026

Selamlar. Son yazılarda hep kol robotlarından bahsettik — al, koy, kavra. Bugün konu farklı: evdeki dronu da robotik agent'la kontrol etmek. Stanford ve Physical Intelligence bir paper yayınladı, biz de yoink ettik.

🎧 First in first, background music.


Sorun: VLA Modelleri Yere Yapışık 🏗️

Bugünkü tüm VLA (Vision-Language-Action) modelleri — bizim Neon dahil, GR00T dahil, Pi0 dahil — yerçekimini bir problem olarak görmüyor. Neden görsün? Masadaki kol yerçekimini zaten kompanse ediyor, servo motorlar yeterince güçlü.

Ama bir dronu havada tutmak? Tamamen farklı fizik.

Kol Robotu Drone
Sabit taban, gravity kompansasyon dahili Sürekli aktif thrust gerekli
6-7 DoF eklem açısı 4-7 DoF: x, y, z, yaw + (roll, pitch, gripper)
Hata = nesne düşer Hata = drone düşer 💥
Payload değişince etkisi az Payload = yerçekimi değişiyor, drone batar

AirVLA'nın çözdüğü problem tam bu: yerden eğitilmiş VLA modelini havaya transfer etmek, modeli yeniden eğitmeden.

AirVLA'nın Çözümü: Physics-Guided Inference 🎯

Paper'ın en güzel fikri şu: VLA modelini yeniden eğitme. Sadece inference sırasında fizik kısıtlamalarını enjekte et.

Flow-matching tabanlı action generation sırasında, velocity field'a bir gradient düzeltmesi ekliyorsun:

\[v_{guided} = v_{base} - \lambda \cdot \nabla_x \Phi(\text{denoise}(x_t))\]

Burada Φ(A; o) senin fizik kaybın — altitude düzeltmesi, payload kompansasyonu, collision avoidance. Model ağırlıklarına dokunmuyorsun. Sampling sürecinin içine fizik bilgisi enjekte ediyorsun.

Bu, classifier-free guidance'ın robotik versiyonu gibi düşünülebilir. Diffusion model'larda "bu resmi daha çok kediye benzer yap" dersin — burada "bu aksiyonu daha çok fizik kurallarına uygun yap" diyorsun.

flowchart LR
    subgraph "Normal VLA Inference"
        V1["Velocity Field<br/>v_base"] --> A1["Action Chunk"]
    end

    subgraph "AirVLA Physics-Guided"
        V2["Velocity Field<br/>v_base"] --> GUIDE["- λ·∇Φ(denoise)"]
        GUIDE --> A2["Physically Feasible<br/>Action Chunk"]
    end

    PHY["⚙️ Physics Loss Φ<br/>Altitude, Payload,<br/>Collision"] --> GUIDE

    style PHY fill:#e65100,color:#fff
    style GUIDE fill:#6a1b9a,color:#fff
    style A2 fill:#2e7d32,color:#fff

Neon'a Neler Yoink Ettik 🏴‍☠️

Üç ana şey:

1. Aerial Action Space 🕹️

ControlMode enum'una üç yeni mod ekledik:

class ControlMode(Enum):
    # Mevcut (kol robotları)
    ARMS_ONLY = "arms_only"      # 14 DoF
    UPPER_BODY = "upper_body"    # 17 DoF
    WHOLE_BODY = "whole_body"    # 29 DoF

    # Yeni — AirVLA'dan yoink
    AERIAL_NAV = "aerial_nav"        # 4 DoF: x, y, z, yaw
    AERIAL_MANIP = "aerial_manip"    # 5 DoF: + gripper
    AERIAL_FULL = "aerial_full"      # 7 DoF: + roll, pitch

Aynı action space abstraction'ı. Robot kolunun 29 DoF'u da, drone'un 7 DoF'u da aynı ActionSpace class'ından geçiyor. Arayüz aynı, fizik farklı.

2. Physics-Aware Guidance 🧭

Bu en büyük yoink. neon/model/guidance.py — 370 satır yeni kod.

PayloadAwareGuidance: Drone bir nesne kaldırdığında ağırlaşır ve batar. Bu guidance, gripper kapandığında otomatik olarak yukarı yönde bias ekliyor:

\[\Phi(A) = \alpha \cdot \sum_t (A[t, z_{idx}] - z_{target})^2\]

α gripper'ın ne kadar kapalı olduğuna bağlı. Gripper açıkken α ≈ 0, guidance etkisiz. Gripper kapandığında α → 1, altitude kompansasyonu aktif.

JointTorqueSafetyGuidance: Eklem tork limitlerini aşmayı cezalandırıyor. Bu sadece drone için değil — G1 humanoid için de geçerli. Bonus yoink.

CompositeGuidance: Birden fazla guidance fonksiyonunu compose ediyor:

guidance = CompositeGuidance([
    (PayloadAwareGuidance(altitude_index=2, gripper_index=4), 2.0),
    (CollisionAvoidanceGuidance(obstacle_map), 1.0),
])
actions = flow_head.sample(features, guidance_fn=guidance)

Bu, fonksiyonel kompozisyon — Strands Agents'ın tool composition'ı ile aynı pattern. Birden fazla kısıtlamayı ağırlıklı olarak birleştir, model'a enjekte et.

3. Real-Time Control (RTC) Optimizasyonları ⚡

Drone'lar 50Hz'de kontrol istiyor. Normal VLA inference ~200ms sürüyor (5Hz). AirVLA'nın çözümü:

  • Speculative decoding: Basit policy ile paralel tahmin, büyük model doğrulasın
  • Action chunk overlap: 16 step chunk üret, 8 step uygula, overlap ile latency gizle
  • KV cache reuse: Ardışık frame'lerin cache'ini tekrar kullan

Bunları Neon'un mevcut speculative_decode() ve compile_optimized() altyapısına entegre ettik — Photon yoink'inden zaten hazırdı.

Mimari: Tek Bakışta 🏗️

graph TB
    subgraph "Input"
        CAM["📹 Drone Camera"]
        IMU["📡 IMU / Altitude"]
        CMD["🗣️ 'Masadaki kutuyu al'"]
    end

    subgraph "Neon VLA"
        BB["Video Backbone 7B ❄️<br/>Frozen"]
        FUSE["Multi-Modal Fusion"]
        FH["Flow-Matching Head<br/>6M trainable"]
    end

    subgraph "Physics Guidance"
        PG["PayloadAwareGuidance"]
        CG["CollisionAvoidance"]
        COMP["CompositeGuidance"]
    end

    subgraph "Output"
        ACT["Action Chunk<br/>7 DoF × 16 steps"]
        DRONE["🚁 Motor Commands"]
    end

    CAM --> BB
    IMU --> FUSE
    CMD --> BB
    BB --> FUSE
    FUSE --> FH

    PG --> COMP
    CG --> COMP
    COMP --> FH

    FH --> ACT --> DRONE

    style BB fill:#0097a7,color:#fff
    style FH fill:#e65100,color:#fff
    style COMP fill:#6a1b9a,color:#fff
    style DRONE fill:#2e7d32,color:#fff

Neden Guidance, Neden Fine-tune Değil? 🤔

Klasik soru: neden model'ı drone verisiyle fine-tune etmiyoruz?

Üç sebep:

1. Veri yok. Drone manipulation verisi neredeyse hiç yok. Kol robotu verisi milyonlarca episode. Drone ile kutu alma verisi? Birkaç yüz.

2. Fizik değişiyor. Farklı payload = farklı dinamik. Her payload için fine-tune? İmkansız. Guidance runtime'da adapte oluyor.

3. Backbone'u bozmak istemiyorsun. Neon'un felsefesi: 7B video backbone'u dondur. Zaten video anlıyor — nesnelerin düştüğünü, hareket ettiğini, fizik kurallarını. Bu bilgiyi bozma, üstüne küçük bir guidance ekle.

Analoji: GPS vs Motor Swap

Fine-tune = arabaya yeni motor takmak (pahalı, riskli, geri dönüş zor). Guidance = GPS ile yön vermek (motor aynı, rotayı düzeltiyorsun).

Beş Satır Yine Yeter 🖐️

from strands_robots import Robot
from strands import Agent

robot = Robot("tello")  # DJI Tello, veya herhangi bir drone
agent = Agent(tools=[robot])
agent("Masadaki kutuyu al ve bana getir")

Arka planda: 1. Strands Agent komutu parse ediyor 2. Robot tool'u Neon VLA policy'yi çağırıyor 3. Neon video backbone ile sahneyi anlıyor 4. Flow-matching head action chunk üretiyor 5. PayloadAwareGuidance kutuyı alınca altitude düzeltiyor 6. Drone havada kalıyor, kutuyu getiriyor

Kullanıcı bunların hiçbirini bilmiyor. Matruşka bebekleri çalışıyor.

Ama Bir Dakika — Evdeki Drone Gerçekten? 🏠

Dürüstlük köşesi.

Limitations

Bu henüz production değil. Aerial action space tanımladık, guidance fonksiyonları yazdık, testler geçiyor. Ama gerçek bir DJI Tello üzerinde end-to-end çalıştırmadık. Pipeline hazır, donanım validasyonu gelecek.

Indoor uçuş zor. GPS yok, dar alan, mobilya. Visual odometry gerekiyor — Neon'un video backbone'u bunu potansiyel olarak çözebilir ama kanıtlanmadı.

Güvenlik kritik. Pervane + ev ortamı = tehlikeli. Soft-capping var ama fiziksel güvenlik katmanları (altitude limiti, no-fly zone) henüz implemente değil.

Benchmark'lar gelecek. Claim küçük tutalım: altyapı hazır, validasyon yolda.

Büyük Resim: Neon Artık Multi-Embodiment 🌍

AirVLA yoink'i ile Neon'un kapsadığı platform sayısı arttı:

Platform DoF Durum
SO-100 Kol 6 ✅ Çalışıyor
Unitree G1 Humanoid 29 ✅ Sim + Real
DJI Tello (Drone Nav) 4 🔧 Action space hazır
Drone + Gripper 7 🔧 Guidance hazır
Boston Dynamics Spot 12 🗓️ Planlanıyor

Hepsi aynı video backbone'u paylaşıyor. Hepsi aynı action space abstraction'ını kullanıyor. Fark sadece: - Action dimension (6 vs 29 vs 7) - Guidance fonksiyonları (yerçekimi kompansasyonu vs payload vs collision) - Hardware driver (servo vs motor controller vs ESC)

Bitwise flags'te 190 satır koşulu 5 satıra düşürmüştük. Burada N farklı robot platformunu tek bir ControlMode enum'u ile tanımlıyoruz. Karmaşıklık kütüphanede yaşar.

AirVLA Paper'dan Key Takeaways 📝

Stanford/Physical Intelligence ekibinin yaptığı iş gerçekten zarif:

  1. Zero-shot aerial transfer: Yerde eğitilmiş π₀ modelini hiç havada eğitmeden drone'a transfer ettiler
  2. Guidance > Fine-tune: Physics guidance ile fine-tune'a yakın performans, %0 ek eğitim maliyeti
  3. Composable constraints: Birden fazla fizik kısıtlamayı runtime'da compose edebilirsin
  4. Real hardware: Gerçek drone ile gerçek görevler (kutu alma, nesne taşıma)

Biz Neon'a 3 numarayı yoink ettik — composable guidance. Ve AirVLA'nın action space tanımını adapte ettik. Ama en değerli insight 1 numara: iyi bir VLA modeli, bedeni bilmese bile, doğru guidance ile yeni bir bedende çalışabilir.

Bu, Neon'un "frozen backbone" felsefesiyle birebir uyumlu. Backbone'u dondur, üstüne küçük adapter + guidance ekle, yeni platform'a git.

Sonraki Adımlar 🗺️

  1. DJI Tello driver — Strands Robots'a drone hardware abstraction eklemek
  2. Indoor SLAM — Video backbone'un spatial feature'larını SLAM'e çevirmek
  3. Safety layer — Altitude limiti, no-fly zone, emergency land
  4. Sim2Real — MuJoCo'da drone sim → 50 gerçek demo → fine-tune

Ama önce kol robotlarını bitirmemiz lazım. PR #56 merge olsun, Neon Phase 2 validasyonu tamamlansın. Drone, Phase 3.

Başla 🚀

pip install neon-vla
from neon import NeonVLA
from neon.model.guidance import PayloadAwareGuidance

model = NeonVLA.from_pretrained("neon-vla/so100-phase1")

# Aerial manipulation with physics guidance
guidance = PayloadAwareGuidance(
    altitude_index=2,
    gripper_index=4,
    target_altitude_offset=0.05,
)

obs = get_drone_camera()
actions = model.predict(
    obs, 
    "pick up the red box",
    guidance_fn=guidance,
    guidance_scale=2.0,
)
# → (16, 7) action chunk — 16 timesteps, 7 DoF aerial_full

Tek satır özet:

Robota "al şunu" dedin, yürüyüp aldı. Şimdi aynı model, aynı backbone, aynı 5 satır — uçup alacak.

Modeli yeniden eğitmene gerek yok. Fizik kurallarını inference sırasında enjekte et. Guidance > Fine-tune.

Afiyet olsun! 🍽️

Çağatay.


Linkler