ANYTHING EVERYTHING

[Robot Studio] 로봇 데이터 수집 시스템: ROS vs FastAPI, 어떤 걸 써야 할까?

by GomSon-E
반응형

🧸 Intro. 고민의 시작

 

로봇 데이터 수집 시스템을 설계하면서 큰 고민에 빠졌습니다.

"로봇에서 데이터를 수집할 때 굳이 ROS를 써야 할까? 그냥 FastAPI만 쓰면 안 되나?"

 

특히 XLeRobot 학습 가이드를 보면서 의문이 더 커졌습니다.

이 가이드에서는 FastAPI만으로 브라우저를 통해 로봇을 제어하는 시스템을 소개하고 있었거든요.

┌─────────────────┐
│     브라우저      │ (클라이언트)
└────────┬────────┘
         │ HTTP/WebSocket
┌────────▼────────┐
│   FastAPI 서버   │ (백엔드)
└────────┬────────┘
         │ Serial/Bluetooth
┌────────▼────────┐
│    XLeRobot     │ (하드웨어)
└─────────────────┘

"이렇게 간단하게 FastAPI로 로봇을 제어할 수 있는데, 데이터 수집도 FastAPI로 하면 안 될까?"

 

게다가 웹 UI를 만들고 싶은데, ROS와 웹을 연결하는 것이 너무 복잡해 보였습니다.

그래서 다음 4가지 옵션을 놓고 고민했습니다.

  1. PySide로 모든 것 하기 - 로컬 데스크톱 앱으로 통합
  2. PySide + 웹 혼용 - 데이터 수집은 PySide, 관리는 웹
  3. 웹 클라이언트만 - ROS + rosbridge + 웹 UI
  4. FastAPI만 사용 - ROS 없이 FastAPI로 센서 직접 제어

 

XLeRobot 웹 제어는 왜 FastAPI만 썼을까?

 

먼저 XLeRobot 웹 제어 시스템을 자세히 살펴보겠습니다.

# 간단한 제어 API
@app.post("/api/robot/gripper")
async def control_gripper(action: str):
    """그리퍼 열기/닫기"""
    if action == "open":
        robot.open_gripper()
    elif action == "close":
        robot.close_gripper()
    return {"status": "success"}
// 브라우저에서 버튼 클릭
document.getElementById('open-btn').onclick = () => {
    fetch('/api/robot/gripper', {
        method: 'POST',
        body: JSON.stringify({ action: 'open' })
    })
}

이 시스템은 제어(Control)만 하기 때문에 FastAPI로 충분합니다.

  • 사용자가 "그리퍼 열어" 버튼 클릭
  • 100ms 후 서버에 도착
  • 로봇이 그리퍼를 엶
  • 타임스탬프는 중요하지 않음

 

하지만 데이터 수집은 다르다

Imitation Learning을 위한 데이터 수집은 완전히 다른 요구사항을 갖습니다.

 

1. 타임스탬프 동기화가 필수

# 학습 데이터 형식
{
  "timestamp": 1.234,
  "observation": {
    "image": [...],      # 이 순간 카메라가 본 것
    "joint_pos": [...]   # 정확히 이 순간의 관절 위치
  },
  "action": {
    "target_pos": [...]  # 다음에 움직일 위치
  }
}

만약 타임스탬프가 맞지 않으면 다음과 같은 문제가 발생합니다.

❌ 잘못된 동기화
이미지: 컵을 들어올리는 중 (t=1.0초)
모터 상태: 아직 테이블에 닿지 않음 (t=0.5초)

→ AI가 "컵을 들려면 테이블에서 멀리 있어야 한다"고 잘못 학습

 

2. 실시간성

예를 들어, 30fps 카메라(33ms 간격)와 50Hz 모터(20ms 간격)의 데이터를 수집하는 상황을 가정해봅시다.

시간 (ms) 카메라 모터
0 ✓ Frame 1 ✓ State 1
20   ✓ State 2
33 ✓ Frame 2  
40   ✓ State 3
60   ✓ State 4
66 ✓ Frame 3  

ROS의 장점

  • DDS 기반 pub-sub: ~1ms 레이턴시
  • 자동 타임스탬프 동기화
  • 센서 데이터를 정확히 매칭

FastAPI의 한계

  • HTTP 오버헤드: ~10-100ms
  • 각 센서가 별도 HTTP 요청으로 전송
  • 서버 도착 시간이 제각각 → 동기화 불가능
# FastAPI로 시도하면?
@app.post("/api/camera")
async def receive_image(image: bytes):
    # 언제 도착할지 예측 불가
    pass

@app.post("/api/motor")
async def receive_motor(state: dict):
    # 위 이미지와 어떻게 매칭?
    pass

 

3. 로봇 생태계 호환성

대부분의 로봇 하드웨어는 ROS 드라이버로 제공됩니다.

  • Intel Realsense 카메라: realsense-ros
  • Universal Robots 암: ur_robot_driver
  • Lidar 센서: velodyne_driver

