# 02_robot_grasping: 2D 로봇 그리핑 커스텀 환경

간단한 2D 로봇 그리핑 문제를 Gymnasium 커스텀 환경으로 만들고, SB3 `PPO`로 학습하는 실습

## 목적

- 직접 만든 Gymnasium 환경 구조 확인
- SB3가 커스텀 환경과 상호작용하는 방식 확인
- 학습 중 관측값을 `.npy`로 저장하고 mp4 영상으로 변환

## 폴더 구조

- `grasp_env_2d.py`: `SimpleGraspEnv` 커스텀 Gymnasium 환경
- `train.py`: PPO 학습 실행 스크립트
- `obs_save_callback.py`: 학습 중 observation을 `.npy`로 저장하는 SB3 콜백
- `obs_to_video.py`: 저장된 observation `.npy`를 mp4로 변환
- `trained_models/`: 학습된 모델 저장 위치
- `obs_logs/`: 학습 중 저장된 observation 로그
- `videos/`: 변환된 영상 저장 위치

## 실행 전 준비

루트 프로젝트에서 공통 의존성을 먼저 설치

```bash
cd /home/kafa46/studies/reinforce_learning/play_with_sb3
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
```

## 환경 정의

- 행동(`Discrete(6)`)
  - `0`: left
  - `1`: right
  - `2`: up
  - `3`: down
  - `4`: gripper open
  - `5`: gripper close
- 관측(`shape=(6,)`)
  - arm x/y
  - object x/y
  - gripper state
  - grasped state
- 보상
  - 성공: `+1.0`
  - 실패: `-1.0`
  - 진행 중: step penalty + object까지의 거리 기반 penalty
- 종료 조건
  - gripper가 닫힌 상태에서 object와 충분히 가까우면 성공
  - 최대 step에 도달하면 truncated

## 실행 순서

작업 디렉터리: `02_robot_grasping`

### 1) PPO 모델 학습

```bash
cd /home/kafa46/studies/reinforce_learning/play_with_sb3/02_robot_grasping
python train.py --timesteps 50000 --seed 42 --verbose 0
```

예상 결과

- `trained_models/ppo-grasp-50000.model` 생성
- `obs_logs/<run_id>/grasp_obs_*.npy` 생성

### 2) observation 로그를 영상으로 변환

학습 출력의 `obs_logs:` 경로를 확인한 뒤 해당 디렉터리를 입력으로 사용

```bash
python obs_to_video.py \
  --input-dir obs_logs/<run_id> \
  --merge \
  --output videos/grasp_obs_merged.mp4
```

예상 결과

- 저장된 observation sequence를 프레임으로 렌더링
- `videos/grasp_obs_merged.mp4` 생성

## 핵심 흐름

```mermaid
flowchart LR
    A["SimpleGraspEnv<br/>Gymnasium Env"] --> B["SB3 PPO<br/>MlpPolicy"]
    B --> C["learn"]
    C --> D["trained model<br/>trained_models"]
    C --> E["ObsSaveCallback<br/>obs_logs npy"]
    E --> F["obs_to_video.py"]
    F --> G["mp4 videos"]
```

## 참고

- `obs_to_video.py`는 `(T, obs_dim)`과 `(T, n_env, obs_dim)` 형태의 observation 로그를 모두 처리합니다.
- `--merge`를 사용하면 여러 `.npy` 파일을 하나의 mp4로 합칩니다.
- `--fps`, `--size` 옵션으로 영상 속도와 해상도를 조정할 수 있습니다.
