Reinforcement Learning
Rehber Yapay Zeka RL · Robotik

RL Robotics
Isaac Gym & Sim-to-Real.

Robotik RL'nin gerçek dünya zorluklarına karşı çözümleri: GPU paralel simülasyon, domain randomization, sim-to-real transfer ve dexterous manipulation.

00 Robotik RL Zorluğu

Gerçek robot donanımı kırılgandır, yavaştır ve her sıfırlaması insani müdahale gerektirir. Bu kısıtlar robotik RL'yi standart RL'den niteliksel olarak farklı kılar.

Simüle edilmiş ortamlarda milyonlarca adım kolayca toplanabilirken gerçek robotlarda günde birkaç bin adım toplamak bile güçtür. Bunun yanı sıra robotik RL özgü birkaç kritik zorluk daha getirir:

ZorlukAçıklamaÇözüm Yaklaşımı
Sparse rewardBlok kutuda kalana kadar ödül yok; gradyan sinyali çok zayıfDense reward shaping, HER
Contact dynamicsTemas kuvvetleri simülasyonda sık sık hatalı modellenirDomain randomization, soft contacts
Sample efficiencyGerçek donanımda veri toplama son derece yavaş ve pahalıSim-to-real, offline RL
SafetyExploration sırasında donanım veya çevre zarar görebilirSafe RL, constrained optimization
Partial observabilityKameralar gürültülü; joint state tahmini hatalı olabilirState estimation, RNN policy
SIM-FIRST YAKLAŞIMI

Modern robotik RL neredeyse istisnasız önce simülasyonda eğitim, sonra gerçek donanıma transfer (sim-to-real) prensibini izler. Bu, keşif maliyetini ve donanım riskini dramatik biçimde düşürür.

01 Isaac Gym / Isaac Lab

NVIDIA Isaac Gym, GPU üzerinde binlerce paralel ortam çalıştırarak robotik RL'nin sample efficiency sorununu kökten çözer.

Geleneksel simülatörlerde ortam CPU'da çalışır, sadece RL gradyanları GPU'ya geçer. Isaac Gym ise fizik simülasyonunu doğrudan GPU'da koşturur. Tüm tensörler GPU belleğinde kaldığı için CPU-GPU transferi ortadan kalkar. Sonuç: A100 GPU ile 4.096 paralel Ant ortamı 100.000+ fps hızında çalışır.

terminal — Isaac Lab kurulumu
# Isaac Lab (Isaac Gym halefi) — Omniverse tabanlı
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab
./isaaclab.sh --install

# Isaac Gym (eski, hâlâ yaygın kullanım)
# NVIDIA Developer sitesinden indir: developer.nvidia.com/isaac-gym
pip install isaacgym/
pip install -e rl_games/    # RL Games framework
isaac_gym_basic.py
from isaacgym import gymapi, gymtorch
import torch

# Simülatör ve ortam oluştur
gym  = gymapi.acquire_gym()
sim  = gym.create_sim(
    compute_device_id=0,
    graphics_device_id=0,
    type=gymapi.SIM_PHYSX,
    params=gymapi.SimParams())

# Ortam gridi: 64x64 = 4096 paralel ortam
num_envs  = 4096
env_lower = gymapi.Vec3(-2.0, -2.0, 0.0)
env_upper = gymapi.Vec3( 2.0,  2.0, 2.0)

envs   = []
actors = []
for i in range(num_envs):
    env = gym.create_env(sim, env_lower, env_upper, 64)
    envs.append(env)

# Tensor API ile GPU üzerinde gözlem al
gym.prepare_sim(sim)
dof_state_tensor = gym.acquire_dof_state_tensor(sim)
dof_states = gymtorch.wrap_tensor(dof_state_tensor)
# dof_states: (num_envs * num_dof, 2) — pos ve vel — GPU'da!
print(f"DOF states shape: {dof_states.shape}, device: {dof_states.device}")

02 MuJoCo ile Locomotion

MuJoCo, Hopper, Ant ve Humanoid gibi klasik locomotion benchmark'larıyla RL algoritmalarının standart test zeminidir.

MuJoCo (Multi-Joint dynamics with Contact), DeepMind tarafından satın alındıktan sonra ücretsiz hale getirildi. Hızlı temas dinamiği simülasyonu ve Gymnasium entegrasyonu sayesinde continuous control RL'nin fiili standardıdır.

