How it works¶
Myo armband ──BLE──► myo_lsl_publisher.py ──LSL──► Myo_EMG (8 ch, 200 Hz) + Myo_IMU (10 ch, 50 Hz)
│
▼
myo_gestures.py drive --mode lever
IMU → arm angle → speed and steering
EMG → 16 features → LDA: fist or not → brake
lidar → slow before obstacles, gate nudge
│ (v, w) at 20 Hz
▼
jackal-bridge ──WebSocket──► browser sim (scores every run)
Signals¶
| Signal | What we compute | Drives |
|---|---|---|
| Tilt (accelerometer, 50 Hz) | Forearm height and roll from gravity, never yaw, so it does not drift | Speed, steering, reverse |
| Muscle (8 EMG channels, 200 Hz) | Log RMS and log waveform length per channel, 200 ms windows | Brake only |
| Brake classifier | Your fist against your other poses, by linear discriminant analysis (yours, or a pooled model), plus an EMG level near your calibrated fist | Brake after a fist held 0.4 s |
| Lidar (from the sim) | Free space ahead and beside the robot | Slow down, nudge off walls |
Why the motion sensor steers¶
We started with five EMG gestures classified by LDA. On still poses it read 99 % of windows correctly. Hold a fist with the forearm rolled, which is what you do while steering, and it read 38 % correctly: rolling the arm moves the muscles under the electrodes. So the band's tilt sets speed and steering, and EMG decides only the brake.
Calibration¶
myo_gestures.py record prompts six poses (GO, STOP, LEFT, RIGHT, REVERSE, BRAKE), each held for 2, 3
and 5 s, and saves every take as CSV. The arm axes are learned from those takes, so the band works
whichever way it is worn. Each drive starts by checking the straight pose still fits; if the band has
moved, it refuses to start.
Assists¶
- Lidar assist: slows before obstacles and keeps the robot off walls.
- Gate assist (Xinyi): when you are already aimed within 20° of a gate, it steers toward the gate's
centre by at most 0.3 rad/s. It never picks a gate for you;
--no-gateswitches it off. - Lag compensation: measures the command lag from the sim's echoes and drives the assist from the predicted pose. It switches on by itself when the link is slow.
Logs¶
Every drive writes drives/drive_*.csv: one row per 20 Hz command, with the arm angles, the EMG
features, the command sent and course progress.
Code: lever.py, myo_gestures.py, armdrive.py and gestures.py in
examples/. Tests: pytest examples/tests.