Skip to main content

studio-creating-a-robot-plugin

Creates or modifies an external Physical AI robot plugin for Studio. Use when implementing a Runtime Robot driver outside Studio, adding studio_catalog.py, RobotCatalogDefinition, RobotProbe, RobotAsset, the physicalai.studio.catalog_plugins entry point, or a curated entry in application/backend/src/plugins/manifest.json.

소스 정보

저장소
open-edge-platform/physical-ai-studio
최근 소스 활동
2026년 9월 16일 13:35
감지된 SKILL.md 언어
영어
스타
128
포크
51

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
studio-creating-a-robot-plugin
description
Creates or modifies an external Physical AI robot plugin for Studio. Use when implementing a Runtime Robot driver outside Studio, adding studio_catalog.py, RobotCatalogDefinition, RobotProbe, RobotAsset, the physicalai.studio.catalog_plugins entry point, or a curated entry in application/backend/src/plugins/manifest.json.
license
Apache-2.0
# Creating a Studio Robot Plugin Build the Physical AI robot driver independently before adding Studio support. A plugin owns its driver, device integration, Pydantic payloads, catalog definitions, and optional assets. Studio owns project persistence, generated configuration forms, runtime orchestration, and the curated Plugins page. Read `application/docs/robot-plugins.md` and the [`physicalai-studio-plugin` SDK README](https://github.com/openvinotoolkit/physicalai/blob/main/packages/physicalai-studio-plugin/README.md) before editing. For complete plugin examples, use the packages under [`openvinotoolkit/physicalai/packages`](https://github.com/openvinotoolkit/physicalai/tree/main/packages), including [`physicalai-rebot-b601-plugin`](https://github.com/openvinotoolkit/physicalai/tree/main/packages/physicalai-rebot-b601-plugin). Use Studio's built-in network robot implementation at `application/backend/src/robots/catalog/widowxai.py` as a schema example. ## Workflow 1. **Choose the plugin boundary and stable identifiers.** Keep the driver and its vendor dependencies in the plugin repository; do not add the robot to Studio's built-in catalog. Choose a globally unique, stable `RobotCatalogDefinition.type` for every configuration, such as `AcmeArm_Follower` and `AcmeArm_Leader`. - `type` is persisted in Studio projects and must never be casually renamed or duplicated by another installed plugin. - Decide which configurations are `follower` robots that execute actions and which are `leader` robots that supply teleoperation input. - Done when: every supported driver mode has a stable type, display name, role, connection method, and expected joint order. 2. **Implement the Runtime robot without Studio imports.** Follow the Runtime skill `physicalai-runtime-adding-a-robot-integration` in the Physical AI repository. The driver structurally implements `physicalai.robot.interface.Robot`; it does not need a Studio base class. - Implement idempotent `connect()`, safe `disconnect()`, and `is_connected()`. - Expose `joint_names` in exactly the order used by observations and actions. `get_observation()` returns joint positions in that order and a `time.monotonic()` timestamp. The returned observation must also expose `sensor_data` and `images`, set to `None` when unused. `send_action(action, *, goal_time=...)` accepts an action with shape `(len(joint_names),)`. - Expose `device_ids` from constructor arguments without hardware I/O, including every exclusive device for composite robots. - Put vendor SDK imports behind the driver connection path when they are optional or heavy. Validate user-configured ports and addresses; do not invoke a shell with them. - Decorate every driver class returned to Studio with `@physicalai.config.export_config`. Studio serializes the disconnected driver to start its hardware-owner process; an undecorated driver fails with `ConfigError`. - Done when: mocked-hardware tests prove `isinstance(driver, Robot)`, lifecycle behavior, safe disconnected behavior, joint/action order, and configuration round-tripping, with no import of `physicalai_studio_plugin`. 3. **Package the standalone driver.** Create a normal Python distribution with the driver package, tests, and optional URDF/mesh files. Add `physicalai`, `physicalai-studio-plugin`, vendor dependencies, and test extras as appropriate. - Declare the Studio entry point in the plugin package's `pyproject.toml`: ```toml [project.entry-points."physicalai.studio.catalog_plugins"] acme-arm = "physicalai_acme_arm_plugin.studio_catalog:register_physicalai_studio_plugin" ``` - Include URDF resources in both wheel and source distributions if the catalog exposes a `RobotAsset`. - Build or install the package in the same Python environment used by `application/backend/`; entry points from another virtual environment are invisible to Studio. - Done when: the package imports, its entry point resolves, and its standalone test suite passes. 4. **Define one typed payload per Studio robot configuration.** Add `studio_catalog.py` in the plugin package. Define Pydantic `BaseModel` payloads for connection values and driver options; the payload is the persisted data and generated form contract. - Use Pydantic `Field` titles, descriptions, defaults, literals/enums, and validators for ordinary configuration behavior. - Use `robot_field_ui({"advanced_configuration": True})` only for fields that belong behind Studio's advanced configuration control. - Use `robot_payload_ui(...)` to order fields, add sections or guidance, and render a serial connection selector. A `connection` item owns the fields named by `bind.connection` and optional `bind.serial_number`, so do not also render those fields as `field` items. - Connection bindings are relative to the Pydantic model declaring the UI metadata. Nested arm models define their own bindings; never use dotted paths such as `left.connection_string`. - Done when: `validate_robot_payload_ui(Payload)` and `Payload.model_rebuild(raise_errors=True)` pass for every payload model. 5. **Build and register catalog definitions.** Implement an async builder for each driver shape and register a `RobotCatalogDefinition` for every stable type. - The builder receives `CatalogRobot[Payload]` and `CatalogRobotFactory`. Read `robot.payload`, validate or normalize it if necessary, resolve serial or network connections with `factory.find_port(SerialPortInfo(...))` when appropriate, and return the plain `@export_config` Runtime driver. Do not return a `SharedRobot`; Studio wraps the driver. - Raise a clear error if a configured device cannot be resolved. - Add a structural `RobotProbe` only when discovery, visual identification, or online checks have meaningful implementations. Keep probe behavior separate from driver construction. - Add `RobotAsset` only when the plugin ships a valid URDF, mesh package map, and observation-key-to-joint mapping. An asset-less robot is still supported but has no 3D preview. - Register each definition from the entry-point function: ```python def register_physicalai_studio_plugin(registry) -> None: for definition in _definitions(): registry.register_robot(definition) ``` - Done when: direct registration into a fake registry produces exactly the expected types, payload models, builders, roles, and optional assets/probes. 6. **Test the catalog contract without Studio.** Add focused tests alongside the plugin package. - Test the entry-point registration and exact set of catalog types. - Test payload defaults, required-field and cross-field validation, `model_rebuild`, and `validate_robot_payload_ui(...)`. - Test each builder with fake payload containers and a fake `CatalogRobotFactory`, including both a resolved connection and a missing-device error. - Test `RobotAsset.root_resolver()` and the URDF path when assets are supplied. - Run the package's focused test command from its repository, for example: ```bash uv run pytest packages/physicalai-acme-arm-plugin/tests/ ``` - Done when: driver and catalog tests pass without physical hardware. 7. **Install locally and restart Studio for catalog discovery.** From `application/backend/`, install the plugin into the backend environment, then restart the backend. For a local plugin, use an editable dependency relative to the backend directory: ```bash uv add --editable ../../physicalai-acme-arm-plugin uv sync ``` - Entry points and catalog schemas load only at backend startup. Re-run `uv sync` after dependency-source changes and restart the backend after changes to entry points, payload models, or `studio_catalog.py`. - With the UI started by `npm run start` from `application/ui/`, its development server proxies `/api` to the backend and is available on port 3000. - Done when: the backend starts without catalog registration errors and the plugin type is available from the live catalog. 8. **Debug through the live catalog APIs before debugging the UI.** Use the browser or `curl` against the UI proxy: ```bash curl --fail http://localhost:3000/api/robots/catalog curl --fail http://localhost:3000/api/robots/catalog/Trossen_Bimanual_WidowXAI_Follower/schema curl --fail http://localhost:3000/api/robots/catalog/AcmeArm_Follower/schema ``` - Treat `Trossen_Bimanual_WidowXAI_Follower/schema` as the known-good reference for a network bimanual payload. Compare your schema's `properties`, required fields, defaults, descriptions, nested `$defs`, and `x-physicalai-ui` metadata against the desired form. - If the plugin type is absent from `/catalog`, inspect backend startup logs for entry-point import, registration, duplicate-type, or UI-schema validation failures. Confirm the distribution is installed in the backend environment and restart it. - If the type appears but its form is wrong, inspect `/{robot_type}/schema`. Correct Pydantic field metadata or `robot_payload_ui` ownership/bindings rather than adding plugin-specific React code. - For a probe, test `/{robot_type}/discover`, `/{robot_type}/identify`, and `/{robot_type}/is-online` with a JSON body that conforms to the schema. For a build failure, inspect the saved payload, `find_port` result, device permissions, vendor dependencies, and driver logs. - If visualization fails, request `/{robot_type}/urdf` and verify the asset root resolver, relative URDF path, package map, and joint map. - Done when: catalog and schema endpoints return the expected definition and JSON Schema, and the generated Studio form reflects it without duplicate or missing fields. 9. **Add curated UI installation only after the package is installable.** Add a reviewed entry to `application/backend/src/plugins/manifest.json` when Studio should expose the plugin on its Plugins page. - `id` must equal the Python distribution name. `install_source` must be a reviewed package, Git, or path requirement accepted by `uv pip install`. Add user-facing metadata and known robot types under `robots`. - The manifest controls what the UI may install; it does not replace the package entry point that registers the actual robot definitions. - Restart the backend after a manifest change. - Done when: the Plugins page lists the plugin before installation, installs the reviewed source, prompts for restart, and the restarted backend exposes the registered types through `/api/robots/catalog`. ## Verify Run the plugin's driver and catalog tests first. Then validate the Studio skill changes from the Studio repository root: ```bash python3 .github/scripts/skills/agent_skills.py sync python3 .github/scripts/skills/agent_skills.py validate prek run --all-files ``` ## References - `application/docs/robot-plugins.md` - installation, catalog, form, manifest, and troubleshooting contract. - [`openvinotoolkit/physicalai/packages/physicalai-studio-plugin/README.md`](https://github.com/openvinotoolkit/physicalai/blob/main/packages/physicalai-studio-plugin/README.md) - Studio plugin SDK types and examples. - `application/backend/src/api/robot_catalog.py` - live catalog, schema, probe, and asset endpoints. - `application/backend/src/robots/catalog/widowxai.py` - built-in single-arm and bimanual network payload example. - [Physical AI Runtime robot-integration skill](https://github.com/openvinotoolkit/physicalai/blob/main/skills/runtime/physicalai-runtime-adding-a-robot-integration/SKILL.md) - Runtime-only driver workflow.
GitHub에서 보기