Add README and CLAUDE.md
README covers installation, hardware setup, tools, prompts, and cross-server integration with mcnanovna for 3D pattern measurement. CLAUDE.md provides project guidance for Claude Code.
This commit is contained in:
parent
ec3f75e47b
commit
ce93070a04
102
CLAUDE.md
Normal file
102
CLAUDE.md
Normal file
@ -0,0 +1,102 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code when working with code in this repository.
|
||||
|
||||
## What This Is
|
||||
|
||||
mcpositioner is a FastMCP server that gives LLMs direct control of an ESP32 dual-axis antenna positioner over WiFi HTTP. It exposes 5 MCP tools and 3 guided workflow prompts for moving stepper motors, homing axes via StallGuard, and orchestrating 3D antenna radiation pattern measurement in coordination with a VNA MCP server (mcnanovna).
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Run the server
|
||||
uv run mcpositioner # from source
|
||||
uvx mcpositioner # from installed package
|
||||
python -m mcpositioner # module invocation
|
||||
|
||||
# Lint and format
|
||||
ruff check src/
|
||||
ruff format src/
|
||||
|
||||
# Install dependencies
|
||||
uv sync
|
||||
|
||||
# Build/verify ESP32 firmware (requires PlatformIO)
|
||||
cd firmware && pio run
|
||||
|
||||
# Add to Claude Code for testing
|
||||
claude mcp add mcpositioner-local --scope project -- uv run --directory /home/rpm/claude/ham/nanovna/mcpositioner mcpositioner
|
||||
```
|
||||
|
||||
There are no tests yet. The project has no README.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/mcpositioner/
|
||||
__init__.py Package docstring
|
||||
__main__.py python -m mcpositioner
|
||||
server.py FastMCP server -- tool registration, version banner, entry point
|
||||
positioner.py Async HTTP client for the ESP32 (httpx)
|
||||
tools.py 5 MCP tool methods on a simple PositionerTools class
|
||||
prompts.py 3 guided workflow prompts (home, configure, measure_pattern_grid)
|
||||
|
||||
firmware/ PlatformIO ESP32 project for antenna positioner hardware
|
||||
platformio.ini Build config: espressif32, AccelStepper, TMCStepper, ESPAsyncWebServer
|
||||
include/config.h Pin assignments, motor constants, TMC2209 UART config
|
||||
src/main.cpp Dual-axis stepper control, HTTP API, mDNS, StallGuard homing
|
||||
|
||||
hardware/ KiCad 9 schematic for positioner wiring
|
||||
positioner.kicad_pro Project file (JSON)
|
||||
positioner.kicad_sch Root schematic -- ESP32 + 2x TMC2209 + motors + power
|
||||
positioner.kicad_sym Local symbol library (6 custom module symbols)
|
||||
sym-lib-table Registers local symbol lib with project
|
||||
generate_kicad.py Python generator for all KiCad files (dev tool)
|
||||
```
|
||||
|
||||
### How tools get registered
|
||||
|
||||
`server.py` holds a flat list `_TOOL_METHODS` of method name strings. `create_server()` instantiates one `PositionerTools` object, iterates the list, and wraps each bound method with `FunctionTool.from_function()`. To add a new tool: add a public method to `tools.py` then add its name to `_TOOL_METHODS`.
|
||||
|
||||
### HTTP client (positioner.py)
|
||||
|
||||
The `Positioner` class wraps httpx async calls to the ESP32's HTTP API:
|
||||
- `GET /status` -- theta/phi position, moving, homed
|
||||
- `POST /move` -- absolute move to theta/phi
|
||||
- `POST /move/relative` -- relative offset move
|
||||
- `POST /home` -- StallGuard sensorless homing
|
||||
- `POST /stop` -- emergency stop
|
||||
- `GET /config` -- read motion parameters
|
||||
- `POST /config` -- update speed, accel, microstepping
|
||||
|
||||
Default host: `positioner.local` (mDNS). Override with `MCPOSITIONER_HOST` env var.
|
||||
|
||||
### Cross-server orchestration
|
||||
|
||||
This server controls physical positioning only. For 3D antenna pattern measurement, the LLM orchestrates both mcpositioner and mcnanovna (VNA MCP server):
|
||||
|
||||
1. `positioner_move` (mcpositioner) -- position antenna at theta/phi
|
||||
2. `scan` (mcnanovna) -- measure S21 transmission
|
||||
3. Repeat across theta/phi grid
|
||||
4. Assemble pattern dict from collected measurements
|
||||
|
||||
The `measure_pattern_grid` prompt provides step-by-step guidance for this workflow.
|
||||
|
||||
### ESP32 firmware (firmware/)
|
||||
|
||||
PlatformIO project targeting ESP32. Controls 2x NEMA 17 steppers via TMC2209 drivers in UART mode. Features:
|
||||
- AccelStepper for smooth acceleration profiles
|
||||
- TMCStepper for UART configuration and StallGuard sensorless homing
|
||||
- ESPAsyncWebServer for the HTTP API
|
||||
- mDNS advertisement as `positioner.local`
|
||||
- Pin assignments and motor constants in `include/config.h`
|
||||
|
||||
## Key conventions
|
||||
|
||||
- Date-based versioning: `2026.02.02` in pyproject.toml
|
||||
- Python 3.11+, ruff at 120-char line length
|
||||
- `httpx` is a core dependency (not optional -- it IS the transport layer)
|
||||
- Single `PositionerTools` instance per server lifetime
|
||||
- No mixin pattern -- flat class with 5 methods (single-concern server)
|
||||
- Custom exception: `PositionerError`
|
||||
- Env var: `MCPOSITIONER_HOST` (default `positioner.local`)
|
||||
94
README.md
Normal file
94
README.md
Normal file
@ -0,0 +1,94 @@
|
||||
# mcpositioner
|
||||
|
||||
MCP server for controlling an ESP32 dual-axis antenna positioner over WiFi.
|
||||
|
||||
Drives two NEMA 17 stepper motors via TMC2209 drivers for theta (polar, 0-180°) and phi (azimuth, 0-360°) rotation. Designed for automated antenna radiation pattern measurement in coordination with a VNA.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# From PyPI (when published)
|
||||
uvx mcpositioner
|
||||
|
||||
# From source
|
||||
uv run mcpositioner
|
||||
```
|
||||
|
||||
## Hardware
|
||||
|
||||
- **ESP32** (any DevKit variant) running the firmware in `firmware/`
|
||||
- **2x TMC2209** stepper drivers in UART mode
|
||||
- **2x NEMA 17** stepper motors (0.9° or 1.8° step angle)
|
||||
- **24V power supply** for motors (5V for ESP32)
|
||||
|
||||
See `hardware/` for KiCad schematics showing the wiring.
|
||||
|
||||
### Firmware
|
||||
|
||||
Build and flash with PlatformIO:
|
||||
|
||||
```bash
|
||||
cd firmware
|
||||
pio run -t upload
|
||||
```
|
||||
|
||||
The ESP32 advertises itself as `positioner.local` via mDNS. Override with the `MCPOSITIONER_HOST` environment variable if needed.
|
||||
|
||||
## MCP Tools
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `positioner_status` | Get theta/phi position, moving state, homed state |
|
||||
| `positioner_move` | Move to absolute theta/phi with optional wait |
|
||||
| `positioner_home` | StallGuard sensorless homing on one or both axes |
|
||||
| `positioner_stop` | Emergency stop all motors |
|
||||
| `positioner_config` | Get/set speed, acceleration, microstepping |
|
||||
|
||||
## Prompts
|
||||
|
||||
| Prompt | Description |
|
||||
|--------|-------------|
|
||||
| `home_positioner` | Guided homing with safety checks |
|
||||
| `configure_positioner` | Motion parameter tuning guide |
|
||||
| `measure_pattern_grid` | Cross-server 3D pattern measurement workflow |
|
||||
|
||||
## Cross-Server Pattern Measurement
|
||||
|
||||
This server controls positioning only. For 3D antenna pattern measurement, use together with [mcnanovna](../mcnanovna/) (VNA MCP server):
|
||||
|
||||
1. `positioner_move` (mcpositioner) — position antenna at theta/phi
|
||||
2. `scan` (mcnanovna) — measure S21 transmission
|
||||
3. Repeat across theta/phi grid
|
||||
4. Assemble pattern from collected measurements
|
||||
|
||||
The `measure_pattern_grid` prompt provides step-by-step guidance for this workflow.
|
||||
|
||||
### Adding Both Servers to Claude Code
|
||||
|
||||
```bash
|
||||
claude mcp add mcpositioner -- uvx mcpositioner
|
||||
claude mcp add mcnanovna -- uvx mcnanovna
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
| Environment Variable | Default | Description |
|
||||
|---------------------|---------|-------------|
|
||||
| `MCPOSITIONER_HOST` | `positioner.local` | ESP32 hostname or IP |
|
||||
|
||||
## HTTP API (ESP32 Firmware)
|
||||
|
||||
The ESP32 exposes these endpoints:
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/status` | GET | Current position, moving, homed |
|
||||
| `/move` | POST | `{"theta_deg": 90, "phi_deg": 45}` |
|
||||
| `/move/relative` | POST | `{"d_theta": 5, "d_phi": 10}` |
|
||||
| `/home` | POST | `{"axis": "both"}` (or "theta"/"phi") |
|
||||
| `/stop` | POST | Emergency stop |
|
||||
| `/config` | GET/POST | Motion parameters |
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Loading…
x
Reference in New Issue
Block a user