Metadata-Version: 2.4
Name: rainbow-rb-sdk
Version: 0.0.9.dev10
Summary: Rainbow Robotics 통합 Python SDK — AMR, 매니퓰레이터, RB-Y1 휴머노이드와 Rainbow Robot Service(common) 연동
Author-email: Derek <dfd1123@rainbow-robotics.com>
Requires-Python: <3.13,>=3.12
Description-Content-Type: text/markdown
Requires-Dist: rainbow-rb-utils==0.0.9.dev10
Requires-Dist: rainbow-rb-zenoh==0.0.9.dev10
Requires-Dist: rainbow-rb-flat-buffers==0.0.9.dev10
Requires-Dist: rainbow-rb-schemas==0.0.9.dev10
Requires-Dist: rainbow-rb-log==0.0.9.dev10
Requires-Dist: rby1-sdk>=0.9.1

# rb_sdk

Rainbow Robotics 통합 Python SDK. AMR · Manipulator · RB-Y1 휴머노이드 제어와 Rainbow Robot Service(common) 연동을 단일 API로 제공합니다.

## 진입점

| 클래스 | 용도 |
|---|---|
| `RBAmrSDK` | AMR(자율 주행) 로봇 제어 |
| `RBManipulateSDK` | 협동 로봇 매니퓰레이터 제어 |
| `RBRby1SDK` | RB-Y1 휴머노이드 제어 |
| `RBBaseSDK` | 공통 베이스 (직접 상속하지 않는 한 사용할 일 없음) |

내부적으로 Zenoh pub/sub/query 메시 위에서 동작하며, 같은 PC(로봇 본체)에서 실행할 때는 별도 설정 없이 즉시 사용 가능합니다.

---

## 1. 설치

### 워크스페이스(rby2 모노레포 내부)

```bash
cd /path/to/rby2/backend
uv add rb_sdk --package your_package
```

### PyPI 설치

```bash
pip install rb_sdk
# RB-Y1 휴머노이드 제어가 필요하면 함께 설치
pip install rby1-sdk
```

`requires-python = ">=3.12,<3.13"` — Python 3.12 전용.

---

## 2. 기본 사용 (로봇 본체에서 실행하는 경우)

`common` 서비스와 같은 PC에서 실행되는 스크립트라면 추가 설정 없이 그대로 사용 가능합니다.

```python
from rb_sdk import RBAmrSDK, RBManipulateSDK

amr = RBAmrSDK()
manipulate = RBManipulateSDK()

# 이 시점에 ZenohClient가 127.0.0.1:7447(common)에 자동 연결
manipulate.move.call_move_j(
    robot_model="C500920",
    target={"tar_values": [0, 0, 0, 0, 0, 0], "tar_frame": 0, "tar_unit": 0},
)
```

`rb_sdk`는 lazy import 지원: `from rb_sdk import ...` 한 줄로 가져옵니다.

---

## 3. 외부 PC에서 사용 (Remote Connect)

개발용 노트북, 태블릿 등 **로봇 본체와 다른 머신**에서 SDK를 사용하는 경우, 두 가지를 함께 해야 합니다.

### 3-1. Zenoh 메시 연결 (필수)

ZenohClient가 remote common에 붙도록 환경변수 설정:

```bash
export ZENOH_PEER_CONNECT_ENDPOINTS=tcp/<common_host_ip>:7447
python my_script.py
```

### 3-2. common 측 peer 등록 (권장) — `sdk.connect()`

서버에서 외부 peer를 추적하고 끊김 감지가 필요하면 SDK의 `connect()`를 호출합니다.

```python
import asyncio
from rb_sdk import RBManipulateSDK

async def main():
    sdk = RBManipulateSDK()

    # common 서비스에 peer 등록 + 자동 heartbeat 시작
    peer_id = await sdk.connect(
        token="<JWT 토큰>",         # common 서비스 인증 토큰
        host="192.168.1.100",       # common이 떠 있는 PC IP
        ttl=30,                     # 서버 측 세션 TTL(초). heartbeat 끊기면 자동 해제
        # zenoh_port=None,          # None → OS가 빈 포트 자동 배정 (충돌 없음)
        # heartbeat_interval=15.0,  # 기본: ttl / 2
    )

    # ... SDK 호출 ...
    sdk.move.call_move_j(robot_model="C500920", target={...})

    await sdk.disconnect()

asyncio.run(main())
```

#### 주요 특징

