rainbow-rb-sdk 0.0.9.dev17__tar.gz → 0.0.9.dev18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {rainbow_rb_sdk-0.0.9.dev17/src/rainbow_rb_sdk.egg-info → rainbow_rb_sdk-0.0.9.dev18}/PKG-INFO +138 -7
  2. rainbow_rb_sdk-0.0.9.dev17/PKG-INFO → rainbow_rb_sdk-0.0.9.dev18/README.md +132 -15
  3. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/pyproject.toml +6 -6
  4. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_setting.py +43 -67
  5. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/base.py +11 -0
  6. rainbow_rb_sdk-0.0.9.dev17/README.md → rainbow_rb_sdk-0.0.9.dev18/src/rainbow_rb_sdk.egg-info/PKG-INFO +146 -1
  7. rainbow_rb_sdk-0.0.9.dev18/src/rainbow_rb_sdk.egg-info/requires.txt +6 -0
  8. rainbow_rb_sdk-0.0.9.dev17/src/rainbow_rb_sdk.egg-info/requires.txt +0 -6
  9. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/setup.cfg +0 -0
  10. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/__init__.py +0 -0
  11. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr.py +0 -0
  12. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/__init__.py +0 -0
  13. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_accessory.py +0 -0
  14. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_capability.py +0 -0
  15. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_control.py +0 -0
  16. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_file.py +0 -0
  17. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_localization.py +0 -0
  18. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_map.py +0 -0
  19. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_move.py +0 -0
  20. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_program.py +0 -0
  21. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/amr_status.py +0 -0
  22. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/amr_sdk/schema/__init__.py +0 -0
  23. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/base_sdk/__init__.py +0 -0
  24. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/base_sdk/base_schema.py +0 -0
  25. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate.py +0 -0
  26. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/__init__.py +0 -0
  27. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_config.py +0 -0
  28. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_get_data.py +0 -0
  29. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_io.py +0 -0
  30. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_maintenance.py +0 -0
  31. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_move.py +0 -0
  32. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_point.py +0 -0
  33. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_program.py +0 -0
  34. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_service.py +0 -0
  35. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/manipulate_state.py +0 -0
  36. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/schema/__init__.py +0 -0
  37. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/schema/manipulate_config_schema.py +0 -0
  38. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/schema/manipulate_io_schema.py +0 -0
  39. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/schema/manipulate_move_schema.py +0 -0
  40. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/manipulate_sdk/schema/manipulate_program_schema.py +0 -0
  41. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/program_sdk/__init__.py +0 -0
  42. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/program_sdk/client_modules.pyi +0 -0
  43. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/program_sdk/program.py +0 -0
  44. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/program_sdk/program_interface.py +0 -0
  45. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/program_sdk/test_binding.py +0 -0
  46. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1.py +0 -0
  47. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/__init__.py +0 -0
  48. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/base.py +0 -0
  49. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/client.py +0 -0
  50. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/config.py +0 -0
  51. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/control.py +0 -0
  52. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/exceptions.py +0 -0
  53. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/rby1_sdk/state.py +0 -0
  54. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/schema/__init__.py +0 -0
  55. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/schema/amr_schema.py +0 -0
  56. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/schema/base_schema.py +0 -0
  57. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/schema/manipulate_schema.py +0 -0
  58. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow/rb_sdk/schema/program_schema.py +0 -0
  59. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow_rb_sdk.egg-info/SOURCES.txt +0 -0
  60. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow_rb_sdk.egg-info/dependency_links.txt +0 -0
  61. {rainbow_rb_sdk-0.0.9.dev17 → rainbow_rb_sdk-0.0.9.dev18}/src/rainbow_rb_sdk.egg-info/top_level.txt +0 -0
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rainbow-rb-sdk
3
- Version: 0.0.9.dev17
3
+ Version: 0.0.9.dev18
4
4
  Summary: Rainbow Robotics 통합 Python SDK — AMR, 매니퓰레이터, RB-Y1 휴머노이드와 Rainbow Robot Service(common) 연동
5
5
  Author-email: Derek <dfd1123@rainbow-robotics.com>
6
6
  Requires-Python: <3.13,>=3.12
7
7
  Description-Content-Type: text/markdown
8
- Requires-Dist: rainbow-rb-utils==0.0.9.dev17
9
- Requires-Dist: rainbow-rb-zenoh==0.0.9.dev17
10
- Requires-Dist: rainbow-rb-flat-buffers==0.0.9.dev17
11
- Requires-Dist: rainbow-rb-schemas==0.0.9.dev17
12
- Requires-Dist: rainbow-rb-log==0.0.9.dev17
8
+ Requires-Dist: rainbow-rb-utils==0.0.9.dev18
9
+ Requires-Dist: rainbow-rb-zenoh==0.0.9.dev18
10
+ Requires-Dist: rainbow-rb-flat-buffers==0.0.9.dev18
11
+ Requires-Dist: rainbow-rb-schemas==0.0.9.dev18
12
+ Requires-Dist: rainbow-rb-log==0.0.9.dev18
13
13
  Requires-Dist: rby1-sdk>=0.9.1
