add a probe that shows what the gamepad is doing
validate / validate (pull_request) Failing after 58m47s
validate / test (pull_request) Successful in 58m48s
validate / markdownlint (pull_request) Successful in 58m43s

The axis and button indices in mapping.py are SDL's documented layout rather
than an observed one, and until now the only way to find a pad that numbers
things differently was to watch a real arm move the wrong way.

`dora-teleop-probe` prints the raw axes, the buttons it sees and the velocity
that would be sent, live, with no dataflow and no arm — it cannot move anything.
It goes through the same Gamepad and velocity() the node runs, so what it prints
is what the arm would get; that is the whole reason it is worth having, and the
reason it must not grow its own copy of the mapping.

Every axis is listed, including ones the layout does not use, because an axis
marked unused that moves when a stick is pushed is exactly the finding this is
for. The centred bar makes a worn stick that does not return to zero obvious.
This commit is contained in:
2026-09-15 15:47:36 -05:00
parent 7250396a1f
commit 8a7bfb02e0
5 changed files with 262 additions and 2 deletions
+41 -1
View File
@@ -38,6 +38,46 @@ somebody can read.
`home` is deliberately **not** on the pad. It is a large unattended motion and belongs
behind a deliberate click, not a thumb resting on a face button.
### Checking your pad
```bash
uv run dora-teleop-probe
```
Prints the raw axes, the buttons it sees, and the velocity this node would send — live,
with no dataflow and no arm. **It cannot move anything.** There is no dora node and no
connection to the robot; it only reads.
```text
axes (6 reported)
0 left stick X +0.600 ----------|-----#----
1 left stick Y -0.800 --#-------|----------
2 left trigger -1.000 #---------|----------
...
buttons (6 reported)
5:yaw right
velocity this would send to the arm
vx +38.89 mm/s forward / back <--
vy +23.53 mm/s left / right <--
vz +20.39 mm/s up / down <--
wz +30.00 deg/s yaw <--
moving: yes
```
Run this before trusting the table above. The indices are SDL's documented layout, not
observed ones, and a pad that numbers its axes differently is much better found here than
by watching an arm move the wrong way. Two things to look for:
- **Every axis is listed, including ones the layout does not use** — an axis marked
`unused` that moves when you push a stick means the layout needs changing.
- **A bar that does not sit centred with the stick released** is a worn pad announcing
itself, and a reason to raise `DEADZONE`.
It goes through the same `Gamepad` and `velocity()` the node runs, so what it prints is
what the arm would be sent.
## The lease
Two sources, one arm. Whoever holds the lease drives; the other is ignored.
@@ -143,7 +183,7 @@ gamepad if you want one — the node starts without and says so.
```bash
uv sync --group dev
uv run pytest # 66 tests, no gamepad, arm, browser or daemon needed
uv run pytest # 76 tests, no gamepad, arm, browser or daemon needed
uv run ruff check .
uv run ruff format --check .
```