Robonix package wrapping the AgileX Piper arm URDF + robot_state_publisher. Stand-in for system.soma (URDF + RSP), which is on robonix’s v0.2 roadmap. Until soma ships that responsibility natively, this package owns the joint-driven TF tree for the Piper arm.
driven from /arm/joint_states_single via robot_state_publisher.
This package does not publish camera hand-eye calibration. In the
current vertical-grasp deploy, grasp_pose consumes
rbnx-boot/hand-eye-data/2d_homography.npy to map RGB bbox pixels
directly into arm/base_link XY, then combines that with the configured
desktop height.
Boot ordering
This package needs to boot after piper_ctl (which publishes
/arm/joint_states_single). Without joint feedback, RSP stays quiet
on /tf and the arm appears “frozen at zero” in RViz. The deploy
manifest enforces this by listing piper_ctl before
piper_description under primitive:.
Independent of orbbec_camera; the camera stream is consumed later by
llm_detect and grasp_pose, while this package only publishes the arm TF
subtree.
Capability surface
Empty on purpose:
capabilities: []
The package registers a provider on atlas (so rbnx boot proceeds through the primitive block) but declares no routed contracts.
TF is a global ROS 2 side-channel — every tf2-aware node joins /tf + /tf_static automatically — so atlas-routing it would only add indirection. With capabilities: [], rbnx boot‘s spawn_and_init walks wait_for_registration → finds driver_contract=None → marks the package ACTIVE without trying to drive INIT / ACTIVATE.
Driver-init lifecycle
There is no Driver(CMD_INIT) handler — the package skips CMD_INIT entirely and is considered “up” the moment it registers on atlas. start.sh launches robot_state_publisher directly with the vendored Piper URDF, remapping joint_states → /arm/joint_states_single.
It is independent of primitive-agilex-piper-handeye-rbnx and primitive-orbbec-dabai_dcw-camera-rbnx; those publish disjoint data or TF subtrees.
Frame names — NOT prefixed with arm/
The vendored upstream URDF uses bare names (base_link, link1… link6). We keep the upstream names verbatim — that matches what primitive-agilex-piper-arm-rbnx actually publishes in JointState.name = ['joint1', 'joint2', ..., 'joint6', 'gripper'].
⚠️ Future moving-platform conflict: if the Piper ever sits on a Ranger Mini / mobile chassis whose own URDF also defines base_link, the two TF roots collide. Resolution then will be to fork the URDF and add a tf_prefix (e.g. arm/) to all link/joint names, AND update primitive-agilex-piper-arm-rbnx‘s JointState.name accordingly. For the current fixed-arm grasp deploy no chassis is involved, so collision is impossible.
colcon build --packages-select piper_description — installs URDF + meshes under rbnx-build/ws/install/piper_description/share/ so the URDF’s package://piper_description/meshes/... references resolve at RViz / MoveIt time. RSP itself does not need this for TF computation, but downstream visualisers do.
Config
This package has no Driver(CMD_INIT) handler, so the per-package config: block in the deploy manifest is ignored. Configuration comes from the top-level env: block instead:
Env
Meaning
PIPER_URDF_PATH
Absolute path to the URDF variant to use. Defaults to the vendored with-gripper URDF.
ROBONIX_ATLAS
Atlas gRPC endpoint. Defaults to 127.0.0.1:50051.
Example override to switch to the no-gripper variant:
The script exits if atlas is unreachable (5s RPC timeout). Once the launch is running, /tf should carry base_link → link6iffprimitive-agilex-piper-arm-rbnx is also up and publishing JointState.
Verification
rbnx caps | grep piper_description
# Expected: piper_description provider, no caps
ros2 run tf2_ros tf2_echo base_link link6
# Should report a transform that moves when you ros2 topic pub to
# /arm/pos_command or wiggle the arm by hand.
# Optional: if primitive-agilex-piper-handeye-rbnx is up too, the chain
# base_link → link6 → camera_color_optical_frame should resolve:
ros2 run tf2_ros tf2_echo base_link camera_color_optical_frame
Vendor / upstream
src/piper_description/ is a verbatim subset of agilexrobotics/piper_rossrc/piper_description/, with the following stripped (none needed for TF publishing in a robonix deploy):
launch/ — upstream launches add joint_state_publisher_gui + RViz, both inappropriate for a headless deploy.
rviz/ — display config; users who want RViz should write their own outside this package.
mujoco_model/ — sim-only; not in pipeline.
License
This package: MulanPSL-2.0. Vendored URDF + meshes inherit upstream piper_ros‘s licensing (upstream package.xml declares “TODO”; the practical assumption is the non-commercial Solidworks export defaults — consult AgileX before redistribution).
primitive-agilex-piper-description-rbnx
Robonix package wrapping the AgileX Piper arm URDF +
robot_state_publisher. Stand-in forsystem.soma(URDF + RSP), which is on robonix’s v0.2 roadmap. Until soma ships that responsibility natively, this package owns the joint-driven TF tree for the Piper arm.Catalog name:
robonix.primitive.agilex.piper.description.What this package publishes
driven from
/arm/joint_states_singleviarobot_state_publisher.This package does not publish camera hand-eye calibration. In the current vertical-grasp deploy,
grasp_poseconsumesrbnx-boot/hand-eye-data/2d_homography.npyto map RGB bbox pixels directly intoarm/base_linkXY, then combines that with the configured desktop height.Boot ordering
This package needs to boot after
piper_ctl(which publishes/arm/joint_states_single). Without joint feedback, RSP stays quiet on /tf and the arm appears “frozen at zero” in RViz. The deploy manifest enforces this by listingpiper_ctlbeforepiper_descriptionunderprimitive:.Independent of
orbbec_camera; the camera stream is consumed later byllm_detectandgrasp_pose, while this package only publishes the arm TF subtree.Capability surface
Empty on purpose:
The package registers a provider on atlas (so
rbnx bootproceeds through the primitive block) but declares no routed contracts.TF is a global ROS 2 side-channel — every tf2-aware node joins
/tf+/tf_staticautomatically — so atlas-routing it would only add indirection. Withcapabilities: [],rbnx boot‘sspawn_and_initwalkswait_for_registration→ findsdriver_contract=None→ marks the package ACTIVE without trying to drive INIT / ACTIVATE.Driver-init lifecycle
There is no
Driver(CMD_INIT)handler — the package skips CMD_INIT entirely and is considered “up” the moment it registers on atlas.start.shlaunchesrobot_state_publisherdirectly with the vendored Piper URDF, remappingjoint_states → /arm/joint_states_single.It is independent of
primitive-agilex-piper-handeye-rbnxandprimitive-orbbec-dabai_dcw-camera-rbnx; those publish disjoint data or TF subtrees.Frame names — NOT prefixed with
arm/The vendored upstream URDF uses bare names (
base_link,link1…link6). We keep the upstream names verbatim — that matches whatprimitive-agilex-piper-arm-rbnxactually publishes inJointState.name = ['joint1', 'joint2', ..., 'joint6', 'gripper'].Layout
Build
scripts/build.shdoes two things, both fast:rbnx codegen— generatesatlas_pb2 / atlas_pb2_grpcPython stubs forscripts/atlas_register_and_launch.py.colcon build --packages-select piper_description— installs URDF + meshes underrbnx-build/ws/install/piper_description/share/so the URDF’spackage://piper_description/meshes/...references resolve at RViz / MoveIt time. RSP itself does not need this for TF computation, but downstream visualisers do.Config
This package has no
Driver(CMD_INIT)handler, so the per-packageconfig:block in the deploy manifest is ignored. Configuration comes from the top-levelenv:block instead:PIPER_URDF_PATHROBONIX_ATLAS127.0.0.1:50051.Example override to switch to the no-gripper variant:
Choosing the URDF variant
piper_description.urdf(default)gripper_exist: truein piper_ctl config (skill-pick-rbnxuses gripper)piper_no_gripper_description.urdfgripper_exist: false(rare; manual EE swap)Override via
PIPER_URDF_PATH, or by editingatlas_register_and_launch.py::_resolve_urdf_path.Run standalone
The script exits if atlas is unreachable (5s RPC timeout). Once the launch is running,
/tfshould carrybase_link → link6iffprimitive-agilex-piper-arm-rbnxis also up and publishing JointState.Verification
Vendor / upstream
src/piper_description/is a verbatim subset of agilexrobotics/piper_rossrc/piper_description/, with the following stripped (none needed for TF publishing in a robonix deploy):launch/— upstream launches addjoint_state_publisher_gui+ RViz, both inappropriate for a headless deploy.rviz/— display config; users who want RViz should write their own outside this package.mujoco_model/— sim-only; not in pipeline.License
This package: MulanPSL-2.0. Vendored URDF + meshes inherit upstream
piper_ros‘s licensing (upstreampackage.xmldeclares “TODO”; the practical assumption is the non-commercial Solidworks export defaults — consult AgileX before redistribution).