Agent skill
03-simulation
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/03-simulation
SKILL.md
3.5 ManiSkill 강화학습 환경
ManiSkill은 GPU 가속 병렬 시뮬레이션을 제공하는 강화학습 전용 로봇 환경입니다.
목차
- ManiSkill 소개
- 환경 설정
- XLeRobot 에이전트
- 키보드 제어 실습
- 강화학습 학습
- 커스텀 태스크 생성
ManiSkill 소개
ManiSkill이란?
ManiSkill은 로봇 조작(manipulation) 강화학습을 위한 벤치마크 환경으로, SAPIEN 물리 엔진 기반의 GPU 병렬 시뮬레이션을 제공합니다.
┌─────────────────────────────────────┐
│ ManiSkill 아키텍처 │
├─────────────────────────────────────┤
│ │
│ ┌─────────────────────────────┐ │
│ │ Gymnasium API │ │
│ │ (RL 표준 인터페이스) │ │
│ └─────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────┐ │
│ │ SAPIEN (물리 엔진) │ │
│ │ - GPU 병렬화 │ │
│ │ - PhysX 기반 │ │
│ └─────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────┐ │
│ │ 로봇 에이전트 │ │
│ │ - XLeRobot │ │
│ │ - Fetch, Panda 등 │ │
│ └─────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
주요 특징
- GPU 병렬 시뮬레이션: 수백 개 환경 동시 실행
- Gymnasium 호환: 표준 RL 인터페이스
- 벤치마크 태스크: PushCube, PickPlace, AssemblyTask 등
- 다양한 로봇: Fetch, Panda, XLeRobot 등
- 사실적인 환경: ReplicaCAD 씬 (실제 방 스캔)
MuJoCo vs ManiSkill 비교
| 항목 | MuJoCo | ManiSkill |
|---|---|---|
| 목적 | 제어 개발 | 강화학습 |
| 병렬화 | 1개 환경 | 수백 개 (GPU) |
| Gym 호환 | 수동 래핑 | 네이티브 |
| 태스크 | 직접 구현 | 사전 정의됨 |
| 학습 속도 | 느림 (CPU) | 빠름 (GPU) |
| 커스터마이징 | 쉬움 | 중간 |
환경 설정
시스템 요구사항
| 구성 요소 | 최소 | 권장 |
|---|---|---|
| OS | Ubuntu 20.04 | Ubuntu 22.04 |
| Python | 3.8 | 3.10+ |
| GPU | NVIDIA GTX 1060 (6GB) | RTX 3060 (12GB) |
| CUDA | 11.8+ | 12.0+ |
| RAM | 8GB | 16GB |
| 디스크 | 10GB | 20GB |
1단계: ManiSkill 설치
# XLeRobot ManiSkill 디렉토리로 이동
cd ~/XLeRobot/simulation/Maniskill/
# Python 가상 환경 생성
python3 -m venv .venv
source .venv/bin/activate
# ManiSkill 설치 (최신 버전)
pip install mani-skill
# 추가 의존성
pip install gymnasium
pip install sapien
pip install numpy
pip install torch # PyTorch (선택, RL 학습용)
설치 시간: 5-10분
2단계: XLeRobot 에이전트 등록 확인
# XLeRobot 에이전트 파일 확인
ls ~/XLeRobot/simulation/Maniskill/agents/xlerobot/
# 예상 출력:
# __init__.py
# xlerobot.py
agents/xlerobot/xlerobot.py 파일에 XLeRobot 에이전트 정의되어 있음:
xlerobot_single: 단일 팔 버전xlerobot_dual: 듀얼 팔 버전
3단계: 첫 실행 테스트
# ManiSkill 디렉토리에서
cd ~/XLeRobot/simulation/Maniskill/
# 가상 환경 활성화
source .venv/bin/activate
# 간단한 시뮬레이션 실행
python run_xlerobot_sim.py
예상 출력:
Starting XLeRobot simulation...
Environment created successfully!
Observation space: Dict(...)
Action space: Box(...)
Control mode: pd_joint_delta_pos
Reward mode: normalized_dense
Simulation is running. Close the viewer window to exit.
Keyboard Controls:
- W/S: Base Forward/Back
- A/D: Base Rotation
- Arrow keys: Arm control
- Space: Pause/Resume
3D 뷰어 창이 열리고 XLeRobot이 PushCube 태스크 환경에 있어야 합니다.
XLeRobot 에이전트
에이전트 종류
ManiSkill XLeRobot 구현에는 2가지 버전이 있습니다:
1. xlerobot_single (단일 팔)
robot_uids = "xlerobot_single"
구성:
- 옴니휠 베이스 (3자유도)
- 단일 SO-100 팔 (6자유도)
- 그리퍼 (1자유도)
- 총 10 DOF
용도: 단순한 pick-and-place 태스크
2. xlerobot_dual (듀얼 팔)
robot_uids = "xlerobot_dual"
구성:
- 옴니휠 베이스 (3자유도)
- 왼팔 SO-100 (6자유도)
- 오른팔 SO-100 (6자유도)
- 양손 그리퍼 (2자유도)
- 총 17 DOF
용도: 양손 협업 작업 (조립, 정리 등)
제어 모드
ManiSkill은 여러 제어 모드를 지원합니다:
| 모드 | 설명 | 입력 차원 | 난이도 |
|---|---|---|---|
pd_joint_delta_pos |
관절 증분 위치 | DOF 수 | ⭐⭐ 쉬움 |
pd_joint_pos |
관절 절대 위치 | DOF 수 | ⭐⭐ 쉬움 |
pd_joint_vel |
관절 속도 | DOF 수 | ⭐⭐⭐ 중간 |
pd_ee_delta_pose |
엔드이펙터 증분 포즈 | 7 (pos + quat) | ⭐⭐⭐⭐ 어려움 |
pd_ee_target_pose |
엔드이펙터 목표 포즈 | 7 | ⭐⭐⭐⭐ 어려움 |
추천: pd_joint_delta_pos (학습 초기)
관찰 모드
| 모드 | 설명 | 크기 | 용도 |
|---|---|---|---|
state |
로봇 상태 (관절 각도, 속도) | ~20-50 | 초기 학습 |
rgbd |
RGB-D 이미지 | (H, W, 4) | 비전 기반 정책 |
pointcloud |
포인트 클라우드 | (N, 3) | 3D 인식 |
sensor |
모든 센서 데이터 | 가변 | 복합 정책 |
추천: state (학습 초기)
키보드 제어 실습
ManiSkill에서 XLeRobot을 키보드로 제어하며 환경을 이해합니다.
실행 방법
cd ~/XLeRobot/simulation/Maniskill/
source .venv/bin/activate
# 키보드 제어 예제 실행 (단일 팔)
python examples/demo_ctrl_action_ee_keyboard_single.py \
-e "ReplicaCAD_SceneManipulation-v1" \
-r "xlerobot_single" \
--render-mode="human" \
--shader="rt-fast" \
-c "pd_joint_delta_pos"
파라미터 설명:
-e: 환경 ID (ReplicaCAD_SceneManipulation-v1)-r: 로봇 UID (xlerobot_single)--render-mode: 렌더링 모드 (human= GUI)--shader: 셰이더 (rt-fast= 빠른 렌더링)-c: 제어 모드 (pd_joint_delta_pos)
키보드 제어 키
베이스 제어
| 키 | 동작 |
|---|---|
W |
전진 |
S |
후진 |
A |
좌회전 |
D |
우회전 |
Q |
좌이동 |
E |
우이동 |
팔 제어 (화살표 키)
| 키 | 동작 |
|---|---|
↑ |
팔 위로 |
↓ |
팔 아래로 |
← |
팔 왼쪽으로 |
→ |
팔 오른쪽으로 |
[ |
팔 앞으로 |
] |
팔 뒤로 |
그리퍼
| 키 | 동작 |
|---|---|
G |
그리퍼 열기 |
H |
그리퍼 닫기 |
시스템
| 키 | 동작 |
|---|---|
Space |
일시정지/재개 |
R |
환경 리셋 |
ESC |
종료 |
실습: PushCube 태스크
목표: 큐브를 목표 위치로 밀기
절차:
- 프로그램 실행 (위 명령어)
- 뷰어 창에서 큐브와 목표 영역 확인
W/A/S/D로 베이스 이동- 화살표 키로 팔 위치 조정
- 큐브에 접근하여 밀기
- 목표 영역에 큐브가 들어가면 성공!
성공 기준:
- 큐브가 녹색 목표 영역 안에 위치
- Reward 값이 1.0에 가까워짐
강화학습 학습
ManiSkill의 진정한 강점은 GPU 병렬 시뮬레이션을 통한 빠른 RL 학습입니다.
1. Gymnasium 환경 생성
# simple_rl_example.py
import gymnasium as gym
import numpy as np
from mani_skill.envs.sapien_env import BaseEnv
# 병렬 환경 생성 (64개)
env_kwargs = dict(
obs_mode="state",
control_mode="pd_joint_delta_pos",
render_mode=None, # 학습 시에는 렌더링 OFF
robot_uids="xlerobot_single",
num_envs=64, # GPU 병렬화!
sim_backend="gpu", # GPU 시뮬레이션
)
env: BaseEnv = gym.make("PushCube-v1", **env_kwargs)
# 환경 리셋
obs, info = env.reset(seed=0)
print(f"Observation shape: {obs['agent']['qpos'].shape}") # (64, 10)
print(f"Action shape: {env.action_space.shape}") # (64, 10)
# 랜덤 액션 실행
for _ in range(100):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
print(f"Mean reward: {reward.mean():.3f}")
if terminated.any():
env.reset()
env.close()
실행:
python simple_rl_example.py
출력:
Observation shape: (64, 10) ← 64개 환경 병렬
Action shape: (64, 10)
Mean reward: -0.124
Mean reward: -0.089
...
2. PPO 학습 예제
Stable Baselines3를 사용한 PPO 학습:
# Stable Baselines3 설치
pip install stable-baselines3
# train_ppo.py
import gymnasium as gym
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
# 환경 생성 함수
def make_env():
env = gym.make(
"PushCube-v1",
obs_mode="state",
control_mode="pd_joint_delta_pos",
robot_uids="xlerobot_single",
num_envs=1,
render_mode=None,
)
return env
# 벡터화된 환경 (8개 병렬)
env = DummyVecEnv([make_env for _ in range(8)])
# PPO 모델 생성
model = PPO(
"MultiInputPolicy",
env,
verbose=1,
learning_rate=3e-4,
n_steps=2048,
batch_size=64,
n_epochs=10,
gamma=0.99,
device="cuda", # GPU 사용
)
# 학습 시작 (100만 스텝)
model.learn(total_timesteps=1_000_000)
# 모델 저장
model.save("xlerobot_pushcube_ppo")
print("Training complete!")
실행:
python train_ppo.py
예상 학습 시간:
- CPU: 8-12시간
- GPU (RTX 3060): 2-3시간
3. 학습된 모델 평가
# eval_policy.py
import gymnasium as gym
from stable_baselines3 import PPO
# 모델 로드
model = PPO.load("xlerobot_pushcube_ppo")
# 환경 생성 (렌더링 ON)
env = gym.make(
"PushCube-v1",
obs_mode="state",
control_mode="pd_joint_delta_pos",
robot_uids="xlerobot_single",
num_envs=1,
render_mode="human",
)
# 평가 루프
obs, _ = env.reset()
for _ in range(1000):
action, _ = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
env.render()
if terminated or truncated:
obs, _ = env.reset()
env.close()
실행:
python eval_policy.py
관찰 포인트:
- 로봇이 자동으로 큐브를 목표 위치로 이동
- 부드러운 움직임 (학습된 정책)
커스텀 태스크 생성
ManiSkill에서 자신만의 태스크를 만들 수 있습니다.
예제: PickAndPlace 태스크
# custom_task.py
import numpy as np
import sapien
from mani_skill.envs.sapien_env import BaseEnv
from mani_skill.utils import sapien_utils
from mani_skill.utils.registration import register_env
@register_env("XLeRobotPickPlace-v1", max_episode_steps=200)
class XLeRobotPickPlaceEnv(BaseEnv):
"""XLeRobot Pick and Place 태스크"""
SUPPORTED_ROBOTS = ["xlerobot_single"]
agent: "XLeRobotSingle"
def __init__(self, *args, robot_uids="xlerobot_single", **kwargs):
super().__init__(*args, robot_uids=robot_uids, **kwargs)
def _load_scene(self, options: dict):
"""씬 로드: 바닥, 테이블, 큐브, 목표 영역"""
# 바닥
self.scene.add_ground(altitude=0)
# 테이블
builder = self.scene.create_actor_builder()
builder.add_box_collision(half_size=[0.4, 0.4, 0.02])
builder.add_box_visual(half_size=[0.4, 0.4, 0.02], color=[0.8, 0.6, 0.4])
self.table = builder.build_static(name="table")
self.table.set_pose(sapien.Pose([0.5, 0, 0.4]))
# 큐브 (집을 물체)
builder = self.scene.create_actor_builder()
builder.add_box_collision(half_size=[0.02, 0.02, 0.02])
builder.add_box_visual(half_size=[0.02, 0.02, 0.02], color=[1, 0, 0])
self.cube = builder.build(name="cube")
# 목표 위치 시각화
builder = self.scene.create_actor_builder()
builder.add_sphere_visual(radius=0.03, color=[0, 1, 0, 0.5])
self.goal_site = builder.build_static(name="goal")
def _initialize_episode(self, env_idx: np.ndarray, options: dict):
"""에피소드 초기화: 로봇, 큐브, 목표 위치 랜덤 배치"""
# 큐브 위치 랜덤 (테이블 위)
cube_pos = np.array([0.5, 0, 0.45]) + np.random.uniform(-0.1, 0.1, 3)
cube_pos[2] = 0.45 # Z는 고정
self.cube.set_pose(sapien.Pose(cube_pos))
# 목표 위치 랜덤
goal_pos = np.array([0.5, 0, 0.45]) + np.random.uniform(-0.15, 0.15, 3)
goal_pos[2] = 0.45
self.goal_site.set_pose(sapien.Pose(goal_pos))
# 로봇 초기 위치
self.agent.robot.set_pose(sapien.Pose([0, 0, 0]))
def evaluate(self):
"""보상 계산"""
# 큐브와 목표 사이 거리
cube_pos = self.cube.pose.p
goal_pos = self.goal_site.pose.p
distance = np.linalg.norm(cube_pos - goal_pos)
# 거리 기반 보상
reward = -distance
# 성공 판정 (거리 < 5cm)
success = distance < 0.05
return {
"success": success,
"distance": distance,
"reward": reward,
}
def compute_dense_reward(self, obs, action, info):
"""Dense reward"""
return info["reward"]
def compute_normalized_dense_reward(self, obs, action, info):
"""Normalized reward [0, 1]"""
max_dist = 0.5
return np.clip(1 - info["distance"] / max_dist, 0, 1)
사용 방법:
# test_custom_task.py
import gymnasium as gym
from custom_task import XLeRobotPickPlaceEnv
env = gym.make(
"XLeRobotPickPlace-v1",
obs_mode="state",
control_mode="pd_joint_delta_pos",
render_mode="human",
)
obs, _ = env.reset()
for _ in range(1000):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
env.render()
print(f"Reward: {reward:.3f}, Distance: {info['distance']:.3f}")
if terminated or truncated:
obs, _ = env.reset()
env.close()
고급 기능
1. 데이터셋 수집
# collect_dataset.py
import gymnasium as gym
from mani_skill.utils.wrappers import RecordEpisode
# 환경 래핑 (데이터 기록)
env = gym.make("PushCube-v1", render_mode="cameras")
env = RecordEpisode(
env,
output_dir="./demos",
save_trajectory=True,
save_video=True,
)
# 데모 수집 (키보드 텔레오퍼레이션)
# ... 키보드로 제어하며 데이터 수집
# 저장된 데이터:
# - demos/trajectory_0.h5 (상태, 액션)
# - demos/video_0.mp4 (비디오)
활용: Imitation Learning (BC, GAIL)
2. ReplicaCAD 씬
# ReplicaCAD: 실제 방 스캔 데이터 기반 환경
env = gym.make(
"ReplicaCAD_SceneManipulation-v1",
robot_uids="xlerobot_single",
render_mode="human",
)
# 사실적인 가구, 물체 배치
# 복잡한 네비게이션 + 조작 태스크
3. Multi-Task Learning
# 여러 태스크 동시 학습
tasks = ["PushCube-v1", "PickCube-v1", "StackCube-v1"]
for task in tasks:
env = gym.make(task, robot_uids="xlerobot_dual")
# ... 학습
문제 해결
문제 1: ImportError: cannot import name 'XLeRobotSingle'
원인: XLeRobot 에이전트가 등록되지 않음
해결:
# 스크립트 맨 위에 추가
import sys
sys.path.insert(0, "/home/사용자명/XLeRobot/simulation/Maniskill")
from agents.xlerobot import xlerobot
문제 2: GPU 메모리 부족
원인: num_envs 너무 큼
해결:
# num_envs 줄이기
env_kwargs = dict(
num_envs=16, # 64 → 16
sim_backend="gpu",
)
문제 3: 렌더링 느림
원인: 고급 셰이더 사용
해결:
# rt-fast 대신 minimal 사용
--shader="minimal"
요약
핵심 포인트
- ManiSkill: GPU 병렬 RL 환경 (수백 개 동시 실행)
- XLeRobot 에이전트:
xlerobot_single,xlerobot_dual - 제어 모드:
pd_joint_delta_pos(초보자 추천) - 학습: PPO, SAC 등 표준 RL 알고리즘 사용
- 커스텀 태스크:
BaseEnv상속으로 쉽게 생성
다음 단계
- 3.6 URDF/MJCF 모델 →: 로봇 모델 파일 구조 이해
- 4장 하드웨어 →: 실제 로봇 조립
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?