Feature: Accept the standard twist and command ports
User Story
As someone wiring a control surface to this arm,
I want it to accept the same ports any of our other robots would,
so that a teleop node does not have to learn this arm's units and service names.
Requirements
Accept a twist input: {linear: [x, y, z], angular: [x, y, z], frame} in SI —
metres per second and radians per second. Convert to the mm/s and deg/s the driver wants
(×1000, math.degrees) and feed it to the same path jog uses today.
Accept a command input: {action, value} with the robot-agnostic verbs gripper_close, gripper_open, stop, home, clear, freedrive. Map them onto the
existing services — gripper_close → grasp, gripper_open → release, and so on. freedrive carries 1.0/0.0 in value.
Keep jog and request working. Nothing may break while consumers move across.
Document both in dora-node.yml, untyped, with the struct written out — dora 1.0 has no
standard type for either.
Acceptance Criteria
A dataflow wiring teleop/twist to this node's twist moves the arm exactly as
wiring teleop/jog does today
All six verbs on command reach the same services request reaches
jog and request still behave as they do now, with their tests unchanged
dora validate passes with the new ports annotated
VELOCITY_COMMAND_TTL_S still governs a twist, as it does a jog — the controller
expiry is the outermost deadman layer and must not be bypassed by a new port
Notes
The contract is written up in the vault at resources/robotics/teleop-contract.md.
dora-teleop publishes both the standard and the deprecated ports as of liria/dora-teleop#2, so this can land whenever. Nothing is blocked on it.
Wire one or the other, never both.twist and jog carry the same intent, and a
dataflow wiring both would drive the arm twice.
Units are the thing to be careful with: this node speaks mm/s and deg/s, twist is m/s and
rad/s. A missed conversion is a thousandfold error, and jog has no feedback channel — a
malformed one is logged and dropped with no response, so it would surface as an arm moving
wrongly rather than as an error.
# Feature: Accept the standard `twist` and `command` ports
## User Story
As someone wiring a control surface to this arm,
I want it to accept the same ports any of our other robots would,
so that a teleop node does not have to learn this arm's units and service names.
## Requirements
- Accept a `twist` input: `{linear: [x, y, z], angular: [x, y, z], frame}` in **SI** —
metres per second and radians per second. Convert to the mm/s and deg/s the driver wants
(×1000, `math.degrees`) and feed it to the same path `jog` uses today.
- Accept a `command` input: `{action, value}` with the robot-agnostic verbs
`gripper_close`, `gripper_open`, `stop`, `home`, `clear`, `freedrive`. Map them onto the
existing services — `gripper_close` → `grasp`, `gripper_open` → `release`, and so on.
`freedrive` carries `1.0`/`0.0` in `value`.
- Keep `jog` and `request` working. Nothing may break while consumers move across.
- Document both in `dora-node.yml`, untyped, with the struct written out — dora 1.0 has no
standard type for either.
## Acceptance Criteria
- [ ] A dataflow wiring `teleop/twist` to this node's `twist` moves the arm exactly as
wiring `teleop/jog` does today
- [ ] All six verbs on `command` reach the same services `request` reaches
- [ ] `jog` and `request` still behave as they do now, with their tests unchanged
- [ ] `dora validate` passes with the new ports annotated
- [ ] `VELOCITY_COMMAND_TTL_S` still governs a `twist`, as it does a `jog` — the controller
expiry is the outermost deadman layer and must not be bypassed by a new port
## Notes
The contract is written up in the vault at `resources/robotics/teleop-contract.md`.
`dora-teleop` publishes both the standard and the deprecated ports as of
liria/dora-teleop#2, so this can land whenever. Nothing is blocked on it.
**Wire one or the other, never both.** `twist` and `jog` carry the same intent, and a
dataflow wiring both would drive the arm twice.
Units are the thing to be careful with: this node speaks mm/s and deg/s, `twist` is m/s and
rad/s. A missed conversion is a thousandfold error, and `jog` has no feedback channel — a
malformed one is logged and dropped with no response, so it would surface as an arm moving
wrongly rather than as an error.
Reopening: this was marked closed, but the ports are not implemented.
Checked against merged main (3b941e7):
dora_ulite6/main.py handles neither twist nor command — the event router knows tick, request and jog only.
dora-node.yml declares tick, request, jog as its inputs. No twist, no command.
PR #4 (the jogging fix, v0.3.1) touched driver.py and control.py only and never went
near the input ports, so it is not what completed this — it simply landed in between.
Why it matters that this looks done.liria/dora-teleop#3 — deleting the deprecated jog and request outputs — is blocked on exactly this issue. dora-teleop currently
publishes both contracts at once:
teleop ──┬── twist / command (standard) ← nothing reads these yet
└── jog / request (deprecated) ← this node reads these
That overlap is the only reason the arm moves today. If this issue reads as finished,
the next reasonable step is to remove the deprecated pair from dora-teleop — and the
arm stops receiving anything it understands.
Nothing is broken right now. This is bookkeeping, so the ordering stays visible.
Reopening: this was marked closed, but the ports are not implemented.
Checked against merged `main` (`3b941e7`):
- `dora_ulite6/main.py` handles neither `twist` nor `command` — the event router knows
`tick`, `request` and `jog` only.
- `dora-node.yml` declares `tick`, `request`, `jog` as its inputs. No `twist`, no `command`.
PR #4 (the jogging fix, v0.3.1) touched `driver.py` and `control.py` only and never went
near the input ports, so it is not what completed this — it simply landed in between.
**Why it matters that this looks done.** liria/dora-teleop#3 — deleting the deprecated
`jog` and `request` outputs — is blocked on exactly this issue. `dora-teleop` currently
publishes both contracts at once:
```
teleop ──┬── twist / command (standard) ← nothing reads these yet
└── jog / request (deprecated) ← this node reads these
```
That overlap is the only reason the arm moves today. If this issue reads as finished,
the next reasonable step is to remove the deprecated pair from `dora-teleop` — and the
arm stops receiving anything it understands.
Nothing is broken right now. This is bookkeeping, so the ordering stays visible.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Feature: Accept the standard
twistandcommandportsUser Story
As someone wiring a control surface to this arm,
I want it to accept the same ports any of our other robots would,
so that a teleop node does not have to learn this arm's units and service names.
Requirements
twistinput:{linear: [x, y, z], angular: [x, y, z], frame}in SI —metres per second and radians per second. Convert to the mm/s and deg/s the driver wants
(×1000,
math.degrees) and feed it to the same pathjoguses today.commandinput:{action, value}with the robot-agnostic verbsgripper_close,gripper_open,stop,home,clear,freedrive. Map them onto theexisting services —
gripper_close→grasp,gripper_open→release, and so on.freedrivecarries1.0/0.0invalue.jogandrequestworking. Nothing may break while consumers move across.dora-node.yml, untyped, with the struct written out — dora 1.0 has nostandard type for either.
Acceptance Criteria
teleop/twistto this node'stwistmoves the arm exactly aswiring
teleop/jogdoes todaycommandreach the same servicesrequestreachesjogandrequeststill behave as they do now, with their tests unchangeddora validatepasses with the new ports annotatedVELOCITY_COMMAND_TTL_Sstill governs atwist, as it does ajog— the controllerexpiry is the outermost deadman layer and must not be bypassed by a new port
Notes
The contract is written up in the vault at
resources/robotics/teleop-contract.md.dora-teleoppublishes both the standard and the deprecated ports as ofliria/dora-teleop#2, so this can land whenever. Nothing is blocked on it.
Wire one or the other, never both.
twistandjogcarry the same intent, and adataflow wiring both would drive the arm twice.
Units are the thing to be careful with: this node speaks mm/s and deg/s,
twistis m/s andrad/s. A missed conversion is a thousandfold error, and
joghas no feedback channel — amalformed one is logged and dropped with no response, so it would surface as an arm moving
wrongly rather than as an error.
Reopening: this was marked closed, but the ports are not implemented.
Checked against merged
main(3b941e7):dora_ulite6/main.pyhandles neithertwistnorcommand— the event router knowstick,requestandjogonly.dora-node.ymldeclarestick,request,jogas its inputs. Notwist, nocommand.PR #4 (the jogging fix, v0.3.1) touched
driver.pyandcontrol.pyonly and never wentnear the input ports, so it is not what completed this — it simply landed in between.
Why it matters that this looks done. liria/dora-teleop#3 — deleting the deprecated
jogandrequestoutputs — is blocked on exactly this issue.dora-teleopcurrentlypublishes both contracts at once:
That overlap is the only reason the arm moves today. If this issue reads as finished,
the next reasonable step is to remove the deprecated pair from
dora-teleop— and thearm stops receiving anything it understands.
Nothing is broken right now. This is bookkeeping, so the ordering stays visible.