OrtamGözlem BoyutuEylem BoyutuZorluk
HalfCheetah-v4176Orta — düzlem hareketi
Hopper-v4113Orta — denge kritik
Ant-v41118Zor — 3D locomotion
Humanoid-v437617Çok Zor — tam vücut
mujoco_sac_train.py
import gymnasium as gym
from stable_baselines3 import SAC
from stable_baselines3.common.env_util import make_vec_env
from stable_baselines3.common.callbacks import EvalCallback

# 8 paralel ortam
env      = make_vec_env("Ant-v4", n_envs=8)
eval_env = make_vec_env("Ant-v4", n_envs=4)

model = SAC(
    "MlpPolicy", env,
    learning_rate=3e-4,
    batch_size=256,
    buffer_size=1_000_000,
    learning_starts=10_000,
    train_freq=1,
    gradient_steps=1,
    tau=0.005,
    gamma=0.99,
    ent_coef="auto",
    verbose=1,
    tensorboard_log="./tb_ant/"
)

eval_cb = EvalCallback(
    eval_env, best_model_save_path="./models/",
    eval_freq=50_000, n_eval_episodes=10, deterministic=True)

model.learn(total_timesteps=3_000_000, callback=eval_cb)
model.save("ant_sac")

03 Domain Randomization

Domain randomization, simülasyonu kasıtlı olarak geniş bir parametre aralığında değiştirerek politikayı gerçek dünya varyasyonlarına karşı robust kılar.

Simülasyon ile gerçek dünya arasındaki fark (sim-to-real gap) büyük ölçüde modelleme hataları ve bilinmezlikten kaynaklanır. Domain randomization bu belirsizliği modele bilerek enjekte eder; politika, parametrelerin geniş bir dağılımında çalışmayı öğrenerek gerçek donanıma karşı toleranslı hale gelir.

Physics DRKütle, sürtünme katsayısı, eklem rijitliği, motor kuvveti, temas dinamiği — her episode rastgele çekilir.
Visual DRDoku, ışık rengi, kamera pozisyonu, arka plan — görüntü tabanlı policy için sim'den real'e transfer sağlar.
Action DREylem gecikmesi, motor gürültüsü, aktuatör kalibrasyonu bozuklukları eklenir.
domain_rand_wrapper.py
import gymnasium as gym
import numpy as np

class PhysicsDRWrapper(gym.Wrapper):
    """
    Her episode başında MuJoCo fizik parametrelerini rastgele değiştirir.
    Politikayı real transfer için robust yapar.
    """
    def __init__(self, env,
                 mass_scale=(0.8, 1.2),
                 friction_scale=(0.5, 1.5),
                 damping_scale=(0.8, 1.2)):
        super().__init__(env)
        self.mass_scale     = mass_scale
        self.friction_scale = friction_scale
        self.damping_scale  = damping_scale
        self.original_mass    = self.env.model.body_mass.copy()
        self.original_frict   = self.env.model.geom_friction.copy()
        self.original_damping = self.env.model.dof_damping.copy()

    def reset(self, **kwargs):
        obs, info = self.env.reset(**kwargs)
        self._randomize()
        return obs, info

    def _randomize(self):
        m = self.env.model
        m.body_mass[:]    = self.original_mass    * np.random.uniform(*self.mass_scale)
        m.geom_friction[:] = self.original_frict  * np.random.uniform(*self.friction_scale)
        m.dof_damping[:]  = self.original_damping * np.random.uniform(*self.damping_scale)

# Kullanım
base_env = gym.make("Hopper-v4")
dr_env   = PhysicsDRWrapper(base_env)
obs, _   = dr_env.reset()
print("DR ortamı hazır — her episode farklı fizik parametreleri")

04 Sim-to-Real Gap

Sim-to-real gap, simülasyonda mükemmel çalışan politikaların gerçek donanımda neden başarısız olduğunu açıklar.

Sim-to-real gap'in başlıca kaynakları ve teknik çözümleri:

Gap KaynağıBelirtiÇözüm
Modelleme hatasıGerçek robotun kütlesi/rijitliği farklıSystem identification, Adaptive DR
Sensor gürültüsüSimde gürültüsüz gözlem, gerçekte gürültülüObservation noise DR, state estimator
Gecikme (latency)Simde anlık eylem, gerçekte 5–50 ms gecikmeAction delay DR, history observations
Temas dinamiğiYumuşak/esnek yüzey temaşası simde hatalıSoft contact DR, rigid body approximation
Wear and tearGerçek motor/eklem zamanla değişirOnline adaptation, meta-learning
RMA — Rapid Motor Adaptation

