https://github.com/matiaspalmac/everything-imu-mobile
Turn an Android phone or Wear OS watch into full-body SlimeVR trackers — stream the built-in IMU over Wi-Fi, forward paired controllers, and feel haptics back.
https://github.com/matiaspalmac/everything-imu-mobile
android fbt full-body-tracking haptics imu jetpack-compose kotlin osc rust sensor-fusion slimevr vr vrchat wear-os
Last synced: 23 days ago
JSON representation
Turn an Android phone or Wear OS watch into full-body SlimeVR trackers — stream the built-in IMU over Wi-Fi, forward paired controllers, and feel haptics back.
- Host: GitHub
- URL: https://github.com/matiaspalmac/everything-imu-mobile
- Owner: matiaspalmac
- License: mit
- Created: 2026-06-03T23:27:37.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-20T08:44:52.000Z (about 1 month ago)
- Last Synced: 2026-06-20T10:12:03.677Z (about 1 month ago)
- Topics: android, fbt, full-body-tracking, haptics, imu, jetpack-compose, kotlin, osc, rust, sensor-fusion, slimevr, vr, vrchat, wear-os
- Language: Kotlin
- Size: 521 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
No extra hardware: the device's own IMU is streamed to the eimu desktop app
over Wi-Fi, and haptics are sent back to the device's vibration motor.
Companion to the desktop [**everything-imu**](https://github.com/matiaspalmac/everything-imu)
bridge, which turns game controllers into trackers. This repo is the mobile half.
---
## Features
**Phone tracker**
- Streams the phone's raw IMU to the eimu desktop app over UDP, which runs
sensor fusion and registers the phone as a tracker — one place for all your
devices, mounting, and calibration.
- **Auto-discover**: one tap finds the desktop on your LAN and connects — no
IP typing.
- Live link health in the header: connection state, endpoint, and **round-trip
time**; the desktop measures real packet loss from sequence numbers.
- Configurable send rate up to 400 Hz with a live *streaming / sensor*
readout, magnetometer toggle, and shake-to-recenter — applied live, no
restart.
- Magnetometer figure-8 calibration wizard + automatic gyro-bias estimation.
- Battery level reported to the desktop; notification quick actions for
**Recenter** and **Stop**.
- Foreground service with wake + Wi-Fi locks, plus an OEM battery-optimization
helper so aggressive power managers don't kill tracking.
- Auto-reconnect on Wi-Fi changes.
- EN / ES localization.
**Controller forwarding**
- Forwards BLE controllers paired to the phone as **additional trackers**:
Joy-Con 2, Switch 2 Pro Controller, and HOPX BLE pucks. Scan, tap connect,
and they appear in the desktop device list.
- Forwards **regular paired gamepads** too (Android 12+): DualSense,
DualShock 4, Joy-Con 1, Pro Controller, and any pad whose motion sensors
the system exposes — read through Android's InputDevice sensor API, with
battery and rumble. Pair in system Bluetooth settings and they stream
automatically while connected to the desktop.
- Hub roles: phone + gamepads, phone only, or gamepads only.
**Haptics**
- Desktop-initiated rumble flows to the phone's vibration motor and to
forwarded controllers; every pulse shows in the haptics log.
- VRChat OSC → device vibration bridge (UDP `9001`).
**Wear OS companion**
- Runs standalone — the watch streams its own IMU as an independent tracker.
- Auto-syncs the desktop address from the phone over the Wearable Data Layer,
or set the IP directly on the watch with a rotary/swipe wheel picker (works on
AOSP / de-Googled watches with no Play Services — no keyboard, no companion).
---
## Install
Download the latest APKs from [**Releases**](https://github.com/matiaspalmac/everything-imu-mobile/releases/latest):
- `everything-imu-phone-.apk` — the phone tracker.
- `everything-imu-wear-.apk` — the Wear OS companion (optional).
Release APKs are signed. If you previously installed an unsigned build, uninstall
it first — Android refuses an in-place upgrade when the signing key changes.
### Quick start
1. Install the phone APK, open it, grant sensor + notification permissions.
2. With the eimu desktop app running on your PC, tap **Auto-discover** — the
app finds it and connects (or type the PC's IP manually).
3. Mount the phone on your body; calibrate; assign the tracker in SlimeVR.
---
## Build from source
### Native fusion core (Rust)
```sh
cargo build # host build
cargo test
```
### Android apps
Requires JDK 17, the Android SDK, an Android NDK, and `cargo-ndk` for the native
core:
```sh
cargo install cargo-ndk
cd mobile
./gradlew :app-mobile:assembleDebug :app-wear:assembleDebug
```
APKs land in `mobile/app-*/build/outputs/apk/`. The Gradle build cross-compiles
the Rust core into `mobile/core/src/main/jniLibs/` automatically.
---
## Release signing
To produce signed release APKs you need a keystore.
```sh
keytool -genkey -v -keystore release.keystore -alias eimu \
-keyalg RSA -keysize 2048 -validity 10000
```
**Local builds** — copy `mobile/keystore.properties.example` to
`mobile/keystore.properties` and fill in your store/key passwords. Both files are
gitignored.
**CI builds** — set these repository secrets (the release workflow signs with
them automatically; without them it builds unsigned):
| Secret | Value |
|--------|-------|
| `ANDROID_RELEASE_KEYSTORE_B64` | `base64 -w0 release.keystore` |
| `ANDROID_RELEASE_KEYSTORE_PASSWORD` | store password |
| `ANDROID_RELEASE_KEY_ALIAS` | key alias (`eimu`) |
| `ANDROID_RELEASE_KEY_PASSWORD` | key password |
Tag a commit `v*` to build, sign, and attach phone + wear APKs to a draft
release.
---
## Repository layout
```
crates/
imu-math/ shared math primitives
imu-fusion/ VQF / Madgwick orientation fusion (native core)
jni-android/ JNI cdylib bridging the core to the Android apps
mobile/
app-mobile/ phone app
app-wear/ Wear OS app
core/ shared Android library (consumes the native .so)
```
The `imu-math` / `imu-fusion` crates are shared with the desktop project and
kept in sync manually — they change rarely.
## License
[MIT](LICENSE). Contributions are accepted under the same license.