Commit Graph
12 Commits
Author SHA1 Message Date
cristhian a2bf59065d add dora-node.yml manifest and a service example dataflow
The manifest is the only contract a consumer has, since no source package
is shared between node repositories, and dora validate checks a dataflow
against it without running the node — so CI needs no robot.

request and response are deliberately untyped. They carry request_id, and
dora defines that as the marker for a pattern-correlated port where
several Arrow schemas legitimately flow, one per service; the runtime
skips type checks on those messages, so annotating them would claim a
contract neither side keeps.

examples/ carries its own manifest because dora resolves a node's
manifest by walking up from its path, and a manifest applies only when
<manifest dir>/<entrypoint> names the same file as the dataflow's path.
Without it the example caller would be matched against the arm node's
manifest and strict validation would fail on the entrypoint mismatch.
2026-09-12 11:47:06 -03:00
cristhian fdabf7e241 refactor node into services over the dora 1.0 contract
Replaces the command/status JSON pair with dora's own service pattern:
one request, one response, correlated by the request_id dora puts in the
message metadata. Motions take a wait flag, and their lifecycle is
published as the arm's state on motion_state rather than as a per-goal
stream — the arm is one resource, so a new motion preempts the one in
play and a state describes that exactly.

motion_state is keyed by request_id and publishes accepted before the
control thread reaches the motion. Both exist to close one race: a caller
polling a bare moving/idle flag right after its request would read "not
moving" and conclude the motion had already finished.

Three threads, because the SDK blocks. The control thread carries out one
job at a time and may block; the reporter thread only ever reads the
report cache, so telemetry keeps flowing through a ten-second move; the
stopper thread exists because a stop fits nowhere else — it must not
queue behind the motion it aborts, and emergency_stop re-commands the
controller for up to three seconds, which is far too long to stop routing
a dataflow.

The event loop never calls anything that can block, get_state included:
that one is allowed there only because it reads the cache. The node is
built before the arm threads start, so INIT_MODE cannot move a robot
before the process has joined the dataflow, and a restart leaves the arm
where it is rather than driving it home unasked. Shutdown halts the arm
first — a motion lives in the controller, and dropping the connection
does not abort it.
2026-09-12 11:46:59 -03:00
cristhian eccd9e3c24 add xArm driver layer ported from littlehand
Brings across the robot layer from monolitic-littlehand-python, which was
written against this same controller. The point of it is that a command
either moved the arm or raised: the SDK returns a code for a motion the
controller quietly refused, wait_move calls that refusal finished, and
arm.error_code is the report stream's stale copy.

So errors are read live, arrival is confirmed rather than assumed, and a
move whose straight-line path leaves the joint envelope is refused before
it is commanded. Failures are typed, because the distinctions decide the
response: an unreachable pose is not an unavailable arm, and a joint past
its limit needs a motion nobody should start without warning the room.

read_report is the deliberate exception to all of it: a report-cache read
that costs no round trip and cannot block, which is the only read that
works while a motion is in flight.
2026-09-12 11:46:54 -03:00
cristhian aguilera 69ba84e406 add markdownlint GitHub Actions workflow 2026-04-09 09:00:00 -04:00
cristhian aguileraandClaude Sonnet 4.6 a5f05ddc6f fix AGENTS.md line-length lint errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.1.3
2026-04-09 08:52:13 -04:00
cristhian aguilera 1c7654e429 add markdownlint config and fix README lint errors
Add .markdownlint.json with 120-column line limit.
Fix MD060 table separator style to match padded header rows.
2026-04-02 14:19:05 -03:00
cristhian aguilera b7aa1dd3aa add TOOL_TYPE offset to tcp_pose for vacuum and gripper
Apply Z-axis tool offset when publishing tcp_pose so the output
reflects the actual tool tip. Adds TOOL_TYPE (none/vacuum/gripper)
and TOOL_OFFSET_MM env vars with standard Lite6 accessory presets.
Bump version to 0.1.2.
v0.1.2
2026-04-02 14:07:28 -03:00
cristhian aguilera 4174d566e9 fix requires-python and pin dora-rs to 0.5.0
Bump requires-python to >=3.12 to satisfy scipy>=1.14.0.
Pin dora-rs==0.5.0 to match dora-cli 0.5.0 message format.
Bump version to 0.1.1.
v0.1.1
2026-04-02 13:27:05 -03:00
cristhian aguilera f2059e9636 refactor dataflow to run from local path
Remove git/git_checkout fields so the node runs directly
from the local checkout without fetching from remote.
2026-04-02 13:26:51 -03:00
cristhian 8333e53018 Update README.md 2026-04-01 23:42:22 +00:00
cristhian aguilera 8e3d976a17 add dora_ulite6 standalone node with command lifecycle status
Migrates the ulite6 Python dora node from dora_littlehand into a
self-contained repository following the dora-zed structure. Adds
command lifecycle state ("started"/"done"/"failed") and type
("command"/"error") to the status output so coordinator nodes can
reliably sequence robot actions without polling.
2026-04-01 08:51:19 -03:00
cristhian 19ef9c074f Initial commit 2026-04-01 08:03:25 +00:00