135 lines
5.5 KiB
YAML
135 lines
5.5 KiB
YAML
# Node manifest: the typed contract a consumer wires against.
|
|
#
|
|
# No source package is shared between node repositories, so this file and its
|
|
# type URNs are the only contract a consumer has. `dora validate` checks a
|
|
# dataflow against it without running the node, so CI needs no robot.
|
|
#
|
|
# The `request` and `response` ports are deliberately **untyped**. They carry
|
|
# dora's pattern-correlation metadata (`request_id`), and dora defines that as
|
|
# the marker for a port where several Arrow schemas legitimately flow — one per
|
|
# service — distinguished by metadata rather than by a fixed Arrow type. The
|
|
# runtime skips type checks on such messages, so annotating them would claim a
|
|
# contract neither side keeps.
|
|
apiVersion: 1
|
|
name: dora-ulite6
|
|
namespace: liria
|
|
description: UFactory Lite6 arm node serving motion and control services, and publishing joint and tool pose
|
|
categories: [robot, actuator]
|
|
keywords: [ufactory, lite6, xarm, robot-arm, manipulator, service, vacuum, gripper]
|
|
|
|
runtime: python
|
|
entrypoint: dora-ulite6
|
|
# `dora build --uv` / `dora run --uv` rewrites this to `uv pip install .` and
|
|
# gives the node its own managed venv under `.dora/python-envs/`, so the
|
|
# dependencies it sees at runtime are the ones installed here.
|
|
build: pip install .
|
|
dora: ">=1.0"
|
|
|
|
inputs:
|
|
tick:
|
|
type: std/core/v1/UInt64
|
|
required: true
|
|
description: >-
|
|
Each tick publishes whatever the arm threads produced since the last one.
|
|
It does not drive the arm — the tick rate is the publication rate, and
|
|
TELEMETRY_INTERVAL_MS is how often the arm is actually read. Connect to
|
|
dora/timer/millis/N.
|
|
request:
|
|
required: true
|
|
description: >-
|
|
A service request: a one-row struct {service, ...arguments}, with the
|
|
caller's `request_id` in the metadata. Services: move_to, move_joints,
|
|
home, home_and_clear, clear, recover, stop, freedrive, grasp, release,
|
|
get_state. Answered on `response` under the same request_id, exactly once.
|
|
A motion takes `wait`: true (the default) holds the caller until the arm
|
|
stops; false answers at once with an acknowledgement and reports the rest
|
|
on `motion_state`.
|
|
jog:
|
|
required: false
|
|
description: >-
|
|
A continuous velocity command: a one-row struct {velocity} of 6 numbers
|
|
[vx, vy, vz, wx, wy, wz] in mm/s and deg/s. A topic rather than a service
|
|
because a sender keeps sending and nothing is published in answer. It
|
|
drives the arm, so the first non-zero one preempts a motion in play and
|
|
robot_state turns to moving.
|
|
|
|
The velocity is set on the controller once and held: an unchanged one is
|
|
not sent to the arm again, because re-arming it makes the controller
|
|
re-plan the same motion and the arm step rather than travel. A sender that
|
|
goes quiet for longer than VELOCITY_COMMAND_TTL_S is stopped by this node,
|
|
which is the deadman behind a sender that dies mid-jog.
|
|
|
|
outputs:
|
|
response:
|
|
description: >-
|
|
The answer to one service request, under its `request_id`: a struct
|
|
{ok, service, message, ...extras}. get_state adds connected, ready,
|
|
tool_engaged, freedrive, pose and joints. Exactly one response per
|
|
request, including for one that was refused or preempted.
|
|
motion_state:
|
|
description: >-
|
|
Where the current motion stands, published on every change: a struct
|
|
{request_id, service, state, message} with state one of accepted, moving,
|
|
done, failed, preempted. The request_id is in the fields rather than the
|
|
metadata because this is the arm's state, not an answer to a request. A
|
|
new motion preempts the one in play, so there is only ever one.
|
|
joint_pose:
|
|
type: std/core/v1/Float32
|
|
description: The six joint angles in degrees, base to wrist.
|
|
tcp_pose:
|
|
type: std/core/v1/Float32
|
|
description: >-
|
|
The mounted tool's tip as [x, y, z, roll, pitch, yaw] in mm and degrees,
|
|
in the robot base frame. With TOOL_TYPE none this is the flange itself.
|
|
robot_state:
|
|
type: std/core/v1/String
|
|
description: >-
|
|
One of connecting, ready, moving, recovering, unavailable. Published on
|
|
every change, never repeated.
|
|
|
|
env:
|
|
ROBOT_IP:
|
|
type: string
|
|
description: Controller address. Defaults to 192.168.1.192.
|
|
TOOL_TYPE:
|
|
type: string
|
|
description: What is mounted at the flange - none, vacuum or gripper. Defaults to none.
|
|
TOOL_OFFSET_MM:
|
|
type: float
|
|
description: Extra reach past the flange, added to the mounted tool's own. Defaults to 0.
|
|
DEFAULT_SPEED:
|
|
type: float
|
|
description: Cartesian speed in mm/s for a move_to with no speed of its own. Defaults to 30.
|
|
DEFAULT_JOINT_SPEED:
|
|
type: float
|
|
description: Joint speed in deg/s for a move_joints with no speed of its own. Defaults to 20.
|
|
TELEMETRY_INTERVAL_MS:
|
|
type: int
|
|
description: >-
|
|
How often the reporter reads the arm, and so how often telemetry is
|
|
produced. Keeps running through a motion. Defaults to 100.
|
|
RECONNECT_INTERVAL_S:
|
|
type: float
|
|
description: How long to wait before trying an unreachable arm again. Defaults to 5.
|
|
INIT_MODE:
|
|
type: string
|
|
description: Where the arm goes on startup - none, home or pose. Defaults to none.
|
|
|
|
example: |
|
|
- id: ulite6
|
|
git: ssh://git@gitea.liria.cl:5001/liria/dora-ulite6.git
|
|
tag: v0.3.1
|
|
build: pip install .
|
|
path: dora-ulite6
|
|
inputs:
|
|
tick: dora/timer/millis/100
|
|
request: planner/request
|
|
outputs:
|
|
- response
|
|
- joint_pose
|
|
- tcp_pose
|
|
- robot_state
|
|
env:
|
|
ROBOT_IP: "192.168.1.192"
|
|
TOOL_TYPE: "vacuum"
|