Wavedriver is a privacy-first sex machine controller for the Iris Dynamics Orca 6 linear actuator. It runs headless on a Raspberry Pi and is controlled entirely from a physical front panel — two rotary encoders and a status display — with no browser, screen, or companion app required.
🔒 Privacy-First: Your sessions are your business. Wavedriver runs entirely offline — no cloud dependencies, no analytics, no microphone, no camera, and no data leaving the device. See PRIVACY.md.
- 🛡️ Safety Watchdogs: Dedicated local safety layers monitor force limits, motor temperature, and connectivity, and disarm the machine immediately if any boundary is crossed. See SAFETY.md.
- 🌀 4 Motion Patterns: Wave, Realistic, Thrust, and Escalate — see below.
- 🎛️ Front-Panel Control: Two rotary encoders and an OLED status display. No screen, keyboard, or app pairing needed.
Wavedriver targets a Raspberry Pi 5 wired to the Orca 6 over RS-485, with two Adafruit I2C QT rotary encoders and a small OLED as the entire interaction surface. See BUILD_SHEET.md for the full parts list, wiring, and systemd setup.
Python 3.12+ and the task runner just.
# 1. Install dependencies
uv sync --all-extras
# 2. Launch the application
# For hardware control:
just run
# Or run in simulation/mock mode (no hardware connected):
just run-mockOn a Pi with no I2C encoders/display attached, the front panel automatically falls back to a no-op mock so the rest of the app still runs — useful for testing the motor control path before the panel is wired up.
| Pattern | Sensation Profile |
|---|---|
| Wave | Smooth, even, predictable sinusoidal movement. |
| Realistic | Asymmetric stroke modeling a physical crank mechanism. |
| Thrust | Fast forward stroke, slow retraction, brief hold. |
| Escalate | Starts gentle and builds intensity over the session. |
Everything is controlled by two knobs — no screen or companion app:
| Control | Action |
|---|---|
| Speed knob — rotate | Adjust frequency, 0.1–4.0 Hz |
| Speed knob — press | Start / stop the pattern, or clear an e-stop |
| Speed knob — long-press (1.5 s) | Re-run endpoint calibration |
| Depth knob — rotate | Adjust stroke depth, 10–100% of calibrated length |
| Depth knob — press | Cycle to the next pattern |
| E-stop button | Hardware kill switch — cuts motor power directly, independent of software |
Turning a knob while a pattern is running updates it live rather than restarting the stroke. The OLED shows the active pattern, state, speed, depth, force, and temperature at a glance.
There is no adjustable "intensity" control and no adjustable safety limit — both are fixed, non-negotiable safety constants (see SAFETY.md), not something a knob can dial past.
Wavedriver runs 12 software-level safety watchdogs locally on the controller loop, including a fixed software force limit, a hardware force limit enforced by the actuator firmware independent of software, thermal warning/shutdown thresholds, a communications watchdog, and an HMI heartbeat that soft-stops the motor if the front-panel loop ever wedges. A physical e-stop button cuts motor power directly at the hardware level, independent of any of this.
For detailed technical analysis of the safety architecture, see SAFETY.md.
If you are a developer looking to build or contribute to the project:
- Architecture: Read ARCHITECTURE.md to understand the multi-rate control loop, the HMI thread, and telemetry.
- Build Sheet: BUILD_SHEET.md has the parts list, wiring diagram, and systemd deployment steps.
- Development Commands:
- Formatting & Linting: Run
just lintandjust typecheckto analyze styles and types. - Testing: Run
just testto execute the test suite.
- Formatting & Linting: Run
- Troubleshooting: Visit TROUBLESHOOTING.md for help with installation, hardware communication, and connection issues.
- Contributing Guidelines: Review CONTRIBUTING.md.