14
14
 
15
15
  # rb_sdk
@@ -326,6 +326,137 @@ RBBaseSDK.close_all_for_pid() # 현재 프로세스의 모든 SDK 인스
326
326
 
327
327
  ---
328
328
 
329
- ## 11. 라이선스 / 문의
329
+ ## 11. Subscribe / Queryable
330
+
331
+ SDK를 상속하거나 직접 사용해 **Zenoh 이벤트를 수신(subscribe)** 하거나 **RPC 응답자(queryable)** 를 등록할 수 있습니다.
332
+
333
+ ### 11-1. `zenoh_subscribe` — 토픽 구독 (데코레이터)
334
+
335
+ ```python
336
+ from rb_sdk import RBManipulateSDK
337
+ from rb_zenoh.schema import SubscribeOptions, OverflowPolicy
338
+
339
+ sdk = RBManipulateSDK()
340
+
341
+ # dict 페이로드로 수신 (기본)
342
+ @sdk.zenoh_subscribe("amr/AMR001/status")
343
+ def on_status(*, dict_payload: dict | None, **kwargs):
344
+ print("status:", dict_payload)
345
+
346
+ # FlatBuffer 오브젝트로 수신
347
+ from rb_flat_buffers.IPC.MoveStatus import MoveStatusT
348
+
349
+ @sdk.zenoh_subscribe(
350
+ "amr/AMR001/moveStatus",
351
+ flatbuffer_obj_t=MoveStatusT,
352
+ opts=SubscribeOptions(
353
+ dispatch="queue",
354
+ overflow=OverflowPolicy.LATEST_ONLY,
355
+ parse_dict_payload=False,
356
+ ),
357
+ )
358
+ def on_move_status(*, obj_payload: MoveStatusT, **kwargs):
359
+ print("move status:", obj_payload)
360
+
361
+ # mv를 직접 받아 수동으로 파싱하는 패턴 (flatbuffer_obj_t 미지정)
362
+ from rb_flat_buffers.IPC.State_Core import State_Core
363
+
364
+ @sdk.zenoh_subscribe(
365
+ "C500920/state_core",
366
+ opts=SubscribeOptions(
367
+ dispatch="queue",
368
+ overflow=OverflowPolicy.LATEST_ONLY,
369
+ parse_dict_payload=False,
370
+ ),
371
+ )
372
+ def on_state_core(*, mv=None, **kwargs):
373
+ if mv is None:
374
+ return
375
+ obj = State_Core.GetRootAs(mv, 0)
376
+ print("motion mode:", obj.MotionMode())
377
+ ```
378
+
379
+ #### `zenoh_subscribe` 인자
380
+
381
+ | 인자 | 타입 | 기본 | 설명 |
382
+ |---|---|---|---|
383
+ | `topic` | `str` | (필수) | Zenoh key expression (예: `"amr/{model}/status"`) |
384
+ | `flatbuffer_obj_t` | FlatBuffer T 클래스 \| `None` | `None` | FlatBuffer로 역직렬화할 때 지정. `None`이면 콜백에 `mv: memoryview` 전달 |
385
+ | `opts` | `SubscribeOptions \| None` | `None` | 디스패치 / 오버플로우 옵션 |
386
+
387
+ #### `SubscribeOptions` 필드
388
+
389
+ | 필드 | 기본 | 설명 |
390
+ |---|---|---|
391
+ | `dispatch` | `"immediate"` | `"immediate"`: 수신 스레드에서 바로 콜백. `"queue"`: C++ bounded queue + 전용 dispatch 스레드 |
392
+ | `parse_dict_payload` | `True` | FlatBuffer 수신 시 `False`로 지정 |
393
+ | `overflow` | `DROP_OLDEST` | `DROP_OLDEST` / `DROP_NEW` / `LATEST_ONLY` |
394
+ | `maxsize` | `50` | `"queue"` 모드의 C++ 큐 최대 크기 |
395
+ | `rate_limit_per_sec` | `None` | 초당 최대 콜백 호출 수 |
396
+ | `sample_every` | `1` | N개 중 1개만 전달 (1 = 전부) |
397
+ | `max_async_inflight` | `1` | async 콜백 동시 실행 허용 수 |
398
+
399
+ #### 직접 subscribe (handle 보관이 필요한 경우)
400
+
401
+ 데코레이터 대신 `zenoh_client.subscribe()`를 직접 호출하면 handle을 직접 관리할 수 있습니다.
402
+
403
+ ```python
404
+ sub_handle = sdk.zenoh_client.subscribe(
405
+ "amr/AMR001/moveStatus",
406
+ callback,
407
+ flatbuffer_obj_t=MoveStatusT,
408
+ options=SubscribeOptions(dispatch="queue", overflow=OverflowPolicy.LATEST_ONLY),
409
+ )
410
+
411
+ # 구독 해제
412
+ sub_handle.close()
413
+ ```
414
+
415
+ ---
416
+
417
+ ### 11-2. `zenoh_queryable` — RPC 응답자 (데코레이터)
418
+
419
+ 원격에서 `get(keyexpr)` 요청이 오면 등록된 handler가 호출되어 응답을 반환합니다.
420
+
421
+ ```python
422
+ from rb_sdk import RBManipulateSDK
423
+
424
+ sdk = RBManipulateSDK()
425
+
426
+ # dict 요청 (payload 없음) → dict 반환
427
+ # params는 URL query string (예: ?model=C500920)을 파싱한 dict[str, str]
428
+ @sdk.zenoh_queryable("my_service/robot_status")
429
+ def handle_status_query(*, params: dict[str, str]) -> dict:
430
+ return {"status": "ok", "model": params.get("model")}
431
+
432
+ # FlatBuffer 요청 수신 → FlatBuffer 응답
433
+ from rb_flat_buffers.manipulate.RB_Functions import RB_FunctionsT
434
+
435
+ @sdk.zenoh_queryable(
436
+ "my_service/move_j",
437
+ flatbuffer_req_T_class=RB_FunctionsT,
438
+ flatbuffer_res_buf_size=256,
439
+ )
440
+ def handle_move_j(*, req: RB_FunctionsT, params: dict[str, str]) -> RB_FunctionsT:
441
+ res = RB_FunctionsT()
442
+ res.returnValue = 0
443
+ return res
444
+ ```
445
+
446
+ #### `zenoh_queryable` 인자
447
+
448
+ | 인자 | 타입 | 기본 | 설명 |
449
+ |---|---|---|---|
450
+ | `keyexpr` | `str` | (필수) | Zenoh key expression (예: `"my_service/status"`) |
451
+ | `flatbuffer_req_T_class` | FlatBuffer T 클래스 \| `None` | `None` | 요청 페이로드를 FlatBuffer로 역직렬화할 때 지정 |
452
+ | `flatbuffer_res_buf_size` | `int \| None` | `None` | FlatBuffer 응답 직렬화 버퍼 크기(바이트). FlatBuffer 응답 시 필수 |
453
+
454
+ #### 중복 등록 방지
455
+
456
+ 같은 `keyexpr`로 이미 등록된 queryable이 있으면 경고 메시지를 출력하고 기존 handler를 유지합니다. SDK `close()` 시 자동 해제됩니다.
457
+
458
+ ---
459
+
460
+ ## 12. 라이선스 / 문의
330
461
 