- **로컬 IP 자동 감지**: `host` 방향의 라우팅 인터페이스 IP를 자동으로 찾아 common에 알림
- **포트 자동 배정**: 별도 지정 없이 OS가 빈 포트를 잡아주므로 포트 충돌 없음
- **자동 heartbeat**: 주기적으로 TTL 연장. 스크립트 종료 / 크래시 시 TTL 만료로 서버 측 정리
- **같은 PC 자동 감지**: `host`가 localhost거나 자기 IP인 경우 `connect()`는 아무것도 하지 않고 `None` 반환 (이미 메시 안에 있음)

#### connect() 인자

| 인자 | 타입 | 기본 | 설명 |
|---|---|---|---|
| `token` | `str` | (필수) | common 서비스 JWT |
| `host` | `str` | (필수) | common이 실행 중인 PC IP |
| `common_port` | `int` | `8000` | common HTTP 포트 |
| `zenoh_port` | `int \| None` | `None` | 로컬 Zenoh listen 포트. `None`이면 자동 |
| `ttl` | `int` | `30` | 서버 측 세션 TTL(초) |
| `heartbeat_interval` | `float \| None` | `None` | heartbeat 주기. `None`이면 `ttl/2` |

---

## 4. AMR SDK (`RBAmrSDK`)

```python
from rb_sdk import RBAmrSDK

sdk = RBAmrSDK()
```

| 하위 모듈 | 기능 |
|---|---|
| `move` | 이동 명령(`move_to`, `move_jog` 등) |
| `control` | 전원/긴급정지/잠금 등 |
| `localization` | 위치 추정 |
| `map` | 맵 로드/저장 |
| `setting` | 환경설정 |
| `file` | 맵/리소스 파일 관리 |
| `status` | 상태 조회 |

---

## 5. Manipulate SDK (`RBManipulateSDK`)

```python
from rb_sdk import RBManipulateSDK

sdk = RBManipulateSDK()
```

| 하위 모듈 | 기능 |
|---|---|
| `program` | 프로그램 실행/제어 |
| `move` | `call_move_j`, `call_move_l`, `call_move_jb_*` 등 |
| `config` | 환경설정/파라미터 |
| `io` | DIO/AIO 제어 |
| `get_data` | 상태·좌표 조회 |
| `point` | 포인트/좌표 등록 |
| `service` | 미니 탭 기능 |
| `maintenance` | 관리자 설정 |
| `state` | 실시간 상태 구독 |

---

## 6. RB-Y1 SDK (`RBRby1SDK`)

공식 `rby1-sdk` 래퍼.

```python
from rb_sdk import RBRby1SDK

sdk = RBRby1SDK(endpoint="192.168.30.1:50051", model=None, auto_connect=True)

print(sdk.connected)
print(sdk.whoami())

sdk.control.power_on()
sdk.control.servo_on()

state = sdk.state.get_state()
print(state)

sdk.disconnect()
```

> ⚠️ `RBRby1SDK.connect()` / `disconnect()`는 RB-Y1 gRPC endpoint 전용 메서드로, `RBBaseSDK.connect()`(common HTTP 등록)와 별개입니다. 자세한 차이는 클래스 docstring 참조.

지원 메서드:

- 공통: `connect()`, `disconnect()`, `whoami()`, `call(method, *args, **kwargs)`
- 제어: `control.invoke(...)`, `control.power_on()`, `control.servo_on()`
- 상태: `state.get_state()`

---

## 7. Flow Manager (PyFM) 연동

여러 SDK 메서드는 `flow_manager_args`를 받아 Step 실행 완료 시 `done()` 콜백을 호출합니다.

```python
from rb_schemas.sdk import FlowManagerArgs
from rb_sdk import RBManipulateSDK

sdk = RBManipulateSDK()

def step_func(flow_manager_args: FlowManagerArgs | None = None):
    sdk.move.call_move_j(
        robot_model="C500920",
        target={"tar_values": [0]*6, "tar_frame": 0, "tar_unit": 0},
        flow_manager_args=flow_manager_args,
    )
```

---

## 8. 주의사항

- `RBBaseSDK`는 프로세스 단위 싱글톤 + 공유 ZenohClient 구조입니다. 같은 프로세스에서 여러 번 `RBManipulateSDK()`를 호출해도 동일 인스턴스가 반환됩니다.
- `RBRby1SDK`는 최초 `endpoint/model` 기준으로 세션이 공유됩니다.
- 연결 대상(zenoh, rby1 endpoint, common HTTP)이 준비되지 않으면 런타임 예외가 발생합니다.
- 외부 PC에서 SDK 사용 시 **방화벽이 7447/TCP(zenoh)와 8000/TCP(common HTTP)을 양방향으로 허용**해야 합니다.

---

## 9. 라이선스 / 문의

© Rainbow Robotics. 내부 이슈/문의: [GitHub Issues](https://github.com/rainbowrobotics/rby2/issues)