Kumar et al. (2021) tarafından geliştirilen RMA mimarisi sim-to-real'i iki aşamayla çözer: (1) Base policy eğitimi — explicit extrinsics (kütle, sürtünme) ile. (2) Adaptation module — yalnızca geçmiş gözlemlerden extrinsics tahmin eder. Deploy sırasında sadece adaptation module çalışır; explicit fizik parametresi gerekmez.

05 Reward Shaping

Doğru tasarlanmış dense reward, sparse reward'ın verdiği zayıf gradyan sinyalini zenginleştirerek öğrenmeyi dramatik biçimde hızlandırır.

Robotik RL'de en yaygın ödül bileşenleri:

Hedef mesafesir_dist = −‖pos_ee − pos_target‖ — her adımda end-effector hedef uzaklığı. Sürekli gradyan sinyali sağlar.
Hız cezasır_vel = −α‖ẋ‖² — aşırı hızlı hareketi engeller; güvenli, pürüzsüz hareket öğretir.
Torque cezasır_torque = −β‖τ‖² — enerji tüketimini minimize eder; gerçek donanım için kritik.
Başarı bonusur_success = +S (S büyük, örn. 10) — görev tamamlanınca büyük sparse ödül; dense reward'ı tamamlar.
reward_shaping.py
import numpy as np

def pick_place_reward(obs, info,
                      dist_weight=1.0,
                      vel_penalty=0.01,
                      torque_penalty=0.001,
                      success_bonus=10.0,
                      success_thresh=0.02):
    """
    Pick-and-place görevi için dense + sparse ödül bileşimi.
    obs: dict içinde 'ee_pos', 'target_pos', 'ee_vel', 'joint_torques'
    """
    ee_pos     = obs["ee_pos"]        # end-effector konumu
    target     = obs["target_pos"]    # hedef konum
    ee_vel     = obs["ee_vel"]        # end-effector hızı
    torques    = obs["joint_torques"] # eklem momentleri

    dist    = np.linalg.norm(ee_pos - target)
    r_dist  = -dist_weight    * dist
    r_vel   = -vel_penalty    * np.linalg.norm(ee_vel) ** 2
    r_torq  = -torque_penalty * np.linalg.norm(torques) ** 2
    r_succ  =  success_bonus  if dist < success_thresh else 0.0

    total = r_dist + r_vel + r_torq + r_succ
    return total, {
        "r_dist": r_dist, "r_vel": r_vel,
        "r_torque": r_torq, "r_success": r_succ}

06 SAC ve TD3 — Continuous Control

SAC ve TD3, robotik continuous control için en olgun ve yaygın kullanılan off-policy RL algoritmalarıdır.

SAC (Soft Actor-Critic): Entropi düzenleme terimi ile maximum entropy RL çerçevesinde çalışır. Otomatik entropi katsayısı (ent_coef="auto") hiperparametre arayışını kolaylaştırır. Locomotion ve manipülasyon görevlerinde genellikle en iyi sonucu verir.

TD3 (Twin Delayed DDPG): Overestimation bias'ını iki critic ile düzeltir, delayed policy update ve target policy smoothing ekler. SAC'tan biraz daha kararlıdır; sürekli temas içeren görevlerde avantajlı olabilir.

sac_vs_td3.py
from stable_baselines3 import SAC, TD3
from stable_baselines3.common.noise import NormalActionNoise
import numpy as np
import gymnasium as gym

env = gym.make("HalfCheetah-v4")
n_actions = env.action_space.shape[0]

# SAC — entropi tabanlı, az hiperparametre
sac = SAC(
    "MlpPolicy", env,
    learning_rate=3e-4,
    buffer_size=1_000_000,
    batch_size=256,
    ent_coef="auto",        # otomatik entropi katsayısı
    target_entropy="auto",
    verbose=0)

# TD3 — deterministic, action noise gerekli
action_noise = NormalActionNoise(
    mean=np.zeros(n_actions),
    sigma=0.1 * np.ones(n_actions))
td3 = TD3(
    "MlpPolicy", env,
    learning_rate=3e-4,
    buffer_size=1_000_000,
    batch_size=256,
    action_noise=action_noise,
    policy_delay=2,        # actor her 2 critic update'te bir güncellenir
    target_policy_noise=0.2,
    verbose=0)

