A hybrid Rust/Python prosthetic arm controller with hardware interfaces in Rust and control logic in Python.
This project restructures the original GPM codebase to separate concerns:
-
Rust Layer (PyO3 Extension): Hardware-facing drivers for low-latency sensor/actuator control
- Maestro servo controller
- EMG sensor reading
- FSR (Force Sensitive Resistor) sensors
- BMS (Battery Management System)
-
Python Layer: High-level control logic and application orchestration
- Grip controller
- Safety monitoring
- State machine
- Command sequencing
GPM-rework/
├── src/ # Rust hardware drivers
│ ├── lib.rs # PyO3 module root
│ ├── hardware/ # Hardware abstractions
│ │ ├── maestro.rs
│ │ ├── emg.rs
│ │ ├── fsr.rs
│ │ ├── bms.rs
│ │ └── adc.rs
│ └── python_bindings/ # PyO3 wrappers
│ ├── maestro.rs
│ ├── emg.rs
│ ├── fsr.rs
│ └── bms.rs
├── gpm/ # Python type stubs
│ ├── __init__.py
│ ├── maestro.pyi
│ ├── emg.pyi
│ ├── fsr.pyi
│ └── bms.pyi
├── application/ # Python application logic
│ ├── hardware.py # Hardware initialization
│ ├── grip_controller.py # Grip orchestration
│ ├── safety_monitor.py # Safety constraints
│ ├── state_machine.py # State management
│ └── command_sequencer.py # Command sequencing
├── config/ # Configuration
│ ├── config.yaml
│ └── constants.py
├── main.py # Application entry point
├── Cargo.toml # Rust dependencies
└── pyproject.toml # Python build config
- Rust toolchain (rustup)
- Python 3.9+
- Maturin (
pip install maturin)
This project is currently in transition to use gpm_original as a git submodule for hardware implementations.
Current State:
- Using local
src/hardware/directory (temporary implementations) - All Python bindings have TODO comments marking transition points
- Project can build and run independently for development
Target State:
gpm_originalas git submodule providing hardware drivers- Python bindings import from
gpm_original::resources - Local
src/hardware/removed
Documentation:
SUBMODULE_INTEGRATION.md- Step-by-step integration guideTEAM_CHECKLIST.md- Requirements for gpm_original teamARCHITECTURE_DIAGRAMS.md- Visual architecture diagrams
Testing Current Version: You can build and test now with temporary hardware:
python -m venv venv
.\venv\Scripts\activate # Windows
source venv/bin/activate # Linux/Mac
pip install maturin
maturin develop
python main.py demo# Install dependencies
pip install -r requirements.txt
# Build Rust extension in development mode
maturin develop
# Or for Pi with hardware features
maturin develop --features pi# Build wheel
maturin build --release --features pi
# Install wheel
pip install target/wheels/gpm-*.whlpython main.py demoThis runs a demo sequence cycling through grip positions without requiring actual hardware.
python main.pyStarts the EMG processing loop for real-time gesture recognition and grip control.
Edit config/config.yaml to adjust:
- Hardware parameters (CS pins, thresholds, sampling rates)
- Grip positions (PWM values for each servo)
- Safety constraints (voltage, temperature, current limits)
- Application settings (loop rate, debug mode)
- No IPC overhead - Python calls Rust hardware functions directly
- Sub-millisecond latency for servo control
- Efficient sensor buffering
- Continuous battery monitoring
- Temperature and current limits
- Pre-execution safety checks
- Graceful error handling
- Formal state machine with validated transitions
- Error state tracking
- Operational state checks
- Multi-step command orchestration
- Configurable delays between steps
- Sequence registration and reuse
Type stubs (.pyi files) provide IDE autocomplete and type checking for the Rust extension:
from gpm import Maestro
maestro = Maestro() # IDE knows the signature
maestro.set_target(0, 1500) # IDE provides parameter hints# Run tests
pytest
# With coverage
pytest --cov=application --cov-report=htmlThe Rust layer includes mock implementations when built without the pi feature, allowing development and testing on non-Pi hardware.
- EMG sampling: 1000 Hz
- Control loop: 100 Hz (configurable)
- Servo command latency: <1ms
- Hardware call overhead: <100μs
Default limits (configurable in config.yaml):
- Critical voltage: 7.0V
- Max temperature: 60°C
- Max current: 10.0A
- Min charge: 10%
Original Architecture:
- Monolithic Rust application
- Manager pattern with MPSC channels
- TCP dispatchers for remote control
- Protocol Buffers serialization
Rework Architecture:
- Hybrid Rust/Python
- Direct function calls (no channels)
- Python control logic
- Simpler, more maintainable
[Your License Here]
UBC Bionics Team