331
462
  © Rainbow Robotics. 내부 이슈/문의: [GitHub Issues](https://github.com/rainbow-mobile/rainbow-release-apps/issues)
@@ -1,17 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: rainbow-rb-sdk
3
- Version: 0.0.9.dev17
4
- Summary: Rainbow Robotics 통합 Python SDK — AMR, 매니퓰레이터, RB-Y1 휴머노이드와 Rainbow Robot Service(common) 연동
5
- Author-email: Derek <dfd1123@rainbow-robotics.com>
6
- Requires-Python: <3.13,>=3.12
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: rainbow-rb-utils==0.0.9.dev17
9
- Requires-Dist: rainbow-rb-zenoh==0.0.9.dev17
10
- Requires-Dist: rainbow-rb-flat-buffers==0.0.9.dev17
11
- Requires-Dist: rainbow-rb-schemas==0.0.9.dev17
12
- Requires-Dist: rainbow-rb-log==0.0.9.dev17
13
- Requires-Dist: rby1-sdk>=0.9.1
14
-
15
1
  # rb_sdk
16
2
 
17
3
  Rainbow Robotics 통합 Python SDK. AMR · Manipulator · RB-Y1 양팔로봇 제어와 Rainbow Robot Service(common) 연동을 단일 API로 제공합니다.
@@ -326,6 +312,137 @@ RBBaseSDK.close_all_for_pid() # 현재 프로세스의 모든 SDK 인스
326
312
 
327
313
  ---
328
314
 
329
- ## 11. 라이선스 / 문의
315
+ ## 11. Subscribe / Queryable
316
+
317
+ SDK를 상속하거나 직접 사용해 **Zenoh 이벤트를 수신(subscribe)** 하거나 **RPC 응답자(queryable)** 를 등록할 수 있습니다.
318
+
319
+ ### 11-1. `zenoh_subscribe` — 토픽 구독 (데코레이터)
320
+
321
+ ```python
322
+ from rb_sdk import RBManipulateSDK
323
+ from rb_zenoh.schema import SubscribeOptions, OverflowPolicy
324
+
325
+ sdk = RBManipulateSDK()
326
+
327
+ # dict 페이로드로 수신 (기본)
328
+ @sdk.zenoh_subscribe("amr/AMR001/status")
329
+ def on_status(*, dict_payload: dict | None, **kwargs):
330
+ print("status:", dict_payload)
331
+
332
+ # FlatBuffer 오브젝트로 수신
333
+ from rb_flat_buffers.IPC.MoveStatus import MoveStatusT
334
+
335
+ @sdk.zenoh_subscribe(
336
+ "amr/AMR001/moveStatus",
337
+ flatbuffer_obj_t=MoveStatusT,
338
+ opts=SubscribeOptions(
339
+ dispatch="queue",
340
+ overflow=OverflowPolicy.LATEST_ONLY,
341
+ parse_dict_payload=False,
342
+ ),
343
+ )
344
+ def on_move_status(*, obj_payload: MoveStatusT, **kwargs):
345
+ print("move status:", obj_payload)
346
+
347
+ # mv를 직접 받아 수동으로 파싱하는 패턴 (flatbuffer_obj_t 미지정)
348
+ from rb_flat_buffers.IPC.State_Core import State_Core
349
+
350
+ @sdk.zenoh_subscribe(
351
+ "C500920/state_core",
352
+ opts=SubscribeOptions(
353
+ dispatch="queue",
354
+ overflow=OverflowPolicy.LATEST_ONLY,
355
+ parse_dict_payload=False,
356
+ ),
357
+ )
358
+ def on_state_core(*, mv=None, **kwargs):
359
+ if mv is None:
360
+ return
361
+ obj = State_Core.GetRootAs(mv, 0)
362
+ print("motion mode:", obj.MotionMode())
363
+ ```
364
+
365
+ #### `zenoh_subscribe` 인자
366
+
367
+ | 인자 | 타입 | 기본 | 설명 |
368
+ |---|---|---|---|
369
+ | `topic` | `str` | (필수) | Zenoh key expression (예: `"amr/{model}/status"`) |
370
+ | `flatbuffer_obj_t` | FlatBuffer T 클래스 \| `None` | `None` | FlatBuffer로 역직렬화할 때 지정. `None`이면 콜백에 `mv: memoryview` 전달 |
371
+ | `opts` | `SubscribeOptions \| None` | `None` | 디스패치 / 오버플로우 옵션 |
372
+
373
+ #### `SubscribeOptions` 필드
374
+
375
+ | 필드 | 기본 | 설명 |
376
+ |---|---|---|
377
+ | `dispatch` | `"immediate"` | `"immediate"`: 수신 스레드에서 바로 콜백. `"queue"`: C++ bounded queue + 전용 dispatch 스레드 |
378
+ | `parse_dict_payload` | `True` | FlatBuffer 수신 시 `False`로 지정 |
379
+ | `overflow` | `DROP_OLDEST` | `DROP_OLDEST` / `DROP_NEW` / `LATEST_ONLY` |
380
+ | `maxsize` | `50` | `"queue"` 모드의 C++ 큐 최대 크기 |
381
+ | `rate_limit_per_sec` | `None` | 초당 최대 콜백 호출 수 |
382
+ | `sample_every` | `1` | N개 중 1개만 전달 (1 = 전부) |
383
+ | `max_async_inflight` | `1` | async 콜백 동시 실행 허용 수 |
384
+
385
+ #### 직접 subscribe (handle 보관이 필요한 경우)
386
+
387
+ 데코레이터 대신 `zenoh_client.subscribe()`를 직접 호출하면 handle을 직접 관리할 수 있습니다.
388
+
389
+ ```python
390
+ sub_handle = sdk.zenoh_client.subscribe(
391
+ "amr/AMR001/moveStatus",
392
+ callback,
393
+ flatbuffer_obj_t=MoveStatusT,
394
+ options=SubscribeOptions(dispatch="queue", overflow=OverflowPolicy.LATEST_ONLY),
395
+ )
396
+
397
+ # 구독 해제
398
+ sub_handle.close()
399
+ ```
400
+
401
+ ---
402
+
403
+ ### 11-2. `zenoh_queryable` — RPC 응답자 (데코레이터)
404
+
405
+ 원격에서 `get(keyexpr)` 요청이 오면 등록된 handler가 호출되어 응답을 반환합니다.
406
+
407
+ ```python
408
+ from rb_sdk import RBManipulateSDK
409
+
410
+ sdk = RBManipulateSDK()
411
+
412
+ # dict 요청 (payload 없음) → dict 반환
413
+ # params는 URL query string (예: ?model=C500920)을 파싱한 dict[str, str]
414
+ @sdk.zenoh_queryable("my_service/robot_status")
415
+ def handle_status_query(*, params: dict[str, str]) -> dict:
416
+ return {"status": "ok", "model": params.get("model")}
417
+
418
+ # FlatBuffer 요청 수신 → FlatBuffer 응답
419
+ from rb_flat_buffers.manipulate.RB_Functions import RB_FunctionsT
420
+
421
+ @sdk.zenoh_queryable(
422
+ "my_service/move_j",
423
+ flatbuffer_req_T_class=RB_FunctionsT,
424
+ flatbuffer_res_buf_size=256,
425
+ )
426
+ def handle_move_j(*, req: RB_FunctionsT, params: dict[str, str]) -> RB_FunctionsT:
427
+ res = RB_FunctionsT()
428
+ res.returnValue = 0
429
+ return res
430
+ ```
431
+
432
+ #### `zenoh_queryable` 인자
433
+
434
+ | 인자 | 타입 | 기본 | 설명 |
435
+ |---|---|---|---|
436
+ | `keyexpr` | `str` | (필수) | Zenoh key expression (예: `"my_service/status"`) |
437
+ | `flatbuffer_req_T_class` | FlatBuffer T 클래스 \| `None` | `None` | 요청 페이로드를 FlatBuffer로 역직렬화할 때 지정 |
438
+ | `flatbuffer_res_buf_size` | `int \| None` | `None` | FlatBuffer 응답 직렬화 버퍼 크기(바이트). FlatBuffer 응답 시 필수 |
439
+
440
+ #### 중복 등록 방지
441
+
442
+ 같은 `keyexpr`로 이미 등록된 queryable이 있으면 경고 메시지를 출력하고 기존 handler를 유지합니다. SDK `close()` 시 자동 해제됩니다.
443
+
444
+ ---
445
+
446
+ ## 12. 라이선스 / 문의
330
447
 
331
448
  © Rainbow Robotics. 내부 이슈/문의: [GitHub Issues](https://github.com/rainbow-mobile/rainbow-release-apps/issues)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rainbow-rb-sdk"
7
- version = "0.0.9.dev17"
7
+ version = "0.0.9.dev18"
8
8
  requires-python = ">=3.12,<3.13"
9
9
  description = "Rainbow Robotics 통합 Python SDK — AMR, 매니퓰레이터, RB-Y1 휴머노이드와 Rainbow Robot Service(common) 연동"
10
10
  authors = [
@@ -13,11 +13,11 @@ authors = [
13
13
  readme = "README.md"
14
14
 
15
15
  dependencies = [
16
- "rainbow-rb-utils==0.0.9.dev17",
17
- "rainbow-rb-zenoh==0.0.9.dev17",
18
- "rainbow-rb-flat-buffers==0.0.9.dev17",
19
- "rainbow-rb-schemas==0.0.9.dev17",
20
- "rainbow-rb-log==0.0.9.dev17",
16
+ "rainbow-rb-utils==0.0.9.dev18",
17
+ "rainbow-rb-zenoh==0.0.9.dev18",
18
+ "rainbow-rb-flat-buffers==0.0.9.dev18",
19
+ "rainbow-rb-schemas==0.0.9.dev18",
20
+ "rainbow-rb-log==0.0.9.dev18",
21
21
  "rby1-sdk>=0.9.1",
22
22
  ]
23
23
 
@@ -9,6 +9,7 @@ from rainbow.rb_flat_buffers.SLAMNAV.RequestGetSensorInfo import RequestGetSenso
9
9
  from rainbow.rb_flat_buffers.SLAMNAV.RequestGetSensorMode import RequestGetSensorModeT
10
10
  from rainbow.rb_flat_buffers.SLAMNAV.RequestGetSettingCategory import RequestGetSettingCategoryT
11
11
  from rainbow.rb_flat_buffers.SLAMNAV.RequestGetSettingParam import RequestGetSettingParamT
12
+ from rainbow.rb_flat_buffers.SLAMNAV.RequestRTSPSubscribe import RequestRTSPSubscribeT
12
13
  from rainbow.rb_flat_buffers.SLAMNAV.RequestSetPduParam import RequestSetPduParamT
13
14
  from rainbow.rb_flat_buffers.SLAMNAV.RequestSetRobotType import RequestSetRobotTypeT
14
15
  from rainbow.rb_flat_buffers.SLAMNAV.RequestSetSensorInfo import RequestSetSensorInfoT
@@ -17,10 +18,12 @@ from rainbow.rb_flat_buffers.SLAMNAV.RequestSetSettingParam import RequestSetSet
17
18
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetDriveParam import ResponseGetDriveParamT
18
19
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetPduParam import ResponseGetPduParamT
19
20
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetRobotType import ResponseGetRobotTypeT
21
+ from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetRTSPInfo import ResponseGetRTSPInfoT
20
22
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetSensorInfo import ResponseGetSensorInfoT
21
23
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetSensorMode import ResponseGetSensorModeT
22
24
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetSettingCategory import ResponseGetSettingCategoryT
23
25
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseGetSettingParam import ResponseGetSettingParamT
26
+ from rainbow.rb_flat_buffers.SLAMNAV.ResponseRTSPSubscribe import ResponseRTSPSubscribeT
24
27
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseSetPduParam import ResponseSetPduParamT
25
28
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseSetRobotType import ResponseSetRobotTypeT
26
29
  from rainbow.rb_flat_buffers.SLAMNAV.ResponseSetSensorInfo import ResponseSetSensorInfoT
@@ -599,70 +602,43 @@ class RBAmrSettingSDK(RBBaseSDK):
599
602
 
600
603
  return result.get("obj_payload")
601
604
 
602
- # def set_rtsp_mode(self, robot_model: str, switch: bool, cam_id: list[int], req_id: str | None = None, flow_manager_args: FlowManagerArgs | None = None) -> ResponseSetSensorModeT:
603
- # """
604
- # [RTSP 모드 설정]
605
- # - req_id: 요청 ID
606
- # - switch: RTSP 모드
607
- # - cam_id: 카메라 ID (특정 카메라만 켜기 / 없으면 전부, switch가 off면 null)
608
- # """
609
- # if req_id is None:
610
- # req_id = str(uuid.uuid4())
611
-
612
- # # 1) RequestSetRTSPModeT 객체 생성
613
- # req = RequestSetRTSPModeT()
614
- # req.id = req_id
615
- # req.switch = switch
616
- # req.cam_id = cam_id
617
-
618
- # # 2) 요청 전송
619
- # result = self.zenoh_client.query_one(
620
- # f"amr/{robot_model}/setting/setRTSPMode",
621
- # flatbuffer_req_obj=req,
622
- # flatbuffer_res_T_class=ResponseSetRTSPModeT,
623
- # flatbuffer_buf_size=125,
624
- # )
625
- # # 3) 결과 처리 및 반환
626
- # if result.get("obj_payload") is None:
627
- # raise RuntimeError("Call Set RTSP Mode failed: obj_payload is None")
628
-
629
- # if flow_manager_args is not None:
630
- # if result["dict_payload"].get("result") == "accept":
631
- # flow_manager_args.done()
632
- # else:
633
- # raise RuntimeError(result["dict_payload"].get("message"))
634
-
635
- # return result.get("obj_payload")
636
-
637
- # def get_rtsp_mode(self, robot_model: str, req_id: str | None = None, flow_manager_args: FlowManagerArgs | None = None) -> ResponseSetSensorModeT:
638
- # """
639
- # [RTSP 모드 설정]
640
- # - req_id: 요청 ID
641
- # - switch: RTSP 모드
642
- # - cam_id: 카메라 ID (특정 카메라만 켜기 / 없으면 전부, switch가 off면 null)
643
- # """
644
- # if req_id is None:
645
- # req_id = str(uuid.uuid4())
646
-
647
- # # 1) RequestSetRTSPModeT 객체 생성
648
- # req = RequestGetRTSPModeT()
649
- # req.id = req_id
650
-
651
- # # 2) 요청 전송
652
- # result = self.zenoh_client.query_one(
653
- # f"amr/{robot_model}/setting/getRTSPMode",
654
- # flatbuffer_req_obj=req,
655
- # flatbuffer_res_T_class=ResponseGetRTSPModeT,
656
- # flatbuffer_buf_size=125,
657
- # )
658
- # # 3) 결과 처리 및 반환
659
- # if result.get("obj_payload") is None:
660
- # raise RuntimeError("Call Get RTSP Mode failed: obj_payload is None")
661
-
662
- # if flow_manager_args is not None:
663
- # if result["dict_payload"].get("result") == "accept":
664
- # flow_manager_args.done()
665
- # else:
666
- # raise RuntimeError(result["dict_payload"].get("message"))
667
-
668
- # return result.get("obj_payload")
605
+ def rtsp_subscribe(self, robot_model: str, cam_id: int, quality: str) -> ResponseRTSPSubscribeT:
606
+ """
607
+ [RTSP 구독]
608
+ - robot_model: 로봇 모델
609
+ - cam_id: 카메라 ID
610
+ - quality: 비디오 품질
611
+ - ResponseRTSPSubscribeT 객체 반환
612
+ """
613
+ req = RequestRTSPSubscribeT()
614
+ req.camId = cam_id
615
+ req.quality = quality
616
+
617
+ result = self.zenoh_client.query_one(
618
+ f"amr/{robot_model}/setting/rtsp/subscribe",
619
+ flatbuffer_req_obj=req,
620
+ flatbuffer_res_T_class=ResponseRTSPSubscribeT,
621
+ flatbuffer_buf_size=125,
622
+ )
623
+
624
+ if result.get("obj_payload") is None:
625
+ raise RuntimeError("Call RTSP Subscribe failed: obj_payload is None")
626
+
627
+ return result.get("obj_payload")
628
+
629
+ def get_rtsp_info(self, robot_model: str) -> ResponseGetRTSPInfoT:
630
+ """
631
+ [RTSP 정보 조회]
632
+ - robot_model: 로봇 모델
633
+ - ResponseGetRTSPInfoT 객체 반환
634
+ """
635
+ result = self.zenoh_client.query_one(
636
+ f"amr/{robot_model}/setting/rtsp/getInfo",
637
+ flatbuffer_res_T_class=ResponseGetRTSPInfoT,
638
+ flatbuffer_buf_size=125,
639
+ )
640
+
641
+ if result.get("obj_payload") is None:
642
+ raise RuntimeError("Call Get RTSP Info failed: obj_payload is None")
643
+
644
+ return result.get("obj_payload")
@@ -718,6 +718,17 @@ class RBBaseSDK:
718
718
  )
719
719
 
720
720
  print(f"[SDK] disconnected zenoh peer {peer_id}", flush=True)
721
+
722
+ # peer 해제 후 Zenoh 세션도 닫아 gossip/multihop 경로까지 완전히 차단
723
+ self._cleanup_resources()
724
+ pid = getattr(self, "_pid", None)
725
+ if pid is not None:
726
+ with RBBaseSDK._lock:
727
+ zenoh_client = RBBaseSDK._zenoh_clients.pop(pid, None)
728
+ if zenoh_client is not None:
729
+ with contextlib.suppress(Exception):
730
+ zenoh_client.close()
731
+
721
732
  return True
722
733
 
723
734
  async def _heartbeat_loop(self, peer_id: str, *, ttl: int, interval: float) -> None:
@@ -1,3 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: rainbow-rb-sdk
3
+ Version: 0.0.9.dev18
4
+ Summary: Rainbow Robotics 통합 Python SDK — AMR, 매니퓰레이터, RB-Y1 휴머노이드와 Rainbow Robot Service(common) 연동
5
+ Author-email: Derek <dfd1123@rainbow-robotics.com>
6
+ Requires-Python: <3.13,>=3.12
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: rainbow-rb-utils==0.0.9.dev18
9
+ Requires-Dist: rainbow-rb-zenoh==0.0.9.dev18
10
+ Requires-Dist: rainbow-rb-flat-buffers==0.0.9.dev18
11
+ Requires-Dist: rainbow-rb-schemas==0.0.9.dev18
12
+ Requires-Dist: rainbow-rb-log==0.0.9.dev18
13
+ Requires-Dist: rby1-sdk>=0.9.1
14
+
1
15
  # rb_sdk
2
16
 
3
17
  Rainbow Robotics 통합 Python SDK. AMR · Manipulator · RB-Y1 양팔로봇 제어와 Rainbow Robot Service(common) 연동을 단일 API로 제공합니다.
@@ -312,6 +326,137 @@ RBBaseSDK.close_all_for_pid() # 현재 프로세스의 모든 SDK 인스
312
326
 
313
327
  ---
314
328
 
315
- ## 11. 라이선스 / 문의
329
+ ## 11. Subscribe / Queryable
330
+
331
+ SDK를 상속하거나 직접 사용해 **Zenoh 이벤트를 수신(subscribe)** 하거나 **RPC 응답자(queryable)** 를 등록할 수 있습니다.
332
+
333
+ ### 11-1. `zenoh_subscribe` — 토픽 구독 (데코레이터)
334
+
335
+ ```python
336
+ from rb_sdk import RBManipulateSDK
337
+ from rb_zenoh.schema import SubscribeOptions, OverflowPolicy
338
+
339
+ sdk = RBManipulateSDK()
340
+
341
+ # dict 페이로드로 수신 (기본)
342
+ @sdk.zenoh_subscribe("amr/AMR001/status")
343
+ def on_status(*, dict_payload: dict | None, **kwargs):
344
+ print("status:", dict_payload)
345
+
346
+ # FlatBuffer 오브젝트로 수신
347
+ from rb_flat_buffers.IPC.MoveStatus import MoveStatusT
348
+
349
+ @sdk.zenoh_subscribe(
350
+ "amr/AMR001/moveStatus",
351
+ flatbuffer_obj_t=MoveStatusT,
352
+ opts=SubscribeOptions(
353
+ dispatch="queue",
354
+ overflow=OverflowPolicy.LATEST_ONLY,
355
+ parse_dict_payload=False,
356
+ ),
357
+ )
358
+ def on_move_status(*, obj_payload: MoveStatusT, **kwargs):
359
+ print("move status:", obj_payload)
360
+
361
+ # mv를 직접 받아 수동으로 파싱하는 패턴 (flatbuffer_obj_t 미지정)
362
+ from rb_flat_buffers.IPC.State_Core import State_Core
363
+
364
+ @sdk.zenoh_subscribe(
365
+ "C500920/state_core",
366
+ opts=SubscribeOptions(
367
+ dispatch="queue",
368
+ overflow=OverflowPolicy.LATEST_ONLY,
369
+ parse_dict_payload=False,
370
+ ),
371
+ )
372
+ def on_state_core(*, mv=None, **kwargs):
373
+ if mv is None:
374
+ return
375
+ obj = State_Core.GetRootAs(mv, 0)
376
+ print("motion mode:", obj.MotionMode())
377
+ ```
378
+
379
+ #### `zenoh_subscribe` 인자
380
+
381
+ | 인자 | 타입 | 기본 | 설명 |
382
+ |---|---|---|---|
383
+ | `topic` | `str` | (필수) | Zenoh key expression (예: `"amr/{model}/status"`) |
384
+ | `flatbuffer_obj_t` | FlatBuffer T 클래스 \| `None` | `None` | FlatBuffer로 역직렬화할 때 지정. `None`이면 콜백에 `mv: memoryview` 전달 |
385
+ | `opts` | `SubscribeOptions \| None` | `None` | 디스패치 / 오버플로우 옵션 |
386
+
387
+ #### `SubscribeOptions` 필드
388
+
389
+ | 필드 | 기본 | 설명 |
390
+ |---|---|---|
391
+ | `dispatch` | `"immediate"` | `"immediate"`: 수신 스레드에서 바로 콜백. `"queue"`: C++ bounded queue + 전용 dispatch 스레드 |
392
+ | `parse_dict_payload` | `True` | FlatBuffer 수신 시 `False`로 지정 |
393
+ | `overflow` | `DROP_OLDEST` | `DROP_OLDEST` / `DROP_NEW` / `LATEST_ONLY` |
394
+ | `maxsize` | `50` | `"queue"` 모드의 C++ 큐 최대 크기 |
395
+ | `rate_limit_per_sec` | `None` | 초당 최대 콜백 호출 수 |
396
+ | `sample_every` | `1` | N개 중 1개만 전달 (1 = 전부) |
397
+ | `max_async_inflight` | `1` | async 콜백 동시 실행 허용 수 |
398
+
399
+ #### 직접 subscribe (handle 보관이 필요한 경우)
400
+
401
+ 데코레이터 대신 `zenoh_client.subscribe()`를 직접 호출하면 handle을 직접 관리할 수 있습니다.
402
+
403
+ ```python
404
+ sub_handle = sdk.zenoh_client.subscribe(
405
+ "amr/AMR001/moveStatus",
406
+ callback,
407
+ flatbuffer_obj_t=MoveStatusT,
408
+ options=SubscribeOptions(dispatch="queue", overflow=OverflowPolicy.LATEST_ONLY),
409
+ )
410
+
411
+ # 구독 해제
412
+ sub_handle.close()
413
+ ```
414
+
415
+ ---
416
+
417
+ ### 11-2. `zenoh_queryable` — RPC 응답자 (데코레이터)
418
+
419
+ 원격에서 `get(keyexpr)` 요청이 오면 등록된 handler가 호출되어 응답을 반환합니다.
420
+
421
+ ```python
422
+ from rb_sdk import RBManipulateSDK
423
+
424
+ sdk = RBManipulateSDK()
425
+
426
+ # dict 요청 (payload 없음) → dict 반환
427
+ # params는 URL query string (예: ?model=C500920)을 파싱한 dict[str, str]
428
+ @sdk.zenoh_queryable("my_service/robot_status")
429
+ def handle_status_query(*, params: dict[str, str]) -> dict:
430
+ return {"status": "ok", "model": params.get("model")}
431
+
432
+ # FlatBuffer 요청 수신 → FlatBuffer 응답
433
+ from rb_flat_buffers.manipulate.RB_Functions import RB_FunctionsT
434
+
435
+ @sdk.zenoh_queryable(
436
+ "my_service/move_j",
437
+ flatbuffer_req_T_class=RB_FunctionsT,
438
+ flatbuffer_res_buf_size=256,
439
+ )
440
+ def handle_move_j(*, req: RB_FunctionsT, params: dict[str, str]) -> RB_FunctionsT:
441
+ res = RB_FunctionsT()
442
+ res.returnValue = 0
443
+ return res
444
+ ```
445
+
446
+ #### `zenoh_queryable` 인자
447
+
448
+ | 인자 | 타입 | 기본 | 설명 |
449
+ |---|---|---|---|
450
+ | `keyexpr` | `str` | (필수) | Zenoh key expression (예: `"my_service/status"`) |
451
+ | `flatbuffer_req_T_class` | FlatBuffer T 클래스 \| `None` | `None` | 요청 페이로드를 FlatBuffer로 역직렬화할 때 지정 |
452
+ | `flatbuffer_res_buf_size` | `int \| None` | `None` | FlatBuffer 응답 직렬화 버퍼 크기(바이트). FlatBuffer 응답 시 필수 |
453
+
454
+ #### 중복 등록 방지
455
+
456
+ 같은 `keyexpr`로 이미 등록된 queryable이 있으면 경고 메시지를 출력하고 기존 handler를 유지합니다. SDK `close()` 시 자동 해제됩니다.
457
+
458
+ ---
459
+
460
+ ## 12. 라이선스 / 문의
316
461
 
317
462
  © Rainbow Robotics. 내부 이슈/문의: [GitHub Issues](https://github.com/rainbow-mobile/rainbow-release-apps/issues)
@@ -0,0 +1,6 @@
1
+ rainbow-rb-utils==0.0.9.dev18
2
+ rainbow-rb-zenoh==0.0.9.dev18
3
+ rainbow-rb-flat-buffers==0.0.9.dev18
4
+ rainbow-rb-schemas==0.0.9.dev18
5
+ rainbow-rb-log==0.0.9.dev18
6
+ rby1-sdk>=0.9.1
@@ -1,6 +0,0 @@
1
- rainbow-rb-utils==0.0.9.dev17
2
- rainbow-rb-zenoh==0.0.9.dev17
3
- rainbow-rb-flat-buffers==0.0.9.dev17
4
- rainbow-rb-schemas==0.0.9.dev17
5
- rainbow-rb-log==0.0.9.dev17
6
- rby1-sdk>=0.9.1