# Kısa benchmark karşılaştırması
for name, model in [("SAC", sac), ("TD3", td3)]:
    model.learn(total_timesteps=200_000)
    print(f"{name} eğitimi tamamlandı")

07 Dexterous Manipulation

İnsan elinin maharetini taklit eden dexterous manipulation, robotik RL'nin en zorlu açık problemleri arasındadır.

Dexterous manipulation — parmaklarla nesne yönlendirme, in-hand rotation, karmaşık kavrama — çok sayıda eklem, yüksek boyutlu eylem uzayı ve kritik temas dinamiği içerir. OpenAI'nin Shadow Hand üzerindeki Dactyl çalışması bu alanda dönüm noktası oldu: domain randomization + LSTM policy + self-play ile insan seviyesi nesne döndürme başarıldı.

SistemEklem SayısıBaşarıTeknik
Shadow Hand (Dactyl)24 DOFRubik küp çözmeDR + LSTM + self-play
Allegro Hand16 DOFKalem döndürmeIsaac Gym + PPO
DexHand (Google)20 DOFÇeşitli kavramaDR + offline RL + sim2real
TEMAS ZENGİN GÖREVLERDE BAŞARININ ANAHTARLARI

(1) Yüksek frekanslı kontrol (100–500 Hz) — temas olayları çok kısadır. (2) İmpedance control + RL hiyerarşisi — low-level compliance kontrolü RL üzerinde. (3) Kapsamlı domain randomization — temas parametreleri en kritik stochasticity kaynağıdır. (4) Uzun horizon history — RNN/Transformer policy geçmiş temas geçmişini kullanır.

08 Pratik: Franka Panda Pick-Place Eğitimi

gymnasium-robotics kütüphanesindeki FetchPickAndPlace ortamında SAC ile eğitim ve HER (Hindsight Experience Replay) uygulaması.

terminal — kurulum
pip install "gymnasium-robotics[mujoco]" stable-baselines3 tensorboard
franka_pick_place.py
import gymnasium as gym
import gymnasium_robotics
from stable_baselines3 import SAC, HerReplayBuffer
from stable_baselines3.common.callbacks import EvalCallback

# FetchPickAndPlace: hedef konuma tutma görev
# GoalEnv arayüzü: obs dict içinde 'observation', 'desired_goal', 'achieved_goal'
env      = gym.make("FetchPickAndPlace-v2")
eval_env = gym.make("FetchPickAndPlace-v2")

# SAC + HER: sparse reward GoalEnv için ideal kombinasyon
model = SAC(
    "MultiInputPolicy",
    env,
    replay_buffer_class=HerReplayBuffer,
    replay_buffer_kwargs={
        "n_sampled_goal": 4,            # her transition için 4 hindsight goal
        "goal_selection_strategy": "future",  # gelecek gözlemden hedef
    },
    learning_rate=1e-3,
    buffer_size=1_000_000,
    batch_size=256,
    ent_coef="auto",
    gamma=0.98,
    tau=0.005,
    verbose=1,
    tensorboard_log="./tb_pick_place/"
)

eval_cb = EvalCallback(
    eval_env,
    best_model_save_path="./models/pick_place/",
    eval_freq=20_000,
    n_eval_episodes=20,
    deterministic=True,
    verbose=1
)

print("Eğitim başlıyor: FetchPickAndPlace + SAC + HER")
model.learn(total_timesteps=1_000_000, callback=eval_cb)
model.save("franka_pick_place_sac_her")
print("Model kaydedildi: franka_pick_place_sac_her.zip")

# Değerlendirme
mean_reward = 0.0
for _ in range(50):
    obs, _ = eval_env.reset()
    done = False
    ep_r  = 0.0
    while not done:
        action, _ = model.predict(obs, deterministic=True)
        obs, r, done, trunc, _ = eval_env.step(action)
        ep_r += r
        done  = done or trunc
    mean_reward += ep_r
print(f"50 ep ortalama ödül: {mean_reward/50:.3f}")
HER NEDEN ÖNEMLİ?

FetchPickAndPlace sparse reward kullanır: yalnızca nesne hedefe ulaşınca +0 (başarı) veya -1 (başarısız) döner. HER olmadan SAC milyonlarca adımda hiç başarı sinyali göremeyebilir. HER, başarısız trajectory'leri geriye dönük "aslında orada durmayı hedefledim" yorumuyla yeniden etiketler; böylece negatif deneyimden de öğrenme mümkün olur.