Refactor voice control core and robot behavior
This commit is contained in:
236
dora_voice_control/PLAN.md
Normal file
236
dora_voice_control/PLAN.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# Voice Control Simplification Plan
|
||||
|
||||
## Current State
|
||||
|
||||
**30 files** across 7 directories (~3300 lines):
|
||||
|
||||
```
|
||||
dora_voice_control/
|
||||
├── behaviors/ # 2 files
|
||||
│ ├── __init__.py
|
||||
│ └── base.py
|
||||
├── node/ # 5 files
|
||||
│ ├── __init__.py
|
||||
│ ├── adapter.py
|
||||
│ ├── context.py
|
||||
│ ├── dispatcher.py
|
||||
│ └── logging.py
|
||||
├── robot/ # 6 files
|
||||
│ ├── __init__.py
|
||||
│ ├── adapter.py # VacuumGripperAdapter, ParallelGripperAdapter
|
||||
│ ├── command_queue.py
|
||||
│ ├── image_handler.py
|
||||
│ ├── pose_handler.py
|
||||
│ └── status_handler.py
|
||||
├── scene/ # 4 files
|
||||
│ ├── __init__.py
|
||||
│ ├── notifier.py
|
||||
│ ├── objects_handler.py
|
||||
│ └── state.py
|
||||
├── utils/ # 3 files
|
||||
│ ├── __init__.py
|
||||
│ ├── config.py
|
||||
│ └── state.py
|
||||
├── voice/ # 4 files
|
||||
│ ├── __init__.py
|
||||
│ ├── handler.py
|
||||
│ ├── intent.py
|
||||
│ └── parser.py
|
||||
├── web/ # 4 files
|
||||
│ ├── __init__.py
|
||||
│ ├── api.py
|
||||
│ ├── models.py
|
||||
│ └── templates.py
|
||||
├── __init__.py
|
||||
└── main.py
|
||||
```
|
||||
|
||||
## Problems
|
||||
|
||||
1. **Too many small files** - Many files are <50 lines
|
||||
2. **Robot-specific code scattered** - Adapter in robot/, behavior in behaviors/
|
||||
3. **Hard to add new robots** - Need to touch multiple directories
|
||||
4. **Deep import chains** - `from ..node import ...`
|
||||
|
||||
---
|
||||
|
||||
## Proposed Structure
|
||||
|
||||
**12 files** across 3 directories:
|
||||
|
||||
```
|
||||
dora_voice_control/
|
||||
├── __init__.py
|
||||
├── main.py
|
||||
├── node.py # Dora infrastructure (adapter, context, dispatcher, logger)
|
||||
├── handlers.py # All event handlers (voice, robot, scene)
|
||||
├── scene.py # SceneState, SceneObject
|
||||
├── state.py # SharedState, RobotStep, config loading
|
||||
├── web.py # API server (api + models + templates)
|
||||
└── behaviors/
|
||||
├── __init__.py # get_behavior() factory
|
||||
├── base.py # ActionContext, ActionInfo, RobotBehavior base
|
||||
└── littlehand/
|
||||
├── __init__.py
|
||||
└── robot.py # LittlehandBehavior + VacuumGripperAdapter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Consolidation Map
|
||||
|
||||
### `node.py` (merge 5 files)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `node/logging.py` | VoiceControlLogger |
|
||||
| `node/adapter.py` | NodePort, DoraNodeAdapter, MockNodeAdapter |
|
||||
| `node/context.py` | OutputPort, NodeContext |
|
||||
| `node/dispatcher.py` | EventHandler, EventDispatcher |
|
||||
|
||||
### `handlers.py` (merge 7 files)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `voice/handler.py` | VoiceInputHandler |
|
||||
| `voice/intent.py` | Intent, IntentQueue |
|
||||
| `robot/pose_handler.py` | PoseHandler |
|
||||
| `robot/status_handler.py` | StatusHandler |
|
||||
| `robot/image_handler.py` | ImageHandler |
|
||||
| `robot/command_queue.py` | CommandQueueService |
|
||||
| `scene/objects_handler.py` | ObjectsHandler |
|
||||
| `scene/notifier.py` | SceneNotifier |
|
||||
|
||||
### `scene.py` (merge 2 files)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `scene/state.py` | SceneState, SceneObject |
|
||||
|
||||
Already consolidated - just move to root.
|
||||
|
||||
### `state.py` (merge 2 files)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `utils/state.py` | SharedState, RobotStep, VoiceState, DebugState |
|
||||
| `utils/config.py` | VoiceConfig, ApiConfig, LLMConfig, loaders |
|
||||
|
||||
### `web.py` (merge 3 files)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `web/api.py` | create_api(), start_api_server() |
|
||||
| `web/models.py` | CommandRequest, CommandResponse |
|
||||
| `web/templates.py` | HTML_TEMPLATE |
|
||||
|
||||
### `behaviors/littlehand/robot.py` (new)
|
||||
|
||||
| From | Content |
|
||||
|------|---------|
|
||||
| `robot/adapter.py` | VacuumGripperAdapter (robot-specific) |
|
||||
| `behaviors/base.py` | Action implementations (robot-specific) |
|
||||
|
||||
Robot adapter moves INTO the behavior folder.
|
||||
|
||||
---
|
||||
|
||||
## Per-Robot Folder Structure
|
||||
|
||||
Each robot gets its own folder with everything it needs:
|
||||
|
||||
```
|
||||
behaviors/
|
||||
├── __init__.py # get_behavior(robot_type) factory
|
||||
├── base.py # Shared base classes
|
||||
│ - ActionContext
|
||||
│ - ActionInfo
|
||||
│ - RobotBehavior (abstract)
|
||||
│
|
||||
└── littlehand/ # Vacuum gripper robot
|
||||
├── __init__.py
|
||||
└── robot.py
|
||||
- VacuumGripperAdapter
|
||||
- LittlehandBehavior (actions, LLM signature)
|
||||
- ACTIONS dict
|
||||
- CommandSignature (DSPy)
|
||||
```
|
||||
|
||||
### Adding a New Robot (e.g., "gripper_arm")
|
||||
|
||||
1. Create `behaviors/gripper_arm/`
|
||||
2. Create `robot.py` with:
|
||||
- `ParallelGripperAdapter`
|
||||
- `GripperArmBehavior`
|
||||
- Custom actions
|
||||
3. Register in `behaviors/__init__.py`
|
||||
|
||||
No need to touch other files.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Phase 1: Consolidate node/ → node.py
|
||||
|
||||
1. Create `node.py` merging adapter, context, dispatcher, logging
|
||||
2. Update imports in all files
|
||||
3. Delete `node/` directory
|
||||
|
||||
### Phase 2: Consolidate handlers
|
||||
|
||||
1. Create `handlers.py` merging all handlers
|
||||
2. Update imports
|
||||
3. Delete `voice/`, `robot/` directories (except adapter)
|
||||
|
||||
### Phase 3: Consolidate utils/ → state.py
|
||||
|
||||
1. Create `state.py` merging config and state
|
||||
2. Update imports
|
||||
3. Delete `utils/` directory
|
||||
|
||||
### Phase 4: Move scene/ → scene.py
|
||||
|
||||
1. Move `scene/state.py` to `scene.py`
|
||||
2. Update imports
|
||||
3. Delete `scene/` directory
|
||||
|
||||
### Phase 5: Consolidate web/ → web.py
|
||||
|
||||
1. Create `web.py` merging api, models, templates
|
||||
2. Update imports
|
||||
3. Delete `web/` directory
|
||||
|
||||
### Phase 6: Restructure behaviors per robot
|
||||
|
||||
1. Create `behaviors/littlehand/robot.py`
|
||||
2. Move VacuumGripperAdapter from robot/adapter.py
|
||||
3. Move action implementations from behaviors/base.py
|
||||
4. Update `behaviors/__init__.py` factory
|
||||
5. Delete old robot/adapter.py
|
||||
|
||||
### Phase 7: Update main.py
|
||||
|
||||
1. Update all imports to new structure
|
||||
2. Simplify initialization
|
||||
|
||||
---
|
||||
|
||||
## Final Structure Comparison
|
||||
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| 30 files | 12 files |
|
||||
| 7 directories | 3 directories |
|
||||
| Robot code scattered | Robot code in one folder |
|
||||
| Deep imports | Flat imports |
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Easier navigation** - Fewer files to search
|
||||
2. **Self-contained robots** - One folder per robot type
|
||||
3. **Simpler imports** - `from .node import ...` instead of `from ..node import ...`
|
||||
4. **Easier testing** - Mock one module instead of many
|
||||
5. **Clear ownership** - Robot-specific code in robot folder
|
||||
Reference in New Issue
Block a user