mirror of
https://github.com/deepmodeling/Uni-Lab-OS
synced 2026-03-24 09:17:39 +00:00
fast registry load minor fix on skill & registry stripe ros2 schema desc add create-device-skill new registry system backwards to yaml remove not exist resource new registry sys exp. support with add device add ai conventions correct raise create resource error ret info fix revert ret info fix fix prcxi check add create_resource schema re signal host ready event add websocket connection timeout and improve reconnection logic add open_timeout parameter to websocket connection add TimeoutError and InvalidStatus exception handling implement exponential backoff for reconnection attempts simplify reconnection logic flow add gzip change pose extra to any add isFlapY
88 lines
5.1 KiB
Markdown
88 lines
5.1 KiB
Markdown
# AGENTS.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
Also follow the monorepo-level rules in `../AGENTS.md`.
|
|
|
|
## Build & Development
|
|
|
|
```bash
|
|
# Install in editable mode (requires mamba env with python 3.11)
|
|
pip install -e .
|
|
uv pip install -r unilabos/utils/requirements.txt
|
|
|
|
# Run with a device graph
|
|
unilab --graph <graph.json> --config <config.py> --backend ros
|
|
unilab --graph <graph.json> --config <config.py> --backend simple # no ROS2 needed
|
|
|
|
# Common CLI flags
|
|
unilab --app_bridges websocket fastapi # communication bridges
|
|
unilab --test_mode # simulate hardware, no real execution
|
|
unilab --check_mode # CI validation of registry imports
|
|
unilab --skip_env_check # skip auto-install of dependencies
|
|
unilab --visual rviz|web|disable # visualization mode
|
|
unilab --is_slave # run as slave node
|
|
|
|
# Workflow upload subcommand
|
|
unilab workflow_upload -f <workflow.json> -n <name> --tags tag1 tag2
|
|
|
|
# Tests
|
|
pytest tests/ # all tests
|
|
pytest tests/resources/test_resourcetreeset.py # single test file
|
|
pytest tests/resources/test_resourcetreeset.py::TestClassName::test_method # single test
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Startup Flow
|
|
|
|
`unilab` CLI → `unilabos/app/main.py:main()` → loads config → builds registry → reads device graph (JSON/GraphML) → starts backend thread (ROS2/simple) → starts FastAPI web server + WebSocket client.
|
|
|
|
### Core Layers
|
|
|
|
**Registry** (`unilabos/registry/`): Singleton `Registry` class discovers and catalogs all device types, resource types, and communication devices from YAML definitions. Device types live in `registry/devices/*.yaml`, resources in `registry/resources/`, comms in `registry/device_comms/`. The registry resolves class paths to actual Python classes via `utils/import_manager.py`.
|
|
|
|
**Resource Tracking** (`unilabos/resources/resource_tracker.py`): Pydantic-based `ResourceDict` → `ResourceDictInstance` → `ResourceTreeSet` hierarchy. `ResourceTreeSet` is the canonical in-memory representation of all devices and resources, used throughout the system. Graph I/O is in `resources/graphio.py` (reads JSON/GraphML device topology files into `nx.Graph` + `ResourceTreeSet`).
|
|
|
|
**Device Drivers** (`unilabos/devices/`): 30+ hardware drivers organized by device type (liquid_handling, hplc, balance, arm, etc.). Each driver is a Python class that gets wrapped by `ros/device_node_wrapper.py:ros2_device_node()` to become a ROS2 node with publishers, subscribers, and action servers.
|
|
|
|
**ROS2 Layer** (`unilabos/ros/`): `device_node_wrapper.py` dynamically wraps any device class into `ROS2DeviceNode` (defined in `ros/nodes/base_device_node.py`). Preset node types in `ros/nodes/presets/` include `host_node`, `controller_node`, `workstation`, `serial_node`, `camera`. Messages use custom `unilabos_msgs` (pre-built, distributed via releases).
|
|
|
|
**Protocol Compilation** (`unilabos/compile/`): 20+ protocol compilers (add, centrifuge, dissolve, filter, heatchill, stir, pump, etc.) that transform YAML protocol definitions into executable sequences.
|
|
|
|
**Communication** (`unilabos/device_comms/`): Hardware communication adapters — OPC-UA client, Modbus PLC, RPC, and a universal driver. `app/communication.py` provides a factory pattern for WebSocket client connections to the cloud.
|
|
|
|
**Web/API** (`unilabos/app/web/`): FastAPI server with REST API (`api.py`), Jinja2 template pages (`pages.py`), and HTTP client for cloud communication (`client.py`). Runs on port 8002 by default.
|
|
|
|
### Configuration System
|
|
|
|
- **Config classes** in `unilabos/config/config.py`: `BasicConfig`, `WSConfig`, `HTTPConfig`, `ROSConfig` — all class-level attributes, loaded from Python config files
|
|
- Config files are `.py` files with matching class names (see `config/example_config.py`)
|
|
- Environment variables override with prefix `UNILABOS_` (e.g., `UNILABOS_BASICCONFIG_PORT=9000`)
|
|
- Device topology defined in graph files (JSON with node-link format, or GraphML)
|
|
|
|
### Key Data Flow
|
|
|
|
1. Graph file → `graphio.read_node_link_json()` → `(nx.Graph, ResourceTreeSet, resource_links)`
|
|
2. `ResourceTreeSet` + `Registry` → `initialize_device.initialize_device_from_dict()` → `ROS2DeviceNode` instances
|
|
3. Device nodes communicate via ROS2 topics/actions or direct Python calls (simple backend)
|
|
4. Cloud sync via WebSocket (`app/ws_client.py`) and HTTP (`app/web/client.py`)
|
|
|
|
### Test Data
|
|
|
|
Example device graphs and experiment configs are in `unilabos/test/experiments/` (not `tests/`). Registry test fixtures in `unilabos/test/registry/`.
|
|
|
|
## Code Conventions
|
|
|
|
- Code comments and log messages in simplified Chinese
|
|
- Python 3.11+, type hints expected
|
|
- Pydantic models for data validation (`resource_tracker.py`)
|
|
- Singleton pattern via `@singleton` decorator (`utils/decorator.py`)
|
|
- Dynamic class loading via `utils/import_manager.py` — device classes resolved at runtime from registry YAML paths
|
|
- CLI argument dashes auto-converted to underscores for consistency
|
|
|
|
## Licensing
|
|
|
|
- Framework code: GPL-3.0
|
|
- Device drivers (`unilabos/devices/`): DP Technology Proprietary License — do not redistribute
|