| Name | Size | Uploaded | Xet hash |
|---|---|---|---|
| __pycache__ | 8 items | ||
| airmouse_go_new | 10,095 items | ||
| airmouse_server | 24 items | ||
| docs | 1 items | ||
| .DS_Store | 6.15 kB xet | fd15c753 | |
| Proximity-Aware_Connectivity.md | 20.7 kB xet | 7d1e22ba | |
| README.md | 8.88 kB xet | 0e3e17d2 | |
| Structure.md | 1.89 kB xet | 1ac44c32 | |
| airmouse-mcp-go | 11 MB xet | 637832e1 | |
| airmouse.log | 2.01 kB xet | 5d69d8f7 | |
| config.json | 432 Bytes xet | e9d6a265 | |
| perfetto_analyzer.py | 16.2 kB xet | 78804b00 | |
| perfetto_queries.sql | 970 Bytes xet | 0857dbc3 | |
| requirements.txt | 266 Bytes xet | 801bf4de | |
| run.bat | 97 Bytes xet | b2ed74aa | |
| run.py | 133 Bytes xet | 63878e81 | |
| run.sh | 57 Bytes xet | 12f5c618 | |
| server.py | 6.93 kB xet | a99842b4 |
Air Mouse – Embedded Systems Exercise
University of Tehran, Faculty of Electrical and Computer Engineering
Second Semester 1404-1405 (2025-2026)
Project Overview
An Air Mouse that uses an Android smartphone’s sensors to control a computer’s mouse cursor.
The system consists of three main components:
- Android App – reads and fuses sensor data, detects gestures, and sends commands over TCP.
- PC Server (Python / Go) – receives commands, moves the mouse cursor, and sends ACK responses.
- Perfetto Trace Analysis – profiles the Android app for performance evaluation.
All communication follows a standardised JSON‑line protocol over TCP, with UDP used only for auto‑discovery and mDNS for effortless pairing.
🎯 Exercise Requirements (All Implemented)
| Requirement | Implementation |
|---|---|
| Calibration UI (gyro, accel, magnetometer) | CalibrationActivity with 3 tabs, animated phone orientations, timer, back/next/stop |
| Sensor fusion (Madgwick AHRS) | SensorFusion.kt – hand‑written, no external libraries |
| Cursor movement (Z/X axes) | Euler angles → dx,dy via GestureDetector.kt |
| Click detection (Y‑axis quick rotation) | Angular velocity threshold + cooldown |
| Scroll detection (Y‑axis linear movement) | TYPE_LINEAR_ACCELERATION → threshold + cooldown |
| Visual indicator (green square) | fragment_home.xml → orientationIndicator |
| Click/scroll feedback | Flashing label in HomeFragment |
TCP with JSON (DeltaX, DeltaY, Click, Scroll) |
DataSender.kt → PC server |
| ACK & retransmission | Client retries up to 3 times if no ACK within 500ms |
| Auto‑reconnect | AutoReconnect.kt |
| QR code pairing | zxing scanner + QR generation in PC server |
| UDP discovery | UdpDiscoveryClient.kt + server’s udp_discovery.py / server/udp.go |
| mDNS (Bonjour) | server/mdns.go (fixed) |
| Perfetto tracing | Tracepoints in sensor callback, filter, network send |
| Perfetto analysis | perfetto_analyzer.py answers all 11 questions |
| Adaptive app icon | mipmap-anydpi-v26/ic_launcher.xml with foreground/background vectors |
📡 Communication Protocol
Transport
- TCP port
8080– all mouse commands (reliable, ordered). - UDP port
8081– only for discovery broadcast (no reply needed for movement).
Message Format
Every message is a single JSON line terminated by \n.
Client → Server
| Type | Fields | Description |
|---|---|---|
move |
dx (float), dy (float) |
Mouse displacement (no ACK required) |
click |
id (int) |
Left click (ACK expected) |
doubleclick |
id (int) |
Double click (ACK expected) |
rightclick |
id (int) |
Right click (ACK expected) |
scroll |
delta (int), id (int) |
Scroll amount (positive = up) |
hello |
name (string) |
Device identification on connect |
Server → Client
| Type | Fields | Description |
|---|---|---|
ack |
id (int) |
Acknowledges a click/scroll |
ACK & Retransmission
- The client stores every
click/scrollmessage in aPendingCommandmap. - If no
ackwith matchingidarrives within 500ms, the message is resent up to 3 times. movemessages are fire‑and‑forget – they are dropped if the network is congested.
📁 Project Structure
code/
├── android/ # Android Studio project (Kotlin)
│ ├── app/src/main/java/com/airmouse/
│ │ ├── ui/ # Activities & fragments
│ │ ├── network/ # DataSender, AutoReconnect, UdpDiscoveryClient
│ │ ├── sensors/ # SensorFusion, CalibrationManager, GestureDetector
│ │ ├── calibration/ # CalibrationPagerAdapter, step fragments
│ │ └── utils/ # LogManager, PreferencesManager, ValidationUtils
│ └── ... # layouts, drawables, manifest, etc.
├── pc/ # PC server (Python)
│ ├── airmouse_server/ # Modular server package
│ │ ├── config.py
│ │ ├── mouse_controller.py
│ │ ├── tcp_server.py
│ │ ├── udp_discovery.py
│ │ ├── mdns_advertiser.py
│ │ ├── qr_manager.py
│ │ ├── tray_manager.py
│ │ ├── notification_manager.py
│ │ ├── performance_monitor.py
│ │ └── gui.py
│ └── run.py
├── pc/airmouse-go/ # PC server (Go)
│ ├── config/
│ ├── control/ # MouseController interface + darwin/other implementations
│ ├── server/ # tcp.go, udp.go, mdns.go
│ ├── ui/ # app.go (Fyne multi‑tab GUI)
│ ├── main.go
│ └── go.mod / go.sum
└── profiling/ # Perfetto config & analysis
├── config.pbtx
└── perfetto_analyzer.py
🔧 Calibration System
Gyroscope
- Keep the phone perfectly still on a flat surface.
- Press Start – 100 samples are collected.
- The mean bias is computed and subtracted from all future readings.
Accelerometer (6‑position)
- The user is guided through 6 orientations with an animated phone graphic.
- For each position, 100 samples are collected.
- Offsets and scale factors are calculated so that gravity reads exactly 9.81 m/s².
Magnetometer (hard‑iron)
- The user moves the phone in a figure‑8 pattern until 200 samples are collected.
- Min/max per axis are used to compute hard‑iron offset and soft‑iron scale.
All calibration data is saved in SharedPreferences and applied before sensor fusion.
⚙️ Sensor Fusion & Gestures
- Madgwick AHRS fuses gyroscope, accelerometer, and magnetometer to produce a drift‑free orientation.
- Euler angles (pitch, roll, yaw) are extracted from the quaternion.
- Gesture mapping:
- Horizontal movement ← pitch (Z‑axis rotation)
- Vertical movement ← roll (X‑axis rotation)
- Click ← quick yaw left (angular velocity > threshold)
- Scroll ← rapid linear acceleration along Y‑axis
All thresholds and the sensitivity multiplier (0.2–2.0) are configurable in the app or in the PC server.
🖥️ PC Server (Python / Go)
Python Server
- Professional dark‑mode GUI built with
tkinter. - QR code generation, live log, client list, tray icon, etc.
- Run:
cd pc && pip install -r requirements.txt && python run.py
Go Server
- Beautiful multi‑tab GUI built with Fyne (Dashboard, Network, Clients, Settings, Logs).
- Statically linked binary – no runtime dependencies.
- Cross‑platform (Windows, macOS, Linux) thanks to platform‑specific mouse controllers.
- Run:
cd pc/airmouse-go && go run .
Both servers implement the same protocol, so you can use either one with the Android app.
📱 Android App
Key Features
- Home screen: IP/port entry, QR scan button, device name, sensitivity slider.
- Calibration wizard: step‑by‑step with visual animations.
- Live log: in‑app and full‑screen view with filtering.
- Auto‑reconnect: seamless recovery after network disruptions.
- ACK/retransmission: reliable delivery of clicks and scrolls.
Build & Install
- Open
android/in Android Studio. - Ensure
gradle.propertieshasandroid.useAndroidX=true. - Build APK:
./gradlew assembleDebug - Install on device:
adb install -r app/build/outputs/apk/debug/app-debug.apk
📊 Profiling (Perfetto)
- Record a trace while using the app:
python record_android_trace -o trace_file.perfetto-trace -t 15s sched freq idle wm gfx view - Run the analysis script:
python profiling/perfetto_analyzer.py trace_file.perfetto-trace - The script outputs answers to all 11 required questions, including average filter CPU time, sampling period, thread contention, and end‑to‑end latency.
🧪 Testing
Go Server
cd pc/airmouse-go
go test ./...
Android
- Manual testing on a physical device (API 29+).
- UI test (
CalibrationUITest.kt) can be added to verify calibration workflow.
📦 Deliverables
CPS-CA2-<SID1>-<SID2>-<SID3>-<SID4>.zip- Source code (Android + PC server + profiling tools)
- APK file
- Perfetto trace and analysis results
- Report (with screenshots and answers to all questions)
- Short video (≤5 min) showing phone and laptop simultaneously
👥 Authors
- Arian Firoozi
- Arsalan Talaee
- (Your group members)
Supervised by Dr. Mohsen Shokri and Dr. Mehdi Kargahi.
- Total size
- 5.54 GB
- Files
- 51,854
- Last updated
- Sep 12
- Pre-warmed CDN
- US EU US EU