# {{ module_name | pascal_case }} Robot Arm Module

{{ module_description }}

Generated by MADSci template: `module/robot_arm` v{{ template_version }}

## Overview

This module provides a MADSci robot arm node for controlling the {{ module_name }} robot arm
with material handling operations and resource tracking.

### Robot Arm Lifecycle

The robot arm module implements a standard lifecycle pattern:

1. **Connect** - Establish communication with the robot arm
2. **Initialize** - Perform arm-specific setup (enable motors, load calibration)
3. **Home** - Move the arm to its calibrated home/reference position
4. **Execute Operations** - Run arm operations via `@action` methods (pick, place, move)
5. **Shutdown** - Safely put the arm into a safe state
6. **Disconnect** - Close the communication channel

### Resource Management

The robot arm module creates and manages resource templates and instances:

- **Slot Template**: Defines the arm gripper slot type
- **Slot Instance**: Specific slot created from the template for this arm node
- Resources are registered with the MADSci Resource Manager for tracking

## Project Structure

```
{{ module_name }}_module/
├── src/
│   ├── {{ module_name }}_rest_node.py       # MADSci REST node server with @action methods
│   ├── {{ module_name }}_interface.py       # Real hardware interface with lifecycle
│   ├── {{ module_name }}_fake_interface.py  # Fake interface for testing
│   └── {{ module_name }}_types.py           # Type definitions and config
├── tests/
│   └── test_{{ module_name }}_interface.py  # Comprehensive lifecycle tests
├── Dockerfile
├── pyproject.toml
└── README.md
```

## Quick Start

### Installation

```bash
# Install in development mode
pip install -e ".[dev]"
```

### Running with Fake Interface (Testing)

```bash
# Start the node with fake interface (no hardware required)
python src/{{ module_name }}_rest_node.py --fake

# Verify it's running
curl http://localhost:{{ port }}/health
```

### Running with Real Interface

```bash
# Start the node with real interface
python src/{{ module_name }}_rest_node.py
```

### Available Actions

Once the node is running, the following actions are available via the REST API:

| Action | Description |
|--------|-------------|
| `home` | Home the robot arm to its reference position |
| `pick` | Pick up an item from a named location |
| `place` | Place an item at a named location |
| `move_to` | Move the arm to specific XYZ coordinates |
| `get_arm_status` | Get current robot arm status |

### Using the Interface Directly

The interface can be used independently of MADSci:

```python
from {{ module_name }}_interface import {{ module_name | pascal_case }}Interface

# Create and connect
interface = {{ module_name | pascal_case }}Interface()
interface.connect()
interface.initialize()
interface.home()

# Perform material handling
result = interface.pick("sample_station")
result = interface.place("analysis_station")
result = interface.move(100.0, 200.0, 50.0, speed=25.0)
status = interface.get_status()

# Clean shutdown
interface.shutdown()
interface.disconnect()
```

## Testing

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=src
```

## Development

### Implementing the Real Interface

1. Edit `src/{{ module_name }}_interface.py` to implement hardware communication
2. Replace TODO placeholders in `connect()`, `disconnect()`, `initialize()`, `shutdown()`, `home()`, `pick()`, `place()`, `move()`, `get_position()`, and `get_status()`
3. Update the fake interface to match any new behavior
4. Add tests in `tests/test_{{ module_name }}_interface.py`

### Adding Actions

1. Add interface methods in `{{ module_name }}_interface.py`
2. Add corresponding methods in `{{ module_name }}_fake_interface.py`
3. Create `@action` decorated methods in `{{ module_name }}_rest_node.py`

### Adding Resource Templates

To add additional resource types (e.g., a pool for consumables):

```python
from madsci.common.types.resource_types import Pool

consumable_pool = Pool(
    resource_name="{{ module_name }}_consumable",
    resource_class="{{ module_name | pascal_case }}Consumable",
    capacity=100.0,
    attributes={"description": "Consumable resource pool"},
)

self.resource_client.init_template(
    resource=consumable_pool,
    template_name="{{ module_name }}_consumable_pool",
    description="Template for {{ module_name }} consumable pool.",
    required_overrides=["resource_name"],
    tags=["{{ module_name }}", "consumable", "pool"],
    created_by=self.node_definition.node_id,
    version="1.0.0",
)
```

## Docker

```bash
# Build the image
docker build -t {{ module_name }}-module .

# Run with fake interface
docker run -p {{ port }}:{{ port }} {{ module_name }}-module --fake
```

## Documentation

For more information, see the [MADSci documentation](https://ad-sdl.github.io/MADSci/).