LeRobot, Phosphobot 같은 Imitation Learning 프레임워크도 ROS기반입니다.

 

제어 vs 데이터 수집: 핵심 차이

구분 제어 데이터 수집
목적 로봇 조작 학습 데이터셋 생성
타임스탬프 불필요 필수 (마이크로초 단위)
예시 그리퍼 열어 이미지@1.234초=모터@1.234초
레이턴시 100ms도 괜찮음 1ms이하필요
적합기술 FastAPI ROS
프로토콜 HTTP/WebSocket DDS (pub-sub)

여러 센서(카메라, 모터, IMU 등)의 데이터를 정확한 타임스탬프로 동기화해야 하는

Imitation Learning 데이터 수집에는 ROS가 필수입니다.

XLeRobot 웹 제어 시스템은 단순 제어만 하기 때문에 FastAPI로 충분했지만,

우리는 AI 학습을 위한 정밀한 데이터를 수집해야 합니다.

FastAPI로는 이런 마이크로초 단위 동기화가 불가능합니다.

 

그렇다면 UI는 어떻게 구성해야 할까?

데이터 수집에는 ROS가 필요하다는 것을 알았습니다. 하지만 UI는 어떻게 해야 할까요?

데이터 수집 중에는 실시간 응답이 중요하지만, 수집이 끝난 후에는 원격에서 편리하게 관리할 수 있어야 합니다.

 

PySide (로컬 데스크톱 UI)

PySide는 ROS와 같은 PC에서 실행되기 때문에 네트워크 지연 없이 빠른 응답을 제공합니다.

Python 기반이라 ROS 노드와 쉽게 통합할 수 있으며, 인터넷 연결 없이도 오프라인으로 동작 가능합니다.

특히 데이터 수집 중에는 실시간 카메라 프리뷰와 모터 상태를 즉각적으로 확인할 수 있어야 하는데,

PySide는 이런 요구사항에 최적화되어 있습니다.

 

사용 시나리오

  • 데이터 수집 중 실시간 모니터링
  • 로봇 옆에서 직접 조작할 때
  • 낮은 레이턴시가 필요한 작업

 

웹 UI (FastAPI + 브라우저)

웹 UI는 브라우저만 있으면 어디서나 접근할 수 있다는 것이 가장 큰 장점입니다.

XLeRobot 웹 제어 레퍼런스처럼 간단한 HTTP/WebSocket 구조로 구현할 수 있으며,

대시보드와 차트 같은 시각화 도구를 쉽게 활용할 수 있습니다.

데이터 수집이 끝난 후에는 실시간성이 중요하지 않기 때문에,

저장된 에피소드를 조회하거나 모델을 학습하는 등의 작업은 웹으로 하는 것이 훨씬 편리합니다.

 

사용 시나리오

  • 데이터 수집 외 모든 것 (관리, 모니터링, 분석)
  • 원격에서 접근할 때
  • 여러 사람이 동시에 접근해야 할 때

 

역할 분담

작업 UI 이유
데이터 수집 중 제어 PySide 실시간 응답 필요
수집 중 카메라 프리뷰 PySide 낮은 레이턴시
에피소드 목록 조회 원격 접근
데이터셋 통계 확인 차트 시각화 편리
학습 결과 모니터링 어디서나 확인
간단한 로봇 제어 XLeRobot 레퍼런스와 같은 원격 제어

 

최종 결정

로봇 PC                        

  ROS2                 
  ├── 카메라 노드                
  ├── 모터 노드                   
  └── 데이터 집계 노드                       
                                      
  PySide UI                  
  ├── [시작] [중지] [완료] 버튼            
  ├── 실시간 카메라 프리뷰               
  └── 모터 상태 모니터링                 
                                     
          │      
          │	HTTP (에피소드 완료 시)
          ↓

서버 PC
                                        
  FastAPI
  ├── REST API                        
  ├── PostgreSQL           
  └── MinIO  
                            
  웹 UI             
  ├── 에피소드 목록 및 검색     
  ├── 데이터셋 통계 대시보드
  ├── 모델 학습         
  ├── 간단한 로봇 제어
  └── ...

 

왜 이 구조인가?

  1. ROS (데이터 수집)
    • 타임스탬프 동기화 필수
    • 실시간성 필수
    • 로봇 하드웨어 생태계 활용에 용이
  2. PySide (데이터 수집 UI)
    • 로봇 옆에서 빠른 응답 필요
    • ROS와 같은 PC에서 실행 필수
    • 레이턴시 최소화
  3. FastAPI + 웹 (관리 UI)
    • 데이터 수집은 끝남 → 실시간성 불필요
    • 어디서나 접근 가능
    • 간단한 구조
    • 대시보드, 분석, 통계에 최적

 

🔗 Reference.

반응형

블로그의 정보

Anything Everything

GomSon-E

활동하기