99 lines
5.2 KiB
Markdown
99 lines
5.2 KiB
Markdown
# llm_fsm
|
||
|
||
LLM을 이용해 로봇 조작(task) 스펙을 **런타임에 생성**하고, 이를 **FSM(Finite State Machine) 형태의 스킬 시퀀스**로 컴파일/실행하는 실험용 모듈입니다.
|
||
목적은 “LLM 기반 task를 실시간(online) 생성하는 시스템”을 IsaacLab 작업흐름에 연결했을 때, **스펙 생성 → 검증 → 실행 → 성공 판정**까지의 end-to-end 파이프라인을 빠르게 테스트하는 것입니다.
|
||
|
||
## 목표(What this is for)
|
||
|
||
- 활동(Activity) 템플릿(예: peg 삽입, drawer 상호작용)을 입력으로 받아 LLM이 `TaskSpec(JSON)`를 생성
|
||
- 생성된 스펙을 **화이트리스트 기반**으로 검증(허용 skill/predicate 및 필수 args)
|
||
- `TaskSpec`을 **배치 멀티 환경(N envs)**에서 실행 가능한 FSM으로 컴파일
|
||
- 환경 상태/센서 기반 predicate로 성공 여부를 판정
|
||
|
||
## 구성 요소(Modules)
|
||
|
||
- `task_activities.py`: 활동(시나리오) 카탈로그와 허용 오브젝트/픽스처 정의
|
||
- `llm_task_generator.py`: 활동 정의 + 허용 목록을 프롬프트로 넣고 `TaskSpec(JSON)`를 생성(OpenAI API)
|
||
- `llm_task_validator.py`: 생성 결과의 최소 계약(allowed skills/predicates, required args) 검증
|
||
- `llm_fsm_multi_env.py`: `TaskSpec` → Batched FSM/SuccessEvaluator 컴파일 및 러너
|
||
- `dotenv_loader.py`: `.env`를 `os.environ`에 주입(키 설정 용도)
|
||
- `run.py`: “활동 선택 → task 생성 → 검증 → 컴파일/실행” 예시 엔트리(현재는 스켈레톤)
|
||
|
||
## 시스템 설계(System Design)
|
||
|
||
### 핵심 아이디어
|
||
|
||
1) **스펙 레벨(TaskSpec)** 에서는 좌표/연속 제어를 금지하고, “무엇을 할지”만 기술합니다.
|
||
2) 실행 레벨에서는 `BatchedEnvAPI`/`RobotFacadeBatched`가 IsaacLab 환경과 컨트롤러를 감싸며, 스킬을 실제 동작으로 바꿉니다.
|
||
3) 성공 판정은 predicate의 AND 조합으로 처리합니다(`SuccessEvaluatorBatched.check()`).
|
||
|
||
### 데이터 흐름(Online task generation → execution)
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as run.py
|
||
participant Act as task_activities.py
|
||
participant LLM as llm_task_generator.py
|
||
participant Val as llm_task_validator.py
|
||
participant Comp as LLMFSMCompilerBatched
|
||
participant Env as BatchedEnvAPI/IsaacLab
|
||
User->>Act: activity 선택
|
||
User->>LLM: TaskSpec(JSON) 생성 요청
|
||
LLM-->>User: task_dict
|
||
User->>Val: validate_task_spec(task_dict)
|
||
User->>Comp: compile(env, TaskSpec)
|
||
Comp-->>User: CompiledTaskBatched
|
||
loop sim steps
|
||
User->>Env: evaluator.check()에 필요한 상태 조회
|
||
User->>Env: fsm.step() + step_physics()
|
||
end
|
||
```
|
||
|
||
1. `run.py`가 활동 키를 선택(`task_activities.py`)
|
||
2. `llm_task_generator.generate_task_spec_from_activity()`가 `TaskSpec(JSON dict)` 생성
|
||
3. `llm_task_validator.validate_task_spec()`가 스펙을 화이트리스트로 검증
|
||
4. `TaskSpec.from_dict()`로 dataclass로 변환(`llm_fsm_multi_env.py`)
|
||
5. `LLMFSMCompilerBatched.compile(env, task_spec)`가 다음을 구성
|
||
- `RobotFacadeBatched(env)`: EE 이동/그리퍼 동작/그립 판정 등의 로봇 파사드(사용자 구현 필요)
|
||
- `SkillFSMBatched`: env별 skill index를 가진 batched FSM
|
||
- `SuccessEvaluatorBatched`: predicate 기반 성공 판정
|
||
6. `run_compiled_task_multi_env()` 루프가 매 스텝
|
||
- predicate 체크 → 활성 env 선택 → FSM 진행 → 물리 스텝 → (옵션) 성공 env 리셋
|
||
|
||
## 실행(Quick Start)
|
||
|
||
### 1) API 키 설정
|
||
|
||
`scripts/llm_fsm/.env`에 OpenAI 키를 설정합니다.
|
||
|
||
```env
|
||
OPENAI_API_KEY=...
|
||
```
|
||
|
||
`run.py`는 실행 초기에 `.env`를 읽어 `os.environ`에 주입합니다.
|
||
|
||
### 2) 실행
|
||
|
||
```bash
|
||
python scripts/llm_fsm/run.py
|
||
python scripts/llm_fsm/run.py peg_alignment
|
||
```
|
||
|
||
현재 `run.py`는 예시 스켈레톤이며, 실제로는 IsaacLab의 배치 환경 인스턴스(예: `batched_env`)를 구성해 `compile(env=..., task_spec=...)`에 넘겨야 합니다.
|
||
온라인(실시간) 생성 실험을 하려면, 에피소드 시작/리셋 시점마다 2~6 단계를 반복하도록 루프를 구성하면 됩니다(예: `auto_reset_success=True` + 성공 env마다 새 task 생성 정책).
|
||
|
||
## IsaacLab 연동 포인트(You must implement)
|
||
|
||
`llm_fsm_multi_env.py`는 “어떤 환경/로봇이든” 붙일 수 있게 인터페이스만 정의해 두었습니다.
|
||
|
||
- `BatchedEnvAPI`: 이름으로 오브젝트/픽스처 pose 조회, contains 체크, 버튼/스위치/픽스처 상태, step/reset 등
|
||
- `RobotFacadeBatched`: EE pose 조회, IK 기반 이동(`move_ee_pose`), 그리퍼 open/close, grasp 판정(`is_grasped`) 등
|
||
|
||
스킬(`PickSkillBatched`, `AlignSkillBatched`, `InsertSkillBatched` 등)은 내부적으로 `RobotFacadeBatched`를 호출하므로, 위 두 레이어를 IsaacLab 컨트롤러/센서로 채우면 end-to-end가 동작합니다.
|
||
|
||
## 제약과 안전장치(Why it’s structured this way)
|
||
|
||
- LLM 출력은 **JSON only**이며, 허용된 엔티티/스킬/프레디킷만 사용하도록 프롬프트/검증으로 제약합니다.
|
||
- 스킬은 “연속 제어 목표(좌표/pose)”를 LLM이 만들지 않도록 하며, 실제 제어는 환경/컨트롤러가 담당합니다.
|
||
- 멀티 환경 실행을 기본으로 하여, 데이터 생성/통계 수집/안정성 평가에 유리합니다.
|